如何使用
Python和Matplotlib设置一个子图的视觉宽度等于另一个子图的宽度?第一幅图具有固定的纵横比和来自imshow的正方形像素.然后我想把一个线条放在下面,但是不能这样做,并且使所有的对齐.
我相当肯定该解决方案涉及这个Transform Tutorial页面上的信息.我已经尝试使用fig.transFigure,ax.transAxes,ax.transData等,但还没有成功.我需要找到上面的轴的宽度和高度和偏移量,然后可以设置下面的轴的宽度,高度和偏移量.不应包括轴标签和刻度等,或更改对齐方式.
例如,以下代码
fig = plt.figure(1) fig.clf() data = np.random.random((3,3)) xaxis = np.arange(0,3) yaxis = np.arange(0,3) ax = fig.add_subplot(211) ax.imshow(data,interpolation='none') c = ax.contour(xaxis,yaxis,data,colors='k') ax2 = fig.add_subplot(212)
解决方法
matplotlib轴的轮廓由三件事情控制:
>图中的轴的边界框(由子图规范或特定范围(如fig.add_axes([left,bottom,width,height])控制).轴限制(不计算刻度标签)将始终在此框.
>通过更改数据限制或轴“Box”的形状来控制是否允许限制或高宽比更改的可调整参数.这可以是“datalim”,“Box”或“Box-forced”. (后者用于共享轴.)
轴的极限和纵横比.对于具有固定宽高比的曲线图,轴框或数据限制(取决于可调整)将被更改,以保持指定的纵横比.纵横比是指数据坐标,而不是轴的形状.
对于最简单的情况:
import numpy as np import matplotlib.pyplot as plt fig,axes = plt.subplots(nrows=2) data = np.random.random((3,3) axes[0].imshow(data,interpolation='none') c = axes[0].contour(xaxis,colors='k') axes[1].set_aspect(1) plt.show()
共享轴
但是,如果您希望确保它保持不变的形状,并且您可以使用具有相同数据限制的两个图形,您可以执行以下操作:
import numpy as np import matplotlib.pyplot as plt fig,axes = plt.subplots(nrows=2),sharex=True,sharey=True) plt.setp(axes.flat,adjustable='Box-forced') data = np.random.random((5,5) axes[0].imshow(data,colors='k') axes[1].plot([-0.5,2.5],[-0.5,4.5]) axes[1].set_aspect(1) plt.show()
但是,您可能会注意到这看起来不对.这是因为第二个子图由于我们绘制的顺序控制了第一个子图的范围.
基本上,使用共享轴,无论我们上面绘制的是什么,都可以控制初始范围,所以如果我们只是交换我们绘制的顺序:
import numpy as np import matplotlib.pyplot as plt fig,axes = plt.subplots(nrows=2,sharey=True) plt.setp(axes.flat,adjustable='Box-forced') data = np.random.random((5,3)) xaxis = np.arange(0,3) yaxis = np.arange(0,5) axes[1].plot([-0.5,4.5]) axes[1].set_aspect(1) axes[0].imshow(data,interpolation='none') c = axes[0].contour(xaxis,colors='k') plt.show()
当然,如果您不关心正在链接的绘图的交互式缩放/平移,则可以完全跳过共享轴,只需:
import numpy as np import matplotlib.pyplot as plt fig,axes = plt.subplots(nrows=2) data = np.random.random((5,4.5]) # Copy extents and aspect from the first axes... axes[1].set_aspect(axes[0].get_aspect()) axes[1].axis(axes[0].axis()) plt.show()
非共享轴
如果您不希望两个轴具有相同的数据范围,可以强制它们具有相同的大小(尽管如果您进行了交互式缩放,它们将不会被链接).为此,您需要计算第二个图形的宽高比应基于其第一个图的范围和范围/方面.
import numpy as np import matplotlib.pyplot as plt fig,colors='k') axes[1].plot(np.linspace(0,10,100),np.random.normal(0,1,100).cumsum()) # Calculate the proper aspect for the second axes aspect0 = axes[0].get_aspect() if aspect0 == 'equal': aspect0 = 1.0 dy = np.abs(np.diff(axes[1].get_ylim())) dx = np.abs(np.diff(axes[1].get_xlim())) aspect = aspect0 / (float(dy) / dx) axes[1].set_aspect(aspect) plt.show()