how to change chart type based on user slection radion button in bokeh

扶醉桌前 提交于 2020-01-06 04:34:29

问题


enter image description here I want to change bokeh chart at run time when click on a radio button. Here is what I've tried till now:

import numpy as np
import pandas as pd
from bokeh.core.properties import value
from bokeh.models.widgets import Paragraph,PreText,RadioButtonGroup
from bokeh.layouts import widgetbox
from bokeh.models.widgets import CheckboxGroup, RadioGroup
from bokeh.layouts import column, row
from bokeh.models import ColumnDataSource,LabelSet,CustomJS,Row
from bokeh.plotting import figure, show,save
from bokeh.transform import dodge
from bokeh.palettes import Viridis

colors = ["#c9d9d3", "#718dbf", "#e84d60"]

dataframe = pd.read_csv('Experience.csv')

source = ColumnDataSource(dataframe)
exp = dataframe['Experience']
ys = list(dataframe.keys())
ys.remove('Experience')
TOOLTIPS = [("Experience", "@Experience")]

p = figure(x_range=exp, y_range=(0, 100), plot_height=350, tools=['hover','save','reset','zoom_out','zoom_in','pan','box_zoom'],tooltips=TOOLTIPS)
stacked = p.vbar_stack(stackers=ys, x='Experience',color=colors,source=source,legend=[value(x) for x in ys],name=ys,width=0.5,)

colorList = Viridis[len(ys)]
labels = []
for y, offset, color in zip(ys, [-0.25, 0, 0.25], colorList):
    bar = p.vbar(x=dodge('Experience', offset, range=p.x_range), top=y, width=0.2, source=source, legend=y + ' ', color=color)
    bar.visible = False

radiogroup = RadioGroup(labels = ["StackedBar", "Bar"], active = 0,)
radiogroup.callback = CustomJS(args = dict(stacked = stacked, bar = bar), code = """
    for (i in stacked)
        stacked[i].visible = false;

    bar.visible = false;

    if (cb_obj.active == 0)
        for (i in stacked)
            stacked[i].visible = true;
    else if (cb_obj.active == 1)
        bar.visible = true; """)

layout = Row(p, radiogroup)
show(layout)

It is showing two graphs in one figure, but I want bar graph default and when I click on the radio button the graph should change based on click event.here is my full code..pl check and tell what i am doing wrong


回答1:


The vbar_stack returns a list of glyphs so you need to toggle visibility each of them separately like this:

from bokeh.plotting import show, figure
from bokeh.models import RadioGroup, CustomJS, Row
from bokeh.models.sources import ColumnDataSource
import pandas as pd

data = {'fruits' : ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries'],
        '2015'   : [2, 1, 4, 3, 2, 4],
        '2016'   : [5, 3, 4, 2, 4, 6],
        '2017'   : [3, 2, 4, 4, 5, 3]}
df = pd.DataFrame(data)
df['total'] = df.sum(axis = 1)

p = figure(x_range = data['fruits'], title = "Fruit Counts by Year", tools = "hover", tooltips = "$name     @fruits: @$name")

vbar_stack = p.vbar_stack(["2015", "2016", "2017"], x = 'fruits', width = 0.9, color = ["#c9d9d3", "#718dbf", "#e84d60"], source = data)
vbar = p.vbar(x = 'fruits', width = 0.5, top = 'total', source = ColumnDataSource(df))
vbar.visible = False

radiogroup = RadioGroup(labels = ["StackedBar", "Bar"], active = 0,)
radiogroup.callback = CustomJS(args = dict(vbar_stack = vbar_stack, vbar = vbar), code = """
    for (i in vbar_stack)
        vbar_stack[i].visible = false;

    vbar.visible = false;

    if (cb_obj.active == 0)
        for (i in vbar_stack)
            vbar_stack[i].visible = true;
    else if (cb_obj.active == 1)
        vbar.visible = true; """)

layout = Row(p, radiogroup)
show(layout)




回答2:


See below your code with some small corrections:

import os
import numpy as np
import pandas as pd
from bokeh.core.properties import value
from bokeh.models.widgets import Paragraph, PreText, RadioButtonGroup
from bokeh.layouts import widgetbox
from bokeh.models.widgets import CheckboxGroup, RadioGroup
from bokeh.layouts import column, row
from bokeh.models import ColumnDataSource, LabelSet, CustomJS, Row
from bokeh.plotting import figure, show, save
from bokeh.transform import dodge
from bokeh.palettes import Viridis

colors = ["#c9d9d3", "#718dbf", "#e84d60"]

dataframe = pd.read_csv(os.path.join(os.path.dirname(__file__), 'Experience.csv'))

source = ColumnDataSource(dataframe)
exp = dataframe['Experience']
ys = list(dataframe.keys())
ys.remove('Experience')
TOOLTIPS = [("Experience", "@Experience")]

p = figure(x_range = exp, y_range = (0, 100), plot_height = 350, tools = ['hover', 'save', 'reset', 'zoom_out', 'zoom_in', 'pan', 'box_zoom'], tooltips = TOOLTIPS)
stacked = p.vbar_stack(stackers = ys, x = 'Experience', color = colors, source = source, legend = [value(x) for x in ys], name = ys, width = 0.5,)

colorList = Viridis[len(ys)]
labels = []
bars = []
for y, offset, color in zip(ys, [-0.25, 0, 0.25], colors):
    bar = p.vbar(x = dodge('Experience', offset, range = p.x_range), top = y, width = 0.2, source = source, color = color)
    bar.visible = False
    bars.append(bar)

radiogroup = RadioGroup(labels = ["StackedBar", "Bar"], active = 0,)
radiogroup.callback = CustomJS(args = dict(stacked = stacked, bars = bars), code = """
    for (i in stacked)
        stacked[i].visible = false;

    for (i in bars)
        bars[i].visible = false;

    if (cb_obj.active == 0)
        for (i in stacked)
            stacked[i].visible = true;
    else if (cb_obj.active == 1)
        for (i in bars)
            bars[i].visible = true; """)

layout = Row(p, radiogroup)
show(layout)



来源:https://stackoverflow.com/questions/56042740/how-to-change-chart-type-based-on-user-slection-radion-button-in-bokeh

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!