Bokeh Server plot 未按需更新,它还不断移动并且轴信息消失

Bokeh Server plot not updating as wanted, also it keeps shifting and axis information vanishes

我希望在单击 "refresh button" 后使用新数据更新绘图。但是旧数据保留在图中,并且它一直向右下移并且刻度消失。

一开始,情节符合我的预期(除了 X 轴信息。作为附带问题,我在 Bokeh 属性中查找了 DataSpec(),但不确定如何传递 accept_datetime=False 到线图中的 x 参数。我的代码看起来像这样。)

数据目录看起来像

root-|
     |-weeklydata1.pkl
     |-weeklydata2.pkl
     |-datashow.py

Here 是 pickled 数据文件。

from bokeh.layouts import column, row
from bokeh.models.widgets import Button
from bokeh.plotting import figure, show
from pandas import *

# Callbacks
def update_data():
    # Set up plot
    global p
    global f
    # p = figure(title="testing plot")

    # Set up data
    # weeklybdxdata(1)
    print("reading new data")
    df1 = read_pickle('weeklydata2.pkl')
    for j in df1.columns:
        p.line(df1.index,
               df1[j],
               legend=j,
               line_color=f[j])
        p.circle(df1.index,
                 df1[j],
                 size=10,
                 color=f[j])
    return p

# Set up data
df =read_pickle('weeklydata1.pkl')
f = dict(OAT='green', SAT='orange', OAH='red')

# Set up plot
p = figure(title="testing plot")

for i in df.columns:
    p.line(df.index,
           df[i],
           legend=i,
           line_color=f[i])
    p.circle(df.index,
             df[i],
             size=10,
             color=f[i])

# Set up widgets
button = Button(label='Refresh')
button.on_click(update_data)
inputs = column(button)

curdoc().add_root(row(inputs, p, width=800))
curdoc().title = "Test Plot"

我避免使用 bokeh.models.ColumnDataSource,因为我找不到一些关于如何传递数据帧的好例子。

在我使用 bokeh serve datashow.py 启动代码后,初始图如下所示(小抱怨:但 x 轴以毫秒为单位)

点击刷新后,连续刷新多次,剧情一直在移动,坐标轴信息消失

我正在使用最新版本的 Bokeh 1.4.0

默认情况下,Bokeh 自动调整所有可用字形的范围。你上面的代码无限地积累了新的字形。所以,你看到的结果是意料之中的。您可以尝试在更新函数中主动删除之前的圆圈和线条字形,但这不是我推荐的。 更新 绘图的最佳方法,也就是 Bokeh 被优化以高效且良好地执行的方法,是设置所有字形 一次,然后稍后,只为他们更新 data

即需要直接使用ColumnDataSource。我注意到你说:

I avoided using bokeh.models.ColumnDataSource as I couldn't find some good examples on how to pass dataframes.

我不确定你在看哪里。在文档和回购协议的 examples 文件夹中有很多示例同时使用 CDS 和 Pandas。您可以通过直接适配 DataFrame 来初始化 CDS:

source = ColumnDataSource(df)

然后当你想更新 source 时,你可以这样做;

source = ColumnDataSource.from_df(new_df)

这是一个完整的原型示例:

import pandas as pd
from bokeh.layouts import column
from bokeh.models import Button, ColumnDataSource
from bokeh.plotting import figure
from bokeh.io import curdoc

df = pd.DataFrame(dict(x=[1,2,3], y1=[4,5,6], y2=[2,3,4]))

source = ColumnDataSource(df)

plot = figure()
plot.line('x', 'y1', line_width=3, source=source)
plot.line('x', 'y2', line_width=3, color="red", source=source)

def update():
    new_df = pd.DataFrame(dict(x=[1,2,3], y1=[6,5,4], y2=[4,3,2]))
    source.data = ColumnDataSource.from_df(new_df)

button = Button()
button.on_click(update)

curdoc().add_root(column(button, plot))

small gripe: but with the xaxis in milliseconds

你当然可以有一个日期时间轴,如果那是你想要的:

https://docs.bokeh.org/en/latest/docs/user_guide/plotting.html#datetime-axes