Reputation: 1418
In matlab, it's straightforward to get and set the position of an existing axes on the figure:
pos = get(gca(), 'position')
set(gca(), 'position', pos)
How do I do this in matplotlib?
I need this for two related reasons:
These are the specific problems I'm trying to solve:
I have a column of subplots where some have colorbars and some don't, and they aren't the same width i.e. the X axes don't align. The colorbar steals space from the axes. This also happens in matlab, and there, I'd use the above trick to make all the axes equally wide by copying the width from an axes with a colorbar to those without.
Add space between individual subplots by shrinking an axes. The adjust_subplots()
function adjusts all subplots the same.
Upvotes: 27
Views: 89030
Reputation: 23041
get_position()
or _position
gets the position of ax
; set_position()
sets an existing ax
at a new position on the figure.
However, for many cases, it may be better to add a new axes at a specific position on the figure, in which case, add_axes()
may be useful. It allows a very flexible way to add an axes (and a plot) to an existing figure. For example, in the following code, a line plot (which is drawn on ax2
) is superimposed on a scatter plot (which is drawn on ax1
)
import matplotlib.pyplot as plt
x = range(10)
fig, ax1 = plt.subplots()
ax1.scatter(x, x)
# get positional data of the current axes
l, b, w, h = ax1.get_position().bounds
# add new axes on the figure at a specific location
ax2 = fig.add_axes([l+w*0.6, b+h/10, w/3, h/3])
# plot on the new axes
ax2.plot(x, x);
The very same figure can be made using pyplot as follows.
plt.scatter(x, x)
l, b, w, h = plt.gca()._position.bounds
plt.gcf().add_axes([l+w*0.6, b+h/10, w/3, h/3])
plt.plot(x, x);
add_axes
is especially useful for OP's specific problem of colorbar "stealing" space from the axes; because instead of changing the position of the axes itself, it allows to add another axes next to it which can be used to draw the colorbar.1
import matplotlib.pyplot as plt
data = [[0, 1, 2], [2, 0, 1]]
fig, (ax1, ax2) = plt.subplots(1, 2)
ax1.imshow(data) # without colorbar
im = ax2.imshow(data) # with colorbar
l, b, w, h = ax2.get_position().bounds # get position of `ax2`
cax = fig.add_axes([l + w + 0.03, b, 0.03, h]) # add colorbar's axes next to `ax2`
fig.colorbar(im, cax=cax)
As you can see, both axes have the same dimensions.
1: This is based on my answer to another Stack Overflow question.
Upvotes: 2
Reputation: 13610
Setting axes position is similar in Matplotlib. You can use the get_position and set_position methods of the axes.
import matplotlib.pyplot as plt
ax = plt.subplot(111)
pos1 = ax.get_position() # get the original position
pos2 = [pos1.x0 + 0.3, pos1.y0 + 0.3, pos1.width / 2.0, pos1.height / 2.0]
ax.set_position(pos2) # set a new position
You might also want to take a look at GridSpec if you haven't already.
Upvotes: 60