Python 以交互方式更改bokeh绘图中的图示符

Python 以交互方式更改bokeh绘图中的图示符,python,python-3.x,bokeh,Python,Python 3.x,Bokeh,我正在尝试生成一个bokeh应用程序,它允许用户更改绘图的图示符。不幸的是,在调用下拉按钮的_change()方法后,glyph没有改变,尽管我可以用类似的方式改变轴标签。但是,在调用的函数之外更改plot.glyph可以正常工作 from bokeh.layouts import layout from bokeh.models import ColumnDataSource from bokeh.models.widgets import Dropdown from bokeh.plotti

我正在尝试生成一个bokeh应用程序,它允许用户更改绘图的图示符。不幸的是,在调用下拉按钮的_change()方法后,glyph没有改变,尽管我可以用类似的方式改变轴标签。但是,在调用的函数之外更改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)

我不确定您的方法不起作用的确切原因,但这一方法有效:

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
标志


另外,请注意正确的术语。你所说的绘图,实际上不是一个绘图,而是一个字形渲染器。图和图基本上是一样的。

谢谢!这正是我想要做的。也谢谢你纠正我的术语。