为了账号安全,请及时绑定邮箱和手机立即绑定

移位的颜色栏matplotlib

/ 猿问

移位的颜色栏matplotlib

慕容708150 2019-10-30 11:04:02

我正在尝试为数据集填充轮廓。它应该非常简单:


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

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


查看完整描述

3 回答

?
拉莫斯之舞

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


使用colorskwarg contourf并手动指定颜色

使用自定义Normalize类,并将实例作为normkwarg传入。

使用由构建的离散色彩图matplotlib.colors.from_levels_and_colors。

最简单的方法是使用传递特定的颜色colors=sequence_of_colors。但是,如果您没有手动设置轮廓的数量,可能会很不方便。


最灵活的方法是第二个选项:使用normkwarg指定自定义规范化。对于您想要的内容,您需要将其子类化Normalize,但这并不难做到。这是唯一允许您使用连续颜色图的选项。


使用第二或第三选择的原因是,他们将使用一个颜色表任何类型的matplotlib情节的(如工作imshow,scatter等等)。


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


作为第二个选项的示例(我将imshow在这里使用,因为它比contourf随机数据更有意义,但contourf除了该interpolation选项外,其他用法也相同):


import numpy as np

import matplotlib.pyplot as plt

from matplotlib.colors import Normalize


class MidpointNormalize(Normalize):

    def __init__(self, vmin=None, vmax=None, midpoint=None, clip=False):

        self.midpoint = midpoint

        Normalize.__init__(self, vmin, vmax, clip)


    def __call__(self, value, clip=None):

        # I'm ignoring masked values and all kinds of edge cases to make a

        # simple example...

        x, y = [self.vmin, self.midpoint, self.vmax], [0, 0.5, 1]

        return np.ma.masked_array(np.interp(value, x, y))


data = np.random.random((10,10))

data = 10 * (data - 0.8)


fig, ax = plt.subplots()

norm = MidpointNormalize(midpoint=0)

im = ax.imshow(data, norm=norm, 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()


查看完整回答
反对 回复 2019-10-30
?
侃侃尔雅

就像@JoeKington上面提到的那样,MidpointNormalize不能处理许多边缘情况。我需要一个解决方案,该解决方案可以处理包含全零的起始数组,然后随着值随时间的变化而更新。我最终采用了github.com/matplotlib/matplotlib/pull/5054的DivergingNorm来处理这种情况。解决这一问题的可靠解决方案是如此困难,以至于不再进行开发。这似乎很奇怪,因为在使用带有正负数据的发散调色板时,将0设置为中心点是常见的用例。

查看完整回答
反对 回复 2019-10-30
?
繁星coding

加油!但是,保罗·霍布森(Paul Hobson)整理了与最近对mpl的拉取请求相同的一般事物的更完整版本: github.com/matplotlib/matplotlib/pull/3858根据您所需的功能,您可能最好根据这些东西相反。

查看完整回答
反对 回复 2019-10-30

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信