0

Very simple and stupid question, which I could not find answer for; when I do manual axis positioning, like so:

fig = plt.figure(figsize=(17.5,8.0))
left = 0.1
bottom = 0.03
width = 0.3
height = 0.6
ax1 = plt.axes([left, bottom, width, height])
left += (width+0.12)
ax2 = plt.axes([left, bottom, width, height])

these left, bottom, width, height variables are set in the units relative to the figure size, but which corresponds to which: is left and width ~ horizontal fig_size while bottom and height ~ vertical fig_size? My experimenting with this disproves this, and it is not clear at all, as it seems to depend on the vertical and horizontal components of the figsize... Shouldn't i say that matplotlib documentation is very unclear about it as well (neither plt.axes, nor fig.add_axes provide any useful info). So, please help?!

EDIT: I'll post my findings here, as maybe it would be helpful for others too... First of all, it seems now, that I was correct in the first place (as answers and comments confirm) and indeed left and width is measured in horizontal-fig_size units, while bottom and height is measured vertical-fig_size units - and everything is exactly the way it is shown in the first answer.

However, it is context dependent(!), in case you're doing plt.imshow downstream - this seems to overwrite width, height ratio and create square axes (for my data, as I have n by n matrix) with the size of min(width, height). I didn't know about this behavior of the imshow.

Examples:

left = 0.1 bottom = 0.03 width = 0.3 height = 0.3 with imshow: <code>left = 0.1 bottom = 0.03 width = 0.3 height = 0.3</code> with <code>imshow</code>

left = 0.1 bottom = 0.03 width = 0.3 height = 0.3 without imshow or any other content:

<code>left = 0.1 bottom = 0.03 width = 0.3 height = 0.3</code> without <code>imshow</code> or any other content So the imshow was the source of the confusion and the "disproval".

sergpolly
  • 112
  • 8
  • You're correct in that the arguments to `plt.axes` are in relative figure coordinates. Why do you think that your example disproves this? – David Zwicker Jul 28 '14 at 16:00
  • For the `imshow` problem, try adding the keyword `aspect='auto'` to `imshow`. Then it does not do anything special to try to keep the pixels square. See this: http://stackoverflow.com/questions/13384653/imshow-extent-and-aspect – DrV Jul 28 '14 at 20:29

1 Answers1

1

As David Zwicker says, the coordinates are relative to the figure size. If your experimenting seems to disprove this, please consider the placement of the ticks, axis labels, etc.

Let us create a third axes with the same coordinate system as the figure and show the axes areas there:

fig = plt.figure(figsize=(17.5,8.0))
left = 0.1
bottom = 0.03
width = 0.3
height = 0.6

# let us create third axes with the figure coordinates:
ax3 = plt.axes([0, 0, 1, 1], frameon=False, zorder=10)

ax1 = plt.axes([left, bottom, width, height])
ax3.add_artist(plt.Rectangle((left, bottom), width, height, facecolor=(1,0,0,.5), edgecolor='none'))

left += (width+0.12)
ax2 = plt.axes([left, bottom, width, height])
ax3.add_artist(plt.Rectangle((left, bottom), width, height, facecolor=(1,0,0,.5), edgecolor='none'))

This gives:

enter image description here

The axes positions are:

In [37]: ax1.get_position()
Out[37]: Bbox('array([[ 0.1 ,  0.03],\n       [ 0.4 ,  0.63]])')

In [38]: ax2.get_position()
Out[38]: Bbox('array([[ 0.52,  0.03],\n       [ 0.82,  0.63]])')

Maybe this clarifies the positioning.

At least visually it seems that the lower edge of the axes may really be 3 % above the bottom, and the left edges 10 % and 52 % from the left edge of the figure.

DrV
  • 22,637
  • 7
  • 60
  • 72