使用twinx绘制Pandas时间序列双Y轴时X轴标签重叠的解决方法
问题描述
我有如下Pandas Series数据:
2022-10-08 0.357143 2022-10-09 0.500000 2022-10-10 0.500000 2022-10-11 0.500000 2022-10-12 0.642857 ... 2022-12-26 1.792857 2022-12-27 1.757143 2022-12-28 1.807143 2022-12-29 2.092857 2022-12-30 1.785714 Name: amount, Length: 84, dtype: float64
我希望为其绘制双Y轴图表:左Y轴显示原始数值,右Y轴显示数值乘以7的结果(代表7天均值对应的总和)。使用以下代码绘图:
#plot 7 day rolling average weekly.plot() # Create a second y-axis to show total weekly hours y2 = plt.twinx() # plot the summation of a 7 day window y2.plot(weekly*7)
但生成的图表出现X轴标签重叠问题;若删除数据中间的一行(如2022-10-12),问题则不会出现,对应代码:
weekly.drop(index="2022-10-12",inplace=True) #plot 7 day rolling average weekly.plot() # Create a second y-axis to show total weekly hours y2 = plt.twinx() # plot the summation of a 7 day window y2.plot(weekly*7)
请问如何解决X轴标签重叠问题?是否有更优的绘图实现方式?
解决方案
一、解决X轴标签重叠问题
1. 自动旋转标签+调整布局
这是最直接的处理方式,通过旋转X轴标签并让布局自动适配,避免重叠:
import matplotlib.pyplot as plt weekly.plot() y2 = plt.twinx() y2.plot(weekly*7) # 旋转X轴标签,避免拥挤 plt.xticks(rotation=45) # 自动调整图表布局,确保标签完整显示 plt.tight_layout() plt.show()
2. 自定义时间刻度密度
针对时间序列数据,可手动设置X轴刻度的显示间隔,比如只保留每周的日期标签:
import matplotlib.pyplot as plt import matplotlib.dates as mdates fig, ax1 = plt.subplots() # 左Y轴绘制原始数据 ax1.plot(weekly.index, weekly.values, label='7天均值') ax1.set_ylabel('7天均值') # 右Y轴绘制乘以7后的结果 ax2 = ax1.twinx() ax2.plot(weekly.index, weekly.values*7, color='orange', label='7天总和') ax2.set_ylabel('7天总和') # 设置X轴为每周一个刻度 ax1.xaxis.set_major_locator(mdates.WeekdayLocator()) # 格式化日期显示格式 ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d')) plt.xticks(rotation=45) plt.tight_layout() # 合并双轴图例 lines1, labels1 = ax1.get_legend_handles_labels() lines2, labels2 = ax2.get_legend_handles_labels() ax1.legend(lines1 + lines2, labels1 + labels2, loc='upper left') plt.show()
3. 修复时间索引连续性
删除某一行后问题消失,说明原数据的时间索引可能存在隐性的非连续/异常问题,先检查并修复索引:
# 强制索引为连续的每日序列 weekly = weekly.asfreq('D') # 用前向填充补全缺失值(按需选择填充方式) weekly = weekly.fillna(method='ffill')
修复索引后再绘图,标签重叠问题大概率会自然解决。
二、更优的绘图实现方式
直接使用Pandas内置的secondary_y参数,代码更简洁,还能自动处理部分布局逻辑:
# 左Y轴绘制原始数据 weekly.plot(ylabel='7天均值', label='7天均值') # 右Y轴绘制乘以7后的结果,无需手动创建twinx (weekly*7).plot(secondary_y=True, ylabel='7天总和', label='7天总和', color='orange') plt.xticks(rotation=45) plt.tight_layout() plt.legend(loc='upper left') plt.show()
这种方式代码紧凑,能自动关联双轴图例,减少手动配置的工作量。
内容的提问来源于stack exchange,提问作者Omar Naguib
相关产品推荐
相关产品推荐

