
本文介绍在 expense tracker 应用中正确绘制柱状图的方法:当日期列表存在重复值(如多笔同日支出)时,避免 matplotlib 自动去重,确保每个数据点独立显示,并精准对应 x 轴标签。
在开发个人记账应用时,常需可视化每日多笔支出——例如同一天内发生三笔消费(100 元、5000 元、1000 元),次日一笔(2000 元)。若直接将 date 列表传入 plt.bar(date, amount),Matplotlib 会将相同日期视为同一类别而自动聚合(如仅显示一个“2014-1-4”柱),导致数据丢失。根本原因在于:bar() 默认将 x 值作为分类标签处理,而非原始索引。
✅ 正确解法是分离位置索引与标签显示:
- 使用 range(len(date)) 生成唯一数值横坐标(0, 1, 2, 3…),保证每笔支出独立成柱;
- 通过 plt.xticks(ticks=..., labels=...) 显式指定每个刻度位置对应的日期字符串,实现“位置不合并,标签可重复”。
以下是完整可运行示例:
import matplotlib.pyplot as plt
# 示例数据:同日多笔支出,日期含重复
date = ['2014-1-4', '2014-1-4', '2014-1-4', '2014-1-5']
amount = [100, 5000, 1000, 2000]
# 创建图形与坐标轴
fig, ax = plt.subplots(figsize=(8, 5))
ind = range(len(date)) # [0, 1, 2, 3] —— 真实绘图位置
# 绘制柱状图(x 为数值索引,非日期字符串)
ax.bar(ind, amount, color='#4a90e2', alpha=0.8)
# 关键:手动设置 x 轴刻度位置和标签
plt.xticks(ticks=ind, labels=date, rotation=30, ha='right')
# 添加基础美化
ax.set_ylabel('Amount (¥)')
ax.set_title('Daily Expense Breakdown (with duplicates)')
ax.grid(axis='y', alpha=0.3)
plt.tight_layout()
plt.show()? 注意事项:
- 切勿使用 ax.bar(date, amount) 或 plt.bar(date, amount) —— 这会导致 Matplotlib 内部对 date 去重并排序;
- 若日期量较大(如数百条),建议添加 rotation=30 和 ha='right' 避免标签重叠;
- 如需按时间顺序分组展示(如汇总每日总额),应先用 pandas.groupby('date').sum() 预处理,而非强制在柱状图中堆叠重复日期;
- 对于长期记账数据,推荐后续升级为 datetime 类型 + matplotlib.dates 模块进行智能时间轴管理。
该方案轻量、可靠,完美适配 Expense Tracker 中“逐笔记录、原样呈现”的需求,是处理非唯一分类标签的通用最佳实践。










