散景按钮回调仅部分起作用

时间:2019-05-17 17:32:53

标签: python python-3.x bokeh jupyter-lab

我正在bokeh中绘制一个复杂的交互式甜甜圈图。下面的代码是此图表组件的简化。

我有一个功能,可为甜甜圈编译数据的数据帧,然后将其转换为CDS。然后将此数据绘制为环形楔形。 单选按钮组应触发到另一个数据帧(如CDS)的切换,并重新绘制环形楔形字形。

该示例提供(针对Jupyter Lab)适用于一个方向。最初绘制button.active == 0(外部_1)时。选择external_2时,图表会正确更改以绘制第二个数据帧(cds)。

但是,当按下external_1按钮时,字形不会变回来。回调被触发-标题更改。但是字形并没有改变。

为什么字形在随后的按钮按下/回调中没有改变?

我已经阅读了几篇类似的SO帖子,还回顾了一些bokeh示例(天气示例here与此类似)

import pandas as pd
from math import pi

from bokeh.plotting import figure

from bokeh.layouts import column, row 
from bokeh.models.widgets import RadioButtonGroup
from bokeh.io import curdoc
from bokeh.models.sources import ColumnDataSource
from bokeh.layouts import column, row

from bokeh.plotting import show, output_notebook
output_notebook()

df = pd.DataFrame({'start':[pi/2, pi, 3*pi/2],
                   'end' :[pi/2+1.5, pi+1.5, (3*pi/2)+1.5],
                   'inner': [100,100,100],
                   'outer': [200,200,200],
                   'color':['red','green','blue']})

df_2 = pd.DataFrame({'start':[pi/2, pi, 3*pi/2],
                   'end' :[pi/2+1, pi+1, (3*pi/2)+1],
                   'inner': [100,100,100],
                   'outer': [250,300,350],
                    'color':['orange','gray','purple']})

data_1 = ColumnDataSource(data=df)
data_2 = ColumnDataSource(data=df_2)


def create_doc(doc):

    button = RadioButtonGroup(labels=["outer_1", "outer_2"], active=0)

    inputs = column(button)

    p = figure(plot_width=600, plot_height=600, title="data_1",
                   x_axis_type=None, y_axis_type=None,
                   x_range=(-300, 300), y_range=(-300, 300),
                   min_border=0, outline_line_color=None,
                   background_fill_color='white', toolbar_location="above")

    circle = p.circle(0,0, radius=100, fill_alpha=0, line_color='grey', line_alpha=0.4)

    source = [data_1, data_2][button.active]

    segments = p.annular_wedge(0,0,'inner', 'outer', 'start', 'end', color='color', alpha=0.6, source=source, name='segments')


    r = row (inputs,p)


    def callback(attr, old, new):
        if button.active == 1:
            p.title.text = 'data_2  {}'.format(button.active)
            source.data.update(data_2.data)
        elif button.active == 0:
            p.title.text = 'data_1 {}'.format(button.active)
            source.data.update(data_1.data)

    button.on_change('active', callback)

    doc.add_root(r)


show(create_doc)

glpyhs一次成功更改,但一次未成功更改,尽管标题文本(按下按钮时)不断变化表明按钮和回调仍部分起作用。

1 个答案:

答案 0 :(得分:1)

为什么在知道内部ColumnDataSource的数据为字典的情况下转换为DataFrame?以下代码适用于Bokeh v1.1.0

from math import pi
from bokeh.plotting import figure, show, curdoc, Row, Column, output_notebook
from bokeh.models import RadioButtonGroup

output_notebook()

data1 = {'start':[pi/2, pi, 3*pi/2],
        'end' :[pi/2+1.5, pi+1.5, (3*pi/2)+1.5],
        'inner': [100,100,100],
        'outer': [200,200,200],
        'color':['red','green','blue']}

data2 = {'start':[pi/2, pi, 3*pi/2],
         'end' :[pi/2+1, pi+1, (3*pi/2)+1],
         'inner': [100,100,100],
         'outer': [250,300,350],
         'color':['orange','gray','purple']}

def create_doc(doc):

    button = RadioButtonGroup(labels=["outer_1", "outer_2"], active=0)

    p = figure(plot_width=600, plot_height=600, title="data_1",
                   x_axis_type=None, y_axis_type=None,
                   x_range=(-300, 300), y_range=(-300, 300),
                   min_border=0, outline_line_color=None,
                   background_fill_color='white', toolbar_location="above")

    circle = p.circle(0,0, radius=100, fill_alpha=0, line_color='grey', line_alpha=0.4)
    segments = p.annular_wedge(0,0,'inner', 'outer', 'start', 'end', color='color', alpha=0.6, source = data1, name='segments')

    def callback(attr, old, new):
        if button.active == 0:
            print '000'
            p.title.text = 'data_1 {}'.format(button.active)
            segments.data_source.data = data1
        elif button.active == 1:
            print '111'
            p.title.text = 'data_2  {}'.format(button.active)
            segments.data_source.data = data2 

    button.on_change('active', callback)

    inputs = Column(button)
    r = Row(inputs,p)
    doc.add_root(r)

show(create_doc)

enter image description here