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

纳秒级时间帧蝴蝶图绘制异常:仅显示直条问题求助

问题描述

编写代码意图绘制蝴蝶图:bid_size_1(买盘量)为向上的蓝色条形,ask_size_1(卖盘量)为向下的红色条形,但实际运行后仅显示两条直条,推测是纳秒级的极小时间尺度导致。原本需要同时展示微秒级和秒级的时序变化,简化问题后仍存在纳秒级数据展示异常。

相关代码与数据如下:

import pandas as pd
import matplotlib.pyplot as plt

# Your DataFrame
data = {
    'event_timestamp': ['2023-12-01 09:03:30.253234659', '2023-12-01 09:03:30.253258248', '2023-12-01 09:03:30.253284376',
                        '2023-12-01 09:03:30.253286780', '2023-12-01 09:03:30.253293758', '2023-12-01 09:03:30.253299003',
                        '2023-12-01 09:03:30.253334034', '2023-12-01 09:03:30.259143344'],
    'bid_size_1': [110.0, 30.0, 65.0, 96.0, 146.0, 146.0, 161.0, 111.0],
    'ask_size_1': [145.0, 145.0, 145.0, 145.0, 145.0, 125.0, 125.0, 125.0]
}

df = pd.DataFrame(data)

# Convert 'event_timestamp' column to datetime
df['event_timestamp'] = pd.to_datetime(df['event_timestamp'])

# Plotting
plt.figure(figsize=(12, 6))

# Plot bid_size_1 (blue bars going up)
plt.bar(df['event_timestamp'], df['bid_size_1'], color='blue')

# Plot ask_size_1 (red bars going down)
plt.bar(df['event_timestamp'], -df['ask_size_1'], color='red')

plt.xlabel('Timestamp')
plt.ylabel('Size')
plt.title('Butterfly Chart')
plt.grid(True)
plt.xticks(rotation=45)
plt.tight_layout()
#plt.xscale('log')
plt.show()

完整数据集:

+-------------------------------+------------+------------+
|        event_timestamp        | bid_size_1 | ask_size_1 |
+-------------------------------+------------+------------+
| 2023-12-01 09:03:30.253234659 |    110.0   |    145.0   |
| 2023-12-01 09:03:30.253258248 |    30.0    |    145.0   |
| 2023-12-01 09:03:30.253284376 |    65.0    |    145.0   |
| 2023-12-01 09:03:30.253286780 |    96.0    |    145.0   |
| 2023-12-01 09:03:30.253293758 |    146.0   |    145.0   |
| 2023-12-01 09:03:30.253299003 |    146.0   |    125.0   |
| 2023-12-01 09:03:30.253334034 |    161.0   |    125.0   |
| 2023-12-01 09:03:30.259143344 |    111.0   |    125.0   |
| 2023-12-01 09:03:33.831668204 |    76.0    |    125.0   |
| 2023-12-01 09:03:34.300859840 |    61.0    |    145.0   |
| 2023-12-01 09:03:35.250246888 |    70.0    |    145.0   |
| 2023-12-01 09:03:42.867285196 |    40.0    |    145.0   |
+-------------------------------+------------+------------+
问题原因

matplotlib的bar函数处理datetime类型x轴时,会根据数据点的时间间隔自动设置条形宽度。前7条数据的时间间隔仅为几纳秒到几十纳秒,默认宽度被压缩到几乎不可见,只有最后几条时间间隔较大(秒级)的条形能显示,因此看起来只有两条直条。

解决方案

以下两种方法可解决条形重叠问题,同时支持展示微秒和秒级时序变化:

方法1:手动设置条形的时间宽度

将条形宽度设为固定时间增量(如微秒级),确保每个条形清晰显示:

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.dates import DateFormatter

