首页 > 解决方案 > Bokeh 使用 Column Data Source 和 Box_Select

问题描述

我不知道如何设置列数据源,以便我可以从一个图表中选择点并在另一个图表中突出显示相应的点。我正在尝试更多地了解它是如何工作的。

我使用的示例代码是名为Linked Brushing的示例。我想看看我是否可以在下面使用我自己的代码获得相同的效果。该网页解释还提到了带有过滤数据的链接选择,但我不明白filters=[BooleanFilter([True if y > 250 or y < 100 else False for y in y1]该页面上的代码是做什么的,所以我不确定如何调整它,或者它是否相关。

这是我的代码:

from bokeh.plotting import figure, output_file, show, Column
from bokeh.models import ColumnDataSource, CDSView, BooleanFilter
from MyFiles import *

class bokehPlot:
    def __init__(self, filename, t, a, b, c, d):

        self.source = ColumnDataSource(data=dict(x=t, y1=a, y2=b, y3=c, y4=d))

        p1 = self.makePlot(filename, 'x', 'y1', 'A')
        p2 = self.makePlot(filename, 'x', 'y2', 'B', x_link=p1)
        p3 = self.makePlot(filename, 'x', 'y3', 'C', x_link=p1)
        p4 = self.makePlot(filename, 'x', 'y4', 'D', x_link=p1)

        output_file('scatter_plotting.html', mode='cdn')

        p = Column(p1, p2, p3, p4)
        show(p)

    def makePlot(self,filename,x0,y0,y_label, **optional):

        TOOLS = "box_zoom,box_select,reset"

        p = figure(tools=TOOLS, plot_width=1800, plot_height=300)

        if ('x_link' in optional):
            p0 = optional['x_link']
            p.x_range = p0.x_range

        p.scatter(x=x0, y=y0, marker='square', size=1, fill_color='red', source=self.source)
        p.title.text = filename
        p.title.text_color = 'orange'
        p.xaxis.axis_label = 'T'
        p.yaxis.axis_label = y_label
        p.xaxis.minor_tick_line_color = 'red'
        p.yaxis.minor_tick_line_color = None
        return p

我的主要看起来像这样(设置为从文件中传递多达 10 万个数据点):web

p = readMyFile(path+filename+extension, 100000)
t = p.time()
a = p.a()
b = p.b()
c = p.c()
d = p.d()
v = bokehPlot(filename, t, a, b, c, d)

变量 t、a、b、c 和 d 是 numpy ndarray 类型。

我已经设法将这些图链接起来,这样我就可以从一张图中平移和缩放它们。我想从一个图中获取一组数据并突出显示它们,以及在其他图表上突出显示的相应值(在相同的 t 值处)。

在这段代码中,我可以绘制一个选择框,但它只保留片刻,然后消失,我看不出对任何绘图有任何影响。box_select 如何与源链接以及导致绘图重绘的原因是什么?

这只是尝试熟悉 Bokeh 的一步。我的下一个目标是使用 TSNE 对我的数据进行聚类,并在每个图表中显示具有同步颜色的聚类。但首先,我想了解这里使用列数据集的机制。例如,在示例代码中,我看不到 box_select 操作和源变量之间的任何显式联系以及导致绘图重绘的原因。

标签: pythonbokeh

解决方案


我的理解是BooleanFilter, theIndexFilterGroupFilter可用于在渲染之前过滤其中一个图中的数据。如果您只希望第二个情节响应第一个情节中的事件,那么您应该gridplot按照评论中的建议使用。只要情节相同ColumnDataSource,就应该将它们链接起来。

from bokeh.layouts import gridplot
from bokeh.models import ColumnDataSource
from bokeh.plotting import figure, show

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

tools = ["box_select", "hover", "reset"]
p_0 = figure(plot_height=300, plot_width=300, tools=tools)
p_0.circle(x="x", y="y", size=10, hover_color="red", source=source)

p_1 = figure(plot_height=300, plot_width=300, tools=tools)
p_1.circle(x="x", y="z", size=10, hover_color="red", source=source)

show(gridplot([[p_0, p_1]]))

推荐阅读