Python Jupyter笔记本中的Bokeh绘图未更新
我想要绘制一些具有多个特征的数据,并想要制作一个交互式2d绘图,用户可以在其中从特征列表中选择轴,以查看任意两个特征之间的关系。但是,在我的代码中,绘图不会根据用户输入进行更新 我用的是Jupyter笔记本,我试着用bokeh软件包来制作情节。我想坚持使用bokeh小部件,而不是iPython小部件。任何帮助都将不胜感激 下面是一些最简单的代码Python Jupyter笔记本中的Bokeh绘图未更新,python,jupyter-notebook,bokeh,python-interactive,Python,Jupyter Notebook,Bokeh,Python Interactive,我想要绘制一些具有多个特征的数据,并想要制作一个交互式2d绘图,用户可以在其中从特征列表中选择轴,以查看任意两个特征之间的关系。但是,在我的代码中,绘图不会根据用户输入进行更新 我用的是Jupyter笔记本,我试着用bokeh软件包来制作情节。我想坚持使用bokeh小部件,而不是iPython小部件。任何帮助都将不胜感激 下面是一些最简单的代码 import numpy as np import pandas as pd from bokeh.layouts import row, widget
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 = val_a;
var val1 = x_axis.value;
var val2 = y_axis.value;
x = data['val1'];
y = data['val2'];
source.trigger('change');
print x
'''
source = ColumnDataSource(data=dict(x=[], y=[]))
callback = CustomJS(args=dict(source=source), 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 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)
#update the plot
def update():
x_name = axis_map[x_axis.value]
y_name = axis_map[y_axis.value]
plot.xaxis.axis_label = x_axis.value
plot.yaxis.axis_label = y_axis.value
print x_name
print val_a[x_name]
source.data = dict(
x=val_a[x_name],
y=val_a[y_name],
)
controls = [ x_axis, y_axis]
for control in controls:
control.on_change('value', lambda attr, old, new: update())
update()
push_notebook()
#Display the graph in a jupyter notebook
layout = row(plot, x_axis, y_axis)
show(layout, notebook_handle=True)
我认为,为了简化代码,您可以只使用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)