2016-06-25 19 views
1

私はBokehのプロットにリンクされているカーソルを希望します。カーソルをあるプロットに移動すると、隣接するプロットに同等の線が現れます。私は組み込みカーソルツールを使ってそれを行う方法を理解していません。だから私の現在の解決策は、ソースを共有する各プロットに線を引くことです。次に、いずれかのプロットにカーソルを合わせると、ソースが更新されます。PythonでBokehとプロットの間にスパンまたはカーソルをリンク

私はこの方法に2つの問題があります: 1.回避策のようです。 2.現在の行は有限の長さです。私は線を無限にしたいので、どのようにグラフのサイズを変更しても、線は端からはみ出してしまいます。現在私が描く線は有限です。無限の水平線を描く正しい方法はスパン注釈ですが、コールバックでスパン位置を渡したり更新したりする方法はわかりません。以下の私のコードを見てください。

from bokeh.io import gridplot, show, output_notebook, output_file 
from bokeh.plotting import figure 
from bokeh.models import HoverTool, ColumnDataSource, CustomJS, Span 


output_notebook() 

x = list(range(11)) 
y1 = x 
y2 = [10 - i for i in x] 


source = ColumnDataSource({'x0': [0], 'y0': [2], 'x1': [10], 'y1': [2]}) 

# create a new plot 
s1 = figure(width=250, plot_height=250, tools="", title=None) 
cr1 = s1.circle(x, y1, size=10, color="navy", alpha=0.5) 
sr1 = s1.segment(x0='x0', y0='y0', x1='x1', y1='y1', color='red', alpha=1, line_width=1, source=source,) 
sp1 = Span(location=source.data['y0'][0], dimension='width', line_color='green') 
s1.renderers.extend([sp1,]) 

# create another one 
s2 = figure(width=250, height=250, title=None) 
cr2 = s2.triangle(x, y1, size=10, color="firebrick", alpha=0.5) 
sr2 = s2.segment(x0='x0', y0='y0', x1='x1', y1='y1', color='red', alpha=1, line_width=1, source=source,) 

# put all the plots in an HBox 
p = gridplot([[s1,s2],[]]) 

code = """ 
var data = {'x0': [], 'y0': [], 'x1': [], 'y1': []}; 
var cdata = circle.get('data'); 
var indices = cb_data.index['1d'].indices; 

for (i=0; i < indices.length; i++) { 
    ind0 = indices[i]; 
     data['x0'].push(0); 
     data['y0'].push(cdata.y[ind0]); 
     data['x1'].push(10); 
     data['y1'].push(cdata.y[ind0]); 

} 
segment.set('data', data); 
""" 


callback1 = CustomJS(args={'circle': cr1.data_source, 'segment': sr2.data_source}, code=code) 
s1.add_tools(HoverTool(tooltips=None, callback=callback1, renderers=[cr1])) 

callback2 = CustomJS(args={'circle': cr2.data_source, 'segment': sr2.data_source}, code=code) 
s2.add_tools(HoverTool(tooltips=None, callback=callback2, renderers=[cr2])) 


# show the results 
show(p) 
+1

データ範囲に関係なく、常に次元全体にまたがる行である「スパン」が必要です。 'dimenions'プロパティを設定して' vertical'または 'horizo​​ntal'の方向を設定し、次に' location'(例えば 'CustomJS'から更新可能)の単一の数値を設定します。また、CSSレンダリングモードのオプションも用意されています。これは、多くの場合、より効果的です。 – bigreddot

+0

ありがとう@bigreddot。それが私の必要なヒントでした。私は機能するコードを掲示した。 – mcragun

答えて

1

@bigreddotがスパンで回答したことに感謝します。私は試してみたが、仕事につかなかったが、彼のヒントでそれを理解した。作業コードは以下の通りです。私は各プロットに範囲を実装し、それぞれの位置を編集します。

from bokeh.io import gridplot, show, output_notebook, output_file 
from bokeh.plotting import figure 
from bokeh.models import HoverTool, ColumnDataSource, CustomJS, Span 

output_file('Test.html') 

#output_notebook() 

x = list(range(11)) 
y1 = x 
y2 = [10 - i for i in x] 

# create a new plot 
s1 = figure(width=250, plot_height=250, tools="", title=None) 
cr1 = s1.circle(x, y1, size=10, color="navy", alpha=0.5) 
sp1 = Span(location=source.data['y0'][0], dimension='width', line_color='green', render_mode='css') 
s1.renderers.extend([sp1,]) 

# create another one 
s2 = figure(width=250, height=250, title=None) 
cr2 = s2.triangle(x, y1, size=10, color="firebrick", alpha=0.5) 
sp2 = Span(location=source.data['y0'][0], dimension='width', line_color='green', render_mode='css') 
s2.renderers.extend([sp2,]) 

# put all the plots in an HBox 
p = gridplot([[s1,s2],[]]) 

code = """ 
var cdata = circle.get('data'); 
var indices = cb_data.index['1d'].indices; 

var sum = 0; 

for (i=0; i < indices.length; i++) { 
    sum += cdata.y[indices[i]]; 
} 

var avg = sum/indices.length 
span1.set('location', [avg]) 
span2.set('location', [avg]) 
""" 

callback1 = CustomJS(args={'circle': cr1.data_source, 'span1': sp1, 'span2': sp2}, code=code) 
s1.add_tools(HoverTool(tooltips=None, callback=callback1, renderers=[cr1])) 

callback2 = CustomJS(args={'circle': cr2.data_source, 'span1': sp1, 'span2': sp2}, code=code) 
s2.add_tools(HoverTool(tooltips=None, callback=callback2, renderers=[cr2])) 

# show the results 
show(p) 
関連する問題