如何使用Python使我的bokeh vbar交互?

问题描述 投票:0回答:1

我正在尝试在POC模型上工作,我可以在其中添加一些交互性(比如选择基于vbar图将改变的学生)。我正在使用带有标记的基本学生数据。

数据如下:

Column 1
Name
Ayan
Deepa
Sayan
Shobhit

Column 2
Marks
98
96
92
94

我可以通过以下代码实现:

我能够创建函数并能够在Bokeh服务器输出中获取输出。我还能够创建一个on_change回调,它根据下拉选择中的用户输入重新创建数据集。

我需要帮助的地方:

我无法更新我的情节中的来源。我尝试了各种在线网站的各种方式,但我无法这样做。

面临的一些问题是:

  1. 当我使用数据框创建ColumnDataSource时,输出图将变为空白
  2. 如果我使用的是数据帧而不是ColumnDataSource,则更新功能显示它无法更改df或列表

码:

## Packages

from bokeh.core.properties import value
from bokeh.io import curdoc
from bokeh.plotting import figure
from bokeh.layouts import layout, column, gridplot, Row, widgetbox, row
from bokeh.models import TapTool, HoverTool, ColumnDataSource, Range1d, BoxSelectTool, LinearAxis, Range1d
from bokeh.models.widgets import Button, RadioButtonGroup, Select, Slider, CheckboxGroup, Panel, Tabs
from bokeh.models.annotations import LabelSet


_tools_to_show = 'box_zoom,pan,save,hover,resize,reset,tap,wheel_zoom'  




import pandas as pd
import numpy as np
from datetime import datetime, timedelta
import datetime

## Creating Dataset

def make_dataset(Input):

    global Piv_INCS2_CD_Plot3old
    global Piv_INCS2_CD_Plot3
    global Week_List
    global P2_Major
    global Total_Incidents_Created
    global Resolution_SLO_Miss_Percent
    global new_src
    global Piv_INCS2_CD_Plot3_List
    global Old
    global Old_Filter
    global Old_CDS
    global Name
    global Marks
    global Names2
    global Old_CDS_Name
    global Old_CDS_Marks

    print("select 2 =", select.value )
    print("Input 2 =", Input)

    Old = pd.read_csv('Check_Data.csv', encoding='ISO-8859-1')
    Old_Filter = pd.DataFrame(Old[Old.Name == Input])
    Old_Filter.to_csv('Old_Filter.csv')


    Name = [Input]
    print("Name = ", Name)
    Names2 = Old_Filter["Name"].tolist()
    Marks = Old_Filter["Marks"].tolist()
    print("Names = ", Name )
    print("Marks = ", Marks )



    Old_CDS = ColumnDataSource(data = Old_Filter)
    print("OLD_CDS = ", Old_CDS)

    Old_CDS_Name = ColumnDataSource(data = {'Name':Name})
    Old_CDS_Marks = ColumnDataSource(data = {'Marks': Marks})


    return Old_CDS



##  Creating Plot


def plot(Old_CDS):


    global p3

    p3 = figure(plot_height=630, plot_width=1000, title="Marks Trend",
                   toolbar_location=None, tools="")
    p3.vbar(x = "Name", top = "Marks", width = 0.9, source=Old_CDS)

    p3.xgrid.grid_line_color = None
    p3.y_range.start = 0


    return p3 # returns the plot

## On Change Function

def update(attr, old, new):

    global Piv_INCS2_CD_Plot3_New
    global Week_List_New
    global Old_CDS_1
    global p3
    global lay
    global Old_CDS_Name_2


    Old_CDS_1 = make_dataset(select.value)
    Old_CDS.data.update(Old_CDS_1.data)

## Selection Option   

options=[("Ayan","Ayan"),("Deepa","Deepa")]
select=Select(title="Name",options=options)
print("select=", select.value )

## Changing value based on user input

select.on_change("value",update)

## Defining intial user selection

Initial_Input = "Ayan"

Old_CDS_2 = make_dataset(Initial_Input)

## Defining Layout

p3 = plot(Old_CDS_2)
lay = row(p3, select)

