如何在不同的子图中绘制contourf colorbar - matplotlib

3
这是一个与"如何在不同的子图中绘制pcolor colorbar - matplotlib"非常相似的问题。我正在尝试绘制一个填充轮廓图和一条线图,共享一个轴,并在单独的子图中绘制颜色条(即使它不占用contourf轴的空间,从而混淆x轴共享)。然而,我的代码中的x轴不能很好地重新调整比例。
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

z = np.random.rand(20, 20)
x, y = np.arange(20), np.arange(20)
y2 = np.random.rand(20)
fig = plt.figure(figsize=(8, 8))
gs = mpl.gridspec.GridSpec(2, 2, height_ratios=[1, 2], width_ratios=[2, 1])
ax1 = fig.add_subplot(gs[1, 0])
ax2 = fig.add_subplot(gs[0, 0], sharex=ax1)
ax3 = fig.add_subplot(gs[1, 1])
cont = ax1.contourf(x, y, z, 20)
plt.tick_params(which='both', top=False, right=False)
ax2.plot(x, y2, color='g')
plt.tick_params(which='both', top=False, right=False)
cbar = plt.colorbar(cont, cax=ax3)
cbar.set_label('Intensity', rotation=270, labelpad=20)
plt.tight_layout()
plt.show()

该代码会产生一个x轴范围从0到20(包括20)而不是从0到19的填充等高线图,这意味着在图中会有不美观的空白。将上述代码中的sharex=ax1注释掉意味着等高线图的x轴尺度很好,但是上面的线图和plt.tick_params代码对任何轴都没有影响。

plot

有没有解决这个问题的方法?


我已将图表作为图片包含在内。仅凭您的描述很难理解问题。如果您不喜欢它的位置,请随意编辑和移动它。 - cel
1
ax1.set_xlim(0, 19) 应该是一个快速解决方法。 - cel
谢谢,cel。奇怪的是,添加 ax1.set_xlim 不起作用。我应该在问题中提到这一点。似乎 contourf 的意外行为干扰或阻止了轴方法。 - t.wood
xlim 设置为 @cel 建议的值对我有效:http://i.imgur.com/LvR3UnF.png - tmdavison
抱歉,@cel和@tom,我当时真是个傻瓜。使用set_xlim很好用。此外,使用ax1.set_params()也可以,而plt.set_params()则不行。不知道为什么。 - t.wood
2个回答

2

您还可以关闭x轴的自动缩放,以便在该轴上的所有后续绘图中保持由contourfsharex=True设置的范围:

ax2.set_autoscalex_on(False)

在调用ax2.plot()之前,您需要进行以下操作,我认为这比调用ax2.set_xlim(0, 19)更好,因为您不需要知道 x 轴的实际限制可能是多少。


import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
 
z = np.random.rand(20, 20)
x, y = np.arange(20), np.arange(20)
y2 = np.random.rand(20)
fig = plt.figure(figsize=(8, 8))
gs = mpl.gridspec.GridSpec(2, 1, height_ratios=[1, 2], width_ratios=[2])
ax1 = fig.add_subplot(gs[1, 0])
ax2 = fig.add_subplot(gs[0, 0], sharex=ax1)
cont = ax1.contourf(x, y, z, 20)
plt.tick_params(which='both', top=False, right=False)

ax2.set_autoscalex_on(False)
ax2.plot(x, y2, color='g')

axins = inset_axes(ax1,
           width="5%", # width = 10% of parent_bbox width
           height="100%", # height : 50%
           loc=6,
           bbox_to_anchor=(1.05, 0., 1, 1),
           bbox_transform=ax1.transAxes,
           borderpad=0,
       )

cbar = plt.colorbar(cont, cax=axins)
plt.show()

example


width_ratios=[2,1]) should be width_ratios=[2]) - Xopi García

-1

您可以使用inset_axes来实现此功能,而无需添加另一个轴。

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import inset_axes

z = np.random.rand(20, 20)
x, y = np.arange(20), np.arange(20)
y2 = np.random.rand(20)
fig = plt.figure(figsize=(8, 8))
gs = mpl.gridspec.GridSpec(2, 2, height_ratios=[1, 2], width_ratios=[2, 1])
ax1 = fig.add_subplot(gs[1, 0])
ax2 = fig.add_subplot(gs[0, 0], sharex=ax1)
cont = ax1.contourf(x, y, z, 20)
plt.tick_params(which='both', top=False, right=False)
ax2.plot(x, y2, color='g')
plt.tick_params(which='both', top=False, right=False)




axins = inset_axes(ax1,
               width="5%", # width = 10% of parent_bbox width
               height="100%", # height : 50%
               loc=6,
               bbox_to_anchor=(1.05, 0., 1, 1),
               bbox_transform=ax1.transAxes,
               borderpad=0,
           )

cbar = plt.colorbar(cont, cax=axins)
plt.savefig('figure.jpg',bbox_inches='tight',dpi=200)

enter image description here


这并没有回答问题,问题是如何在contourf图中删除x=19x=20之间的空白。 - tmdavison
哇!我简直不敢相信我错过了那个。当我读到这个问题时,我把它理解为询问如何在不干扰第二个图相对于第一个图的缩放的情况下插入色条。谈论错过显而易见的事情...哦,真是丢脸。 - tnknepp
1
虽然我在 inset_axes 中学到了一些新东西,所以我很感激这个答案。为什么上面的 plt.tick_params() 对上面的轴起作用,但对下面的轴却没有作用呢? - t.wood
@tnknepp 这种事情发生在最好的人身上! - tmdavison
t.wood:在你发布的代码中,关于轴顺序有点令人困惑(至少对我来说是这样)。ax2是上面的图,而ax1是下面的图(通常我会称上面的为ax1,下面的为ax2...但这只是个人偏好)。重点是,ax2始终是最后创建的轴,因此您的tick_params()命令被发给了它。您可以通过直接向轴发出命令来明确地将其命令传递给轴,这也是我在我的代码中经常使用的方法。例如:ax1.tick_params()。 - tnknepp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接