Matplotlib周间隔日期x轴堆叠柱形图如何减小柱间间距
问题原因
matplotlib 对日期类型x轴是按真实时间跨度计算坐标范围的,调用ax.bar()时默认柱宽为0.8,在日期轴下这个数值的单位是天。周频数据的点间隔为7天,0.8天宽的柱子放在7天的间隔里,自然会留出大量空白。
实现方法
最稳妥的通用方案是:先用连续整数索引作为柱体的实际绘制位置,保证柱之间紧密排列,再手动把x轴刻度替换成对应的周度日期标签,既完全保留日期的显示格式,又不会出现大段空隙。
完整可运行代码
import pandas as pd from datetime import datetime import matplotlib.pyplot as plt import numpy as np # 生成原始周度日期序列 date_list = pd.date_range(end=datetime.today(), periods=150, freq='W').to_pydatetime().tolist() val1 = np.random.rand(150) val2 = np.random.rand(150)/2 # 生成连续整数作为柱体的绘制坐标,保证柱体无空隙 x_pos = np.arange(len(date_list)) fig = plt.figure(figsize=(10,6), dpi=100) ax = fig.add_subplot(111) # 基于整数坐标绘制堆叠柱 ax.bar(x_pos, val1, label='x_1') ax.bar(x_pos, val2, label='x_2', bottom=val1) # 设置x轴刻度:每隔4个数据点(约1个月)显示一个标签,避免文字过密 tick_interval = 4 ax.set_xticks(x_pos[::tick_interval]) # 把刻度位置对应到原始日期,格式化后作为标签显示 ax.set_xticklabels( [dt.strftime('%Y-%m-%d') for dt in date_list[::tick_interval]], rotation=45, ha='right' ) plt.legend() plt.tight_layout() # 自动调整布局,防止日期标签被截断 plt.show()
简易快速方案
如果不想修改x轴的绘制逻辑,也可以直接调整柱宽适配周度间隔:因为两个数据点间隔为7天,给bar()传入width=6.9(略小于7天),就能让柱体基本挨在一起。
只需要修改原代码中两行bar调用即可:
ax.bar(x, x_1, label='x_1', width=6.9) ax.bar(x, x_2, label='x_2', bottom=x_1, width=6.9)
注意:这个方案只适用于周频数据,如果后续把数据改成日度、月度频率,需要同步修改width参数,通用性不如前面的自定义刻度方案。
内容的提问来源于stack exchange,提问作者RemedyS
相关产品推荐
相关产品推荐

