如何在Matplotlib散点图中仅绘制一次均值而非重复绘制?
问题描述
我有一个包含三列的数据集:第一列为实际数据,第二列为第一列的均值,第三列为类别。我希望在散点图中同时展示数据与均值,但目前均值被重复绘制N次,难以控制可视化效果。请问是否有办法仅绘制一次均值?
以下是示例代码,其中代表均值的橙色点被重复绘制14次叠加在一起:
import matplotlib.pyplot as plt import pandas as pd df = pd.DataFrame({ 'Numbers': [10,20,30,40,50,60,11,59,12,58,13,57,25,45], 'Mean': [35,35,35,35,35,35,35,35,35,35,35,35,35,35], 'y': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ] }) fig, ax = plt.subplots(1) ax.scatter(y="y", x= "Numbers", data=df, s = 200, alpha = .5, label = "实际数据") ax.scatter(y="y", x= "Mean", data=df, s = 200, alpha = .15, label = "均值") legend = ax.legend(loc="lower right", framealpha = .4)

解决方案
方法1:提取均值列的唯一值绘制
直接从Mean列中提取唯一值,确保只绘制一次均值点:
import matplotlib.pyplot as plt import pandas as pd df = pd.DataFrame({ 'Numbers': [10,20,30,40,50,60,11,59,12,58,13,57,25,45], 'Mean': [35,35,35,35,35,35,35,35,35,35,35,35,35,35], 'y': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ] }) fig, ax = plt.subplots(1) # 绘制实际数据散点 ax.scatter(y="y", x= "Numbers", data=df, s = 200, alpha = .5, label = "实际数据") # 提取唯一均值并对应类别值绘制 mean_value = df['Mean'].unique()[0] category_value = df['y'].iloc[0] ax.scatter(y=category_value, x=mean_value, s = 200, alpha = 1, label = "均值") legend = ax.legend(loc="lower right", framealpha = .4) plt.show()
方法2:直接传入标量值绘制
如果已知均值和对应的类别是固定值,直接传入标量参数即可,无需从整个DataFrame取数:
import matplotlib.pyplot as plt import pandas as pd df = pd.DataFrame({ 'Numbers': [10,20,30,40,50,60,11,59,12,58,13,57,25,45], 'Mean': [35,35,35,35,35,35,35,35,35,35,35,35,35,35], 'y': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ] }) fig, ax = plt.subplots(1) ax.scatter(y="y", x= "Numbers", data=df, s = 200, alpha = .5, label = "实际数据") # 直接传入标量x=35,y=1绘制均值点 ax.scatter(y=1, x=35, s = 200, alpha = 1, label = "均值") legend = ax.legend(loc="lower right", framealpha = .4) plt.show()
方法3:多类别场景的通用处理
如果数据集包含多个类别(y列有不同取值),可以按类别分组后提取每组的均值,再分别绘制:
import matplotlib.pyplot as plt import pandas as pd # 构造多类别示例数据 df = pd.DataFrame({ 'Numbers': [10,20,30,40,50,60,11,59,12,58,13,57,25,45, 100,110,120], 'Mean': [35,35,35,35,35,35,35,35,35,35,35,35,35,35, 110,110,110], 'y': [1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2] }) fig, ax = plt.subplots(1) # 绘制所有实际数据 ax.scatter(y="y", x= "Numbers", data=df, s = 200, alpha = .5, label = "实际数据") # 按类别分组,提取每组的均值和类别值 grouped_data = df.groupby('y').agg({'Mean': 'first', 'y': 'first'}) # 遍历分组绘制每个类别的均值点 for _, row in grouped_data.iterrows(): ax.scatter(y=row['y'], x=row['Mean'], s=200, alpha=1, label=f"类别{row['y']}均值") legend = ax.legend(loc="lower right", framealpha = .4) plt.show()
内容的提问来源于stack exchange,提问作者Aristide Herve
相关产品推荐
相关产品推荐

