如何同图绘制不同时间戳的两个pandas DataFrame并格式化x轴刻度
错误原因
两种写法的核心问题都是提前转换了x轴输入的类型,导致前后操作类型不匹配:
- 第一种写法提前将epoch时间戳转成字符串传入
plt.plot()作为x值,matplotlib会将字符串识别为离散分类坐标,而后续plt.xlim()传入的是数值型的epoch范围,两类坐标体系完全不兼容,因此无法渲染数据、也无法生成正常刻度。 - 第二种写法误用了pandas内置plot的参数规则:
df.plot()的第一个位置参数是指定x轴所用列的列名,要求传入字符串,你直接传入了转换后的整列时间字符串序列,pandas会把序列里的每个时间值当成要查找的列名,因此触发KeyError。
实现方案
你提出的「内部数据处理全程使用epoch时间格式,仅在x轴刻度最终渲染时转换为人类可读格式」是最适配异步时序数据场景的思路,完全不需要提前修改原始时间列,只需要通过matplotlib的自定义刻度格式化器,在渲染阶段完成格式转换即可。
可直接运行的参考代码:
import pandas as pd import matplotlib.pyplot as plt from matplotlib.ticker import FuncFormatter # 加载两组时序数据 mydict = [{'time': 1651816500, 'b': 2}, {'time': 1651816800, 'b': 200}, {'time': 1651817100, 'b': 2000}] mydf = pd.DataFrame(mydict) yourdict = [{'time': 1651816490, 'b': 20}, {'time': 1651816805, 'b': 170}, {'time': 1651817105, 'b': 1000}] yourdf = pd.DataFrame(yourdict) # 绘图全程使用原始epoch数值作为x轴输入,不做任何提前格式转换 plt.plot(mydf['time'], mydf['b'], label='dataset1') plt.plot(yourdf['time'], yourdf['b'], label='dataset2') # 设置x轴显示范围,直接传入epoch数值即可 start = mydf.iloc[0, 0] end = mydf.iloc[-1, 0] plt.xlim(start, end) # 定义刻度格式化函数:仅在渲染刻度时,将数值型epoch转为可读时间字符串 def format_epoch_tick(tick_val, tick_pos): return pd.to_datetime(tick_val, unit='s').strftime('%Y-%m-%d %H:%M') # 为x轴绑定自定义格式化器 plt.gca().xaxis.set_major_formatter(FuncFormatter(format_epoch_tick)) # 可选:旋转x轴标签避免文字重叠,添加图例 plt.xticks(rotation=30) plt.legend() plt.tight_layout() plt.show()
方案说明
- 所有坐标计算、范围设置、数据对齐逻辑全程基于数值型epoch时间完成,两组异步采集、时间戳不重合的数据可以正常在同一坐标系下展示,不会出现类型不匹配问题。
- 不需要修改原始DataFrame的存储格式,完全符合内部数据保持epoch格式的要求。
- 时间展示格式调整非常灵活,只需要修改
strftime()内的格式串,就可以按需切换展示精度(比如精确到秒、只显示日期等)。 - 如果需要调整x轴刻度密度,可以搭配
matplotlib.ticker下的MultipleLocator等工具设置刻度间隔,所有计算依然基于原始epoch数值,不会引入对齐误差。
内容的提问来源于stack exchange,提问作者Andreas Schuldei
相关产品推荐
相关产品推荐

