2015-08-27 1 views
15

Es wäre nett, Linien in einem Bokeh-Plot interaktiv anzeigen und ausblenden zu können. Sprich: Ich habe meine Handlung etwas wie folgt erstellt:Wie interaktiv Zeilen in einem Bokeh-Plot angezeigt und versteckt werden?

from bokeh.plotting import output_file, figure, show 
from numpy.random import normal, uniform 

meas_data_1 = normal(0, 1, 100) 
meas_data_2 = uniform(-0.5, 0.5, 100) 

output_file("myplot.html", title="My plot") 
fig = figure(width=500, plot_height=500) 

fig.line(x=range(0, len(meas_data_1)), y=meas_data_1) 
fig.line(x=range(0, len(meas_data_2)), y=meas_data_2) 

show(fig) 

Wie kann ich die Möglichkeit hinzufügen, um interaktiv zu aktivieren/deaktivieren einer der beiden Linien?

Ich weiß, dass dies auf der Wunschliste ist (siehe this feature request), aber das klingt nicht so, als würde es zu früh umgesetzt werden.

Ich habe den Eindruck, dass dies möglich sein sollte, eine mit CheckBoxGroup und ein self-defined callback, aber leider hat dieser Rückruf in JavaScript geschrieben werden, was ich absolut keine Erfahrung haben.

Antwort

12

EDIT: Interaktive Legenden sind jetzt in der Bibliothek ab Bokeh gebaut 0.12.5 finden https://bokeh.github.io/blog/2017/4/5/release-0-12-5/


Diese auf dem richtigen Weg erscheint irgendwann als interaktive Legenden umgesetzt werden: https://github.com/bokeh/bokeh/issues/3715

Derzeit (v0.12.1) gibt es ein Beispiel, das CustomJS für die Kontrollkästchen verwendet: https://github.com/bokeh/bokeh/pull/4868

1.363.210

Relevante Code:

import numpy as np 

from bokeh.io import output_file, show 
from bokeh.layouts import row 
from bokeh.palettes import Viridis3 
from bokeh.plotting import figure 
from bokeh.models import CheckboxGroup, CustomJS 

output_file("line_on_off.html", title="line_on_off.py example") 

p = figure() 
props = dict(line_width=4, line_alpha=0.7) 
x = np.linspace(0, 4 * np.pi, 100) 
l0 = p.line(x, np.sin(x), color=Viridis3[0], legend="Line 0", **props) 
l1 = p.line(x, 4 * np.cos(x), color=Viridis3[1], legend="Line 1", **props) 
l2 = p.line(x, np.tan(x), color=Viridis3[2], legend="Line 2", **props) 

checkbox = CheckboxGroup(labels=["Line 0", "Line 1", "Line 2"], 
         active=[0, 1, 2], width=100) 
checkbox.callback = CustomJS(args=dict(l0=l0, l1=l1, l2=l2, checkbox=checkbox), 
          lang="coffeescript", code=""" 
l0.visible = 0 in checkbox.active; 
l1.visible = 1 in checkbox.active; 
l2.visible = 2 in checkbox.active; 
""") 

layout = row(checkbox, p) 
show(layout) 
+0

Danke für die Bearbeitung! Nebenfrage: Gibt es eine Möglichkeit, dies mithilfe einer Liste von Renderern anstelle von separaten Variablen zu tun? Ich möchte einen Satz von ~ 30 verschiedenen Renderern gleichzeitig anzeigen/ausblenden. – user2561747

+0

Wahrscheinlich sollten Sie in der Lage sein, eine Liste als einen der Werte im 'args' dict, IIRC, zu übergeben. – bigreddot

+0

Das konnte nicht funktionieren, bokeh raiste 'ValueError: erwartete ein Element von Dict (String, Instanz (Model)), bekam {'renderers': [, .. .], 'checkbox': } ' – user2561747

2

Ich kann mich irren, aber es mir scheint, dass keine ID gibt es für die verschiedenen Linien zur Verfügung steht, ein Select verwenden entschied ein Weg, sie zu verbergen hätte ein document.getElementById("idSelected").style.visibility = "hidden";

seit CheckBoxGroup zu tun hat, nicht einen Rückruf zur Verfügung ich. kann ich die ausgewählte Quelle in den CustomJS bekommen, aber das ist so ziemlich alles:

from bokeh.io import vform 
from bokeh.models import CustomJS, ColumnDataSource, Select 
from bokeh.plotting import output_file, figure, show 
from numpy.random import normal, uniform 

meas_data_1 = normal(0, 1, 10) 
meas_data_2 = uniform(-0.5, 0.5, 10) 

x1 = range(0, len(meas_data_1)) 
y1 = meas_data_1 
source1 = ColumnDataSource(data=dict(x=x1, y=y1)) 
x2 = range(0, len(meas_data_2)) 
y2 = meas_data_2 
source2 = ColumnDataSource(data=dict(x=x2, y=y2)) 



output_file("myplot.html", title="My plot") 
fig = figure(width=500, plot_height=500) 

fig.line('x', 'y', source=source1, line_width=3, line_alpha=0.6) 
fig.line('x', 'y', source=source2, line_width=3, line_alpha=0.6) 

select = Select(title="Option:", options=["source1", "source2"]) 

select.callback = CustomJS(args=dict(source1=source1, source2=source2, select=select), code=""" 

     console.log(select.attributes.value); 
    """) 



show(vform(fig, select)) 

Vielleicht können Sie „optimieren“ die Daten in den CustomJS sich all 0 je nach zu machen, was ausgewählt ist, oder vielleicht, wenn Sie können Greife auf die line_width-Eigenschaft zu und mache es zu 0, aber das ist alles, woran ich denken kann.

+0

Sorry für die downvote, die neue Antwort re '0.12.1' spiegelt die aktuellsten Informationen/neuen Funktionen diese viel einfacher zu machen. – bigreddot

Verwandte Themen