如何让Plotly Graph Objects折线图正确移除rangebreaks的X轴空白?
Plotly Graph Objects 非等间隔Tick数据时间序列图移除X轴空白问题
我用Plotly的Graph Objects绘制股票时间序列折线图(后续将添加多轨迹),数据源为非等间隔的tick数据,无法按时间聚合,必须将X轴设为type=date以保证刻度正确。
数据集示例
import pandas as pd d = {'plotPrice': [107, 107.1, 107.2, 106.9, 107, 106.5, 106, 106.2, 106.8, 107], 'dateTime': [pd.Timestamp('2023-10-24 08:01:56.668000'), pd.Timestamp('2023-10-24 09:25:58.272'), pd.Timestamp('2023-10-26 11:42:09.199'), pd.Timestamp('2023-10-26 14:54:06.095'),pd.Timestamp('2023-10-26 15:25:50.430'),pd.Timestamp('2023-10-30 09:15:33.546'), pd.Timestamp('2023-10-30 11:34:44.861'),pd.Timestamp('2023-10-30 14:18:27.706'),pd.Timestamp('2023-10-30 15:02:33.771'), pd.Timestamp('2023-10-30 16:30:37.412')]} df = pd.DataFrame(data=d)
已尝试的无效方法
- 使用按小时/周末的
rangebreaks规则,无法满足排除特定工作日的需求; - 为
exclude_dates添加时分秒毫秒信息,仅显示首个日期数据; - 按分/秒级设置
exclude_dates,同样仅显示首日数据。
需求:让Plotly正确移除rangebreaks对应的X轴空白。
解决方案:精准定义rangebreaks的values区间
Plotly的exclude_dates仅能排除完整日期,而我们需要排除的是两个有效日期之间的整个时间段(比如2023-10-24到2023-10-26、2023-10-26到2023-10-30之间的空白)。正确做法是生成所有需要排除的时间区间,用rangebreaks.values参数指定这些区间的起止时间。
步骤1:提取有效日期边界,生成排除区间
从数据中提取唯一日期,找出相邻日期的间隔,生成需要排除的时间段:
# 提取日期部分(仅年月日) df['date'] = df['dateTime'].dt.date unique_dates = sorted(df['date'].unique()) # 生成需要排除的时间区间 exclude_ranges = [] for i in range(len(unique_dates)-1): # 前一个日期的结束时间(当天23:59:59.999) end_of_prev = pd.Timestamp(f"{unique_dates[i]} 23:59:59.999") # 后一个日期的开始时间(当天00:00:00.000) start_of_next = pd.Timestamp(f"{unique_dates[i+1]} 00:00:00.000") # 若两个日期不连续,添加该区间到排除列表 if (start_of_next - end_of_prev).days > 1: exclude_ranges.append([end_of_prev, start_of_next])
步骤2:在Graph Objects中配置X轴
将生成的exclude_ranges传入xaxis.rangebreaks.values,同时保留xaxis.type='date':
import plotly.graph_objects as go fig = go.Figure() # 添加价格轨迹 fig.add_trace(go.Scatter( x=df['dateTime'], y=df['plotPrice'], mode='lines+markers', name='Tick Price' )) # 配置X轴,移除空白区间 fig.update_layout( xaxis=dict( type='date', rangebreaks=[ dict(values=exclude_ranges) # 应用排除区间 ], tickformat='%Y-%m-%d %H:%M' # 自定义刻度显示格式 ), title='股票非等间隔Tick数据时间序列', yaxis_title='价格' ) fig.show()
原理说明
rangebreaks.values接受列表格式,每个子列表包含两个时间戳,代表要排除的时间区间;- 该方式可精准排除任意有效日期之间的空白时间段,支持排除周末或特定工作日;
- 无需聚合原始数据,完全保留非等间隔tick数据的时序关系。
内容的提问来源于stack exchange,提问作者hk0101
相关产品推荐
相关产品推荐

