Matplotlib工单-日期映射柱状图绘制报错及双柱实现咨询
嘿,这个问题我之前踩过坑!Matplotlib 的 bar 函数处理日期数值时确实有小脾气,咱们一步步解决它,顺便实现你要的「每个工单对应两个柱状条」的需求。
先搞懂报错原因
你遇到的 ValueError: ordinal must be >= 1,本质是 ax.yaxis_date() 和 bar 函数的日期处理逻辑冲突了——plot 对日期数值兼容性更好,但 bar 需要我们更明确地告诉 Matplotlib 怎么解析 Y 轴的日期刻度,不能全靠自动处理。
先修正测试代码的报错
咱们先把你简化的测试代码改成能正常显示柱状图的版本:
import matplotlib.pyplot as plt import matplotlib.dates as mdates from numpy import arange from datetime import datetime date = ['3 Jan 2013', '4 Jan 2013', '5 Jan 2013'] tickets = ['ENV-666', 'ENV-999', 'ENV-1000'] # 用datetime转成对象再转Matplotlib数值,比直接用datestr2num更稳妥 date_objs = [datetime.strptime(d, '%d %b %Y') for d in date] y = mdates.date2num(date_objs) x = arange(len(tickets)) width = 0.4 fig, ax = plt.subplots() ax.bar(x, y, width=width) # 手动指定Y轴的日期定位和格式,替代ax.yaxis_date() ax.yaxis.set_major_locator(mdates.DayLocator()) # 按天显示刻度 ax.yaxis.set_major_formatter(mdates.DateFormatter('%d %b %Y')) # 自定义日期显示格式 # 设置X轴的刻度和标签 ax.set_xticks(x) ax.set_xticklabels(tickets) fig.autofmt_xdate() # 自动旋转X轴标签避免重叠 plt.show()
扩展到你的实际需求:每个工单两个柱状条
接下来咱们实现「每个工单对应预计/实际解决日期两个柱子」的核心需求,关键是给两个柱子设置不同的 X 偏移量,避免重叠:
import matplotlib.pyplot as plt import matplotlib.dates as mdates from numpy import arange from datetime import datetime # 模拟你的业务数据 tickets = ['ENV-666', 'ENV-999', 'ENV-1000'] est_dates = ['3 Jan 2013', '4 Jan 2013', '6 Jan 2013'] # 预计解决日期 real_dates = ['5 Jan 2013', '4 Jan 2013', '5 Jan 2013'] # 实际解决日期 # 把日期字符串转成Matplotlib能识别的数值 est_y = mdates.date2num([datetime.strptime(d, '%d %b %Y') for d in est_dates]) real_y = mdates.date2num([datetime.strptime(d, '%d %b %Y') for d in real_dates]) x = arange(len(tickets)) width = 0.35 # 调整宽度让两个柱子刚好并排 fig, ax = plt.subplots() # 给两个柱子设置不同的X偏移,避免重叠 ax.bar(x - width/2, est_y, width=width, label='预计解决日期') ax.bar(x + width/2, real_y, width=width, label='实际解决日期') # 配置Y轴的日期显示 ax.yaxis.set_major_locator(mdates.DayLocator()) ax.yaxis.set_major_formatter(mdates.DateFormatter('%d %b %Y')) # 配置X轴和其他标签 ax.set_xticks(x) ax.set_xticklabels(tickets) ax.set_xlabel('工单编号') ax.set_ylabel('解决日期') # 添加图例区分两个柱子 ax.legend() # 自动优化布局,避免标签被截断 fig.autofmt_xdate() plt.tight_layout() plt.show()
关键要点总结
- 用
datetime.strptime+mdates.date2num转换日期,比直接用datestr2num更可控,避免格式解析错误 - 手动设置 Y 轴的日期定位器和格式化器,是解决
ordinal must be >=1报错的核心 - 通过
x ± width/2给两个柱子设置偏移,实现并排显示的效果
内容的提问来源于stack exchange,提问作者Roman
相关产品推荐
相关产品推荐

