2017-04-11 38 views
1

私はPythonとPandasについては熟練していますが、Bokehパッケージでは非常に新しいので、ここ数日間はこの作業を進めずにこの作業に苦労しています。データを表示するためのダッシュボードを構築しています。ラジオボタンを使用して、同じプロット上の異なる線を選択/表示すると非常に便利です。私はここからの例(https://github.com/bokeh/bokeh/issues/3715)に従っています。これはチェックボックスを使ってうまく動作するようになっています。私は21行目の "CheckboxGroup"を "RadioGroup"に変更し、 "active"引数を変更しました。その結果、ラジオボタンの選択を変更しても戻ってこないと、両方のプロットされた線が消えてしまいます。 CheckboxGroupがどのように機能し、RadioGroupがそうではないかを考慮して、コールバックに「アクティブ」イベントを使用する理由を理解できません。誰かが私の間違いを指摘してもらえますか?Python Bokeh CustomJS RadioGroup

import numpy as np 

from bokeh.io import show 
from bokeh.layouts import widgetbox 
from bokeh.models.widgets import CheckboxGroup, RadioGroup 
from bokeh.models import CustomJS, ColumnDataSource 
from bokeh.layouts import column, row 
from bokeh.plotting import figure 

t = np.arange(0.0, 2.0, 0.01) 
s = np.sin(3*np.pi*t) 
c = np.cos(3*np.pi*t) 

source = ColumnDataSource(data=dict(t=t, s=s, c=c)) 

plot = figure(plot_width=400, plot_height=400) 
a = plot.line('t', 's', source=source, line_width=3, line_alpha=0.6, 
line_color='blue') 
b = plot.line('t', 'c', source=source, line_width=3, line_alpha=0.6, 
line_color='red') 

checkbox = RadioGroup(labels=["Cosinus", "Sinus"], active=0) 

checkbox.callback = CustomJS(args=dict(line0=a, line1=b), code=""" 
    //console.log(cb_obj.active); 
    line0.visible = false; 
    line1.visible = false; 
    for (i in cb_obj.active) { 
     //console.log(cb_obj.active[i]); 
     if (cb_obj.active[i] == 0) { 
      line0.visible = true; 
     } else if (cb_obj.active[i] == 1) { 
      line1.visible = true; 
     } 
    } 
""") 

layout = row(plot, widgetbox(checkbox)) 

show(layout) 

答えて

0

radioboxgroupで、あなただけの整数をループしてみてくださいとしてあなたがループのために役に立たないので、一度に一つの活性値を持つことができます。あなたがループ内でcheckboxgroupで

line_list = [line0,line1]; 

lab_len=cb_obj.labels.length; 

for (i=0;i<lab_len;i++) { 
if (cb_obj.active == i) { 
line_list[i].visible = true; 
} else { 
line_list[i].visible = false; 
} 
} 

を「ラベル」リストの長さを使用することができ、多くのラインを持っている場合は、これを行うには良い方法は、あり

checkbox.callback = CustomJS(args=dict(line0=a, line1=b), code=""" 
    line0.visible = false; 
    line1.visible = false; 

    if (cb_obj.active == 0) { 
     line0.visible = true; 
    } else if (cb_obj.active == 1) { 
     line1.visible = true; 
    } 
""") 

を修正ここにあなたのコードがあります「アクティブ」属性はインデックスのリストです。どちらかが非表示にするには、ユーザーが簡単にあなたが伝説が対話することができ0.12.5ボケののように、グリフの可視性を制御できるようにしようとしている場合

checkbox = CheckboxGroup(labels=["Cosinus", "Sinus"], active=[0,1]) 

checkbox.callback = CustomJS(args=dict(line0=a, line1=b), code=""" 
    line_list = [line0,line1]; 

    lab_len=cb_obj.labels.length; 

    for (i=0;i<lab_len;i++) { 
    if (cb_obj.active.includes(i)) { 
    line_list[i].visible = true; 
    } else { 
    line_list[i].visible = false; 
    } 
    } 
""") 
+0

これはまさに私が探していたものです、今の魅力のように動作します:) – kingfischer

0

私は、これをマルチライン法でプロットする方が簡単だと思います。次に、コールバックで選択されている行を次のように選択できます。

import numpy as np 

from bokeh.io import show 
from bokeh.layouts import widgetbox 
from bokeh.models.widgets import CheckboxGroup, RadioGroup 
from bokeh.models import CustomJS, ColumnDataSource 
from bokeh.layouts import column, row 
from bokeh.plotting import figure 

t = np.arange(0.0, 2.0, 0.01) 
s = np.sin(3*np.pi*t) 
c = np.cos(3*np.pi*t) 

source = ColumnDataSource(data=dict(t=[t]*2, s=[s,c], colors = ['red', 'blue'])) 

plot = figure(plot_width=400, plot_height=400) 
plot.multi_line('t', 's',line_color='colors' ,source=source) 

checkbox = RadioGroup(labels=["Cosinus", "Sinus"], active=0) 

checkbox.callback = CustomJS(args=dict(s=source), code=""" 
    s.selected['1d'].indices = [cb_obj.active] 
    s.trigger('change'); 
""") 

layout = row(plot, widgetbox(checkbox)) 

show(layout) 
+0

私はこのコンパクトさが好きで、次のダッシュボードで使用する必要があります。私はBokehでpandas DataFrames(またはそのスライス)を使用していましたが、私はColumnDataSourceを多くの場所に見ています。関連するデータをDFからColumnDataSourceに入れて、DFを直接使用する代わりにそれをプロットするのは価値がありますか? – kingfischer

+0

ColumnDataSourcesと他のデータソースオブジェクトが使用される主な理由は、ほとんどのレベルの対話性と動的更新に必要とされるためです。データフレームを使用してプロットを更新または変更するには、毎回プロット全体を再作成する必要があります。 これまでの私のところでは、ColumnDataSourceを使うのが簡単で、DFのデータが必要な場合は、単にto_dictメソッドを使用するだけでした。 – Anthonydouc

0

:あなただけの条件は、コードを動作させるためにあれば変更する必要がありますグリフまたは凡例エントリをユーザーがクリックするとき、それらをミュート:あなたは完全にグリフを非表示にする場合

enter image description here

は、伝説のclick_policy"hide"に設定:

p = figure() 
p.circle([1,2,3], [4,5,6], legend="foo") 
p.square([1,2,3], [7,9,8], legend="bar") 
p.legend.click_policy = "hide" 

あなたはまた、ミュートするポリシーを設定することができます

p.legend.click_policy = "mute" 

をしかし、あなたは、例えば、「ミュート」の外観は、各グリフについてどのように見えるかを指定する必要があります。

p.circle([1,2,3], [4,5,6], muted_alpha=0.2, legend="foo") 
関連する問題