python - 轴('square')和set_xlim之间的python相互作用
问题描述
对于相关图,我想要一个光学正方形的图(x 和 y 的像素长度相同),但对 x 和 y 也有一定的轴限制。我可以分别获得这两个,但不能同时获得:
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
),那么我可以手动调整窗口大小以获得我想要的,但我怎样才能自动做到这一点?
解决方案
获取正方形子图的一个选项是设置子图参数,以便生成的子图自动调整为正方形。这有点涉及,因为需要考虑所有边距和间距。
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()
这里的好处是能够自由缩放和自动缩放。缺点是一旦图形大小发生变化,子图大小就不再是正方形了。为了克服这个缺点,可以另外注册一个关于图形大小变化的回调。
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()
上述解决方案通过限制子图在其网格内的空间来工作。相反的方法,其中子图的大小以某种方式固定,将在数据限制不同时创建具有多个轴的相等纵横比(正方形)图的答案中显示?.
推荐阅读
- .htaccess - 使用 .htaccess 限制对文件的直接 URL 访问
- node.js - 在 Echo Show 上循环播放视频
- java - Java:awt 侦听器中的抽象方法是否称为回调方法?
- sql-server-2008 - 如何水平(连续)显示列值并在其周围显示一些文本?
- javascript - 如何在Javascript中填充默认下拉菜单
- javascript - 为什么我的函数在 React 中被调用了两次?
- python-3.x - 将 numpy.ndarray 转换为小写
- datatables - jquery Datatables 直到浏览器刷新才格式化
- visual-studio-code - 如何覆盖文件夹的设置
- python - 这是将 0 作为用户输入处理的最佳方式吗?