使用图表选择过滤散景图表源

时间:2019-04-28 20:41:14

标签: bokeh

我正在尝试通过套索/框选择来更改散景图的来源。

回调仅工作一次,但在第一个源更改后停止工作。 另外,我不能说出为什么单击按钮后某些点会突出显示。

我想通过选择逐渐缩小数据源的范围。

这是一个小例子:

import bokeh
import pandas as pd
import numpy as np
from bokeh.plotting import figure, curdoc, show
from bokeh.layouts import column, row, Spacer
from bokeh.models import ColumnDataSource,GMapOptions, HoverTool
from bokeh.models.widgets import Button


df1 = pd.DataFrame(np.random.randint(0,100,size=(3000, 2)), columns=["X","Y"], index=[str(i) for i in range(1,3000+1)])

pointchart=figure(plot_width=800, plot_height=700, tools=['box_select','lasso_select'])
pointchart_source= ColumnDataSource(df1)
pointchart_glyph= pointchart.circle("X","Y",source=pointchart_source, size=3.5) 


def on_selection_change(attr, old, new):
    global newdataframe
    newdataframe= pd.DataFrame(pointchart_source.data).loc[new]
pointchart_glyph.data_source.selected.on_change('indices', on_selection_change) 


def on_update_button_click():
    pointchart_source.data= ColumnDataSource(newdataframe).data

update_button = Button(label="Update", button_type="success")
update_button.on_click(on_update_button_click)


layout =row(pointchart,update_button)
curdoc().add_root(layout)
!powershell -command {'bokeh serve --show Source_update_interaction.ipynb'}

谢谢

2 个答案:

答案 0 :(得分:2)

我认为这就是您要寻找的(Bokeh v1.1.0):

import bokeh
import pandas as pd
import numpy as np
from bokeh.plotting import figure, curdoc, show
from bokeh.layouts import column, row, Spacer
from bokeh.models import ColumnDataSource, GMapOptions, HoverTool
from bokeh.models.widgets import Button

df1 = pd.DataFrame(np.random.randint(0, 100, size = (3000, 2)), columns = ["X", "Y"], index = [str(i) for i in range(1, 3000 + 1)])
pointchart_source = ColumnDataSource(df1)
pointchart = figure(plot_width = 800, plot_height = 700, tools = ['box_select', 'lasso_select'])
pointchart_glyph = pointchart.circle("X", "Y", source = pointchart_source, size = 3.5)

newdataframe = None

def on_selection_change(attr, old, new):
    global newdataframe
    newdataframe = pd.DataFrame(pointchart_source.data).loc[new]
    newdataframe.index = newdataframe['index']
    newdataframe = newdataframe.drop(['index'], axis = 1)

pointchart_glyph.data_source.selected.on_change('indices', on_selection_change)

def on_update_button_click():
    global newdataframe
    if newdataframe is not None:
        if pointchart_source.selected.indices:
            pointchart_source.data = {'X': newdataframe['X'].values, 'Y': newdataframe['Y'].values, 'index': newdataframe.index.values}
            pointchart_source.selected.indices = []

update_button = Button(label = "Update", button_type = "success")
update_button.on_click(on_update_button_click)

layout = row(pointchart, update_button)
curdoc().add_root(layout)

结果:

enter image description here

答案 1 :(得分:1)

不要这样做:

def on_update_button_click():
    pointchart_source.data = ColumnDataSource(newdataframe).data

.data属性的行为类似于dict,但实际上它是一个检测程度很高的对象,与创建该对象的数据源相关联,并负责Python和JS。永远不要将CDS中的一个.data分配给另一个不同的CDS,并且将来尝试这样做可能会引发明确的例外情况。

您应始终从纯Python字典更新.data。您可以在CDS上使用from_df类方法来构建适当形式的字典:

source.data = ColumnDataSource.from_df(newdataframe)