how to link vbar with circle plots using bokeh?

自古美人都是妖i 提交于 2019-12-11 06:59:46

问题


I have three plots based on the same dataset. How can I link all three plots so that when I select a certain species in vbar plot, two scatter plot also change to plot points in that species only.

any help is appreciated~

from bokeh.sampledata.iris import flowers
from bokeh.plotting import figure, output_file, show
from bokeh.models import ColumnDataSource, CategoricalColorMapper
from bokeh.layouts import column, row

#color mapper to color data by species
mapper = CategoricalColorMapper(factors = ['setosa','versicolor', 'virginica'],\
                                 palette = ['green', 'blue', 'red'])


output_file("plots.html")

#group by species and plot barplot for count
species = flowers.groupby('species')

source = ColumnDataSource(species)

p = figure(plot_width = 800, plot_height = 400, title = 'Count by Species', \
           x_range = source.data['species'], y_range = (0,60),tools = 'box_select')

p.vbar(x = 'species', top = 'petal_length_count', width = 0.8, source = source,\
       nonselection_fill_color = 'gray', nonselection_fill_alpha = 0.2,\
       color = {'field': 'species', 'transform': mapper})

labels = LabelSet(x='species', y='petal_length_count', text='petal_length_count', 
              x_offset=5, y_offset=5, source=source)

p.add_layout(labels)



#scatter plot for sepal length and width
source1 = ColumnDataSource(flowers)
p1 = figure(plot_width = 800, plot_height = 400, tools = 'box_select', title = 'scatter plot for sepal')

p1.circle(x = 'sepal_length', y ='sepal_width', source = source1, \
          nonselection_fill_color = 'gray', nonselection_fill_alpha = 0.2, \
          color = {'field': 'species', 'transform': mapper})


#scatter plot for petal length and width
p2 = figure(plot_width = 800, plot_height = 400, tools = 'box_select', title = 'scatter plot for petal')

p2.circle(x = 'petal_length', y ='petal_width', source = source1, \
          nonselection_fill_color = 'gray', nonselection_fill_alpha = 0.2, \
          color = {'field': 'species', 'transform': mapper})


#show all three plots
show(column(p, row(p1, p2)))

回答1:


I don't think there's some functionality existing for this at the moment. But you can explicitly link two ColumnDataSources with a CustomJS callback:

from bokeh.models import CusomJS

source = ColumnDataSource(species)
source1 = ColumnDataSource(flowers)
source.js_on_change('selected', CustomJS(args=dict(s1=source1), code="""
    const indices = cb_obj.selected['1d'].indices;
    const species = new Set(indices.map(i => cb_obj.data.species[i]));
    s1.selected['1d'].indices = s1.data.species.reduce((acc, s, i) => {if (species.has(s)) acc.push(i); return acc}, []);
    s1.select.emit();
"""))

Note that this callback only synchronizes selection from the bar plot to the scatter plots. To make selections on the scatter plots influence the bar plot, you'll have to write some additional code.



来源:https://stackoverflow.com/questions/47579840/how-to-link-vbar-with-circle-plots-using-bokeh

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!