交互式更改散景图中的字形 [英] Interactively change glyphs in bokeh plot

查看:33
本文介绍了交互式更改散景图中的字形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试生成一个bokeh应用程序,该应用程序允许用户更改情节的字形.不幸的是,尽管我能够以类似方式更改轴标签,但字形在调用下拉按钮的on_change()方法后不会更改.但是,在调用的函数之外更改plot.glyph可以正常工作.

I'm trying to generate a bokeh application which allows the user to change the glyphs of a plot. Unfortunately, the glyphs don't change after calling on_change() method of the dropdown button although I'm able to change the axis label in a similar way. However, changing plot.glyph outside of the called function works fine.

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)

推荐答案

我不确定您的方法行不通的确切原因,但是这种方法行得通:

I'm not sure about the exact reasons why your approach doesn't work, but this one works:

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

Basically, I create all necessary renderers beforehand, and then just switch visible flag of each one.

此外,请注意正确的术语.您所说的绘图实际上不是绘图,而是字形渲染器.图和图基本上是同一件事.

Also, note the correct terminology. What you're calling a plot, is not actually a plot but a glyph renderer. And plot and figure are basically the same thing.

这篇关于交互式更改散景图中的字形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