Axis('square')和set_xlim之间的python相互作用 [英] python interplay between axis('square') and set_xlim
问题描述
对于相关图,我希望有一个光学正方形的图(x和y的长度相同,以像素为单位),但在x和y上也有一定的轴限制.我可以分别获得2个中的每个,但不能同时获得:
For a correlation plot I would like to have a plot that is optically square (same length of x and y in pixels) but also has a certain axis limit on x and y. I can get each of the 2 separately but not at the same time:
import matplotlib.pyplot as plt
f, (ax1, ax2) = plt.subplots(1, 2)
x = [1 , 4 , 6]
y1 = [4, 7, 9]
y2 = [20, 89, 99]
ax1.plot(x, y1, 'o')
ax2.plot(x, y2, 'o')
myXlim = [0, 8]
ax1.set_xlim(myXlim)
ax2.set_xlim(myXlim)
ax1.axis('square')
ax2.axis('square')
# limit is gone here
ax1.set_xlim(myXlim)
ax2.set_xlim(myXlim)
# square is gone here
plt.show()
如果我只使用ax1.set_xlim(myXlim)
(而不是square
),那么我可以手动调整窗口大小以获取所需的图像,但是如何自动执行此操作?
If I just use the ax1.set_xlim(myXlim)
(and not square
) then I can manually adjust the window size to get what I want but how can I do this automatically?
推荐答案
获取方形子图的一个选项是设置子图参数,以使生成的子图自动调整为正方形.这有点涉及,因为需要考虑所有边距和间距.
An option to get square subplots is to set the subplot parameters such that the resulting subplots automatically adjust to be square. This is a little involved, because all the margins and spacings need to be taken into account.
import matplotlib.pyplot as plt
f, (ax1, ax2) = plt.subplots(1, 2)
x = [1 , 4 , 6]
y1 = [4, 7, 9]
y2 = [20, 89, 99]
def square_subplots(fig):
rows, cols = ax1.get_subplotspec().get_gridspec().get_geometry()
l = fig.subplotpars.left
r = fig.subplotpars.right
t = fig.subplotpars.top
b = fig.subplotpars.bottom
wspace = fig.subplotpars.wspace
hspace = fig.subplotpars.hspace
figw,figh = fig.get_size_inches()
axw = figw*(r-l)/(cols+(cols-1)*wspace)
axh = figh*(t-b)/(rows+(rows-1)*hspace)
axs = min(axw,axh)
w = (1-axs/figw*(cols+(cols-1)*wspace))/2.
h = (1-axs/figh*(rows+(rows-1)*hspace))/2.
fig.subplots_adjust(bottom=h, top=1-h, left=w, right=1-w)
ax1.plot(x, y1, 'o')
ax2.plot(x, y2, 'o')
#f.tight_layout() # optionally call tight_layout first
square_subplots(f)
plt.show()
这里的好处是能够自由缩放和自动缩放.缺点是,一旦图形尺寸改变,子图尺寸就不再是正方形.为了克服这一缺陷,可以另外注册一个有关图形尺寸更改的回调.
The benefit here is to be able to freely zoom and autoscale. The drawback is that once the figure size changes, the subplot sizes are not square any more. To overcome this drawback, one may in addition register a callback on size changes of the figure.
import matplotlib.pyplot as plt
f, (ax1, ax2) = plt.subplots(1, 2)
x = [1 , 4 , 6]
y1 = [4, 7, 9]
y2 = [20, 89, 99]
class SquareSubplots():
def __init__(self, fig):
self.fig = fig
self.ax = self.fig.axes[0]
self.figw,self.figh = 0,0
self.params = [self.fig.subplotpars.left,
self.fig.subplotpars.right,
self.fig.subplotpars.top,
self.fig.subplotpars.bottom,
self.fig.subplotpars.wspace,
self.fig.subplotpars.hspace]
self.rows, self.cols = self.ax.get_subplotspec().get_gridspec().get_geometry()
self.update(None)
self.cid = self.fig.canvas.mpl_connect('resize_event', self.update)
def update(self, evt):
figw,figh = self.fig.get_size_inches()
if self.figw != figw or self.figh != figh:
self.figw = figw; self.figh = figh
l,r,t,b,wspace,hspace = self.params
axw = figw*(r-l)/(self.cols+(self.cols-1)*wspace)
axh = figh*(t-b)/(self.rows+(self.rows-1)*hspace)
axs = min(axw,axh)
w = (1-axs/figw*(self.cols+(self.cols-1)*wspace))/2.
h = (1-axs/figh*(self.rows+(self.rows-1)*hspace))/2.
self.fig.subplots_adjust(bottom=h, top=1-h, left=w, right=1-w)
self.fig.canvas.draw_idle()
s = SquareSubplots(f)
ax1.plot(x, y1, 'o')
ax2.plot(x, y2, 'o')
plt.show()
上述解决方案通过限制子图在其网格内部的空间来工作. 创建具有多个轴的数据限制是否不同?.
这篇关于Axis('square')和set_xlim之间的python相互作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!