
本文介绍在支出追踪应用中绘制柱状图的正确方法,解决因日期重复导致 x 轴自动合并的问题——通过使用数值索引作为横坐标、手动设置刻度标签,确保每个数据点独立显示。
在开发个人记账类应用(如 Expense Tracker)时,常需以日期为横轴、金额为纵轴绘制柱状图来直观展示每日多笔支出。但若原始数据中存在重复日期(例如同一天有多笔消费),直接将 date 列表传入 plt.bar(date, amount) 会导致 Matplotlib 自动去重并聚合——这不是我们想要的效果;我们需要的是“每笔记录一个柱子”,即使日期相同也应独立呈现。
正确的做法是:用整数索引(0, 1, 2, ..., n-1)作为柱子的横坐标位置,再通过 plt.xticks() 显式指定每个位置对应的日期标签。这样既保留了所有数据点的独立性,又准确反映了时间维度信息。
以下是一个完整可运行的示例:
import matplotlib.pyplot as plt
# 示例数据:同一天有多笔支出(日期可重复)
date = ['2014-1-4', '2014-1-4', '2014-1-4', '2014-1-5']
amount = [100, 5000, 1000, 2000]
# 创建数值索引:[0, 1, 2, 3]
ind = range(len(date))
# 绘制柱状图(x 坐标为索引,非日期字符串)
fig, ax = plt.subplots(figsize=(8, 5))
ax.bar(ind, amount, color='#4CAF50', alpha=0.8)
# 将索引位置映射为对应日期标签
plt.xticks(ticks=ind, labels=date, rotation=45, ha='right')
# 添加基础图表装饰
ax.set_ylabel('Amount (¥)')
ax.set_title('Daily Expense Breakdown (with duplicates)')
ax.grid(axis='y', linestyle='--', alpha=0.7)
plt.tight_layout() # 防止日期标签被截断
plt.show()✅ 关键要点总结:
- ❌ 不要直接用 bar(date, amount) —— 字符串型日期会触发 Matplotlib 的分类聚合逻辑;
- ✅ 必须用 bar(ind, amount) + xticks(ticks=ind, labels=date) 分离位置与语义;
- ? 若需进一步分组(如按天汇总),应在绘图前用 pandas.groupby('date').sum() 预处理,而非依赖绘图函数;
- ? 对于大量数据,建议添加 rotation=45 和 ha='right' 提升日期标签可读性,并调用 tight_layout() 避免遮挡。
该方案轻量、可靠,适用于 Flask/Django/Streamlit 等各类 Python Web 或桌面记账应用的可视化模块。










