如何在Bokeh中移除无对应数据的日期并消除图表长连线?
解决Bokeh图表中无数据日期的长连线问题
核心原因
当时间序列数据中存在**日期间隔过大(无匹配数据)**的情况时,Bokeh的line方法会直接连接前后两个有效数据点,从而产生横跨无数据日期的长连线。
可行解决方案
方案1:用NaN中断连线(推荐)
在数据中检测到前后两个数据点的时间间隔超过阈值时,插入NaN值,Bokeh绘制线时会自动在NaN位置断开连线。
修改代码步骤:
- 用Pandas处理DataFrame,计算相邻日期的时间间隔
- 在间隔超阈值的位置插入
NaN中断连线 - 重新生成数据源
修改后的完整代码:
def get(self, request): user=request.user historical_me=FinancialInstrument.objects.all() form = self.form_class(historical_me=historical_me) retrive=HistoricalData.objects.all() get_symbol=retrive.filter(instrument__symbol="BTUSD").order_by('datetime') fields=get_symbol.values('datetime','opening_price','closing_price','min_price','max_price','volume') df=pd.DataFrame.from_records(fields) # 转换datetime为Pandas可处理的时间类型 df['datetime'] = pd.to_datetime(df['datetime']) # 计算相邻数据点的时间间隔(单位:小时) df['time_diff'] = df['datetime'].diff().dt.total_seconds() / 3600 # 设定正常时间间隔阈值(可根据数据更新频率调整,日级数据设为24) threshold = 24 x_values = [] y_values = [] for idx, row in df.iterrows(): x_values.append(row['datetime']) y_values.append(float(row['opening_price'])) # 非最后一行且间隔超阈值时,插入NaN中断连线 if idx < len(df)-1 and df.loc[idx+1, 'time_diff'] > threshold: x_values.append(None) y_values.append(None) source = ColumnDataSource(data=dict(dater=x_values,pricer=y_values)) plot = figure(title="New title", width=780, height=400, x_axis_label="Date", y_axis_label="Max Price", x_axis_type="datetime") plot.line(x='dater',y='pricer', source=source,line_width=3) plot.toolbar.autohide = True script, div = components(plot) if user.is_authenticated: return render( request, self.template_name, { 'form':form, 'days_of_month': [i for i in range(1,32)], 'script':script, 'div':div, }) return redirect('home')
方案2:分割连续时间区间绘制多段线
将数据分割为多个连续的时间子序列,使用multi_line分别绘制每个子序列的线,不同子序列之间不会产生跨无数据日期的连线。
方案3:过滤非连续数据
如果只需要展示连续的时间区间,可以直接筛选出无间隔的连续数据段进行绘制,跳过存在大间隔的部分。
额外注意事项
- 原代码中重复调用的
plot.line(x='datetime', y='opening_price', source=source)会报错,因为source中不存在datetime和opening_price字段,建议删除该行。 - 阈值
threshold需根据实际数据更新频率调整(比如小时级数据可设为1)。
内容的提问来源于stack exchange,提问作者D0r1v4ld0
相关产品推荐
相关产品推荐

