如何使用不同列中的类别确定的标记和颜色生成散点图

问题描述 投票:0回答:2

我想绘制具有不同聚类的数据集。

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import sklearn.cluster

rng = np.random.default_rng(seed=5)

df_1_3 = pd.DataFrame(rng.normal(loc=(1, 3), size=(30, 2), scale=0.50), columns=["x", "y"])
df_5_1 = pd.DataFrame(rng.normal(loc=(5, 1), size=(30, 2), scale=0.25), columns=["x", "y"])
df_5_5 = pd.DataFrame(rng.normal(loc=(5, 5), size=(30, 2), scale=0.25), columns=["x", "y"])

df = pd.concat([df_1_3, df_5_1, df_5_5], keys=["df_1_3", "df_5_1", "df_5_5"])

聚类算法将计算聚类标签:

model = sklearn.cluster.AgglomerativeClustering(...)

df["cluster"] = model.fit_predict(df[["x", "y"]]) # [0, 0, 0, ... 1, 1, 1 ... 2, 2, 2] 
df["cluster"] = df["cluster"].astype("category")

我想在一张图中可视化数据。每个原始数据应通过单独的标记进行区分,并且标签应通过颜色可视化。

澄清一下,如果您将所有三个数据的来源设置得彼此接近。该算法将仅创建一个簇(也称为一种类别/颜色),但标记应取决于原始的

keys
'df_1_3'
'df_5_1'
'df_5_5'

实际上我几乎得到了结果:

fig, ax = plt.subplots()
for marker, (name, sdf) in zip(["o", "s", "^", "d"], df.groupby(level=0)):
    sdf.plot.scatter(x="x", y="y", c="cluster", marker=marker, cmap="viridis", ax=ax)

但需要注意的是,颜色条会显示三次

如何去掉多余的颜色条?

python pandas matplotlib seaborn scatter-plot
2个回答
2
投票

使用seaborn,你可以在不使用for循环的情况下做到这一点,并获得更清晰的绘图:

import seaborn as sns

sns.scatterplot(data=df, x='x', y='y', hue='cluster', style='cluster', markers=["o", "^", "d"], palette="viridis")

要保持颜色和标记分开,最好重置数据帧索引,并使用索引的

keys
中的
level=0
作为标记。

# reset the index
df = df.reset_index(level=0, names=['key'])

# plot
ax = sns.scatterplot(data=df, x='x', y='y', hue='cluster', style='key', markers=["o", "^", "d"], palette="viridis")
sns.move_legend(ax, bbox_to_anchor=(1, 0.5), loc='center left', frameon=False)

df.head()
之后
df.reset_index(level=0, names=['key'])

      key         x         y cluster
0  df_1_3  0.599034  2.337821       0
1  df_1_3  0.875819  3.210223       0
2  df_1_3  1.568023  3.054853       0
3  df_1_3  0.723676  2.607610       0
4  df_1_3  1.374373  3.817392       0

0
投票

我尝试用这个来模拟你的代码。

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
rng = np.random


df_1_3 = pd.DataFrame(rng.normal(loc=(1, 3), size=(30, 2), scale=0.50), columns=["x", "y"])
df_5_1 = pd.DataFrame(rng.normal(loc=(5, 1), size=(30, 2), scale=0.25), columns=["x", "y"])
df_5_5 = pd.DataFrame(rng.normal(loc=(5, 5), size=(30, 2), scale=0.25), columns=["x", "y"])

df_1_3["cluster"] = "0"
df_5_1["cluster"] = "1"
df_5_5["cluster"] = "2"

df = pd.concat([df_1_3, df_5_1, df_5_5], keys=["df_1_3", "df_5_1", "df_5_5"])

df["cluster"] = df["cluster"].astype("category")

这是满足您需要的部分:

fig, ax = plt.subplots()

scatter = ax.scatter(df["x"], df["y"], c=df["cluster"].cat.codes, cmap="viridis")
plt.colorbar(scatter, ax=ax, label='Cluster')

plt.show()

这给出了:

© www.soinside.com 2019 - 2024. All rights reserved.