如何绘制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的数值。
具体步骤如下:
- 先创建2×2的子图布局,获取子图数组
axes。 - 把要绘制的列名整理成列表,和子图的位置一一对应。
- 遍历每个列名和对应的子图,对每个列的数据做
unstack('Country')——因为原数据的索引是(Country, Year),unstack后会把Country转成列,Year作为索引,这样plot的时候会自动把每个Country作为一条曲线。 - 在每个子图上绘制,设置标题、标签等美化内容。
完整代码如下:
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
相关产品推荐
相关产品推荐

