Jupyter笔记本中的散景图未更新

时间:2017-05-26 01:39:24

标签: python jupyter-notebook bokeh python-interactive

我想绘制一些具有多个要素的数据,并希望制作一个交互式2D图,用户可以从一系列要素中选择轴,以查看两个要素之间的关系。但是,在我的代码中,绘图不会根据用户输入进行更新。

我正在使用Jupyter笔记本,我正在尝试使用散景包进行绘图。我想坚持使用散景小部件,而不是iPython小部件。任何帮助将不胜感激。

这是一些最小代码

svg.enter().append("svg")
            .classed("chart", true)
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom);


        var g = svg.append("g")
            .classed("circular-heat"+_index, true)
            .attr("transform", "translate(" + parseInt(margin.left + offset) + "," + parseInt(margin.top + offset) + ")");

        var segments = g.selectAll("path").data(data);

1 个答案:

答案 0 :(得分:1)

我认为为了简化你的代码,你可以坚持使用JS回调或python回调,不需要两者。

要更改数据源,您需要将原始数据提供给JS回调,然后在窗口小部件中选择与所选值对应的相应值。

您也可以在JS中以相同的方式设置轴标签。不确定这是否是您期望的实现,但是应该让您更接近。

import numpy as np
import pandas as pd
from bokeh.layouts import row, widgetbox
from bokeh.models import CustomJS, Slider, Select
from bokeh.plotting import figure, output_file, show, ColumnDataSource
from bokeh.io import push_notebook, output_notebook, curdoc
from bokeh.client import push_session
output_notebook()

#create sample pandaframe to work with, this will store the actual data
a = np.arange(50).reshape((5,10))
labels = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J"]
val_a = pd.DataFrame(a, columns=labels )

# Here is a dict of some keys that I want to be able to pick from for plotting
axis_map = {
    "A": "A",
    "B": "B",
    "C": "C"
}

#This is to update during the callback
code = ''' var data = source.data;
           var value1 = val1.value;
           var value2 = val2.value;
           var original_data = original_source.data
           // get data corresponding to selection
           x = original_data[value1];
           y = original_data[value2];
           data['x'] = x;
           data['y'] = y;
           source.trigger('change');
           // set axis labels
           x_axis.axis_label = value1
           y_axis.axis_label = value2
            '''
source = ColumnDataSource(data=dict(x=val_a['A'], y=val_a['B']))
original_source = ColumnDataSource(data=val_a.to_dict(orient='list'))


#plot the figures
plot = figure(plot_width=400, plot_height=400)
plot.circle(x= "x",y="y", source=source, line_width=3, line_alpha=0.6)


callback = CustomJS(args=dict(source=source, original_source = original_source, x_axis=plot.xaxis[0],y_axis=plot.yaxis[0]), code=code)

#Create two select widgets to pick the features of interest 
x_axis = Select(title="X Axis", options=sorted(axis_map.keys()), value="A", callback = callback)
callback.args["val1"] = x_axis

y_axis = Select(title="Y Axis", options=sorted(axis_map.keys()), value="B", callback = callback)
callback.args["val2"] = y_axis

plot.xaxis[0].axis_label = 'A'
plot.yaxis[0].axis_label = 'B'

#Display the graph in a jupyter notebook
layout = row(plot, x_axis, y_axis)
show(layout, notebook_handle=True)