【问题标题】:How to conditionally define color for each cell in matplotlib/seaborn heatmap? [duplicate]如何有条件地为 matplotlib/seaborn 热图中的每个单元格定义颜色? [复制]
【发布时间】:2021-09-16 02:59:26
【问题描述】:

我有一个 seaborn 热图,我想有条件地为每个单元格定义一个自定义颜色。例如,如果单元格值为 60,那么我希望它的值为绿色。

或者,有没有办法定义一个颜色的numpy数组结构,它与数据的形状和大小相同,以便我们可以在绘制数据时直接传递该颜色?

我的数据结构是:

任何单行的数据,即数据[10 ] 是:

【问题讨论】:

  • 是的,这当然是可能的。一种方法是创建一个二维值数组0,1,2,...,并使用具有相同颜色数量的 seaborn 调色板。您能否详细说明一些测试数据以显示您想要使用的条件类型?你的输入是整数还是浮点数? stackoverflow 上的类似问题和答案可能会有所帮助。
  • @JohanC 我的数据结构很大,大约 45*50。我更新了问题中的数据结构。我的动机是根据每个单元格的值对每个单元格进行不同的着色,或者如果我可以创建一个与数据形状相同的颜色数组,我可以在绘图时传递这些颜色数组。
  • 请注意,将数据发布为图像而不是文本isn't recommended at stackoverflow。此外,强烈建议您发布一些您尝试过的示例代码。

标签: python numpy matplotlib seaborn


【解决方案1】:

如果您的数据只是 10 的倍数且介于 0 到 60 之间,您可以直接使用它们来绘制热图。

您可以提供 7 种颜色,例如标准颜色图的 6 种颜色和值 60 的一种特殊颜色。这是一些示例代码。 vminvmax 设置为使颜色条自动设置颜色附近的正确值。

您也可以只使用 7 种颜色的列表,例如 colors = ['dodgerblue', 'gold', 'lime', 'purple', 'turquoise', 'orange', 'crimson'],或使用具有不同颜色的颜色图(例如 cmap=sns.color_palette('tab10', 7, as_cmap=True))。

import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np

data = np.random.randint(0, 7, (45, 50)) * 10.0

fig, ax = plt.subplots(figsize=(8, 5))
colors = sns.color_palette('mako', 6) + ['crimson']
sns.heatmap(data=data, cmap=sns.color_palette(colors, as_cmap=True), vmin=-5, vmax=65, ax=ax)
# sns.heatmap(data=data, cmap=sns.color_palette('tab10', 7, as_cmap=True), vmin=-5, vmax=65, ax=ax)
plt.tight_layout()
plt.show()

这是 14 个数字的方法。 np.unique(data, return_inverse=True) 返回一个包含所有唯一值的数组以及一个映射,其中包含哪个值的位置。这些位置以 1D 列表的形式给出,需要重新整形为 2D。 'tab20' 颜色图最多有 20 种不同的颜色,尽管有些颜色可能难以区分。请参阅 here 获取定性颜色图列表。

import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np

# values between -11 and 61, maximum 15 different values
data = np.random.choice(np.random.randint(-11, 61, 15), (45, 50))
values, positions = np.unique(data, return_inverse=True)
positions = positions.reshape(data.shape)

fig, ax = plt.subplots(figsize=(14, 7))
colors = sns.color_palette('tab20', len(values))
N = len(values)
colors = sns.color_palette('tab20', N)
# or you can give your own list: colors = ['red', 'green', ....][:N]
sns.heatmap(data=positions, cmap=sns.color_palette(colors, as_cmap=True), vmin=-0.5, vmax=N - 0.5,
            annot=data, fmt='.0f', annot_kws={'size': 6},
            cbar_kws={'ticks': range(N)}, ax=ax)
fig.axes[-1].set_yticklabels(values)
plt.tight_layout()
plt.show()

【讨论】:

  • 这能回答你的问题吗?
  • 还没有,很抱歉。我的数据不是均匀分布的,被认为是 10 的倍数,因为有些点可以是 64 或 61 或 58 甚至 59,有些是 -11,每个点都需要不同的颜色。我还不能解决这个问题。
  • 您需要多少种不同的颜色?您可以编辑您的帖子并添加更多信息吗?请注意,超过 12 种颜色将很难在视觉上区分。
  • 至少大约 12 个,在某些情况下可以达到 14 个,我尝试采用不同的方法是:创建一个与数据相同形状和大小的 numpy 数组,其中每个单元格都保存颜色对应于使用矩阵的热图。并使用:cmap1 = matplotlib.colors.ListedColormap(grid_cell_colors.flat) 传递该颜色。但是颜色没有正确渲染。
  • 确实和这个答案很相似;您还可以使用减法和加法 0.5 的技巧来获得正确的颜色条刻度。如果您发布问题,这将有助于全面解释要求。
猜你喜欢
  • 1970-01-01
  • 2020-06-21
  • 2019-02-22
  • 2021-07-06
  • 2021-09-16
  • 2018-07-13
  • 2020-10-21
  • 2018-05-07
  • 2020-09-28
相关资源
最近更新 更多