我花了很长时间研究如何让两个子图共享相同的y轴,并在Matplotlib中共享两个颜色条 .
发生了什么事情,当我在 subplot1
或 subplot2
中调用 colorbar()
函数时,它会自动调整绘图,使得颜色条加上绘图将适合'subplot'边界框内,导致两个并排的图形为两个非常不同的尺寸 .
为了解决这个问题,我尝试创建了第三个子图,然后我将其修改为仅显示一个颜色条的情节 . 唯一的问题是,现在两个地块的高度和宽度是不均匀的,我无法弄清楚如何使它看起来没问题 .
这是我的代码:
from __future__ import division
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import patches
from matplotlib.ticker import NullFormatter
# SIS Functions
TE = 1 # Einstein radius
g1 = lambda x,y: (TE/2) * (y**2-x**2)/((x**2+y**2)**(3/2))
g2 = lambda x,y: -1*TE*x*y / ((x**2+y**2)**(3/2))
kappa = lambda x,y: TE / (2*np.sqrt(x**2+y**2))
coords = np.linspace(-2,2,400)
X,Y = np.meshgrid(coords,coords)
g1out = g1(X,Y)
g2out = g2(X,Y)
kappaout = kappa(X,Y)
for i in range(len(coords)):
for j in range(len(coords)):
if np.sqrt(coords[i]**2+coords[j]**2) <= TE:
g1out[i][j]=0
g2out[i][j]=0
fig = plt.figure()
fig.subplots_adjust(wspace=0,hspace=0)
# subplot number 1
ax1 = fig.add_subplot(1,2,1,aspect='equal',xlim=[-2,2],ylim=[-2,2])
plt.title(r"$\gamma_{1}$",fontsize="18")
plt.xlabel(r"x ($\theta_{E}$)",fontsize="15")
plt.ylabel(r"y ($\theta_{E}$)",rotation='horizontal',fontsize="15")
plt.xticks([-2.0,-1.5,-1.0,-0.5,0,0.5,1.0,1.5])
plt.xticks([-2.0,-1.5,-1.0,-0.5,0,0.5,1.0,1.5])
plt.imshow(g1out,extent=(-2,2,-2,2))
plt.axhline(y=0,linewidth=2,color='k',linestyle="--")
plt.axvline(x=0,linewidth=2,color='k',linestyle="--")
e1 = patches.Ellipse((0,0),2,2,color='white')
ax1.add_patch(e1)
# subplot number 2
ax2 = fig.add_subplot(1,2,2,sharey=ax1,xlim=[-2,2],ylim=[-2,2])
plt.title(r"$\gamma_{2}$",fontsize="18")
plt.xlabel(r"x ($\theta_{E}$)",fontsize="15")
ax2.yaxis.set_major_formatter( NullFormatter() )
plt.axhline(y=0,linewidth=2,color='k',linestyle="--")
plt.axvline(x=0,linewidth=2,color='k',linestyle="--")
plt.imshow(g2out,extent=(-2,2,-2,2))
e2 = patches.Ellipse((0,0),2,2,color='white')
ax2.add_patch(e2)
# subplot for colorbar
ax3 = fig.add_subplot(1,1,1)
ax3.axis('off')
cbar = plt.colorbar(ax=ax2)
plt.show()
8 回答
只需将颜色条放在自己的轴上,然后使用
subplots_adjust
为它腾出空间 .作为一个简单的例子:
按照 abevieiramota 使用轴列表的解决方案非常有效,直到您只使用一行图像,如评论中所指出的那样 . 使用合理的纵横比
figsize
会有所帮助,但仍然远非完美 . 例如:colorbar function提供
shrink
参数,该参数是颜色条轴大小的缩放系数 . 它确实需要一些手动试验和错误 . 例如:使用
make_axes
更容易,并提供更好的结果 . 它还提供了自定义颜色条定位的可能性 . 另请注意subplots
选项以共享x和y轴 .作为一个偶然发现这个线程的初学者,我想添加一个python-for-dummies改编的 abevieiramota 's very neat answer (because I' m,在我必须查找的级别'ravel'来计算出他们的代码在做什么):
更像pythonic,更容易让像我这样的新手看到这里真正发生的事情 .
此解决方案不需要手动调整轴位置或颜色条大小,可以使用多行和单行布局,并且可以使用
tight_layout()
. 它改编自gallery example,使用来自matplotlib的AxesGrid Toolbox的ImageGrid
.我注意到几乎所有发布的解决方案都涉及
ax.imshow(im, ...)
并没有规范化显示在多个子图的颜色条上的颜色 .im
mappable取自最后一个实例,但如果多个im
-s的值不同,该怎么办? (遗憾的是,由于3D轴,我发现了使用plt.subplots(...)
的方法 .如果我能以更好的方式定位彩条...(可能有更好的方法来做到这一点,但至少应该不太难以遵循 . )
正如其他答案中所指出的,通常的想法是定义颜色条所在的轴 . 有多种方法可以做到这一点 . 尚未提及的一个是用
plt.subplots()
在子图创建时直接指定颜色条轴 . 优点是轴位置不需要手动设置,并且在所有情况下都具有自动方面,颜色条将与子图完全相同 . 即使在使用图像的许多情况下,结果也将令人满意,如下所示 .使用
plt.subplots()
时,使用gridspec_kw
参数可以使色条轴比其他轴小得多 .例:
如果绘图的方面是自动缩放的,或者图像由于它们在宽度方向上的方面而缩小(如上所述),则效果很好 . 但是,如果图像比较宽,那么结果看起来如下,这可能是不希望的 .
fix the colorbar height to the subplot height 的解决方案是使用
mpl_toolkits.axes_grid1.inset_locator.InsetPosition
来设置相对于图像子图轴的颜色条轴 .您可以使用
figure.colorbar()
的ax
参数和轴列表简化Joe Kington的代码 . 来自the documentation: