我正在尝试使用交互式散景图在Jupyter笔记本中创建一个仪表板,并使用ipywidgets
作为小部件来控制绘图。我的用例有点复杂,因为我想创建一个带有不同标记的图,在散点图中指定不同的组,我想让用户更改组的划分(从而更改显示在图)。
我考虑了两种不同的方法:
使用散景图表API生成带有不同标记的散点图。除非我弄错了,否则这将不允许我更新情节,而是我必须在用户的每次更改时重新创建它。
使用bokeh.plotting
API自行创建地块。为此,我必须自己将数据分组,并分别自行更新每组标记的数据坐标。
我已经开始尝试第二个选项,因为我想尝试自己更新绘图而不是重新创建它。我创建了一个简单的例子,它已经为我提出了一些问题。这是代码:
p = figure()
s = widgets.Dropdown(options=['circle', 'square'])
x = np.random.normal(size=10)
y = np.random.normal(size=10)
data = ColumnDataSource(dict(x=x, y=y))
r = p.scatter(source=data, x='x', y='y', size=14)
def select_value(change):
renderers = [x for x in p.renderers if x.__view_model__ == "GlyphRenderer"]
for r in renderers:
p.renderers.remove(r)
if change['new'] == 'circle':
r = p.circle(x, y, size=14)
else:
r = p.square(x, y, size=14)
push_notebook()
s.observe(select_value, 'value')
display(s)
show(p, notebook_handle=True)
此代码块已经无法正常工作。当我从小部件中选择“正方形”时,圆圈将被移除,但在绘图的中间只添加一个正方形,而不是在圆圈的先前位置。我尝试使用p.add_glyph
函数产生相同的结果,并确保广场的数据源与圆圈的数据源相同(它是)。
任何帮助将不胜感激! 干杯, 欧米
答案 0 :(得分:0)
首先,我无法使widgets.Dropdown
与options
合作,我使用bokeh.models.widgets.Select
。它可能是散景版,我使用0.12.4版本。
其次,在select_value
更新功能中添加字形,使用bokeh.io.push_notebook()
,然后删除原始渲染器,再次bokeh.io.push_notebook()
我在其中一个单元格中:
import bokeh
import bokeh.plotting
import numpy as np
from ipywidgets import interact
bokeh.io.output_notebook()
p = bokeh.plotting.figure()
s = bokeh.models.widgets.Select(options=['circle', 'square'])
x = np.random.normal(size=10)
y = np.random.normal(size=10)
source = bokeh.models.ColumnDataSource(dict(x=x, y=y))
scatter_plot = p.scatter(source=source, x='x', y='y',color="blue",marker="circle", size=14)
def select_value(change):
renderers = [x for x in p.renderers if x.__view_model__ == "GlyphRenderer"]
for r in renderers:
if change == 'circle':
myglyph = bokeh.models.Circle(x="x",y="y",fill_color="blue", line_color="blue",size=14)
elif change == 'square':
myglyph = bokeh.models.Square(x="x",y="y",fill_color="blue", line_color="blue",size=14)
r.glyph = myglyph
p.add_glyph(source,myglyph)
bokeh.io.push_notebook()
p.renderers.remove(r)
bokeh.io.push_notebook()
bokeh.io.show(p, notebook_handle=True)
创建数字:
在我的另一个单元格中:
interact(select_value,change=['circle', 'square']);
创建交互式工具:
<强>更新强>
另一种方法是使用visible
参数。您可以创建所需的所有标记类型,然后在不使用其他标记类型的情况下显示您的选择:
import bokeh
import bokeh.plotting
import numpy as np
from ipywidgets import interact
bokeh.io.output_notebook()
p = bokeh.plotting.figure()
s = bokeh.models.widgets.Select(options=['circle', 'square'])
x = np.random.normal(size=10)
y = np.random.normal(size=10)
source = bokeh.models.ColumnDataSource(dict(x=x, y=y))
scatter_circle = p.scatter(source=source, x='x', y='y',color="blue", marker='circle', size=14)
scatter_square = p.scatter(source=source, x='x', y='y',color="blue", marker='square', size=14)
scatter_square.visible=False
handle = bokeh.io.show(p, notebook_handle=True)
def select_value(change):
if change == 'circle':
scatter_circle.visible=True
scatter_square.visible=False
elif change == 'square':
scatter_square.visible=True
scatter_circle.visible=False
bokeh.io.push_notebook(handle=handle)