如何根据背景中的用户选择单选按钮更改图表类型

时间:2019-05-08 14:08:53

标签: python bokeh

enter image description here我想在运行时单击单选按钮时更改bokeh图。这是我到目前为止尝试过的:

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)

它在一个图中显示了两个图形,但是我想将条形图设置为默认值,并且当我单击单选按钮时,该图形应根据单击事件进行更改。这是我的完整代码。pl检查并告诉我在做什么错误

2 个答案:

答案 0 :(得分:1)

vbar_stack返回一个字形列表,因此您需要像这样分别切换可见性:

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)

enter image description here

答案 1 :(得分:1)

请在下面的代码中进行一些小的更正:

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)

enter image description here