Bokeh - Ajout de widgets

Le module bokeh.models.widgets contient des définitions d'objets GUI similaires aux éléments de formulaire HTML, tels que bouton, curseur, case à cocher, bouton radio, etc. Ces contrôles fournissent une interface interactive à un tracé. Le traitement d'appel tel que la modification des données de tracé, la modification des paramètres de tracé, etc., peut être effectué par des fonctions JavaScript personnalisées exécutées sur les événements correspondants.

Bokeh permet de définir la fonctionnalité de rappel avec deux méthodes -

  • Utilisez le CustomJS callback afin que l'interactivité fonctionne dans des documents HTML autonomes.

  • Utilisation Bokeh server et mettre en place des gestionnaires d'événements.

Dans cette section, nous verrons comment ajouter des widgets Bokeh et attribuer des callbacks JavaScript.

Bouton

Ce widget est un bouton cliquable généralement utilisé pour appeler un gestionnaire de rappel défini par l'utilisateur. Le constructeur prend les paramètres suivants -

Button(label, icon, callback)

Le paramètre label est une chaîne utilisée comme légende du bouton et le rappel est la fonction JavaScript personnalisée à appeler lorsque l'utilisateur clique dessus.

Dans l'exemple suivant, un graphique et un widget Bouton sont affichés dans la disposition Colonne. Le tracé lui-même rend un glyphe de ligne entre les séries de données x et y.

Une fonction JavaScript personnalisée nommée 'callback' a été définie en utilisant CutomJS() function. Il reçoit la référence à l'objet qui a déclenché le rappel (dans ce cas le bouton) sous la forme variable cb_obj.

Cette fonction modifie les données source ColumnDataSource et émet finalement cette mise à jour dans les données source.

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)

Sortie (initiale)

Cliquez sur le bouton en haut du tracé et voyez la figure mise à jour du tracé qui ressemble à ceci -

Sortie (après clic)

Glissière

À l'aide d'un curseur, il est possible de sélectionner un nombre entre les propriétés de début et de fin qui lui sont attribuées.

Slider(start, end, step, value)

Dans l'exemple suivant, nous enregistrons une fonction de rappel sur l'événement on_change du curseur. La valeur numérique instantanée du curseur est disponible pour le gestionnaire sous la forme de cb_obj.value qui est utilisé pour modifier les données ColumnDatasource. La figure du tracé se met à jour en permanence lorsque vous faites glisser la position.

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)

Production

RadioGroup

Ce widget présente une collection de boutons à bascule mutuellement exclusifs affichant des boutons circulaires à gauche de la légende.

RadioGroup(labels, active)

Où, labels est une liste de légendes et active est l'index de l'option sélectionnée.

Sélectionner

Ce widget est une simple liste déroulante d'éléments de chaîne, dont l'un peut être sélectionné. La chaîne sélectionnée apparaît dans la fenêtre supérieure et il s'agit du paramètre de valeur.

Select(options, value)

La liste des éléments de chaîne dans la liste déroulante est donnée sous la forme d'un objet de liste d'options.

Voici un exemple combiné de bouton radio et de widgets de sélection, tous deux fournissant trois relations différentes entre les séries de données x et y. leRadioGroup et Select widgets sont enregistrés auprès des gestionnaires respectifs via la méthode 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)

Production

Widget onglet

Tout comme dans un navigateur, chaque onglet peut afficher une page Web différente, le widget Onglet est un modèle Bokeh offrant une vue différente à chaque figure. Dans l'exemple suivant, deux graphiques de courbes sinus et cosinus sont rendus dans deux onglets différents -

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)

Production