纳秒级时间帧蝴蝶图绘制异常:仅显示直条问题求助
问题描述
编写代码意图绘制蝴蝶图: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
相关产品推荐
相关产品推荐

