优化多级索引Pandas DataFrame绘图的X轴标签显示
解决多级索引DataFrame绘图时X轴标签冗余的问题
不用动原DataFrame的话,我有两个高效的法子,直接在绘图环节搞定标签显示的问题:
方法一:绘图后直接修改轴标签(最省心)
先正常画完图,再把X轴的标签替换成你要的外层索引日期(不带时间)就行,代码示例如下:
import pandas as pd import matplotlib.pyplot as plt # 你的原始数据生成代码 dt = pd.DatetimeIndex(start='2010-1-1', end='2010-12-31', freq='m') dt2 = pd.DatetimeIndex(start='2011-1-1', end='2011-1-10', freq='d') mi = pd.MultiIndex.from_product([dt, dt2], names=['assessment_date', 'contract_date']) df = pd.DataFrame(index=mi) df['foo'] = 7 # 绘图并拿到轴对象 ax = df.plot(rot=50) # 把每个刻度对应的外层索引提取出来,格式化成不带时间的字符串 new_labels = [idx[0].strftime('%Y-%m-%d') for idx in df.index] # 替换掉原来的X轴标签 ax.set_xticklabels(new_labels) plt.tight_layout() plt.show()
这样原来显示两级索引加时间的冗余标签,就会变成只显示外层的日期,完全符合你的需求。
方法二:绘图时手动指定刻度(更灵活)
如果你的X轴因为内层索引太多显得太挤,想把同一外层索引的多个数据点合并显示一个标签,用这个方法更合适:
import pandas as pd import matplotlib.pyplot as plt # 生成数据(和你原来的代码一致) dt = pd.DatetimeIndex(start='2010-1-1', end='2010-12-31', freq='m') dt2 = pd.DatetimeIndex(start='2011-1-1', end='2011-1-10', freq='d') mi = pd.MultiIndex.from_product([dt, dt2], names=['assessment_date', 'contract_date']) df = pd.DataFrame(index=mi) df['foo'] = 7 # 获取外层索引的唯一值,以及每个外层索引对应的刻度位置 unique_dates = df.index.get_level_values('assessment_date').unique() # 每个外层索引对应len(dt2)行,所以刻度放在每组的中间位置 tick_positions = [i * len(dt2) + len(dt2)//2 for i in range(len(unique_dates))] # 格式化日期为不带时间的字符串 tick_labels = [date.strftime('%Y-%m-%d') for date in unique_dates] # 绘图时指定刻度位置和标签 ax = df.plot(rot=50) ax.set_xticks(tick_positions) ax.set_xticklabels(tick_labels) plt.tight_layout() plt.show()
小提示
- 两种方法都不用修改原DataFrame的结构,所有操作都在绘图阶段完成;
- 日期格式可以自己调,比如把
'%Y-%m-%d'改成'%Y/%m'或者'%Y年%m月'都可以; - 如果你是绘制切片后的子DataFrame(比如
df.loc['2010-01-31']),只要把代码里的df换成切片后的对象就行,逻辑完全通用。
内容的提问来源于stack exchange,提问作者user3556757
相关产品推荐
相关产品推荐

