【问题标题】:Changing marker style in Matplotlib 2D scatter plot with colorbar according to cluster data根据聚类数据使用颜色条更改 Matplotlib 2D 散点图中的标记样式
【发布时间】:2021-01-26 15:52:45
【问题描述】:

我正在进行聚类,并尝试使用matplotlib的散点图功能绘制结果。

一个虚拟数据集是:

x = [48.959 49.758 49.887 50.593 50.683 ]
y = [122.310 121.29 120.525 120.252 119.509]
z = [136.993 133.128 143.710 129.088 139.860]

我正在使用以下代码绘制 x,y 并使用 z 作为颜色轴

plt.scatter(
x=x, y=y, c=z, label="CO2 Emissions Saved Cumulative", cmap=cm1)

Here is how it looks for the entire data

现在,我在我的数据集上执行了 K 均值聚类并找到了三个聚类。例如

[0 0 0 0 0 2 1 2 1 2 1 1 2 1 1 1 2 2 2 2 2]

我找到了以下解决方案,通过区分标记样式来绘制它们

ax.scatter(x[cluster == 0], y[cluster == 0], marker="*")
ax.scatter(x[cluster == 1], y[cluster == 1], marker="^")
ax.scatter(x[cluster == 2], y[cluster == 2], marker="s")

现在的问题是,使用这种方法,它会覆盖颜色轴,如本示例图像所示 cluster plot example

我怎样才能避免它不改变标记的颜色轴并且仍然使用默认的 z 值作为颜色轴。我希望该图仅根据集群数据更改标记样式。并且不会根据集群数据更改颜色。谢谢

【问题讨论】:

    标签: python matplotlib plot cluster-analysis scatter-plot


    【解决方案1】:

    使用pandasseaborn 库是针对大型数据集的一种更简洁且更强大的解决方案:

    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    import seaborn as sns
    
    x = [48.959, 49.758, 49.887, 50.593, 50.683 ]
    y = [122.310, 121.29, 120.525, 120.252, 119.509]
    z = [136.993, 133.128, 143.710, 129.088, 139.860]
    kmean = np.array([0, 1, 0, 2, 2])
    
    df = pd.DataFrame({'x':x,'y':y,'z':z, 'km_z':kmean})
    sns.scatterplot(data = df, x='x', y='y', hue='km_z', style='km_z')
    

    产生以下输出

    此外,您可以使用pandas.cut 函数来绘制箱(这是我经常需要生成的图表,我可以使用第三个连续值作为参数)。使用方法是:

    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    import seaborn as sns
    x = [48.959, 49.758, 49.887, 50.593, 50.683 ]
    y = [122.310, 121.29, 120.525, 120.252, 119.509]
    z = [136.993, 133.128, 143.710, 129.088, 139.860]
    
    df = pd.DataFrame({'x':x,'y':y,'z':z})
    df['bins'] = pd.cut(df.z, bins=3)
    sns.scatterplot(data = df, x='x', y='y', hue='bins', style='bins')
    

    它会产生以下示例:


    我使用后一种方法生成如下图:

    【讨论】:

      【解决方案2】:

      您需要将每个集群的 z 值缩放到相同的比例,以便您可以为 3 个散点图提供统一的颜色条。您可以使用Normalize 对象来执行此操作,并使用norm= 将此规范化传递给散射。

      x = np.array([48.959, 49.758, 49.887, 50.593, 50.683 ])
      y = np.array([122.310, 121.29, 120.525, 120.252, 119.509])
      z = np.array([136.993, 133.128, 143.710, 129.088, 139.860])
      cluster = np.array([0, 1, 0, 2, 2])
      
      mini, maxi = np.min(z), np.max(z)
      norm = plt.Normalize(mini, maxi)
      fig, ax = plt.subplots()
      a = ax.scatter(x[cluster == 0], y[cluster == 0], marker="*", c=z[cluster == 0], norm=norm)
      a = ax.scatter(x[cluster == 1], y[cluster == 1], marker="^", c=z[cluster == 1], norm=norm)
      a = ax.scatter(x[cluster == 2], y[cluster == 2], marker="s", c=z[cluster == 2], norm=norm)
      fig.colorbar(a)
      

      【讨论】:

      • 感谢您的回复@Diziet。但是,我希望保持与第一个附加图像中所示相同的比例。我要添加的唯一更改是具有基于集群的标记样式。使用您建议的解决方案,它仅显示 0-1 的颜色条范围
      • 还有,为什么要标准化 z 值?对整个数据集 (x,y,z) 进行聚类
      • 我通过简单地添加 c=z[cluster == 0] 来达到同样的效果。这个结果和你的解决方案是相似的。这不是我想要的。
      • 目标是将每个集群的 z 值缩放到相同的比例,以便您可以为 3 个散点图提供统一的颜色条。我已经包含了完整的代码
      • 太棒了,明白了。正是我想要的。谢谢。
      猜你喜欢
      • 1970-01-01
      • 2013-10-08
      • 2018-08-23
      • 2018-07-08
      • 2013-03-05
      • 1970-01-01
      • 2014-09-24
      • 2022-01-13
      • 2013-09-19
      相关资源
      最近更新 更多