不同图表使用相同的颜色条范围 - Matplotlib

4

我很难在不同的图形中保持相同的颜色条范围。

例如,我有以下可视化效果:

enter image description here

enter image description here

这些是使用以下代码生成的:

def plot_contour(x_dim, y_dim, x_steps, y_steps, scalar_field, file_path):
    plt.figure()

    x, y = numpy.mgrid[-x_dim:x_dim/:x_steps*1j, -y_dim:y_dim:y_steps*1j] 
    cs = plt.contourf(x, y, scalar_field, zorder=1, extent=[-x_dim, x_dim, -y_dim, y_dim])
    plt.colorbar(cs)

    plt.savefig(file_path + '.png', dpi=Vc.dpi)
    plt.close()

我希望能够比较这两个字段,因此,我想要为它们使用相同的颜色映射。
我的第一种方法是使用参数v_minv_max,使用数据的最小/最大值。
cs = plt.contourf(x, y, scalar_field, zorder=1, extent=[-x_dim, x_dim, -y_dim, y_dim], vmin=-1.00, vmax=1.05) # Manual setting to test

接着我得到了相同的颜色映射:

enter image description here enter image description here

但是我也想在图表中显示相同的颜色条范围。我尝试使用

cb = plt.colorbar(cs)
cb.set_clim(vmin=-1.00, vmax=1.05)

没有成功。

这个完整的示例会产生同样的行为:

import matplotlib
import numpy as numpy
import matplotlib.cm as cm
import matplotlib.mlab as mlab
import matplotlib.pyplot as plt

matplotlib.rcParams['xtick.direction'] = 'out'
matplotlib.rcParams['ytick.direction'] = 'out'

delta = 0.025
x = numpy.arange(-3.0, 3.0, delta)
y = numpy.arange(-2.0, 2.0, delta)
X, Y = numpy.meshgrid(x, y)

Z1 = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
# difference of Gaussians

Za = 10.0 * (Z2 - Z1)
Zb = 5.0 * (Z2 - Z1)

def bounds(scalar_fields):
    """
    Get the bounds of a set of scalar_fields
    :param scalar_fields : the scalar field set
    :return: a set of normalized vector field components
    """
    max_bound = -numpy.inf
    min_bound = numpy.inf

    for scalar_field in scalar_fields:
        max_lim = numpy.max(scalar_field)
        min_lim = numpy.min(scalar_field)
        if max_lim > max_bound:
            max_bound = max_lim
        if min_lim < min_bound:
            min_bound = min_lim

    return min_bound, max_bound

def plot_contour(x_dim, y_dim, x_steps, y_steps, scalar_field, v_min, v_max, file_path):
    plt.figure()

    x, y = numpy.mgrid[-x_dim/2:x_dim/2:x_steps*1j, -y_dim/2:y_dim/2:y_steps*1j]

    cs = plt.contourf(x, y, scalar_field, zorder=1, extent=[-x_dim/2.0, x_dim/2.0, -y_dim/2.0, y_dim/2.0],
                      vmin=v_min, vmax=v_max)
    cb = plt.colorbar(cs)

    plt.savefig(file_path + '.png')
    plt.close()

v_min, v_max = bounds([Za, Zb])
x_dim = y_dim = 6

y_steps = x.shape[0]
x_steps = y.shape[0]    

plot_contour(x_dim, y_dim, x_steps, y_steps, Za, v_min, v_max, 'Za')
plot_contour(x_dim, y_dim, x_steps, y_steps, Zb, v_min, v_max, 'Zb') 

我该怎么做呢?

提前感谢你的帮助。


在两个调用中都放置 vminvmax?你正在做的应该可以工作。你能否在完整的可调用示例中重现此操作(包括合成数据)? - tacaswell
是的,我会在这两个调用中都加入这个参数,因为这两个函数是相同的。 - pceccon
我认为 set_clim 应该放在 cs 对象上,而不是 colorbar 上。 - tacaswell
1个回答

7
如果您想让色条中的颜色对应于两个等高线图中相同的值,则需要控制颜色条和等高线图中的级别。也就是说,要比较图之间相同的级别,这些图应具有相同的等高线级别。这很容易做到。以下是一个示例图:

enter image description here

有两种方法:1)提前计算级别;2)使用一个图中的级别来设置另一个图中的级别。我将使用第二种方法,因为从中可以清楚地了解如何执行第一种方法(例如,使用levels = numpy.linspace(v_min, vmax, 10),但请注意,我在此处未使用该方法,而是让mpl计算级别)。
首先,我还使用了以下内容:
Za = 10.0 * (Z2 - Z1)
Zb = 6.0 * (Z2 - Z1)   # 6, rather than 5

然后,进行绘图:
def plot_contour(x_dim, y_dim, x_steps, y_steps, scalar_field, file_path, v_min, v_max, levels=None):
    x, y = numpy.mgrid[-x_dim/2:x_dim/2:x_steps*1j, -y_dim/2:y_dim/2:y_steps*1j]
    cs = plt.contourf(x, y, scalar_field, zorder=1, cmap=cm.jet, extent=[-x_dim/2.0, x_dim/2.0, -y_dim/2.0, y_dim/2.0], vmin=v_min, vmax=v_max, levels=levels)
    plt.colorbar(cs)
    return cs.levels

v_min, v_max = bounds([Za, Zb])

plt.figure()
plt.subplot(121)
levels = plot_contour(x_dim, y_dim, x_steps, y_steps, Za, 'Za', v_min, v_max)
plt.subplot(122)
plot_contour(x_dim, y_dim, x_steps, y_steps, Zb, 'Zb', v_min, v_max, levels=levels) 
plt.show()

1
那么在这个例子中它不能是5吗?一个图的最小值和最大值应该包含另一个图的限制吗?我无法控制数据,它们来自预测,如果我提到的条件是必要的,那么这将不会在我的集合中成立。 :/ - pceccon
1
不,那只是使用同一组级别的示例。您可以按照自己的方式指定级别,并且可以将 levels=np.arange(-5,6) 传递给两个级别。主要问题是,如果您想要具有与级别匹配的两个离散化的色条(当然,这些级别也与轮廓匹配),则级别本身必须匹配。 - tom10
好的。我会在这里尝试并接受您的答案。谢谢,@tom10。 - pceccon
没问题,如果它不能基本满足你的需求,就没有必要接受它。 - tom10
是的。(: 再次感谢您。 - pceccon
1
谢谢!你让我的一天变得美好了!答案中最重要的部分是,仅仅设置vminvmax或者colorbar的参数是不够的,必须设置levels! - Dr_Zaszuś

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