Bokeh - dodawanie widżetów

Moduł bokeh.models.widgets zawiera definicje obiektów GUI podobnych do elementów formularzy HTML, takich jak przycisk, suwak, pole wyboru, przycisk radiowy itp. Te kontrolki zapewniają interaktywny interfejs do wykresu. Wywołanie przetwarzania, takiego jak modyfikowanie danych wykresu, zmiana parametrów wykresu itp., Może być wykonywane przez niestandardowe funkcje JavaScript wykonywane na odpowiednich zdarzeniach.

Bokeh umożliwia zdefiniowanie funkcji oddzwaniania za pomocą dwóch metod -

  • Użyj CustomJS callback tak, że interaktywność będzie działać w samodzielnych dokumentach HTML.

  • Posługiwać się Bokeh server i skonfiguruj programy obsługi zdarzeń.

W tej sekcji zobaczymy, jak dodawać widżety Bokeh i przypisywać wywołania zwrotne JavaScript.

Przycisk

Ten widżet jest klikalnym przyciskiem, zwykle używanym do wywoływania zdefiniowanej przez użytkownika procedury obsługi połączeń zwrotnych. Konstruktor przyjmuje następujące parametry -

Button(label, icon, callback)

Parametr label to ciąg znaków używany jako podpis przycisku, a wywołanie zwrotne to niestandardowa funkcja JavaScript wywoływana po kliknięciu.

W poniższym przykładzie widżet Wykres i Przycisk są wyświetlane w układzie Kolumna. Sam wykres renderuje glif linii między seriami danych x i y.

Niestandardowa funkcja JavaScript o nazwie „callback” została zdefiniowana za pomocą CutomJS() function. Otrzymuje odniesienie do obiektu, który wywołał wywołanie zwrotne (w tym przypadku przycisku) w postaci zmiennej cb_obj.

Ta funkcja zmienia źródłowe dane ColumnDataSource i ostatecznie emituje tę aktualizację w danych źródłowych.

from bokeh.layouts import column
from bokeh.models import CustomJS, ColumnDataSource
from bokeh.plotting import Figure, output_file, show
from bokeh.models.widgets import Button

x = [x*0.05 for x in range(0, 200)]
y = x

source = ColumnDataSource(data=dict(x=x, y=y))
plot = Figure(plot_width=400, plot_height=400)
plot.line('x', 'y', source=source, line_width=3, line_alpha=0.6)

callback = CustomJS(args=dict(source=source), code="""
   var data = source.data;
   x = data['x']
   y = data['y']
   for (i = 0; i < x.length; i++) {
      y[i] = Math.pow(x[i], 4)
   }
   source.change.emit();
""")

btn = Button(label="click here", callback=callback, name="1")

layout = column(btn , plot)
show(layout)

Wyjście (początkowe)

Kliknij przycisk u góry wykresu i zobacz zaktualizowany rysunek wykresu, który wygląda następująco -

Wyjście (po kliknięciu)

Suwak

Za pomocą suwaka można wybrać liczbę między przypisanymi do niej właściwościami początkowymi i końcowymi.

Slider(start, end, step, value)

W poniższym przykładzie rejestrujemy funkcję zwrotną na zdarzeniu on_change suwaka. Chwilowa wartość liczbowa suwaka jest dostępna dla procedury obsługi w postaci cb_obj.value, która służy do modyfikowania danych ColumnDatasource. Wykres wykresu jest stale aktualizowany w miarę przesuwania pozycji.

from bokeh.layouts import column
from bokeh.models import CustomJS, ColumnDataSource
from bokeh.plotting import Figure, output_file, show
from bokeh.models.widgets import Slider

x = [x*0.05 for x in range(0, 200)]
y = x

source = ColumnDataSource(data=dict(x=x, y=y))
plot = Figure(plot_width=400, plot_height=400)
plot.line('x', 'y', source=source, line_width=3, line_alpha=0.6)

handler = CustomJS(args=dict(source=source), code="""
   var data = source.data;
   var f = cb_obj.value
   var x = data['x']
   var y = data['y']
   for (var i = 0; i < x.length; i++) {
      y[i] = Math.pow(x[i], f)
   }
   source.change.emit();
""")