curdoc().add_root(lay)

预期结果:我应该能够在页面中查看条形图,当我从下拉菜单中更改用户时,情节会发生变化

python bokeh
1个回答
0
投票

这是您的工作代码(适用于Bokeh v1.0.4)。变化:

x_range = Old_CDS.data['Name']补充道

global Old_CDS_2

Old_CDS_2.data['Marks'] = Old_CDS_1.data['Marks']您正在更新Old_CDS而不是Old_CDS_2您传递给vbars

from bokeh.core.properties import value
from bokeh.io import curdoc
from bokeh.plotting import figure
from bokeh.layouts import layout, column, gridplot, Row, widgetbox, row
from bokeh.models import TapTool, HoverTool, ColumnDataSource, Range1d, BoxSelectTool, LinearAxis, Range1d
from bokeh.models.widgets import Button, RadioButtonGroup, Select, Slider, CheckboxGroup, Panel, Tabs
from bokeh.models.annotations import LabelSet

_tools_to_show = 'box_zoom,pan,save,hover,resize,reset,tap,wheel_zoom'

import pandas as pd
import numpy as np
from datetime import datetime, timedelta
import datetime
import os

# # Creating Dataset
def make_dataset(Input):

    global Piv_INCS2_CD_Plot3old
    global Piv_INCS2_CD_Plot3
    global Week_List
    global P2_Major
    global Total_Incidents_Created
    global Resolution_SLO_Miss_Percent
    global new_src
    global Piv_INCS2_CD_Plot3_List
    global Old
    global Old_Filter
    global Old_CDS
    global Name
    global Marks
    global Names2
    global Old_CDS_Name
    global Old_CDS_Marks

    print("select 2 =", select.value)
    print("Input 2 =", Input)

    Old = pd.read_csv(os.path.join(os.path.dirname(__file__), 'Check_Data.csv'), encoding = 'ISO-8859-1')
    Old_Filter = pd.DataFrame(Old[Old.Name == Input])
    Old_Filter.to_csv(os.path.join(os.path.dirname(__file__), 'Old_Filter.csv'), index = False)

    select.options = [(name, name) for name in Old['Name'].values]
    print options

    Name = [Input]
    print("Name = ", Name)
    Names2 = Old_Filter["Name"].tolist()

    Marks = Old_Filter["Marks"].tolist()
    print("Names = ", Name)
    print("Marks = ", Marks)

    Old_CDS = ColumnDataSource(data = Old_Filter)
    print("OLD_CDS = ", Old_CDS)

    Old_CDS_Name = ColumnDataSource(data = {'Name': Name})
    Old_CDS_Marks = ColumnDataSource(data = {'Marks': Marks})

    return Old_CDS

# #  Creating Plot
def plot(Old_CDS):

    global p3

    print Old_CDS.data
    p3 = figure(plot_height = 630, plot_width = 1000, title = "Marks Trend", x_range = Old_CDS.data['Name'],
                   toolbar_location = None, tools = "")
    p3.vbar(x = "Name", top = "Marks", width = 0.9, source = Old_CDS)

    p3.xgrid.grid_line_color = None
    p3.y_range.start = 0

    return p3  # returns the plot

# # On Change Function
def update(attr, old, new):

    global Piv_INCS2_CD_Plot3_New
    global Week_List_New
    global Old_CDS_1
    global p3
    global lay
    global Old_CDS_Name_2
    global Old_CDS_2

    Old_CDS_1 = make_dataset(select.value)
    Old_CDS_2.data['Marks'] = Old_CDS_1.data['Marks']

# # Selection Option
options = [("Ayan", "Ayan"), ("Deepa", "Deepa")]
select = Select(title = "Name", options = options)
print("select=", select.value)

# # Changing value based on user input
select.on_change("value", update)

# # Defining intial user selection
Initial_Input = "Ayan"

Old_CDS_2 = make_dataset(Initial_Input)

# # Defining Layout
p3 = plot(Old_CDS_2)
lay = row(p3, select)
curdoc().add_root(lay)

结果:

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.