You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Matplotlib时间序列柱状图:柱子重叠与时间范围异常修复

时间序列柱状图重叠与时间范围异常修复方案

问题背景

拥有某一日期9:00至13:00的时间序列数据,End_Datetime字段为datetime64[ns]类型,VOLUME字段为float64类型。使用Matplotlib绘制柱状图时出现两个问题:

  • 柱子相互重叠
  • 图表显示的时间范围远超出9:00-13:00窗口
    但绘制折线图时无异常,需在不使用Seaborn的前提下完成修复。

数据示例

{'End_Datetime': {0: Timestamp('2024-02-29 09:14:59.999000'),
  1: Timestamp('2024-02-29 09:29:59.999000'),
  2: Timestamp('2024-02-29 09:44:59.999000'),
  3: Timestamp('2024-02-29 09:59:59.999000'),
  4: Timestamp('2024-02-29 10:14:59.999000'),
  5: Timestamp('2024-02-29 10:29:59.999000'),
  6: Timestamp('2024-02-29 10:44:59.999000'),
  7: Timestamp('2024-02-29 10:59:59.999000'),
  8: Timestamp('2024-02-29 11:14:59.999000'),
  9: Timestamp('2024-02-29 11:29:59.999000'),
  10: Timestamp('2024-02-29 11:44:59.999000'),
  11: Timestamp('2024-02-29 11:59:59.999000'),
  12: Timestamp('2024-02-29 12:14:59.999000'),
  13: Timestamp('2024-02-29 12:29:59.999000'),
  14: Timestamp('2024-02-29 12:44:59.999000'),
  15: Timestamp('2024-02-29 12:59:59.999000'),
  16: Timestamp('2024-02-29 13:14:59.999000'),
  17: Timestamp('2024-02-29 13:29:59.999000'),
  18: Timestamp('2024-02-29 13:44:59.999000')},
 'VOLUME': {0: 45000.0,
  1: 142000.0,
  2: 55000.0,
  3: 39000.0,
  4: 66000.0,
  5: 32000.0,
  6: 28000.0,
  7: 30000.0,
  8: 21000.0,
  9: 18000.0,
  10: 61000.0,
  11: 154000.0,
  12: 33000.0,
  13: 24000.0,
  14: 13000.0,
  15: 12000.0,
  16: 339000.0,
  17: 31000.0,
  18: 281000.0}}

原使用代码

import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import pandas as pd

fig, ax = plt.subplots(nrows=1, ncols = 1,dpi=600, figsize=(12,9))
ax.bar(x=df['End_Datetime'], height = df['VOLUME'].values, color = 'blue', label = '15 mins Bin Volume', edgecolor = 'white', alpha=0.5)
ax.set_ylabel('Volume')
ax.legend(fontsize=6, title_fontsize=8, loc='upper left')
ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))
fig.tight_layout()
fig.show()

问题原因

Matplotlib的bar函数默认宽度为0.8,当x轴为datetime类型时,该宽度会被解析为天。你的数据间隔为15分钟(即1/96天),0.8天的宽度远大于数据间隔,直接导致柱子重叠;同时自动缩放的x轴会包含柱子的全部宽度,因此显示范围超出预期的9:00-13:00。

修复方案

修改思路

  1. 设置匹配数据间隔的柱子宽度:将宽度设置为略小于数据间隔的天数,避免柱子重叠。
  2. 手动限定x轴时间范围:明确设置x轴的起止时间,锁定到目标窗口。

修改后的代码

import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import pandas as pd

fig, ax = plt.subplots(nrows=1, ncols=1, dpi=600, figsize=(12,9))
# 计算15分钟间隔的0.8倍作为柱子宽度(单位:天)
bar_width = 15/(24*60)*0.8
ax.bar(x=df['End_Datetime'], height=df['VOLUME'].values, width=bar_width, 
       color='blue', label='15 mins Bin Volume', edgecolor='white', alpha=0.5)
ax.set_ylabel('Volume')
ax.legend(fontsize=6, title_fontsize=8, loc='upper left')
ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))
# 设置x轴范围为9:00到13:00
x_start = pd.Timestamp('2024-02-29 09:00:00')
x_end = pd.Timestamp('2024-02-29 13:00:00')
ax.set_xlim(x_start, x_end)
# 添加小时刻度,优化x轴显示
ax.xaxis.set_major_locator(mdates.HourLocator(interval=1))
fig.tight_layout()
fig.show()

额外优化

如果数据间隔不固定,可以通过计算相邻时间差的最小值动态设置柱子宽度:

# 计算最小时间间隔(单位:天)
min_diff = df['End_Datetime'].diff().min().total_seconds()/(24*3600)
# 设置为最小间隔的0.8倍
bar_width = min_diff * 0.8

内容的提问来源于stack exchange,提问作者user1769197

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 11:47:04