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

如何无需循环绘制多组含不同X轴坐标数据集的折线图?

问题描述

我有如下格式的数据集:

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib as mpl

df = pd.DataFrame({(1,'x'):[0,1,2],(1,'y'):[10,11,12],
                   (2,'x'):[1,2,3],(2,'y'):[11.5,11.8,13.2]})
df

输出的DataFrame结构如下:

1      2      
   x   y  x     y
0  0  10  1  11.5
1  1  11  2  11.8
2  2  12  3  13.2

简言之,我有多个对象的数据集,每个对象包含若干x/y对,但各自的x值集合不同。我希望将所有数据绘制在同一图表中(效果为两条带标记的折线图)。

目前我可以通过循环轻松实现该绘图需求,代码如下:

fig1,ax = plt.subplots()
for item in range(1,3):
    df.xs(item,axis=1,level=0).plot(ax=ax,kind='line',x='x',y='y',
                                    style='o-',label=str(item))

但我想了解是否存在无需使用循环即可实现相同绘图效果的方法。


无循环实现方案

可以通过重塑数据结构将宽格式转为长格式,再利用分组绘图功能实现无循环绘制,以下是几种可行方法:

方法1:pandas stack 重塑 + 分组绘图

通过stack将列层级中的对象编号转为行维度,整理成每个行对应一个x-y点的长格式,再分组绘图:

import pandas as pd
import matplotlib.pyplot as plt

# 重塑数据:把列的第一层(对象编号)转为行索引,再重置索引得到长格式
df_long = df.stack(level=0).reset_index(names=['row_idx', 'item'])

# 创建画布并按item分组绘图
fig, ax = plt.subplots()
df_long.groupby('item').plot(x='x', y='y', style='o-', ax=ax, legend=True)

# 调整图例显示
ax.legend(title='对象编号')
plt.show()

方法2:melt 拆分合并数据

分别提取所有x、y列,用melt转换后合并,再绘图:

# 提取所有x列并转换为长格式
x_data = df.xs('x', axis=1, level=1).rename_axis('item', axis=1).melt(var_name='item', value_name='x', ignore_index=False)
# 提取所有y列并转换为长格式
y_data = df.xs('y', axis=1, level=1).rename_axis('item', axis=1).melt(var_name='item', value_name='y', ignore_index=False)

# 合并x、y数据得到长格式
df_long = pd.concat([x_data, y_data['y']], axis=1).reset_index(drop=True)

# 绘图
fig, ax = plt.subplots()
df_long.groupby('item').plot(x='x', y='y', style='o-', ax=ax, legend=True)
ax.legend(title='对象编号')
plt.show()

方法3:Seaborn 一键绘图

如果使用Seaborn库,重塑数据后可直接调用lineplot,通过hue参数指定分组,代码更简洁:

import seaborn as sns

# 重塑数据为长格式
df_long = df.stack(level=0).reset_index(names=['row_idx', 'item'])

# 绘制带标记的折线图,hue控制分组,markers指定标记样式
sns.lineplot(data=df_long, x='x', y='y', hue='item', markers='o', dashes=False)
plt.title('多对象x-y折线图')
plt.show()

这些方法的核心是将原始的宽格式数据转换为长格式(每行对应一个对象的一组x-y值),从而利用pandas或Seaborn的分组绘图能力,避免显式循环。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 11:00:28