# 加载完整数据
data = {
    'event_timestamp': ['2023-12-01 09:03:30.253234659', '2023-12-01 09:03:30.253258248', '2023-12-01 09:03:30.253284376',
                        '2023-12-01 09:03:30.253286780', '2023-12-01 09:03:30.253293758', '2023-12-01 09:03:30.253299003',
                        '2023-12-01 09:03:30.253334034', '2023-12-01 09:03:30.259143344',
                        '2023-12-01 09:03:33.831668204', '2023-12-01 09:03:34.300859840',
                        '2023-12-01 09:03:35.250246888', '2023-12-01 09:03:42.867285196'],
    'bid_size_1': [110.0, 30.0, 65.0, 96.0, 146.0, 146.0, 161.0, 111.0,76.0,61.0,70.0,40.0],
    'ask_size_1': [145.0, 145.0, 145.0, 145.0, 145.0, 125.0, 125.0, 125.0,125.0,145.0,145.0,145.0]
}

df = pd.DataFrame(data)
df['event_timestamp'] = pd.to_datetime(df['event_timestamp'])

plt.figure(figsize=(14, 6))

# 设置条形宽度为5微秒(可根据数据密度调整)
bar_width = pd.Timedelta('5us')

# 绘制买盘(向上蓝条)
plt.bar(df['event_timestamp'], df['bid_size_1'], width=bar_width, color='blue', label='Bid Size')
# 绘制卖盘(向下红条)
plt.bar(df['event_timestamp'], -df['ask_size_1'], width=bar_width, color='red', label='Ask Size')

# 自定义时间格式,显示到微秒
date_formatter = DateFormatter('%H:%M:%S.%f')
plt.gca().xaxis.set_major_formatter(date_formatter)

plt.xlabel('Timestamp')
plt.ylabel('Size')
plt.title('Butterfly Chart (Microsecond Resolution)')
plt.grid(True, axis='y')
plt.xticks(rotation=45)
plt.legend()
plt.tight_layout()
plt.show()

方法2:用索引作为x轴,自定义刻度标签

改用数据索引作为x轴,将时间戳设为刻度标签,完全控制显示效果:

import pandas as pd
import matplotlib.pyplot as plt

# 加载完整数据
data = {
    'event_timestamp': ['2023-12-01 09:03:30.253234659', '2023-12-01 09:03:30.253258248', '2023-12-01 09:03:30.253284376',
                        '2023-12-01 09:03:30.253286780', '2023-12-01 09:03:30.253293758', '2023-12-01 09:03:30.253299003',
                        '2023-12-01 09:03:30.253334034', '2023-12-01 09:03:30.259143344',
                        '2023-12-01 09:03:33.831668204', '2023-12-01 09:03:34.300859840',
                        '2023-12-01 09:03:35.250246888', '2023-12-01 09:03:42.867285196'],
    'bid_size_1': [110.0, 30.0, 65.0, 96.0, 146.0, 146.0, 161.0, 111.0,76.0,61.0,70.0,40.0],
    'ask_size_1': [145.0, 145.0, 145.0, 145.0, 145.0, 125.0, 125.0, 125.0,125.0,145.0,145.0,145.0]
}

df = pd.DataFrame(data)
df['event_timestamp'] = pd.to_datetime(df['event_timestamp'])

plt.figure(figsize=(14, 6))

# 使用索引作为x轴
x = df.index

# 绘制买盘和卖盘
plt.bar(x, df['bid_size_1'], width=0.4, color='blue', align='center', label='Bid Size')
plt.bar(x, -df['ask_size_1'], width=0.4, color='red', align='center', label='Ask Size')

# 设置x轴刻度为时间戳,显示到微秒
plt.xticks(x, df['event_timestamp'].dt.strftime('%H:%M:%S.%f'), rotation=45)

plt.xlabel('Timestamp')
plt.ylabel('Size')
plt.title('Butterfly Chart (Custom Index Axis)')
plt.grid(True, axis='y')
plt.legend()
plt.tight_layout()
plt.show()
说明
  • 方法1保留datetime轴的自动缩放特性,调整bar_width参数可适配不同数据密度;
  • 方法2更灵活,完全控制刻度显示,适合时间跨度大(从纳秒到秒级)的数据集;
  • 两种方法均可完整显示所有条形,解决原代码仅显示少数条形的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 10:04:51