在 Jupyter Notebook 中渲染后将字形添加到散景图
Add glyphs to a bokeh plot after it is rendered in the Jupyter Notebook
我正在尝试在 Jupyter Notebook 中创建一个仪表板,其中包含交互式散景图和 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)
这个代码块已经不能正常工作了。当我从小部件 select a 'square' 时,圆圈被删除,但只在绘图中间添加一个正方形,而不是在圆圈的先前位置。我尝试使用产生相同结果的 p.add_glyph
函数,并确保正方形的数据源与圆圈的数据源相同(确实如此)。
如有任何帮助,我们将不胜感激!
干杯,
暗利
首先,我无法让 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)
我正在尝试在 Jupyter Notebook 中创建一个仪表板,其中包含交互式散景图和 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)
这个代码块已经不能正常工作了。当我从小部件 select a 'square' 时,圆圈被删除,但只在绘图中间添加一个正方形,而不是在圆圈的先前位置。我尝试使用产生相同结果的 p.add_glyph
函数,并确保正方形的数据源与圆圈的数据源相同(确实如此)。
如有任何帮助,我们将不胜感激! 干杯, 暗利
首先,我无法让 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)