0

一旦我单击“刷新按钮”,我希望使用新数据更新绘图。但是旧数据保留在图中,并且它不断向右移动并且刻度消失。

一开始,该图看起来符合我的预期(X 轴信息除外。作为一个附带问题,我在 Bokeh 属性中查找了 DataSpec(),但不知道如何将 传递accept_datetime=Falsex线图中的参数。我的代码是看起来像这样。

数据目录看起来像

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

是腌制的数据文件。

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,初始图如下所示(小抱怨:但 xaxis 以毫秒为单位)

在此处输入图像描述

单击刷新后,连续多次刷新后,情节不断移动,轴信息消失。

 在此处输入图像描述

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

4

1 回答 1

1

默认情况下,Bokeh 会自动调整所有可用字形的范围。而且您上面的代码会无限积累新的字形。因此,您看到的结果是预期的。您可以尝试在更新功能中主动删除以前的圆圈和线条字形,但这不是我推荐的。更新绘图的最佳方式是优化 Bokeh 以高效且良好地执行的方式,即设置所有字形一次,然后仅更新它们的数据

也就是说,你需要ColumnDataSource直接使用。我注意到你说:

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

我不确定你在看哪里。在文档和 repo 的文件夹中都有很多同时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))

小抱怨:但 xaxis 以毫秒为单位

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

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

于 2019-11-26T02:13:09.757 回答