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
我希望在单击 "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