开发者

matplotlib - subplots with fixed aspect ratio

开发者 https://www.devze.com 2023-02-05 23:19 出处:网络
I have a problem with plotting multiple subplots. I would like to set the PHYSICAL aspect ratio of the subplots to a fixed value.

I have a problem with plotting multiple subplots. I would like to set the PHYSICAL aspect ratio of the subplots to a fixed value. In my exampl开发者_JS百科e I have 12 subplots (4 rows and 3 columns) on a landscape A4 figure. There all subplots are nicely placed on the whole figure, and for all subplots the height is nearly equal to the width.

But if I change the layout of my figure to portrait, the subplots are stretched vertically. And this is exactly what should not happen. I would like to have the same height and width of the subplots as on the landscape figure. Is there a possibility that the aspect ratio of the subplots stay the same?

Thanks in advance, Peter

EDIT: I have found a workaround. But this just works for non-logarithmic axes...

aspectratio=1.0
ratio_default=(ax.get_xlim()[1]-ax.get_xlim()[0])/(ax.get_ylim()[1]-ax.get_ylim()[0])
ax.set_aspect(ratio_default*aspectratio)


Actually, what you're wanting is quite simple... You just need to make sure that adjustable is set to 'box' on your axes, and you have a set aspect ratio for the axes (anything other than 'auto').

You can either do this with the adjustable kwarg when you create the subplots. Alternatively, you can do this after their creation by calling ax.set_adjustable('box'), or by calling ax.set_aspect(aspect, adjustable='box') (where aspect is either 'equal' or a number).

Now, regardless of how the figure is resized, the subplots will maintain the same aspect ratio.

For example:

import matplotlib.pyplot as plt

fig = plt.figure()
ax1 = fig.add_subplot(2,1,1, adjustable='box', aspect=0.3)
ax2 = fig.add_subplot(2,1,2)

ax1.plot(range(10))
ax2.plot(range(10))

plt.show()

Now, compare how the top subplot responds to resizing, vs. how the bottom subplot responds:


The initial plot

matplotlib - subplots with fixed aspect ratio

Resized to a vertical layout:

matplotlib - subplots with fixed aspect ratio

Resized to a horizontal layout:

matplotlib - subplots with fixed aspect ratio


Your workaround works for me. After plotting the data, I call the following function:

def fixed_aspect_ratio(ratio):
    '''
    Set a fixed aspect ratio on matplotlib plots 
    regardless of axis units
    '''
    xvals,yvals = gca().axes.get_xlim(),gca().axes.get_ylim()

    xrange = xvals[1]-xvals[0]
    yrange = yvals[1]-yvals[0]
    gca().set_aspect(ratio*(xrange/yrange), adjustable='box')


In reply to the remark about the solution not working for logarithmic plots in the edit to the original question - you need to adapt as follows:

def fixed_aspect_ratio_loglog(ratio):
    '''
    Set a fixed aspect ratio on matplotlib loglog plots 
    regardless of axis units
    '''
    xvals,yvals = gca().axes.get_xlim(),gca().axes.get_ylim()

    xrange = log(xvals[1])-log(xvals[0])
    yrange = log(yvals[1])-log(yvals[0])
    gca().set_aspect(ratio*(xrange/yrange), adjustable='box')

(Adaptation for semilog plots should now be obvious)

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号