假设我们想用三个一维数组
x
、y
、z
制作热图。 从三个列表绘制热图:X、Y、强度的答案是有效的,但 Z = np.array(z).reshape(len(y), len(x))
线很大程度上取决于 z 值添加到列表中的顺序。
作为示例,以下 2 个测试给出了完全相同的图,而 不应该。确实:
在测试1中,
z=2
应该代表x=100, y=7
。
在测试2中,
z=2
应该代表x=102, y=5
。
我们应该如何在函数
Z
中创建heatmap
矩阵,这样它就不会依赖于
z 值添加的顺序?
import numpy as np
import matplotlib.pyplot as plt
def heatmap(x, y, z):
z = np.array(z)
x = np.unique(x)
y = np.unique(y)
X, Y = np.meshgrid(x, y)
Z = np.array(z).reshape(len(y), len(x))
plt.pcolormesh(X, Y, Z)
plt.show()
### TEST 1
x, y, z = [], [], []
k = 0
for i in range(100, 120):
for j in range(5, 15):
x.append(i)
y.append(j)
z.append(k)
k += 1
heatmap(x, y, z)
### TEST 2
x, y, z = [], [], []
k = 0
for j in range(5, 15):
for i in range(100, 120):
x.append(i)
y.append(j)
z.append(k)
k += 1
heatmap(x, y, z)
编辑:示例 2:让我们说
x = [0, 2, 1, 2, 0, 1]
y = [3, 4, 4, 3, 4, 3]
z = [1, 2, 3, 4, 5, 6]
应该有一种明确的方法从 3 个数组
x
、y
、z
到热图可绘制网格网格 + z 值矩阵。
在此示例中,
x
和y
没有特定的顺序,非常随机。如何做到这一点?
这里像
reshape
这样的 Z = np.array(z).reshape(len(y), len(x))
的顺序是错误的。
如果您查看
np.meshgrid
,您会发现有两种索引方案:"xy"
(默认)和 "ij"
。使用 "xy"
索引时,X
(np.meshgrid
结果)沿列增加,Y
沿行增加。这与 "ij"
索引相反,其中 X
沿行增加,Y
跨列增加。
在测试 1 中,如果您要使用典型的 c 样式排序 (
x
) 重塑 np.reshape(x, (20, 10))
,您会看到生成的数组沿行增加,因此它使用 "ij"
(和 y
沿列增加)。在测试 2 中,重塑 (np.reshape(x, (10, 20))
) 会导致重塑的 x
沿列增加,因此它使用 "xy"
索引。
也就是说,您可以调整
heatmap
函数调用以获取调用 np.meshgrid
时使用的索引参数,并将 Z
重塑为与 X
/Y
相同的形状。
def heatmap(x, y, z, indexing="xy"):
x = np.unique(x)
y = np.unique(y)
X, Y = np.meshgrid(x, y, indexing=indexing)
Z = np.asarray(z).reshape(X.shape)
fig, ax = plt.subplots()
p = ax.pcolormesh(X, Y, Z)
fig.show()
return p, fig, ax
# test 1 heatmap call
heatmap(x, y, z, "ij")
# test 2 heatmap call
heatmap(x, y, z, "xy")