如何在同一坐标轴正确绘制不同DataFrame的日期折线图?
双坐标轴绘图时折线日期范围被强制对齐的修复方案
问题场景
现有两个DataFrame数据:
dict1 = {'Date': ['2022-12-02', '2022-12-16', '2023-01-15'], 'Impressions': [20, 21, 19]} dict2 = {'Date': ['2022-08-02', '2022-09-16', '2023-02-20'], 'Impressions': [18, 51, 48]} df1 = pd.DataFrame(dict1) df2 = pd.DataFrame(dict2)
使用以下代码绘制双坐标轴折线图时,df1的实线折线起止日期被强制和df2的虚线折线对齐(起始变为2022-08-02,结束变为2023-02-20),不符合预期:
fig, ax = plt.subplots() ax2 = ax.twinx() df1.plot(x="Date", y="Impressions", ax=ax) df2.plot(x="Date", y="Impressions", ax=ax2, ls="--") plt.show()
原因分析
问题出在Date列的类型是字符串,pandas的plot方法会把字符串类型的x轴当作离散类别处理,创建双轴后,两个轴的x轴类别范围会被强制统一,导致折线被拉伸填充整个类别区间。
修复方案
最稳妥的解决方式是将Date列转换为datetime时间类型,让matplotlib识别为连续的时间轴,这样每个折线只会绘制自身存在的日期区间,不会被强制对齐到另一个的范围。
修改后的完整代码:
import pandas as pd import matplotlib.pyplot as plt dict1 = {'Date': ['2022-12-02', '2022-12-16', '2023-01-15'], 'Impressions': [20, 21, 19]} dict2 = {'Date': ['2022-08-02', '2022-09-16', '2023-02-20'], 'Impressions': [18, 51, 48]} df1 = pd.DataFrame(dict1) df2 = pd.DataFrame(dict2) # 关键:将字符串日期转换为datetime类型 df1['Date'] = pd.to_datetime(df1['Date']) df2['Date'] = pd.to_datetime(df2['Date']) # 绘制双轴图 fig, ax = plt.subplots() ax2 = ax.twinx() # 分别绘制折线并添加标签 df1.plot(x="Date", y="Impressions", ax=ax, label='df1 曝光量') df2.plot(x="Date", y="Impressions", ax=ax2, ls="--", label='df2 曝光量') # 添加图例区分两条线 ax.legend(loc='upper left') ax2.legend(loc='upper right') plt.show()
效果说明
转换为datetime类型后,x轴会自动适配两个DataFrame的整体时间范围,但df1的折线只会在2022-12-02到2023-01-15之间绘制,df2的折线则在2022-08-02到2023-02-20之间绘制,各自保留原本的日期区间,不会被强制拉伸。
内容的提问来源于stack exchange,提问作者Dushu
相关产品推荐
相关产品推荐

