python - matplotlib 中带有图例和随机点顺序的散点图

标签 python matplotlib

我正在尝试构建来自 python/matplotlib 中多个类的大量数据的散点图。不幸的是,我似乎必须在数据随机化和图例标签之间做出选择。有没有办法可以同时拥有两者(最好不需要手动编码标签?)

最小可重现示例:

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
X = np.random.normal(0, 1, [5000, 2])
Y = np.random.normal(0.5, 1, [5000, 2]) 
data = np.concatenate([X,Y])
classes = np.concatenate([np.repeat('X', X.shape[0]),
                          np.repeat('Y', Y.shape[0])])

用随机点绘图:

plot_idx = np.random.permutation(data.shape[0])
colors = pd.factorize(classes)
fig, ax = plt.subplots()
ax.scatter(data[plot_idx, 0], 
           data[plot_idx, 1], 
           c=colors[plot_idx],
           label=classes[plot_idx],
           alpha=0.4)
plt.legend()
plt.show()

scatterplot with randomized points

这给了我错误的图例。

使用正确的图例进行绘图:

from matplotlib import cm
unique_classes = np.unique(classes)
colors = cm.Set1(np.linspace(0, 1, len(unique_classes)))
for i, class in enumerate(unique_classes):
    ax.scatter(data[classes == class, 0], 
               data[classes == class, 1],
               c=colors[i],
               label=class,
               alpha=0.4)
plt.legend()
plt.show()

working legend with non-randomized points

但现在这些点不是随机的,结果图不能代表数据。

我正在寻找能给我一个结果的东西,就像我在 R 中得到的结果:

library(ggplot2)
X <- matrix(rnorm(10000, 0, 1), ncol=2)
Y <- matrix(rnorm(10000, 0.5, 1), ncol=2)
data <- as.data.frame(rbind(X, Y))
data$classes <- rep(c('X', 'Y'), times=nrow(X))
plot_idx <- sample(nrow(data))

ggplot(data[plot_idx,], aes(x=V1, y=V2, color=classes)) +
  geom_point(alpha=0.4, size=3)

randomized points with working legend in R

最佳答案

您需要手动创建图例。但这并不是一个大问题。您可以循环遍历标签并为每个标签创建一个图例条目。这里可以使用带有类似于散点图的标记的 Line2D 作为句柄。

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
X = np.random.normal(0, 1, [5000, 2])
Y = np.random.normal(0.5, 1, [5000, 2]) 
data = np.concatenate([X,Y])
classes = np.concatenate([np.repeat('X', X.shape[0]),
                          np.repeat('Y', Y.shape[0])])

plot_idx = np.random.permutation(data.shape[0])
colors,labels = pd.factorize(classes)

fig, ax = plt.subplots()
sc = ax.scatter(data[plot_idx, 0], 
           data[plot_idx, 1], 
           c=colors[plot_idx],
           alpha=0.4)

h = lambda c: plt.Line2D([],[],color=c, ls="",marker="o")
plt.legend(handles=[h(sc.cmap(sc.norm(i))) for i in range(len(labels))],
           labels=list(labels))
plt.show()

enter image description here

或者,您可以使用特殊的分散处理程序,如问题 Why doesn't the color of the points in a scatter plot match the color of the points in the corresponding legend? 中所示。但这在这里似乎有点过分了。

关于python - matplotlib 中带有图例和随机点顺序的散点图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49559776/

相关文章:

python - 语句 print ='' ,end ("\t"中 end ='' 的含义)?

python - 如何在两个不同的远程 Controller 下 ping 连接到在 mininet 中创建的两个不同虚拟交换机的两个虚拟主机

python - 如何避免Python中的循环导入?

python - Matplotlib 使用分层直方图

终端中的 Python ASCII 绘图

python - 在列表中找到所有的山丘和山谷

matplotlib - 控制seaborn中的网格线间距

python - 按月绘制 groupby 数据

python - 值错误 : You must specify a period or x must be a pandas object with a DatetimeIndex with a freq not set to None

python - 如何按日期和度量字段分组来计算排名?