问题描述
我定义了两种绘图函数:plt_percent和plt_number。我想使用RadioGroup按钮在它们之间进行切换。
现在,我在更新功能中通过清除整个屏幕并从头开始进行此操作:
curdoc().clear()
layout = row(menu,p)
curdoc().add_root(layout)
我的仪表板还具有其他图,但是更新功能仅需更改此特定图,而无需触摸任何其他对象。
我怀疑使用CustomJS可能会实现,但我不知道如何。
下面的完整代码:
import pandas as pd
from bokeh.plotting import figure
from bokeh.io import curdoc
from bokeh.layouts import row
from bokeh.models import ColumnDataSource,RadioGroup,PrintfTickFormatter
colors=['navy','red']
data = {'fruits' : ['Apples','Pears','Nectarines','Plums','Grapes','Strawberries'],'2015' : [2,1,4,3,2,4],'2016' : [3,5,3]}
df = pd.DataFrame(data)
def make_dataset(df):
df['total'] = df.sum(axis=1)
df['2015_%'] = round((df['2015'] * 100) / df.total)
df['2016_%'] = round((df['2016'] * 100) / df.total)
print(df)
return ColumnDataSource(df)
def plt_percent(src):
p = figure(x_range=src.data['fruits'],plot_width=500,plot_height=500
)
p.vbar_stack(['2015_%','2016_%'],x='fruits',width=0.5,source=src,color=colors,legend_label=['2015','2016']
)
p.yaxis[0].formatter = PrintfTickFormatter(format='%0.0f%%')
return p
def plt_number(src):
p = figure(x_range=src.data['fruits'],plot_height=500
)
p.vbar_stack(['2015','2016'],'2016']
)
return p
def update(new):
count_type = menu.active
if count_type == 0:
p = plt_percent(source)
elif count_type == 1:
p = plt_number(source)
layout = row(menu,p)
curdoc().clear()
curdoc().add_root(layout)
# menu
menu = RadioGroup(labels=['percentage','number'],active = 0)
menu.on_click(update)
# initialise
source = make_dataset(df)
p = plt_percent(source)
layout = row(menu,p)
curdoc().add_root(layout)
解决方法
代替创建一个完整的新页面,只需使用layout(row / column)的children属性更改图表-
import pandas as pd
from bokeh.plotting import figure
from bokeh.io import curdoc
from bokeh.layouts import row
from bokeh.models import ColumnDataSource,RadioGroup,PrintfTickFormatter
colors=['navy','red']
data = {'fruits' : ['Apples','Pears','Nectarines','Plums','Grapes','Strawberries'],'2015' : [2,1,4,3,2,4],'2016' : [3,5,3]}
df = pd.DataFrame(data)
def make_dataset(df):
df['total'] = df.sum(axis=1)
df['2015_%'] = ((df['2015'] * 100) / df.total).round()
df['2016_%'] = ((df['2016'] * 100) / df.total).round()
print(df)
return df,ColumnDataSource(df)
def plt_percent(src):
p = figure(x_range=src.data['fruits'].tolist(),plot_width=500,plot_height=500)
p.vbar_stack(['2015_%','2016_%'],x='fruits',width=0.5,source=src,color=colors,legend_label=['2015','2016'])
p.yaxis[0].formatter = PrintfTickFormatter(format='%0.0f%%')
return p
def plt_number(src):
p = figure(x_range=src.data['fruits'].tolist(),plot_height=500)
p.vbar_stack(['2015','2016'],'2016'])
return p
def update(new):
count_type = menu.active
if count_type == 0:
p = plt_percent(source)
elif count_type == 1:
p = plt_number(source)
layout.children[1] = p
# menu
menu = RadioGroup(labels=['percentage','number'],active = 0)
menu.on_click(update)
# initialise
source = make_dataset(df)
p = plt_percent(source)
layout = row(menu,p)
curdoc().add_root(layout)
如果只是更改图表后面的数据,将会更好(更无缝),但为此您需要使用基本字形制作图表。