我是python和bokeh的新手,正试图创建一个按国家划分的新冠肺炎发病率和死亡人数的交互式bokeh图。如果没有Select工具,代码可以很好地工作,但当我用Select工具重写它并执行它时,图形不会用新的选择更新。我显然在一些根本问题上出了问题,但我根本无法理解。对于任何正在检查的人来说,此代码都应该独立运行。我不确定是我把更新函数搞砸了,还是更新变量不起作用。
import pandas as pd
from bokeh.plotting import figure, output_file
from bokeh.io import curdoc
from bokeh.models import ColumnDataSource, HoverTool, NumeralTickFormatter, DatetimeTickFormatter, Select
from bokeh.palettes import Category20b
from bokeh.layouts import layout
url_confirmed = 'https://data.humdata.org/hxlproxy/api/data-preview.csv?url=https%3A%2F%2Fraw.githubusercontent.com%2FCSSEGISandData%2FCOVID-19%2Fmaster%2Fcsse_covid_19_data%2Fcsse_covid_19_time_series%2Ftime_series_covid19_confirmed_global.csv&filename=time_series_covid19_confirmed_global.csv'
url_deaths = 'https://data.humdata.org/hxlproxy/api/data-preview.csv?url=https%3A%2F%2Fraw.githubusercontent.com%2FCSSEGISandData%2FCOVID-19%2Fmaster%2Fcsse_covid_19_data%2Fcsse_covid_19_time_series%2Ftime_series_covid19_deaths_global.csv&filename=time_series_covid19_deaths_global.csv'
covid_confirmed = pd.read_csv(url_confirmed)
covid_confirmed_grp = covid_confirmed.groupby('Country/Region').sum()
covid_deaths = pd.read_csv(url_deaths)
covid_deaths_grp = covid_deaths.groupby('Country/Region').sum()
covid_confirmed_dates = covid_confirmed_grp.drop(columns = ['Lat', 'Long'])
covid_confirmed_dates = covid_confirmed_dates.transpose()
covid_confirmed_dates = covid_confirmed_dates.reset_index()
covid_confirmed_dates = covid_confirmed_dates.rename(columns = {'index':'date'})
covid_confirmed_dates['date'] = pd.to_datetime(covid_confirmed_dates['date'])
covid_deaths_dates = covid_deaths_grp.drop(columns = ['Lat', 'Long'])
covid_deaths_dates = covid_deaths_dates.transpose()
covid_deaths_dates = covid_deaths_dates.reset_index()
covid_deaths_dates = covid_deaths_dates.rename(columns = {'index':'date'})
covid_deaths_dates['date'] = pd.to_datetime(covid_deaths_dates['date'])
countrylist = covid_confirmed_dates.columns.tolist()
countrylist.remove('date')
# reset the output so that the file size does not increase
#bokeh.io.reset_output()
source_confirmed = ColumnDataSource(covid_confirmed_dates)
source_deaths = ColumnDataSource(covid_deaths_dates)
countrylist = ['India','US', 'Spain', "Italy", "Germany", "United Kingdom",
"France", "China", "Iran", "Turkey", "Belgium",
"Brazil", "Canada", "Netherlands", "Switzerland"]
mypallette = Category20b[20]
country = 'India'
# name the output file
output_file('covid_confirmed_deaths.html')
def update_country(attr,old,new):
global country
country = select.value
# define the figure variable
f = figure(plot_width=800, plot_height=500, x_axis_type="datetime")
f.xaxis.axis_label = "Date"
f.yaxis.axis_label = "Cases"
f.title.text = 'COVID19 Cases'
f.line(x = 'date', y = country, color='red', alpha=1, source = source_confirmed, line_width = 3, name = country, legend_label=country)
f.legend.location = "top_left"
f.legend.click_policy="hide"
f.legend.title = 'Tap to toggle on/off'
f.yaxis[0].formatter = NumeralTickFormatter(format="0,000,000")
f.xaxis[0].formatter = DatetimeTickFormatter(days="%d/%m")
hover = HoverTool(
tooltips = [
("country", "$name"),
("date", "@date{%d/%m}"),
("cases", "$y{0,000,000}")
],
formatters={
'@date': 'datetime',
},
)
f.add_tools(hover)
# define the figure variable
g = figure(plot_width=800, plot_height=500, x_axis_type="datetime")
g.xaxis.axis_label = "Date"
g.yaxis.axis_label = "Deaths"
g.title.text = 'COVID19 Deaths'
g.line(x = 'date', y = country, color='blue', alpha=1, source = source_deaths, line_width = 3, name = country, legend_label=country)
g.legend.location = "top_left"
g.legend.click_policy="hide"
g.legend.title = 'Tap to toggle on/off'
g.yaxis[0].formatter = NumeralTickFormatter(format="0,000,000")
g.xaxis[0].formatter = DatetimeTickFormatter(days="%d/%m")
hover = HoverTool(
tooltips = [
("country", "$name"),
("date", "@date{%d/%m}"),
("cases", "$y{0,000,000}")
],
formatters={
'@date': 'datetime',
},
)
g.add_tools(hover)
countrylist1 = [('India', 'India'),('US','US'), ('Spain', 'Spain'),
('Italy', 'Italy'), ('Germany', 'Germany'), ('United Kingdom', 'United Kingdom'),
('France', 'France'), ('China', 'China'), ('Iran', 'Iran'),('Turkey', 'Turkey'), ('Belgium', 'Belgium'),
('Brazil', 'Brazil'), ('Canada', 'Canada'), ('Netherlands', 'Netherlands'), ('Switzerland', 'Switzerland')]
select = Select(title="Select Country:", value="India", options=countrylist1)
select.on_change("value", update_country)
lay_out=layout([[select]])
curdoc().add_root(lay_out)
curdoc().add_root(f)
curdoc().add_root(g)
为了让Bokeh了解您所做的更改,您必须将这些更改应用于Bokeh模型。大多数情况下,它是一个数据源,但也可以是任何其他模型。例如,当您调用f.line()
时,它会返回GlyphRenderer
的一个实例。要更改其y
属性,可以使用renderer.glyph.y = select.value
。与name
相同。
但对于legend_label
来说,这要困难得多。问题是,它不是一个属性,只是一种方便的方式来创建Legend
模型的实例并自动为您设置其所有机制。为了更改图例标签,您必须深入了解图例的工作方式,并更改正确模型的正确属性。