如何无需循环绘制多组含不同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
相关产品推荐
相关产品推荐

