如何使用自定义色彩地图与不规则间隔?

3
我正在尝试在matplotlib中使用自定义色条,其中包含不规则间隔。 但是,当按照教程使用色条时,它被用作常规间隔色条。
如何构建/使用具有不规则间隔的色条?
下面是MWE:
我正在使用plt.matshow()绘制各种数据,例如:
testdf = pd.DataFrame([
    (7, 7.1, 8 , 9),
    (0, 1, 1.5, 2),
    (2.001, 3, 3.5, 4),
    (4.001, 5, 6, 6.9999),
], index=[0, 1, 2, 3], columns=('A', 'B', 'C', 'D'),)

并且

plt.matshow(testdf)

默认矩阵

然而,我只想突出显示某些数字,并将其他数字分组。也就是说,我想要一个离散的、自定义的颜色条,而不是默认的连续颜色条。

幸运的是,matplotlib文档提供了我所需的。那么,让我们设置这个颜色条:

fig, ax = plt.subplots(figsize=(6, 1))
fig.subplots_adjust(bottom=0.5)

cmap = (mpl.colors.ListedColormap(['red', 'green', 'blue', 'cyan'])
        .with_extremes(over='0.25', under='0.75'))

bounds = [1, 2, 4, 7, 8]
norm = mpl.colors.BoundaryNorm(bounds, cmap.N)
fig.colorbar(
    mpl.cm.ScalarMappable(cmap=cmap, norm=norm),
    cax=ax,
    boundaries=[0] + bounds + [13],  # Adding values for extensions.
    extend='both',
    ticks=bounds,
    spacing='proportional',
    orientation='horizontal',
    label='Discrete intervals, some other units',
)

自定义颜色条

看起来很好!数字1到2为红色,7到8为蓝色,两个大组将2到7之间的所有无趣的东西都包含了。

所以,让我们使用它吧。

plt.matshow(testdf, cmap=cmap)
plt.colorbar()

自定义矩阵

...这不是我预期的结果。 色条应该像我之前构建的那样,不是等间距的,因此第0和1行应该包含黑色/灰色框表示上/下限,第2行应为全部绿色,第3行则为全部蓝色。

我该如何修复这个问题?我错过了什么吗?


2
你需要将边界规范和颜色映射传递给 matshow,这样 Matplotlib 才知道如何将数据映射到颜色映射上。https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.imshow.html#matplotlib.axes.Axes.imshow - Jody Klymak
1
使用它:plt.matshow(testdf, cmap=cmap, norm=norm) - JohanC
可以,那个方法可行。我知道这可能是一个愚蠢的疏忽。你能把它发布为答案吗? - JC_CL
1个回答

0
如Jody Klymak和JohanC在评论中指出的那样,norm也需要传递到matshow中,即plt.matshow(testdf, cmap=cmap, norm=norm)
然而,对于我无法通过我的颜色映射传递更多参数的内容(或者我无法弄清楚如何这样做...),例如在sns.clustermap中,这种方法不起作用。
一个可能的解决方法是使用常规间隔定义颜色映射,许多后续间隔都是相同的颜色。
fig, ax = plt.subplots(figsize=(6, 1))
fig.subplots_adjust(bottom=0.5)

cmap = (mpl.colors.ListedColormap(['red',
                                   'green', 'green',
                                   'blue', 'blue', 'blue', 'blue',
                                   'cyan'])
                                   .with_extremes(over='0.25', under='0.75'))

bounds = [1, 2, 3, 4, 5, 6, 7, 8]
norm = mpl.colors.BoundaryNorm(bounds, cmap.N)
fig.colorbar(
    mpl.cm.ScalarMappable(cmap=cmap, norm=norm),
    cax=ax,
    boundaries=[0] + bounds + [13],  # Adding values for extensions.
    extend='both',
    ticks=bounds,
    spacing='proportional',
    orientation='horizontal',
    label='Discrete intervals, some other units',
)

结果为

Colorbar

接着

matrix

正如您所看到的,它仍然与我在问题中预期的不同,但事实证明限制与我预期的不同,即间隔1, 2意味着>1,<2,如果您知道/预期此行为,则很容易修复。


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