问题描述
我花了很长时间研究如何在Matplotlib中使用两个颜色共享的单个颜色条来使两个子图共享相同的y轴.
I've spent entirely too long researching how to get two subplots to share the same y-axis with a single colorbar shared between the two in Matplotlib.
发生的事情是,当我在subplot1
或subplot2
中调用colorbar()
函数时,它将自动缩放绘图,以使颜色栏和绘图可以放入子绘图"边界框内,从而导致两个并排图的大小是两个非常不同的.
What was happening was that when I called the colorbar()
function in either subplot1
or subplot2
, it would autoscale the plot such that the colorbar plus the plot would fit inside the 'subplot' bounding box, causing the two side-by-side plots to be two very different sizes.
为了解决这个问题,我尝试创建第三个子图,然后黑客入侵它,仅用一个色条就不渲染任何图.唯一的问题是,现在两个图的高度和宽度是不均匀的,我不知道如何使它看起来还不错.
To get around this, I tried to create a third subplot which I then hacked to render no plot with just a colorbar present.The only problem is, now the heights and widths of the two plots are uneven, and I can't figure out how to make it look okay.
这是我的代码:
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()
推荐答案
只需将颜色栏放置在其自己的轴上,并使用subplots_adjust
为其留出空间.
Just place the colorbar in its own axis and use subplots_adjust
to make room for it.
作为一个简单的例子:
import numpy as np
import matplotlib.pyplot as plt
fig, axes = plt.subplots(nrows=2, ncols=2)
for ax in axes.flat:
im = ax.imshow(np.random.random((10,10)), vmin=0, vmax=1)
fig.subplots_adjust(right=0.8)
cbar_ax = fig.add_axes([0.85, 0.15, 0.05, 0.7])
fig.colorbar(im, cax=cbar_ax)
plt.show()
请注意,即使值的范围由vmin
和vmax
设置,颜色范围也将由最后绘制的图像(引起im
)设置.例如,如果另一个图的最大值更高,则比im
的最大值更高的点将以统一的颜色显示.
Note that the color range will be set by the last image plotted (that gave rise to im
) even if the range of values is set by vmin
and vmax
. If another plot has, for example, a higher max value, points with higher values than the max of im
will show in uniform color.
这篇关于Matplotlib 2个子图,1个颜色条的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!