Bokeh - Aggiunta di widget

Il modulo bokeh.models.widgets contiene definizioni di oggetti GUI simili agli elementi del modulo HTML, come pulsante, cursore, casella di controllo, pulsante di opzione, ecc. Questi controlli forniscono un'interfaccia interattiva a un grafico. Il richiamo di elaborazioni come la modifica dei dati del grafico, la modifica dei parametri del grafico, ecc., Può essere eseguito dalle funzioni JavaScript personalizzate eseguite sugli eventi corrispondenti.

Bokeh consente di definire la funzionalità di richiamata con due metodi:

  • Utilizzare il CustomJS callback in modo che l'interattività funzioni nei documenti HTML autonomi.

  • Uso Bokeh server e impostare gestori di eventi.

In questa sezione vedremo come aggiungere widget Bokeh e assegnare callback JavaScript.

Pulsante

Questo widget è un pulsante cliccabile generalmente utilizzato per richiamare un gestore di richiamata definito dall'utente. Il costruttore accetta i seguenti parametri:

Button(label, icon, callback)

Il parametro label è una stringa utilizzata come didascalia del pulsante e callback è la funzione JavaScript personalizzata da chiamare quando si fa clic.

Nell'esempio seguente, un grafico e un widget Pulsante vengono visualizzati in Layout colonna. Il grafico stesso esegue il rendering di un glifo di linea tra le serie di dati xey.

Una funzione JavaScript personalizzata denominata "callback" è stata definita utilizzando CutomJS() function. Riceve il riferimento all'oggetto che ha attivato la richiamata (in questo caso il pulsante) nella forma variabile cb_obj.

Questa funzione altera i dati di origine ColumnDataSource e infine emette questo aggiornamento nei dati di origine.

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)

Uscita (iniziale)

Fare clic sul pulsante nella parte superiore della trama e vedere la figura della trama aggiornata che appare come segue:

Uscita (dopo il clic)

Slider

Con l'aiuto di un controllo a cursore è possibile selezionare un numero tra le proprietà di inizio e fine assegnate ad esso.

Slider(start, end, step, value)

Nell'esempio seguente, registriamo una funzione di callback sull'evento on_change dello slider. Il valore numerico istantaneo di Slider è disponibile per il gestore sotto forma di cb_obj.value che viene utilizzato per modificare i dati ColumnDatasource. La figura del grafico si aggiorna continuamente mentre fai scorrere la posizione.

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)

Produzione

RadioGroup

Questo widget presenta una raccolta di pulsanti di commutazione che si escludono a vicenda che mostrano pulsanti circolari a sinistra della didascalia.

RadioGroup(labels, active)

Dove, etichette è un elenco di didascalie e attivo è l'indice dell'opzione selezionata.

Selezionare

Questo widget è un semplice elenco a discesa di elementi stringa, uno dei quali può essere selezionato. La stringa selezionata appare nella finestra in alto ed è il parametro del valore.

Select(options, value)

L'elenco degli elementi stringa nel menu a discesa viene fornito sotto forma di oggetto elenco di opzioni.

Di seguito è riportato un esempio combinato di pulsante di opzione e widget di selezione, che forniscono entrambi tre diverse relazioni tra le serie di dati x e y. IlRadioGroup e Select widgets sono registrati con i rispettivi gestori tramite il metodo 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)

Produzione

Widget scheda

Proprio come in un browser, ogni scheda può mostrare una pagina web diversa, il widget Tab è il modello Bokeh che fornisce una vista diversa per ogni figura. Nell'esempio seguente, due figure del grafico delle curve seno e coseno vengono renderizzate in due diverse schede:

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)

Produzione