Невозможно обновить график при выборе значения виджета Select библиотеки Bokeh. - PullRequest
0 голосов
/ 01 мая 2020

Я работаю над анализом COVID19 и использую источник данных JSON. Я преобразовал json в фрейм данных. Я работаю над составлением графика ежедневного случая, ежедневной смерти и ежедневно восстановленной гистограммы по оси x времени и даты для каждого состояния, и состояние можно выбрать с помощью виджета «Выбор». Я не знаю Javascript, поэтому я пытаюсь избежать использования обратных вызовов Javascript, но использую функцию для обновления select.value. Я не уверен, почему сюжет не обновляется, даже когда я запускаю код на сервере Bokeh, и интерпретатор не вызывает никаких исключений.

Может ли кто-нибудь дать мне какое-либо указание или помочь с тем, что может вызвать проблему, поскольку я новичок в Python, и любая помощь приветствуется? Или, если есть какая-то другая альтернатива. Этот код является производным от аналогичного сюжета на [боке дискурс] [1]

#Creating DataFrame
cases_summary = requests.get('https://api.rootnet.in/covid19-in/stats/history')
json_data = cases_summary.json()
cases_summary=pd.json_normalize(json_data['data'], record_path='regional', meta='day')
cases_summary['day']=pd.to_datetime(cases_summary['day'])
cases_summary['daily deaths']=cases_summary['deaths'].groupby(cases_summary['loc']).diff(1)
cases_summary['daily confirmed']=cases_summary['totalConfirmed'].groupby(cases_summary['loc']).diff(1)
cases_summary['daily discharged']=cases_summary['discharged'].groupby(cases_summary['loc']).diff(1)

#Initializing the first default plot
cases=cases_summary[cases_summary['loc']=='Delhi']


source=ColumnDataSource(data=cases)

a = figure(plot_width=1200, plot_height=700, sizing_mode="scale_both", x_axis_type='datetime')


def make_plot(cases_val):
    a.vbar('day', top='daily confirmed', width=timedelta(days=0.5),
                   legend_label='Daily Confirmed', color='#5e4fa2', source=cases_val)
    a.vbar('day', bottom='daily discharged', width=timedelta(days=0.5),
                        legend_label='Daily Recovered', color='#66c2a5', source=cases_val)
    a.vbar('day', bottom='daily deaths', width=timedelta(days=0.5),
                      legend_label='Daily Deaths', color='#3288bd', source=cases_val)
   return a

def update_plot(attr,old,new):
    location=select.value
    data_loc = cases_summary[cases_summary['loc'] == location]
    source = ColumnDataSource(data=dict()).from_df(data_loc)
    layout.children[0]=make_plot(source)

select = Select(title="Select State:", value="Delhi", options=cases_summary['loc'].unique().tolist())

plot = make_plot(cases)

controls = column(select)
layout = row(a, controls)
select.on_change('value', update_plot)

curdoc().add_root(layout)


  [1]: https://discourse.bokeh.org/t/how-to-update-the-bar-chart-that-has-dataframe-as-source-with-bokeh-select-widget/2031/8

1 Ответ

0 голосов
/ 04 мая 2020

Это можно сделать проще, используя вид и фильтр. Вот альтернативный подход:

import requests
import pandas as pd
from bokeh.plotting import figure
from bokeh.layouts import column, row
from bokeh.io import curdoc
from bokeh.models import *
from datetime import timedelta

cases_summary = requests.get("https://api.rootnet.in/covid19-in/stats/history")
json_data = cases_summary.json()
cases_summary = pd.json_normalize(json_data["data"], record_path="regional", meta="day")
cases_summary["day"] = pd.to_datetime(cases_summary["day"])
cases_summary["daily deaths"] = (
    cases_summary["deaths"].groupby(cases_summary["loc"]).diff(1)
)
cases_summary["daily confirmed"] = (
    cases_summary["totalConfirmed"].groupby(cases_summary["loc"]).diff(1)
)
cases_summary["daily discharged"] = (
    cases_summary["discharged"].groupby(cases_summary["loc"]).diff(1)
)

source = ColumnDataSource(cases_summary)
filter = GroupFilter(column_name='loc',group='Delhi')
view = CDSView(source=source, filters = [filter])

a = figure(
    plot_width=1200, plot_height=700, sizing_mode="scale_both", x_axis_type="datetime"
)

a.vbar(
    "day",
    top="daily confirmed",
    width=timedelta(days=0.5),
    legend_label="Daily Confirmed",
    color="#5e4fa2",
    source=source,
    view = view
)

a.vbar(
    "day",
    bottom="daily discharged",
    width=timedelta(days=0.5),
    legend_label="Daily Recovered",
    color="#66c2a5",
    source=source,
    view = view
)

a.vbar(
    "day",
    bottom="daily deaths",
    width=timedelta(days=0.5),
    legend_label="Daily Deaths",
    color="#3288bd",
    source=source,
    view = view
)


def update_plot(attr, old, new):
    view.filters = [GroupFilter(column_name='loc',group=select.value)]

select = Select(
    title="Select State:", value="Delhi", options=cases_summary["loc"].unique().tolist()
)

controls = column(select)
layout = row(a, controls)
select.on_change("value", update_plot)

curdoc().add_root(layout)
...