Python Matplotlib共享坐标轴问题:日期格式丢失与图形分布异常
嘿,我完全懂你遇到的困扰——把两个DataFrame的序列合并到同一个子图后,X轴的日期格式没了,还莫名变成了左右两侧各一个序列的样子,对吧?我来帮你拆解问题、搞定它!
问题根源拆解
- X轴日期丢失:大概率是你第二次绘图时,要么没继承原轴的日期格式设置,要么你的DataFrame日期索引被自动转换成了数值(比如整数 timestamp),导致matplotlib认不出这是日期了。
- 序列分两侧:十有八九是你在第二次绘图时不小心调用了
twinx(),或者没明确指定要复用同一个轴对象,matplotlib自动给第二个序列创建了右侧的Y轴,这才出现了“分两侧”的效果。
解决方案分步走
1. 先统一两个DataFrame的日期索引类型
首先得确保两个DataFrame的索引都是datetime64类型,别让字符串索引搞乱绘图逻辑:
import pandas as pd # 转换索引为datetime(如果还没转的话) df1.index = pd.to_datetime(df1.index) df2.index = pd.to_datetime(df2.index)
2. 在同一个轴上绘制两个序列(核心操作)
明确指定复用同一个ax1对象,不要让matplotlib自动创建新轴。同时手动设置X轴的日期格式,这是找回日期显示的关键:
import matplotlib.pyplot as plt import matplotlib.dates as mdates # 创建单个子图 fig, ax1 = plt.subplots(figsize=(10, 6)) # 绘制第一个DataFrame的序列,指定用ax1 ax1.plot(df1.index, df1['你的列名1'], label='序列1', color='royalblue') # 绘制第二个DataFrame的序列,同样指定ax1,不要新建轴! ax1.plot(df2.index, df2['你的列名2'], label='序列2', color='crimson') # 设置X轴日期格式,自定义成你需要的样式 ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d')) # 自动旋转日期标签,避免重叠 fig.autofmt_xdate() # 添加图例、标题等装饰 ax1.legend() ax1.set_title('同图展示两个序列(带日期X轴)') ax1.set_xlabel('日期') ax1.set_ylabel('数值') plt.tight_layout() plt.show()
3. 如果确实需要双Y轴(可选)
要是你的两个序列数值范围差异极大,真的需要双Y轴,那也要确保X轴日期格式统一:
fig, ax1 = plt.subplots(figsize=(10, 6)) # 第一个序列用左Y轴 ax1.plot(df1.index, df1['列1'], color='royalblue', label='序列1') ax1.set_xlabel('日期') ax1.set_ylabel('序列1数值') ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d')) # 创建右Y轴,共享X轴 ax2 = ax1.twinx() ax2.plot(df2.index, df2['列2'], color='crimson', label='序列2') ax2.set_ylabel('序列2数值') # 合并两个轴的图例 lines1, labels1 = ax1.get_legend_handles_labels() lines2, labels2 = ax2.get_legend_handles_labels() ax1.legend(lines1 + lines2, labels1 + labels2, loc='upper left') fig.autofmt_xdate() plt.tight_layout() plt.show()
避坑提醒
- 绝对不要在第二次绘图时重新创建轴对象,一定要复用一开始的
ax1; - 确保两个DataFrame的日期索引是对齐的,不然会出现X轴错位;
- 字符串类型的日期索引一定要转成
datetime,不然matplotlib会把它当成普通文本处理。
内容的提问来源于stack exchange,提问作者Federico
相关产品推荐
相关产品推荐

