Home > front end >  Matplotlib subplot size, and why does it change on aspect 'equal'?
Matplotlib subplot size, and why does it change on aspect 'equal'?

Time:09-17

Consider this example:

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np

pxwidth=930 ; pxheight=500 ; dpi=120
fig = plt.figure(figsize=(pxwidth/dpi,pxheight/dpi), dpi=dpi)

subplotpars1 = dict(left = 0.05, right=0.99, top=0.95, wspace=0.1)
gs = mpl.gridspec.GridSpec(2,2, width_ratios=(7, 3), height_ratios=(2, 1), **subplotpars1)

ax1 = fig.add_subplot(gs[0,0]) # Y plots
ax2 = fig.add_subplot(gs[1,0], sharex=ax1) # temperature plots
ax3 = fig.add_subplot(gs[:,1]) # CIE plot

ax3.plot([0, 10, 20, 30], [0, 20, 40, 60], color='red')
ax3.set_aspect('equal')

plt.show()

So, let's say I run this example, and from the starting layout, I try to make a rectangular zoom selection:

plot-start-rectsel

Once I release the mouse button, then I get this:

plot-after-rectsel

As you can see, the "size" of the subplot has changed, so it matches the zoom rectangle!

The reason for this is ax3.set_aspect('equal') - if you comment/remove that line, then the zoom is as usual (that is, the subplot size does not change, only what is shown within).

However, I don't really understand why would "equal aspect" cause a change in the plot size when doing a rectangular region zoom - could anyone explain?

Furthermore - is there a way to control the size of the subplot? Let's say, instead of ax3 taking up "all available space" as it is shown on first image, can I force it to, say, a square aspect ratio (the width is calculated to "all available space", and then the height is set to this width as well)?

CodePudding user response:

  • With set_aspect('equal') 5 units on the y axes will have the same size as 5 units on the y axis. If your xaxis goes from 5-25 on the yaxis and 27-37, then the aspect ratio of the plot will be 2:1.
  • You probably want set_box_aspect if you want a square plot. I've also suggested a more modern way to get what you want than gridspecs, which you can take or leave.
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np

pxwidth=930 ; pxheight=500 ; dpi=120
fig = plt.figure(figsize=(pxwidth/dpi,pxheight/dpi), dpi=dpi, constrained_layout=True)
axs = fig.subplot_mosaic([['left0', 'right'], ['left1', 'right']], 
                         gridspec_kw={'height_ratios':[2, 1], 'width_ratios':[7, 3]})
axs['right'].plot([0, 10, 20, 30], [0, 20, 40, 60], color='red')
axs['right'].set_box_aspect(1)

plt.show()

  • Related