'Preserve padding while setting an axis limit in matplotlib
Setting xlim and ylim for axis in pyplot removes the padding. How to set them without changing the padding?
Example:
fig, ax = plt.subplots()
x = np.linspace(0, 200, 500)
ax.set_ylim(ymax=100)
line = ax.plot(x, data, '--', linewidth=2, label='foo bar')
plt.show()
In the plot shown, x axis will have a padding while y axis don't. How to make them both have padding while having the ylim I want?
Solution 1:[1]
Axes.set_ymargin
and Axes.set_ylim
are mutually exclusive. Setting a limit to an axis overwrites the margin.
There are two options to have a margin (padding).
a. use margins
It's possible to adapt the margin using
ax.set_ymargin(0.1) or ax.margins(y=0.1)
where 0.1
would be a 10% margin on both axis ends. (Same for x
axis of course). The drawback here is that the margin is always symmetric.
b. use limits
Using the limits set by ax.set_ylim(0, 100)
and adapt them to the needs.
E.g. if data
is the data to plot in form of a numpy array, and we want to have a 10% margin to the bottom and a 40% margin to the top, we could use
ymin = data.min()-0.1*(data.max()-data.min())
ymax = data.max()+0.4*(data.max()-data.min())
ax.set_ylim((ymin, ymax))
It would of course equally be possible to simply set ymax to ymax = 100
, if this is desired.
Solution 2:[2]
With matplotlib 3.5, I used autoscaling as follows;
axs[row,column].plot(divs['Dividends'], c='red',linewidth=1, marker='.', mec='blue',mfc='blue')
axs[row,column].set_ylim(bottom = 0)
axs[row,column].autoscale()
Solved this problem for me. See attached pics of the graphs for the difference autoscaling did.
Using .margins() with a value or 'tight=True' or .set_ymargin() didn't seem to do anything no matter what values I used to pad.
Changing the lower or bottom limit to <0 moved the Zero line well up the y axis when dividends in my examples are close to zero.
Solution 3:[3]
You can modify the ax.dataLim
bounding box and reapply ax.autoscale_view()
Before:
fig, ax = plt.subplots()
x = np.linspace(0, 10, 11)
line = ax.plot(x, x, '--', linewidth=2, label='foo bar')
After:
pts = ax.dataLim.get_points() # numpy array [[xmin, ymin], [xmax, ymax]]
pts[1, 1] = 11 # new ymax
ax.dataLim.set_points(pts)
ax.autoscale_view()
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Community |
Solution 2 | LennyB |
Solution 3 |