Интерактивная визуализация боке - график не обновляется - PullRequest
0 голосов
/ 19 апреля 2020

Я относительный новичок ie к python и боке, и пытаюсь создать интерактивный боке-график заболеваемости COVID и смертности от страны. Код прекрасно работает без инструмента Выбрать, но когда я переписываю его с помощью инструмента выбора, я выполняю его, график не обновляется с новым выбором. Я явно ошибся в какой-то фундаментальной проблеме, но я просто не могу понять это. Этот код должен выполняться независимо для всех, кто проверяет. Я не уверен, что я обманываю функцию обновления или обновление переменной не работает.

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)

1 Ответ

0 голосов
/ 19 апреля 2020

Чтобы Bokeh узнал об изменениях, которые вы внесли, вы должны применить эти изменения к моделям Bokeh. В большинстве случаев это источник данных, но это может быть любая другая модель. Например, когда вы вызываете f.line(), он возвращает экземпляр GlyphRenderer. Чтобы изменить его y свойство, вы можете использовать renderer.glyph.y = select.value. То же самое для name.

Однако для legend_label сделать намного сложнее. Дело в том, что это не атрибут, а просто удобный способ создания экземпляра модели Legend и автоматической настройки всего его оборудования. Чтобы изменить метку легенды, вам нужно разобраться с тем, как работают легенды, и изменить правильный атрибут нужной модели.

...