Я занимаюсь этим часами. Я пытаюсь представить график распространения (и смертей) Covid-19 в разных странах мира (он показывает новые случаи, общее количество случаев, новые случаи смерти и общее количество смертей в разных таблицах). Я хочу позволить пользователю выбирать, какие страны он хочет видеть, используя виджет CheckBoxGroup из Bokeh, но мой график не обновляется. Кроме того, при отладке я заметил, что функция обновления обновляется только тогда, когда есть новый выбор (или так кажется). Когда я выбираю страну, если я печатаю данные sr c из функции обновления, данные из новой страны присутствуют (но не отображаются на графике). Однако, когда я отменяю выбор страны, данные из этой страны все еще присутствуют после того, как они должны были быть обновлены.
Я не знаю, создает ли проблема использование groupby (я не видел никаких рабочих примеров с groupby, я пытался использовать MultiLine, но я не совсем уверен, что понял цель).
PS: Если кто-нибудь знает, как отформатировать CheckBoxGroup, чтобы иметь столбцы, это также было бы здорово, но сейчас это далеко не приоритет.
Заранее спасибо!
import pandas as pd
import numpy as np
import datetime as dt
from os.path import dirname, join
from bokeh.io import push_notebook
from bokeh.plotting import show, output_notebook,figure,curdoc
from bokeh.models import CategoricalColorMapper, HoverTool, ColumnDataSource, Panel,CustomJS
from bokeh.models.widgets import CheckboxGroup, Slider, RangeSlider, Tabs, MultiSelect
from bokeh.layouts import column, row, WidgetBox
from bokeh.palettes import all_palettes
from bokeh.application.handlers import FunctionHandler
from bokeh.application import Application
def make_dataset(select_countries):
prep_data={}
for i,group in enumerate(select_countries):
group[1].set_index('date', drop=True, inplace=True)
data=group[1].reindex(all_days)
data["location"].fillna(method='backfill',inplace=True)
data.fillna(value=0,inplace=True)
data['color']=color_list[i]
data.reset_index(inplace=True)
prep_data[group[0]]=data
return ColumnDataSource(prep_data)
def make_plot(src):
p1 = figure(plot_width=1000, plot_height=600,x_axis_type='datetime',title = 'Chart of new cases over time',
x_axis_label = 'Date', y_axis_label = 'Number of new cases')
p2 = figure(plot_width=1000, plot_height=600,x_axis_type='datetime',title = 'Chart of total cases over time',
x_axis_label = 'Date', y_axis_label = 'Number of total cases')
p3 = figure(plot_width=1000, plot_height=600,x_axis_type='datetime',title = 'Chart of new deaths over time',
x_axis_label = 'Date', y_axis_label = 'Number of new deaths')
p4 = figure(plot_width=1000, plot_height=600,x_axis_type='datetime',title = 'Chart of total deaths over time',
x_axis_label = 'Date', y_axis_label = 'Number of total deaths')
for group in src.data.values() :
plot1=p1.line(x='index',y='new_cases',source=group,color=group['color'].values[0],legend="location")
plot2=p2.line(x='index',y='total_cases',source=group,color=group['color'].values[0],legend="location")
plot3=p3.line(x='index',y='new_deaths',source=group,color=group['color'].values[0],legend="location")
plot4=p4.line(x='index',y='total_deaths',source=group,color=group['color'].values[0],legend="location")
p1.legend.click_policy = 'hide'
p2.legend.click_policy = 'hide'
p3.legend.click_policy = 'hide'
p4.legend.click_policy = 'hide'
tab1 = Panel(child=p1, title="new_cases")
tab2 = Panel(child=p2, title="total_cases")
tab3 = Panel(child=p3, title="new_deaths")
tab4 = Panel(child=p4, title="total_deaths")
tabs = Tabs(tabs=[ tab1, tab2, tab3, tab4 ])
return tabs
def update(attr, old, new):
# Get the list of countries
select_countries_labels=[country_selection.labels[i] for i in country_selection.active]
#print(select_countries_labels)
select_countries=[countries_selected for countries_selected in countries
if countries_selected[0] in select_countries_labels]
new_src = make_dataset(select_countries)
#print("new countries")
#print(new_country_list.data)
# Update the source used the quad glpyhs
src.data.update(new_src.data)
#=new_country_list.data
#print(country_df.data)
df=pd.read_csv(join(dirname(__file__),'full_data(2).csv'), encoding='utf-8',parse_dates=["date"])
countries=df.groupby("location")
l=countries.describe(include="all")
all_days=pd.date_range(l.loc['World']['date']['first'],l.loc['World']['date']['last'],freq='D')
# Countries and colors
color_dicts=[list(colors.values()) for colors in list(all_palettes.values())]
color_list_int=[color for color_sublist in color_dicts for color in color_sublist]
color_list_dup=[color for color_sublist in color_list_int for color in color_sublist]
color_list=list(set(color_list_dup))
color_list.sort()
available_countries = list(set(df['location']))
available_countries.sort()
# Countries to plot
country_selection = CheckboxGroup(labels=available_countries,
active = [0,1])
country_selection.on_change('active', update)
# Initial carriers and data source
select_countries_labels=[country_selection.labels[i] for i in country_selection.active]
initial_countries=[countries_selected for countries_selected in countries
if countries_selected[0] in select_countries_labels]
# Prep the data
src = make_dataset(initial_countries)
# Make the covid plot
p1 = make_plot(src)
# Put controls in a single element
controls = WidgetBox(country_selection)
# Create a row layout
layout = row(controls, p1)
curdoc().add_root(layout)
curdoc().title = "covid"