Как создать меню «Bokeh Select» для линейного сюжета для неопределенного количества опций? - PullRequest
0 голосов
/ 08 ноября 2019

Я работаю над созданием меню выбора и настройкой Bokeh для работы с набором данных, с которым я работаю. Набор данных можно найти здесь . У меня нет опыта работы с JavaScript, но я считаю, что мое меню выбора не связано с моим сюжетом. Поэтому у меня есть контур сюжета, но данные не отображаются. Когда я запускаю скрипт из консоли с bokeh serve --show test.py, я получаю первые 7 уведомлений в моей консоли JS. Последние три (те, что в красной скобке на скриншоте) появляются, когда я пытаюсь перейти к другому пункту в моем меню выбора.

JS Errors

Цель: Отображение графика данных для строк, для которых эти номера идентификатора (в данном примере 'ndc') выбраны в меню Select.

Вот мой код (изменен с thisсообщение ), которое я использовал, чтобы начать. Этот также использовался, как и несколько других, и сама документация Bokeh.

import pandas as pd
from bokeh.io import curdoc, output_notebook, output_file
from bokeh.layouts import row, column
from bokeh.models import Select, DataRange1d, ColumnDataSource
from bokeh.plotting import figure

# output_notebook()
output_file('test.html')

def get_dataset(src, drug_id):
    src.drop('Unnamed: 0', axis = 1, inplace = True)
    df = src[src.ndc == drug_id].copy()
    df['date'] = pd.to_datetime(df['date'])
    df = df.set_index(['date'])
    df.sort_index(inplace=True)
    source = ColumnDataSource(data=df)
    return source


def make_plot(source, title):
    plot = figure(plot_width=800, plot_height = 800, tools="", x_axis_type = 'datetime', toolbar_location=None)

    plot.xaxis.axis_label = 'Time'
    plot.yaxis.axis_label = 'Price ($)'
    plot.axis.axis_label_text_font_style = 'bold'
    plot.x_range = DataRange1d(range_padding = 0.0)
    plot.grid.grid_line_alpha = 0.3 

    plot.title.text = title
    plot.line(x= 'date', y='nadac_per_unit', source=source)
    return plot


def update_plot(attrname, old, new):
    ver = vselect.value
    plot.title.text = "Drug Prices"
    src = get_dataset(df, ver)
    source.date.update(src.date)


df = pd.read_csv('data/plotting_data.csv')
ver = '54034808' #Initial id number
cc = df['ndc'].astype(str).unique() #select-menu options

vselect = Select(value=ver, title='Drug ID', options=sorted((cc)))

source = get_dataset(df, ver)
plot = make_plot(source, "Drug Prices")

vselect.on_change('value', update_plot)
controls = row(vselect)

curdoc().add_root(row(plot, controls))

1 Ответ

1 голос
/ 08 ноября 2019

В вашем коде возникли проблемы:

  • Вы хотите удалить столбец Безымянный: 0. Это можно сделать только один раз, и при повторной попытке произойдет ошибка, поскольку этот столбец больше не существует.
  • Способ, которым вы пытались отфильтровать кадр данных, не сработал и привел к пустому кадру данных,Вы можете выбрать строки на основе значения столбца, например: df.loc[df['column_name'] == some_value]
  • Обновление объекта ColumnDataSource можно выполнить, заменив source.data новыми данными.
import pandas as pd
from bokeh.io import curdoc, output_notebook, output_file
from bokeh.layouts import row, column
from bokeh.models import Select, DataRange1d, ColumnDataSource
from bokeh.plotting import figure

output_notebook()
output_file('test.html')

def get_dataset(src, drug_id):
    src.drop('Unnamed: 0', axis = 1, inplace = True)
    df = src.loc[src['ndc'] == int(drug_id)]
    df['date'] = pd.to_datetime(df['date'])
    df = df.set_index(['date'])
    df.sort_index(inplace=True)
    source = ColumnDataSource(data=df)
    return source


def make_plot(source, title):
    plot = figure(plot_width=800, plot_height = 800, tools="", x_axis_type = 'datetime', toolbar_location=None)
    plot.xaxis.axis_label = 'Time'
    plot.yaxis.axis_label = 'Price ($)'
    plot.axis.axis_label_text_font_style = 'bold'
    plot.x_range = DataRange1d(range_padding = 0.0)
    plot.grid.grid_line_alpha = 0.3 
    plot.title.text = title
    plot.line(x= 'date', y='nadac_per_unit', source=source)
    return plot


def update_plot(attrname, old, new):
    ver = vselect.value
    df1 = df.loc[df['ndc'] == int(new)]
    df1['date'] = pd.to_datetime(df1['date'])
    df1 = df1.set_index(['date'])
    df1.sort_index(inplace=True)
    newSource = ColumnDataSource(df1) 
    source.data = newSource.data


df = pd.read_csv('data/plotting_data.csv')
ver = '54034808' #Initial id number
cc = df['ndc'].astype(str).unique() #select-menu options

vselect = Select(value=ver, title='Drug ID', options=sorted((cc)))

source = get_dataset(df, ver)
plot = make_plot(source, "Drug Prices")

vselect.on_change('value', update_plot)
controls = row(vselect)

curdoc().add_root(row(plot, controls))
...