使用 class 个标签填充轮廓

Filled contour using class labels

我有一个二维点网格,其中每个点都有相应的标签,标签在 [0.0, 5.0] 范围内。现在我想做以下事情:

绘制网格中的所有点并根据其标签为它们着色。

但是,我不想使用 scatter plot 来执行此操作。我尝试用 contourfpcolormesh 绘图来做到这一点:

import matplotlib.pyplot as plt

np.random.seed(1234)

x = np.linspace(-1.0, 1.0, num=5)
xx, yy = np.meshgrid(x, x)
z = np.random.randint(low=0, high=6, size=xx.shape)
levels = np.arange(0, 6)

fig, axes = plt.subplots(nrows=2, ncols=2)
axes[0, 0].contourf(xx, yy, z)
axes[0, 1].contour(xx, yy, z, colors='k')
axes[1, 0].scatter(xx, yy, marker='.', c=z)
axes[1, 1].pcolormesh(xx, yy, z)
plt.show()

我应该如何指定 contourf 图的水平,以便我得到分隔标签的等高线。 (类似于 pcolormesh 图)

此外,我如何固定每个标签的颜色,即标签 4 应始终为红色?

编辑:这是一个 contourf 图的例子,它产生了太多的彩色区域:

实际上,网格中只有两个标签。然而,在两个区域之间的边界处,绘制了几条额外的等高线。

对于上面的示例,应该有一条等高线分隔两个区域(青色和蓝色)

感谢任何帮助。

如果我没理解错的话,您想要类似于 pcolormesh 情节的东西,但只有轮廓。实现此目的的一种方法是扩展(或加宽)数组,使其在 xy 方向多次包含相同的值。这基本上意味着您的 z 由许多高原组成,中间有非常陡峭的梯度。您可以使用 np.repeat 轻松完成此操作。下面我展示了一个示例,其中原始数据中的每个点都扩展到 20x20 的高原。

绘图的颜色可以通过创建自定义颜色图来固定。在您的情况下,使用 ListedColormap 应该就足够了。使用 contour 时,您还必须指定绘制等高线的级别,以使其正常工作。

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

cmap = colors.ListedColormap([
    'royalblue', 'cyan','yellow', 'orange', 'red', 'green'
])

np.random.seed(1234)

num = 5
x = np.linspace(-1.0, 1.0, num=num)
xx, yy = np.meshgrid(x, x)
z = np.random.randint(low=0, high=6, size=xx.shape)
levels = np.arange(0, 6)

fig, axes = plt.subplots(nrows=2, ncols=2)
axes[0, 0].contourf(xx, yy, z)
axes[0, 1].contour(xx, yy, z, colors='k')
axes[1, 0].scatter(xx, yy, marker='.', c=z)
axes[1, 1].pcolormesh(xx, yy, z, cmap=cmap)  ##I added here the custom colormap for reference

##expanding the arrays
N = 20
x1 = np.linspace(-1.0, 1.0, num=N*num)
xx1, yy1 = np.meshgrid(x1,x1)
z1 = np.repeat(np.repeat(z, N,axis=0),N).reshape(xx1.shape)

fig2, ax2 = plt.subplots()
ax2.contour(xx1, yy1, z1, cmap=cmap, levels = levels)

plt.show()

产生这样的情节:

如您所见,线条仍然不是很直,有时可以看到彼此相邻的两条线。这是因为不同平台之间的梯度不相等。我 运行 另一个使用 N=200 的例子,在这种情况下线条更直:

希望对您有所帮助。

可能您只是忘记提供要显示的关卡。对于 N 个标签,需要 7 个级别,例如对于标签 [0 1 2 3 4 5],人们会选择水平,使标签位于水平区间的中间,[-0.5 0.5 1.5 2.5 3.5 4.5 5.5]

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

np.random.seed(1234)

x = np.linspace(-1.0, 1.0, num=5)
xx, yy = np.meshgrid(x, x)
z = np.random.randint(low=0, high=6, size=xx.shape)

levels = np.arange(0, z.max()+2)-0.5

fig, ax = plt.subplots()
im = ax.contourf(xx, yy, z, levels=levels)

fig.colorbar(im, ax=ax, ticks=np.unique(z))
ax.contour(xx, yy, z, colors='k',levels=levels)
ax.scatter(xx, yy, marker='.', c=z)

plt.show()

请注意,contourf 图的颜色与散点图的颜色略有不同。原因在问题的回答中有说明: