Matplotlib自定义日期X轴柱状图添加双轴折线图后日期偏移问题
问题分析与解决方案
嘿,这个问题我之前也碰到过,核心是Matplotlib对类别型X轴的索引对齐逻辑在搞鬼:你最初画柱状图时,X轴是old_dates(8个日期)加date_list(14个日期)拼成的22个连续类别,每个类别对应一个从0到21的索引。但加双轴折线图时,delta_dates只有13个元素,Matplotlib会默认把这13个当成新的X轴类别,直接打乱了原柱状图的索引映射——旧日期的位置自然就被挤偏了,同时因为类别数量变化,部分标签还会被自动隐藏。
解决思路
要让两者完美对齐,必须让柱状图和折线图基于同一个完整的日期类别列表,然后通过索引定位折线图的绘制位置,而不是直接用delta_dates当X轴。
具体代码修改步骤
- 先创建包含所有日期的完整列表:
full_dates = old_dates.append(date_list) # 拼接得到7.1到7.22的22个日期
- 绘制柱状图时,直接用
full_dates作为X轴,通过切片对应新旧数据的位置:
# 旧数据对应前8个日期(索引0-7) ax1.bar(full_dates[:8], old_data['green'], color='green', zorder=5, linewidth=0.5, edgecolor='white') ax1.bar(full_dates[:8], old_data['orange'], color='orange', bottom=old_data['green'], zorder=5, linewidth=0.5, edgecolor='white') ax1.bar(full_dates[:8], old_data['red'], color='red', bottom=bars_old, zorder=5, linewidth=0.5, edgecolor='white') # 新数据对应后14个日期(索引8-21) ax1.bar(full_dates[8:], df_['Green'], color='green', zorder=5, linewidth=line_width, edgecolor=edge_colors) ax1.bar(full_dates[8:], df_['Orange'], color='orange', bottom=df_['Green'], linewidth=line_width, zorder=5, edgecolor=edge_colors) ax1.bar(full_dates[8:], df_['Red'], color='red', bottom=bars_new, zorder=5, linewidth=line_width, edgecolor=edge_colors)
- 绘制折线图时,先找到
delta_dates在full_dates中的对应索引,再用这些索引作为X轴位置:
# 获取delta_dates对应的索引(对应full_dates里的第9到21个日期,也就是索引8到20) delta_indices = [full_dates.get_loc(date) for date in delta_dates] ax2 = ax1.twinx() # 用索引定位,确保和柱状图的X轴完全对齐 ax2.plot(delta_indices, deltas, 'r', marker='o', markersize=15, lw=5) plt.ylim(-2.5, 2.5)
这样改完之后,柱状图和折线图就共享同一个X轴类别了,索引完全匹配,旧日期偏移、标签丢失的问题就解决了。另外如果觉得X轴标签挤,可以加一行调整旋转:
plt.xticks(rotation=45, ha='right')
内容的提问来源于stack exchange,提问作者Eli Turasky
相关产品推荐
相关产品推荐

