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

如何绘制Pandas多级索引DataFrame:按Var分图,Year为X轴Country为曲线

解决多级索引DataFrame的子图绘制问题

咱们先拆解你遇到的两个问题,再一步步给出正确的实现方法:

你的第一次尝试哪里错了?

你这段代码有三个核心问题:

  • 用错了xs()方法:df.xs()是用来提取索引层级的值的,但Var1是你的列名,不是索引,所以会报KeyError。要选列应该直接用df['Var1']。
  • 子图索引错误:f, a = plt.subplots(nrows=2, ncols=2)创建的a是一个2×2的二维数组,你用a[0]、a[1]这种一维索引会拿到整行的子图,而不是单个子图,正确的索引应该是a[0,0]、a[0,1]、a[1,0]、a[1,1]。
  • 参数拼写错误:x=a[2]应该是ax=a[1,0],kax=a[3]是完全不存在的参数,正确的指定子图参数是ax。

你的第二次尝试哪里错了?

这段代码的问题在于:

  • 循环里每次调用df[indicator].plot()时,没有指定对应的子图ax,所以每次都会创建新的绘图对象,最后只有最后一次的绘图显示出来,前面的子图都是空的。
  • 你嵌套了两个循环,但没有把indicator和子图的位置对应起来,逻辑上混乱了。

正确的实现方法

首先明确咱们的需求:4个子图(2行2列),每个子图对应一个Var列,X轴是Year,不同Country是不同曲线,Y轴是对应Var的数值。

具体步骤如下:

  1. 先创建2×2的子图布局,获取子图数组axes。
  2. 把要绘制的列名整理成列表,和子图的位置一一对应。
  3. 遍历每个列名和对应的子图,对每个列的数据做unstack('Country')——因为原数据的索引是(Country, Year),unstack后会把Country转成列,Year作为索引,这样plot的时候会自动把每个Country作为一条曲线。
  4. 在每个子图上绘制,设置标题、标签等美化内容。

完整代码如下:

import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
%matplotlib inline

# 读取数据
df = pd.read_csv('https://docs.google.com/uc?id=1mjmatO1PVGe8dMXBc4Ukzn5DkkKsbcWY&export=download', index_col=[0,1])

# 创建2行2列的子图
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(12, 10), dpi=80)
# 把二维的axes转成一维列表,方便遍历
axes = axes.flatten()
# 要绘制的列名列表
vars_list = ['Var1', 'Var2', 'Var3', 'Var4']

# 遍历每个列和对应的子图
for var, ax in zip(vars_list, axes):
    # 把数据unstack,让Country成为列,Year成为索引
    df[var].unstack('Country').plot(ax=ax)
    # 设置子图标题
    ax.set_title(f'{var} by Country over Year')
    # 设置X轴、Y轴标签
    ax.set_xlabel('Year')
    ax.set_ylabel(var)
    # 添加图例
    ax.legend(title='Country')

# 调整子图间距,避免重叠
plt.tight_layout()
plt.show()

这段代码会生成你想要的效果:每个Var单独一个子图,每个子图里不同Country是不同的曲线,X轴是Year,完全符合Excel类似的图表效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:40:43