боке кнопка обратного вызова только частично работает - PullRequest
0 голосов
/ 17 мая 2019

Я строю сложную интерактивную карту пончиков в боке.Приведенный ниже код является упрощением компонента этой диаграммы.

У меня есть функция, которая компилирует массив данных для пончика, а затем преобразует его в CDS.Эти данные затем наносятся на график в виде кольцевых клиньев.Группа радиопереключателей должна инициировать переключение на другой фрейм данных (например, CDS) и воспроизвести глифы кольцевого клина.

Пример предоставления (для Jupyter Lab) работает в одном направлении.При первоначальном построении графика button.active == 0 (external_1).Когда выбран external_2, диаграмма корректно изменяется для построения второго кадра данных (cds).

Но когда нажата кнопка external_1, глифы не изменяются обратно.Обратный вызов срабатывает - при изменении названия.Но глифы не меняются.

Почему глифы не меняются при последующих нажатиях / обратном вызове кнопок?

Я прочитал несколько подобных сообщений SO, а также рассмотрел ряд примеров с боке.(пример погоды здесь аналогичен)

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 Ответ

1 голос
/ 17 мая 2019

Зачем преобразовывать в DataFrame, зная, что внутренне данные ColumnDataSource являются словарями? Следующий код отлично работает для 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

...