如何根据值为 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')
注意::如果你的绘图中的数字超过颜色列表的长度,它会尝试展开它,你会失去一点控制。您还可以使用 ListedColormap
的 N
参数,它允许您重复颜色顺序直到 N
,在我的示例中,使用 N=6
,颜色图将是 ["red", "blue", "green", "black", "red", "blue"]
我正在尝试使用 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')
注意::如果你的绘图中的数字超过颜色列表的长度,它会尝试展开它,你会失去一点控制。您还可以使用 ListedColormap
的 N
参数,它允许您重复颜色顺序直到 N
,在我的示例中,使用 N=6
,颜色图将是 ["red", "blue", "green", "black", "red", "blue"]