简体   繁体   中英

Matplotlib: make figure that has x and y labels square in aspect ratio

The question is bettered explained with examples. Let's say below is a figure I tried to plot: 在matlab中

So the figure region is square in shape, and there are axis labels explaining the meaning of the values. In MATLAB the code is simple and works as expected.

t = linspace(0, 2*pi, 101);
y = sin(t);

figure(1)
h = gcf;
set(h,'PaperUnits','inches');
set(h,'PaperSize',[3.5 3.5]);

plot(t, y)
xlim([0, 2*pi])
ylim([-1.1, 1.1])
xlabel('Time (s)')
ylabel('Voltage (V)')
axis('square')

Now let's work with Python and Matplotlib. The code is below:

from numpy import *
from matplotlib import pyplot as plt

t = linspace(0, 2*pi, 101)
y = sin(t)

plt.figure(figsize = (3.5, 3.5))
plt.plot(t, y)
plt.xlim(0, 2*pi)
plt.ylim(-1.1, 1.1)
plt.xlabel('Time (s)')
plt.ylabel('Voltage (V)')
plt.axis('equal') # square / tight
plt.show()

It does not work, see the first row of the figure below, where I tried three options of the axis command ('equal', 'square' and 'tight'). I wondered if this is due to the order of axis() and the xlim/ylim, they do affect the result, yet still I don't have what I want. 蟒蛇 I found this really confusing to understand and frustrating to use. The relative position of the curve and axis seems go haywire. I did extensive research on stackoverflow, but couldn't find the answer. It appears to me adding axis labels would compress the canvas region, but it really should not, because the label is just an addon to a figure, and they should have separate space allocations.

It doesn't explain the figures you obtain but here is one way to achieve square axes with the right axes limits. In this example, I just calculate the axes aspect ratio using the x and y range:

plt.figure()
ax = plt.axes()
ax.plot(t, y)
xrange = (0, 2*pi)
yrange = (-1.1, 1.1)
plt.xlim(xrange)
plt.ylim(yrange)
plt.xlabel('Time (s)')
plt.ylabel('Voltage (V)')
ax.set_aspect((xrange[1]-xrange[0])/(yrange[1]-yrange[0]))
plt.show()

Another method is to create a square figure and square axes:

plt.figure(figsize = (5, 5))
ax = plt.axes([0.15, 0.15, 0.7, 0.7])
ax.plot(t, y)
plt.xlim(0, 2*pi)
plt.ylim(-1.1, 1.1)
plt.xlabel('Time (s)')
plt.ylabel('Voltage (V)')
plt.show()

在此处输入图片说明

I do not have a computer at hand right now but it seems this answer might work: https://stackoverflow.com/a/7968690/2768172 Another solution might be to add the axis with a fixed size manually with: ax=fig.add_axes(bottom, left, width, height) . If width and height are the same the axis should be squared.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM