2017-11-26 3 views
2

私はプロットのグリフを変更できるbokehアプリケーションを生成しようとしています。残念ながら、同様の方法で軸ラベルを変更することはできますが、ドロップダウンボタンのon_change()メソッドを呼び出した後にグリフは変更されません。しかし、呼び出された関数の外でplot.glyphを変更するとうまく動作します。ボケプロットの対話的にグリフを変更する

from bokeh.layouts import layout 
from bokeh.models import ColumnDataSource 
from bokeh.models.widgets import Dropdown 
from bokeh.plotting import figure 
from bokeh.io import curdoc 
from bokeh.models.markers import Cross, Circle 

source=ColumnDataSource(dict(x=[1,2,3],y=[4,5,6])) 

fig=figure() 
plot=fig.circle(x='x', y='y',source=source) 
fig.xaxis.axis_label='This is a label' 

#this changes the glyphs from circle to cross 
plot.glyph=Cross(x='x', y='y', size=20, line_color='firebrick', 
fill_color='firebrick', line_alpha=0.8, fill_alpha=0.3) 

def update_plot(attr,old,new): 
    if dropdown.value=='cross': 
     #this changes the axis label but not the glyphs 
     fig.xaxis.axis_label='Label changed' 
     plot.glyph=Cross(x='x', y='y', size=20, line_color='firebrick', 
     fill_color='firebrick', line_alpha=0.8, fill_alpha=0.3) 
    elif dropdown.value=='circle': 
     #this also only changes the axis label but not the glyphs 
     fig.xaxis.axis_label='Label changed again' 
     plot.glyph=Circle(x='x', y='y', size=20, line_color='firebrick', 
     fill_color='firebrick', line_alpha=0.8, fill_alpha=0.3) 

menu=[('Circle','circle'),('Cross', 'cross')] 
dropdown=Dropdown(label="Select marker", menu=menu, value='circle') 
dropdown.on_change('value', update_plot) 

lay_out=layout([fig, dropdown]) 

curdoc().add_root(lay_out) 

答えて

2

私はあなたのアプローチが動作しない理由を正確な理由についてはよく分からないんだけど、この1つは動作します:

from bokeh.io import curdoc 
from bokeh.layouts import layout 
from bokeh.models import ColumnDataSource 
from bokeh.models.widgets import Dropdown 
from bokeh.plotting import figure 

source = ColumnDataSource(dict(x=[1, 2, 3], y=[4, 5, 6])) 

plot = figure() 

renderers = {rn: getattr(plot, rn)(x='x', y='y', source=source, 
            **extra, visible=False) 
      for rn, extra in [('circle', dict(size=10)), 
           ('line', dict()), 
           ('cross', dict(size=10)), 
           ('triangle', dict(size=15))]} 


def label_fn(item): 
    return 'Select marker ({})'.format(item) 


menu = [('No renderer', None)] 
menu.extend((rn.capitalize(), rn) for rn in renderers) 

dropdown = Dropdown(label=label_fn(None), menu=menu, value=None) 


def update_plot(attr, old, new): 
    dropdown.label = label_fn(new) 
    for renderer_name, renderer in renderers.items(): 
     renderer.visible = (renderer_name == new) 


dropdown.on_change('value', update_plot) 

lay_out = layout([plot, dropdown]) 

curdoc().add_root(lay_out) 

は基本的に、私は、事前に必要なすべてのレンダラーを作成してから、ちょうどvisibleを切り替えますそれぞれの旗。

また、正しい用語に注意してください。プロットと呼んでいるのは、実際にプロットではなく、グリフレンダラーです。プロットとフィギュアは基本的に同じものです。

+0

ありがとうございます!これは私がやろうとしていたことです。また、私の用語を修正してくれてありがとう。 –

関連する問題