You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas多Y值DataFrame绘图:控制颜色、图例与X轴唯一显示

搞定Pandas多Y轴散点图:X轴去重+图例不重复的完美方案

我明白你的需求:既要让X轴上每个人名只显示一次,又要让height和weight的点分别用统一颜色,图例还不能重复。先看看你现有代码的小问题:

  • 第一种方法里,每次循环scatter都加了label,导致图例重复出现;
  • 第二种方法用了DataFrame的索引当X轴,所以重复的名字都显示出来了,不符合X轴去重的要求。

下面给你两个靠谱的解决方案,都能同时满足两个需求:

方法一:Matplotlib手动绘制(灵活可控)

我们先给每个唯一名字分配一个固定的X位置,然后分别绘制height和weight的点,只在第一次绘制时添加label,这样图例就不会重复啦。

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

# 你的示例DataFrame
DF = pd.DataFrame({
    "name": ["Alice", "Alice", "Charles", "Charles", "Kumar", "Kumar"],
    "height": [124, 126, 169, 170, 175, 174],
    "weight": [100, 105, 123, 125, 139, 140]
})

# 获取唯一名字列表,给每个名字分配X轴位置
unique_names = DF["name"].unique()
x_pos = np.arange(len(unique_names))

# 创建画布和轴对象
fig, ax = plt.subplots(figsize=(7,5))

# 画height的点:每个名字对应同一个X位置,只在第一次加label
for i, name in enumerate(unique_names):
    height_vals = DF[DF["name"] == name]["height"]
    ax.scatter([x_pos[i]]*len(height_vals), height_vals, 
               color="green", marker="o", label="height" if i == 0 else "")

# 画weight的点:同理处理
for i, name in enumerate(unique_names):
    weight_vals = DF[DF["name"] == name]["weight"]
    ax.scatter([x_pos[i]]*len(weight_vals), weight_vals, 
               color="blue", marker="o", label="weight" if i == 0 else "")

# 设置X轴刻度和标签
ax.set_xticks(x_pos)
ax.set_xticklabels(unique_names)

# 美化一下图表
ax.set_xlabel("Name")
ax.set_ylabel("Value")
ax.set_title("Height & Weight per Person")
ax.legend(loc="best")

plt.show()

方法二:用Seaborn一键搞定(简洁高效)

Seaborn的分组散点图天生适合这种场景,我们只需要先把DataFrame转成长格式,剩下的交给它就行:

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

# 把宽格式转成长格式(melt),让Seaborn能识别分组
melted_df = DF.melt(
    id_vars="name", 
    value_vars=["height", "weight"], 
    var_name="Measure", 
    value_name="Value"
)

# 绘制分组散点图,自动处理X轴去重和颜色区分
plt.figure(figsize=(7,5))
sns.stripplot(
    data=melted_df, 
    x="name", 
    y="Value", 
    hue="Measure",
    palette={"height": "green", "weight": "blue"},
    size=8
)

plt.title("Height & Weight per Person")
plt.legend(loc="best")
plt.show()

两种方法的效果:

不管用哪种,都能实现你要的:

  • X轴每个名字只显示一次,所有同名字的点都对齐在同一个X位置
  • height全是绿色,weight全是蓝色,颜色统一
  • 图例只有两个条目,没有重复

内容的提问来源于stack exchange,提问作者Chinntimes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:50:06