【问题标题】:Shifted colorbar matplotlib移位的颜色条 matplotlib
【发布时间】:2023-03-03 04:21:01
【问题描述】:

我正在尝试为数据集制作填充轮廓。它应该相当简单:

plt.contourf(x, y, z, label = 'blah', cm = matplotlib.cm.RdBu)

但是,如果我的数据集不是关于 0 对称的,我该怎么办?假设我想从蓝色(负值)变为 0(白色),再到红色(正值)。如果我的数据集从 -8 变为 3,则颜色条的白色部分(应该为 0)实际上是略微负数。有什么方法可以改变颜色条吗?

【问题讨论】:

    标签: python colors matplotlib


    【解决方案1】:

    首先,有不止一种方法可以做到这一点。

    1. 将DivergingNorm 的实例作为norm kwarg 传递。
    2. 使用colors kwarg 到contourf 并手动指定颜色
    3. 使用由matplotlib.colors.from_levels_and_colors 构造的离散颜色图。

    最简单的方法是第一个选项。它也是唯一允许您使用连续颜色图的选项。

    使用第一个或第三个选项的原因是它们适用于使用颜色图的任何类型的 matplotlib 图(例如imshow、scatter 等)。

    第三个选项从特定颜色构造离散的颜色图和规范化对象。它与第二个选项基本相同,但它将 a) 与等值线图以外的其他类型的图一起使用,并且 b) 避免手动指定等值线的数量。

    作为第一个选项的示例(我将在此处使用imshow,因为它比contourf 更适合随机数据,但contourf 的用法与interpolation 选项不同。):

    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib.colors import DivergingNorm
    
    data = np.random.random((10,10))
    data = 10 * (data - 0.8)
    
    fig, ax = plt.subplots()
    im = ax.imshow(data, norm=DivergingNorm(0), cmap=plt.cm.seismic, interpolation='none')
    fig.colorbar(im)
    plt.show()
    

    作为第三个选项的示例(请注意,这给出了离散的颜色图而不是连续的颜色图):

    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib.colors import from_levels_and_colors
    
    data = np.random.random((10,10))
    data = 10 * (data - 0.8)
    
    num_levels = 20
    vmin, vmax = data.min(), data.max()
    midpoint = 0
    levels = np.linspace(vmin, vmax, num_levels)
    midp = np.mean(np.c_[levels[:-1], levels[1:]], axis=1)
    vals = np.interp(midp, [vmin, midpoint, vmax], [0, 0.5, 1])
    colors = plt.cm.seismic(vals)
    cmap, norm = from_levels_and_colors(levels, colors)
    
    fig, ax = plt.subplots()
    im = ax.imshow(data, cmap=cmap, norm=norm, interpolation='none')
    fig.colorbar(im)
    plt.show()
    

    【讨论】:

    • 应该添加到 Matplotlib 中
    • @Joe Kington,那真是太棒了!我正在为一个开源项目复制你的类定义,并将你的名字作为作者。希望你会没事的。
    • @user832 - 去吧!但是,Paul Hobson 将与最近对 mpl 的拉取请求相同的一般事物组合在一起的更完整版本:github.com/matplotlib/matplotlib/pull/3858 根据您需要的功能,您可能最好将其作为基础。
    • @JoeKington 谢谢!我会检查 Paul 的解决方案,但现在您的解决方案正是我所需要的!
    • 正如@JoeKington 上面提到的,MidpointNormalize 不能处理许多边缘情况。我需要一个解决方案,它使用包含全零的起始数组,然后随着值随时间的变化而更新。我最终采用了 github.com/matplotlib/matplotlib/pull/5054 的 DivergingNorm 来处理这种情况。对这个问题的一个强有力的解决方案显然是如此困难,以至于开发不再进行。这似乎很奇怪,因为在使用带有正负数据的发散调色板时,将 0 设置为中心点是一个常见的用例。
    猜你喜欢
    • 2021-05-14
    • 2013-05-18
    • 1970-01-01
    • 2020-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-16
    相关资源
    最近更新 更多