slider = Slider(start=0.0, end=5, value=1, step=.25, title="Slider Value")

slider.js_on_change('value', handler)
layout = column(slider, plot)
show(layout)

Wynik

RadioGroup

Ten widżet przedstawia kolekcję wzajemnie wykluczających się przycisków przełączania, przedstawiających okrągłe przyciski po lewej stronie podpisu.

RadioGroup(labels, active)

Gdzie etykiety to lista podpisów, a aktywny to indeks wybranej opcji.

Wybierz

Ten widżet jest prostą rozwijaną listą elementów ciągów, z których jedną można wybrać. Wybrany ciąg pojawi się w górnym oknie i jest parametrem wartości.

Select(options, value)

Lista elementów string w rozwijanym menu jest podana w postaci obiektu listy opcji.

Poniżej przedstawiono połączony przykład przycisku opcji i widżetów wyboru, które zapewniają trzy różne relacje między seriami danych x i y. PlikRadioGroup i Select widgets są rejestrowane z odpowiednimi programami obsługi za pomocą metody on_change ().

from bokeh.layouts import column
from bokeh.models import CustomJS, ColumnDataSource
from bokeh.plotting import Figure, output_file, show
from bokeh.models.widgets import RadioGroup, Select

x = [x*0.05 for x in range(0, 200)]
y = x

source = ColumnDataSource(data=dict(x=x, y=y))

plot = Figure(plot_width=400, plot_height=400)
plot.line('x', 'y', source=source, line_width=3, line_alpha=0.6)

radiohandler = CustomJS(args=dict(source=source), code="""
   var data = source.data;
   console.log('Tap event occurred at x-position: ' + cb_obj.active);
   //plot.title.text=cb_obj.value;
   x = data['x']
   y = data['y']
   if (cb_obj.active==0){
      for (i = 0; i < x.length; i++) {
         y[i] = x[i];
      }
   }
   if (cb_obj.active==1){
      for (i = 0; i < x.length; i++) {
         y[i] = Math.pow(x[i], 2)
      }
   }
   if (cb_obj.active==2){
      for (i = 0; i < x.length; i++) {
         y[i] = Math.pow(x[i], 4)
      }
   }
   source.change.emit();
""")

selecthandler = CustomJS(args=dict(source=source), code="""
   var data = source.data;
   console.log('Tap event occurred at x-position: ' + cb_obj.value);
   //plot.title.text=cb_obj.value;
   x = data['x']
   y = data['y']
   if (cb_obj.value=="line"){
      for (i = 0; i < x.length; i++) {
         y[i] = x[i];
      }
   }
   if (cb_obj.value=="SquareCurve"){
      for (i = 0; i < x.length; i++) {
         y[i] = Math.pow(x[i], 2)
      }
   }
   if (cb_obj.value=="CubeCurve"){
      for (i = 0; i < x.length; i++) {
         y[i] = Math.pow(x[i], 4)
      }
   }
   source.change.emit();
""")

radio = RadioGroup(
   labels=["line", "SqureCurve", "CubeCurve"], active=0)
radio.js_on_change('active', radiohandler)
select = Select(title="Select:", value='line', options=["line", "SquareCurve", "CubeCurve"])
select.js_on_change('value', selecthandler)

layout = column(radio, select, plot)
show(layout)

Wynik

Widżet karty

Podobnie jak w przeglądarce, każda karta może wyświetlać inną stronę internetową, tak samo widżet Tab jest modelem Bokeh, który zapewnia inny widok każdej figury. W poniższym przykładzie dwa wykresy krzywych sinus i cosinus są renderowane na dwóch różnych kartach -

from bokeh.plotting import figure, output_file, show
from bokeh.models import Panel, Tabs
import numpy as np
import math
x=np.arange(0, math.pi*2, 0.05)
fig1=figure(plot_width=300, plot_height=300)

fig1.line(x, np.sin(x),line_width=2, line_color='navy')

tab1 = Panel(child=fig1, title="sine")
fig2=figure(plot_width=300, plot_height=300)
fig2.line(x,np.cos(x), line_width=2, line_color='orange')
tab2 = Panel(child=fig2, title="cos")

tabs = Tabs(tabs=[ tab1, tab2 ])

show(tabs)

Wynik