Matplotlib 子图的颜色条分配错误

2 投票
1 回答
2147 浏览
提问于 2025-04-18 10:51

我有一个叫做 plot2d 的封装器,它是用来调用 matplotlib 的 imshow 函数,同时也会调用 colorbar(下面的代码可以看到)。当我在子图中以非顺序的方式使用它时,比如先画子图 2 再画子图 1,至少有一个子图的颜色条会出现错误。这种情况在下面代码中的 bad_cb_on_top 函数中可以看到。然而,当我使用 works_just_fine 时,结果是我想要的。这两个函数之间唯一的区别就是它们绘制子图的顺序。

我有两个问题:

  1. 为什么绘制子图的顺序会影响结果?
  2. 我怎么才能让 bad_cb_on_top 得到和 works_just_fine 一样的结果,而不修改 bad_cp_on_top 呢?

版本信息:

  • python 2.7.3
  • matplotlib 1.1.1

示例代码:

from pylab import *

x = linspace(-1, 1, 100)
x, y = meshgrid(x, x)
data = 1./(x**2 + y**2)

def plot2d(data, ax=None, vmax=None):
  '''A simple wrapper for implot.'''
  # if ax was given, set ax as the current axis for plotting
  if ax :
    sca(ax)

  # Plot the data
  im = imshow(data, vmax=vmax, interpolation='lanczos')
  # This line assures that ax is the axis which was just plotted on
  # even if ax was not specified
  ax = im.axes

  # Add the colorbar
  cb = colorbar(ax=ax, orientation='vertical')

  return None

figsize=[4, 7]

def bad_cb_on_top():
  # This function copies the color bar from the bottom panel 
  # to the top panel for some unknown reason.
  fig, axs = subplots(2, 1, figsize=figsize)
  plot2d(data, vmax=31, ax=axs[1])
  plot2d(data, vmax=314, ax=axs[0])
  fig.show()

def works_just_fine():
  # This function works as intended despite little change
  fig, axs = subplots(2, 1, figsize=figsize)
  plot2d(data, vmax=314, ax=axs[0])
  plot2d(data, vmax=31, ax=axs[1])
  fig.show()

bad_cb_on_top()
works_just_fine()

来自 bad_cp_on_top() 的输出:

来自 <code>bad_cp_on_top()</code> 的输出

来自 works_just_fine() 的输出:

来自 <code>works_just_fine()</code> 的输出

1 个回答

4

我可能错得很离谱,但你可以试着把 im 作为 mappable 传给 colorbar(),这样可能能强制使用正确的设置。在 plot2d 里:

cb = colorbar(im, ax=ax, orientation='vertical')

我觉得这样做不仅能指定坐标轴,还能指定 mappable 的输入。顺便说一下,这对我来说没什么影响(我用的是 1.3.1),所以没有什么坏处,但这也意味着我无法进行测试。

撰写回答