散景:与图例标签文本交互
Bokeh: Interact with legend label text
有什么方法可以交互更改 Bokeh 中的图例标签文本吗?
我读过 https://github.com/bokeh/bokeh/issues/2274 and 但两者都不适用。
我不需要修改颜色或任何比更改标签文本更复杂的东西,但我找不到方法。
从 Bokeh 0.12.1
开始,目前似乎不支持此功能。 Legend
对象有一个 legends
属性 将文本映射到字形列表:
{
"foo": [circle1],
"bar": [line2, circle2]
}
理想情况下,您可以更新此 legends
属性 以使其重新呈现。但是查看 the source code 似乎在初始化时使用了该值,但是如果值发生变化,则没有强制重新渲染的管道。一种可能的解决方法是更改 legends
的值,然后立即设置其他 属性 确实 触发重新渲染。
无论如何,在更新时进行这项工作应该不会有太多工作,并且对于新贡献者来说是一个很好的 PR。我鼓励您在 GitHub issue tracker 上提交一个功能请求问题,如果您有能力通过 Pull Request 来实现它(我们总是很乐意帮助新贡献者入门并回答问题)
希望这个回答能对遇到类似问题的其他人有所帮助。
这个问题有一个解决方法:从版本 0.12.3 开始,您的图例可以通过用于生成给定元素的 ColumnDataSource 对象动态修改。例如:
source_points = ColumnDataSource(dict(
x=[1, 2, 3, 4, 5, 6],
y=[2, 1, 2, 1, 2, 1],
color=['blue','red','blue','red','blue','red'],
category=['hi', 'lo', 'hi', 'lo', 'hi', 'lo']
))
self._figure.circle('x',
'y',
color='color',
legend='category',
source=source_points)
然后您应该可以通过再次设置类别值来更新图例,例如:
# must have the same length
source_points.data['category'] = ['stack', 'flow', 'stack', 'flow', 'stack', 'flow']
注意category
和color
之间的关系。如果你有这样的事情:
source = ColumnDataSource(dict(
x=[1, 2, 3, 4, 5, 6],
y=[2, 1, 2, 1, 2, 1],
color=['blue','red','blue','red','blue','red'],
category=['hi', 'hi', 'hi', 'lo', 'hi', 'lo']
))
然后第二个 hi
也会显示为蓝色。它只匹配第一次出现。
在我的例子中,我让它与下一个代码一起工作:
from bokeh.plotting import figure, show
# Create and show the plot
plt = figure()
handle = show(plt, notebook_handle=True)
# Update the legends without generating the whole plot once shown
for legend in plt.legend:
for legend_item, new_value in zip(legend.items, new_legend_values):
legend_item.label['value'] = new_value
push_notebook(handle=handle)
在我的例子中,我绘制了一些分布,然后以交互方式更新(就像分布变化的动画)。在图例中,我有随时间变化的分布参数,我需要在每次迭代时更新它们,因为它们会发生变化。
请注意,此代码仅适用于 Jupyter 笔记本。
最后我每次都重新绘制整个图表,因为在我的例子中线条的数量也不同。
一个小型的 Jupyter notebook 示例:
from bokeh.io import show
from bokeh.plotting import figure
from bokeh.palettes import brewer
from math import sin, pi
output_notebook()
def update(Sine):
p = figure()
r = []
for i in range(sines.index(Sine) + 1):
y = [sin(xi/(10*(i+1))) for xi in x]
r.append(p.line(x, y, legend=labels[i], color=colors[i], line_width = 3))
show(p, notebook_handle=True)
push_notebook()
sines = ["one sine", "two sines", "three sines"]
labels = ["First sine", "second sine", "Third sine"]
colors = brewer['BuPu'][3]
x = [i for i in range(100)]
interact(update, Sine=sines)
有什么方法可以交互更改 Bokeh 中的图例标签文本吗?
我读过 https://github.com/bokeh/bokeh/issues/2274 and
我不需要修改颜色或任何比更改标签文本更复杂的东西,但我找不到方法。
从 Bokeh 0.12.1
开始,目前似乎不支持此功能。 Legend
对象有一个 legends
属性 将文本映射到字形列表:
{
"foo": [circle1],
"bar": [line2, circle2]
}
理想情况下,您可以更新此 legends
属性 以使其重新呈现。但是查看 the source code 似乎在初始化时使用了该值,但是如果值发生变化,则没有强制重新渲染的管道。一种可能的解决方法是更改 legends
的值,然后立即设置其他 属性 确实 触发重新渲染。
无论如何,在更新时进行这项工作应该不会有太多工作,并且对于新贡献者来说是一个很好的 PR。我鼓励您在 GitHub issue tracker 上提交一个功能请求问题,如果您有能力通过 Pull Request 来实现它(我们总是很乐意帮助新贡献者入门并回答问题)
希望这个回答能对遇到类似问题的其他人有所帮助。
这个问题有一个解决方法:从版本 0.12.3 开始,您的图例可以通过用于生成给定元素的 ColumnDataSource 对象动态修改。例如:
source_points = ColumnDataSource(dict(
x=[1, 2, 3, 4, 5, 6],
y=[2, 1, 2, 1, 2, 1],
color=['blue','red','blue','red','blue','red'],
category=['hi', 'lo', 'hi', 'lo', 'hi', 'lo']
))
self._figure.circle('x',
'y',
color='color',
legend='category',
source=source_points)
然后您应该可以通过再次设置类别值来更新图例,例如:
# must have the same length
source_points.data['category'] = ['stack', 'flow', 'stack', 'flow', 'stack', 'flow']
注意category
和color
之间的关系。如果你有这样的事情:
source = ColumnDataSource(dict(
x=[1, 2, 3, 4, 5, 6],
y=[2, 1, 2, 1, 2, 1],
color=['blue','red','blue','red','blue','red'],
category=['hi', 'hi', 'hi', 'lo', 'hi', 'lo']
))
然后第二个 hi
也会显示为蓝色。它只匹配第一次出现。
在我的例子中,我让它与下一个代码一起工作:
from bokeh.plotting import figure, show
# Create and show the plot
plt = figure()
handle = show(plt, notebook_handle=True)
# Update the legends without generating the whole plot once shown
for legend in plt.legend:
for legend_item, new_value in zip(legend.items, new_legend_values):
legend_item.label['value'] = new_value
push_notebook(handle=handle)
在我的例子中,我绘制了一些分布,然后以交互方式更新(就像分布变化的动画)。在图例中,我有随时间变化的分布参数,我需要在每次迭代时更新它们,因为它们会发生变化。
请注意,此代码仅适用于 Jupyter 笔记本。
最后我每次都重新绘制整个图表,因为在我的例子中线条的数量也不同。
一个小型的 Jupyter notebook 示例:
from bokeh.io import show
from bokeh.plotting import figure
from bokeh.palettes import brewer
from math import sin, pi
output_notebook()
def update(Sine):
p = figure()
r = []
for i in range(sines.index(Sine) + 1):
y = [sin(xi/(10*(i+1))) for xi in x]
r.append(p.line(x, y, legend=labels[i], color=colors[i], line_width = 3))
show(p, notebook_handle=True)
push_notebook()
sines = ["one sine", "two sines", "three sines"]
labels = ["First sine", "second sine", "Third sine"]
colors = brewer['BuPu'][3]
x = [i for i in range(100)]
interact(update, Sine=sines)