如何根据值为 plt 图中的单元格着色?

How to color cells in a plt plot based on value?

我正在尝试使用 pylot 来说明机器人路径规划 RL 概念中的布局。 我创建了如下布局,但无法根据单元格的值为单元格着色。我使用 np.array 生成图像和 pyplot,但 matlib 根据标准热图对其着色。

我已经尝试了以下方法来开始为所有单元格着色:

ax.set_facecolor('red')

但它似乎给 ax.imshow 背后的情节着色,使其隐藏在插图中。

整个.py:

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

layout = np.array([
 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 [1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
 [1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1],
 [1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1],
 [1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1],
 [1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1],
 [1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1],
 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1],
 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1],
 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1],
 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]
)


fig, ax = plt.subplots()
im = ax.imshow(layout)


ax.set_xticks(np.arange(len(layout[1])))
ax.set_yticks(np.arange(len(layout)))

# Rotate the tick labels and set their alignment.
plt.setp(ax.get_xticklabels(), rotation=45, ha="right",
         rotation_mode="anchor")

# Loop over data dimensions and create text annotations.
for i in range(len(layout)):
    for j in range(len(layout[1])):
        text = ax.text(j, i, layout[i, j],
                       ha="center", va="center", color="w")
        ax.set_facecolor('red')

ax.set_title("Showroom layout")
fig.tight_layout()

plt.show()

我知道 set_facecolor 现在会将整个地块涂成红色,但我仍在调试。将来它将为值“1”灰色和“0”白色的单元格着色。或类似。

感谢您的帮助和意见! :)

您可以定义 imshow 的工作方式。默认情况下,它使用称为 viridis 的颜色范围,但您可以使用其他颜色。例如,gray 会给你一个介于白色代表 0 和黑色代表 1 之间的比例。但是如果你想要灰色代表 1,你需要创建你自己的 cmap。见下文。它只是创建了一种颜色变化,对于最小值(此处为 0)为白色,对于最大值(此处为 1)为灰色。

from matplotlib.colors import Colormap, ListedColormap
cmap = ListedColormap(["white", "gray"])
im = ax.imshow(layout, cmap=cmap)

如果您仍想看到数字,您可能需要根据值选择文本颜色:

# Loop over data dimensions and create text annotations.
for i in range(len(layout)):
    for j in range(len(layout[1])):
        text = ax.text(j, i, layout[i, j],
                       ha="center", va="center", color='gray' if layout[i, j] == 0 else 'white')

输出

编辑:如果您需要超过 2 种颜色并且不想要渐变而是特定颜色,您可以使用下面的颜色。它将使用每种颜色来匹配其索引(对于不太常见的颜色,您也可以使用 RGB 格式 (255,0,0))

from matplotlib.colors import ListedColormap
cmap=ListedColormap(["red", "blue", "green", "black"])
plt.imshow(a, cmap=cmap)
# Loop over data dimensions and create text annotations.
for i in range(len(a)):
    for j in range(len(a[1])):
        text = plt.text(j, i, a[i, j],
                       ha="center", va="center", color='white')

注意::如果你的绘图中的数字超过颜色列表的长度,它会尝试展开它,你会失去一点控制。您还可以使用 ListedColormapN 参数,它允许您重复颜色顺序直到 N,在我的示例中,使用 N=6,颜色图将是 ["red", "blue", "green", "black", "red", "blue"]