Pyplot 散点图,使用 facecolors='none',并将 edgecolors 保持为默认的确定性标记颜色选择

Pyplot scatter plot, using facecolors='none', and keeping edgecolors to default deterministic marker color choice

我正在尝试为每个数据点生成一系列带有方形和未填充标记的散点图,每个数组在运行之间使用不同但确定性的标记颜色。为此,我尝试使用以下代码:

import matplotlib.pyplot as plt
import numpy as np

x = np.array([1,2,3,4,5,6,7,8,9,10])
plt.scatter(x, x**2, s=50, marker='s',facecolors='none')
plt.scatter(x, x**3, s=50, marker='s',facecolors='none')
plt.scatter(x, x**4, s=50, marker='s',facecolors='none')

这会取消填充方形标记,但不会留下任何标记边缘,因此实际上看不到任何输出。如果我改用

plt.scatter(x, x**2, s=50, marker='s',facecolors='none',edgecolors='r')
plt.scatter(x, x**3, s=50, marker='s',facecolors='none',edgecolors='g')
plt.scatter(x, x**4, s=50, marker='s',facecolors='none',edgecolors='b')

然后我确实看到了一系列由未填充的红色方块表示的数据图,但缺点是我必须使用 edgecolor 明确设置我想要的颜色。但是,由于我的实际数据将包含可变数量的数组,实际数量在运行前是未知的,所以我希望在相同的散点图中绘制每个数据系列并使用不同的颜色,但不必明确指定是什么要使用的颜色。我可以使用

plt.scatter(x, y, s=50, marker='s',facecolors='none',edgecolor=np.random.rand(3,))

正如我看到的关于这个 SO 的回答,但这并不理想,因为我希望在运行之间具有确定性的颜色。因此,例如,如果我有 3 个数组,那么要绘制的第一个数组始终是颜色 'x',第二个始终是颜色 'y',第三个始终是颜色 'z'。将其扩展到 n 数组,绘制的 nth 数组也总是相同的颜色(其中 n 可能非常大)。

举个例子,如果我们考虑一个使用填充颜色的简单图,我们会看到前 3 个图总是相同的颜色(蓝色、橙色、绿色),即使添加了第 4 个图,前 3 个图也是如此地块保留其原始颜色。

3 plots, with default pyplot colors

4 plots, with the original 3 plots retaining their original colors as in the first image above

编辑:顺便说一句,有没有人知道在设置 facecolors='none' 时不包括 edgefaces 的原因(这样我们就可以轻松使用默认的 pyplot 颜色)?这似乎是一个相当奇怪的设计选择。

您可以在 matplotlib 中创建一个颜色图,然后将其包含在系列的迭代中。

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

x = np.array([1,2,3,4,5,6,7,8,9,10])
powers = [2, 3, 4]

# create a list of 5 colors from viridis, we only use the last 3, but there are 
# 5 in the colormap
colors = cm.get_cmap('viridis', 5)

for c, p in zip(colors(powers), powers):
    plt.scatter(x, x**p, s=50, marker='s',facecolors='none', edgecolor=c)

您 运行 遇到的问题是 edgecolor 的默认颜色是 'face',表示它将与您设置的面部颜色相同'none'

有两点需要提前注意。

  1. 你想要 n 不同的颜色,其中 n 是先验未知的。 Matplotlib 的默认颜色循环有 10 种颜色。因此,如果 n 有可能变得大于 10,那么不自己定义任何颜色的前提就会失效。然后您将需要选择自定义颜色循环或定义颜色并循环使用它们。

  2. Scatter 主要用于不同颜色或大小的标记。相反,如果所有标记都具有相同的颜色,则可以轻松地使用 plot 代替。

因此似乎

import matplotlib.pyplot as plt
import numpy as np

x = np.array([1,2,3,4,5,6,7,8,9,10])
plt.plot(x, x**2, ls='none', ms=7, marker='s', mfc='none')
plt.plot(x, x**3, ls='none', ms=7, marker='s', mfc='none')
plt.plot(x, x**4, ls='none', ms=7, marker='s', mfc='none')

plt.show()

只要您要制作的地块少于 11 个,就可以真正满足您的需求。

如果你真的想使用散点图,你可以使用仅由正方形轮廓组成的标记,例如marker="$\u25A1$",类似于

import matplotlib.pyplot as plt
import numpy as np

x = np.array([1,2,3,4,5,6,7,8,9,10])

plt.scatter(x, x**2, s=50, marker="$\u25A1$") 
plt.scatter(x, x**3, s=50, marker="$\u25A1$")
plt.scatter(x, x**4, s=50, marker="$\u25A1$")

plt.show()