如何为散景网格图设置默认/活动工具?
How do I set default / active tools for a bokeh gridplot?
如果要为散景图定义活动(默认)工具,可以通过将 "active_drag"、"active_inspect"、...参数传递给图形实例来进行设置 here.
我还没有成功为网格图设置标准活动工具,其中所有单个图共享一个工具栏。这是我代码的相关部分:
tools = [
PanTool(),
BoxZoomTool(),
WheelZoomTool(),
UndoTool(),
RedoTool(),
ResetTool(),
SaveTool(),
HoverTool(tooltips=[
("Value", "$y")
])
]
x_axes_range = Range1d(self.data.index[0], self.data.index[-1])
for plot_type, plot_settings in pcfg.plot_types[self.name].items():
plots.append(figure(x_axis_type="datetime", title=plot_type, plot_height = 400, x_range = x_axes_range,
tools = tools, active_drag = None, active_inspect = None, active_scroll = None, active_tap = None))
...
plots[plot_counter].line(self.data.index, self.data[parameter], color=parameter_settings[1], legend=parameter_settings[0])
...
gp = gridplot(plots, ncols = 1, sizing_mode = "scale_width")
script, div = components(gp)
所以发生的事情是 "BoxZoomTool()" 在我显示它的网站上被选为活动工具,虽然我在图形初始化中将活动工具设置为 None,但是可用工具是我传递给 figure()
inits 的那些。
我确实看到了 "toolbar_option" here,但我不知道如何使用该参数更改活动工具。
2020 年 6 月 4 日更新
嗯,好像有人创造了一个GitHub Issue and the changes were already merged。让我们看看这是否适用于下一个 Bokeh 版本
旧答案
研究
我相信你只能像这样用toolbar_options
改变标志:
toolbar_options=dict(logo='gray')
希望以后有更多选择
我已经检查了如何实现你想要的(我也需要这样做)并且似乎网格图使用一个特殊的工具栏将所有绘图工具栏连接在一起:a ProxyToolbar
# Make the grid
tools = []
rows = []
for row in children:
row_tools = []
row_children = []
for item in row:
if merge_tools:
if item is not None:
for plot in item.select(dict(type=Plot)):
row_tools = row_tools + plot.toolbar.tools
plot.toolbar_location = None
if item is None:
width, height = 0, 0
for neighbor in row:
if isinstance(neighbor, Plot):
width = neighbor.plot_width
height = neighbor.plot_height
break
item = Spacer(width=width, height=height)
if isinstance(item, LayoutDOM):
item.sizing_mode = sizing_mode
if isinstance(item, Plot):
if plot_width:
item.plot_width = plot_width
if plot_height:
item.plot_height = plot_height
row_children.append(item)
else:
raise ValueError("Only LayoutDOM items can be inserted into Grid")
tools = tools + row_tools
rows.append(Row(children=row_children, sizing_mode=sizing_mode))
grid = Column(children=rows, sizing_mode=sizing_mode)
if not merge_tools:
return grid
if toolbar_location:
proxy = ProxyToolbar(tools=tools, **toolbar_options)
toolbar = ToolbarBox(toolbar=proxy, toolbar_location=toolbar_location)
这些工具被收集在一个列表中,以将它们分配给特殊工具栏。我没有看到任何地方都收集了默认的活动元素。
备选方案
所以你可以做的是手动创建一个工具栏和网格图,你可以在其中为工具栏设置你想要的属性 class。检查我构建的这个示例:
from bokeh.models import Button, ColumnDataSource, Range1d, Toolbar, ToolbarBox
from bokeh.models.tools import HoverTool, WheelZoomTool, PanTool, CrosshairTool
from bokeh.layouts import layout
from bokeh.plotting import curdoc, figure
x_range = Range1d(start=0, end=10)
y_range = Range1d(start=0, end=10)
# ------------------- PLOT 1 --------------------------- #
plot_1 = figure(
title='First figure',
width=400,
height=400,
x_range=x_range,
y_range=y_range,
toolbar_location=None,
x_axis_label='x axis',
y_axis_label='y axis',
)
x = [1, 2, 3, 4]
y = [4, 3, 2, 1]
source = ColumnDataSource(data=dict(x=x, y=y))
plot_1.circle(
x='x',
y='y',
source=source,
radius=0.5,
fill_alpha=0.6,
fill_color='green',
line_color='black',
)
# ------------------- PLOT 2 --------------------------- #
plot_2 = figure(
name='plot_2',
title='Second figure',
width=400,
height=400,
x_range=x_range,
y_range=y_range,
toolbar_location=None,
x_axis_label='x axis',
y_axis_label='y axis',
)
plot_2.circle(
x='x',
y='y',
source=source,
radius=0.5,
fill_alpha=0.6,
fill_color='red',
line_color='black',
)
# ---------------- ADD TOOLS TO THE PLOT --------------------- #
wheel_zoom = WheelZoomTool()
pan_tool = PanTool()
hover = HoverTool()
crosshair = CrosshairTool()
tools = (wheel_zoom, pan_tool, hover, crosshair)
toolbar = Toolbar(
tools=[wheel_zoom, pan_tool, hover, crosshair],
active_inspect=[crosshair],
# active_drag = # here you can assign the defaults
# active_scroll = # wheel_zoom sometimes is not working if it is set here
# active_tap
)
toolbar_box = ToolbarBox(
toolbar=toolbar,
toolbar_location='left'
)
plot_1.add_tools(*tools)
plot_2.add_tools(*tools)
# ----------------- PLOT LAYOUT -------------------------- #
layout_1 = layout(
children=[
[toolbar_box, plot_1, plot_2],
],
sizing_mode='fixed',
)
curdoc().add_root(layout_1)
注意:我正在做一些测试,有时效果不佳。这些工具被标记为默认但随机不起作用,恐怕它与 JavaScript 和异步任务有关。所以也许我们应该等待。
第二种替代解决方案
我想我找到了一个始终有效的解决方案。这是一种解决方法。在我的示例中,我使用了两个图,但只显示了第一个图的工具栏。无论如何,您需要将默认工具栏值设置为两个图。
from bokeh.models import Button, ColumnDataSource, Range1d, Toolbar, ToolbarBox
from bokeh.models.tools import HoverTool, WheelZoomTool, PanTool, CrosshairTool, LassoSelectTool
from bokeh.layouts import layout
from bokeh.plotting import curdoc, figure
x_range = Range1d(start=0, end=10)
y_range = Range1d(start=0, end=10)
# ------------------- PLOT 1 --------------------------- #
plot_1 = figure(
title='First figure',
width=400,
height=400,
x_range=x_range,
y_range=y_range,
toolbar_location='left', # show only the toolbar of the first plot
tools='',
x_axis_label='x axis',
y_axis_label='y axis',
)
x = [1, 2, 3, 4]
y = [4, 3, 2, 1]
source = ColumnDataSource(data=dict(x=x, y=y))
plot_1.circle(
x='x',
y='y',
source=source,
radius=0.5,
fill_alpha=0.6,
fill_color='green',
line_color='black',
)
# ------------------- PLOT 2 --------------------------- #
plot_2 = figure(
name='plot_2',
title='Second figure',
width=400,
height=400,
x_range=x_range,
y_range=y_range,
toolbar_location=None,
tools='',
x_axis_label='x axis',
y_axis_label='y axis',
)
plot_2.circle(
x='x',
y='y',
source=source,
radius=0.5,
fill_alpha=0.6,
fill_color='red',
line_color='black',
)
# ---------------- ADD TOOLS TO THE PLOT --------------------- #
wheel_zoom = WheelZoomTool()
lasso_select = LassoSelectTool()
pan_tool = PanTool()
hover = HoverTool()
crosshair = CrosshairTool()
tools = (wheel_zoom, lasso_select, pan_tool, hover, crosshair)
plot_1.add_tools(*tools)
plot_2.add_tools(*tools)
plot_1.toolbar.active_inspect=[crosshair] # defaults added to the first plot
plot_1.toolbar.active_scroll=wheel_zoom
plot_1.toolbar.active_tap=None
plot_1.toolbar.active_drag=lasso_select
plot_2.toolbar.active_inspect=[crosshair] # defaults added to the second plot
plot_2.toolbar.active_scroll=wheel_zoom
plot_2.toolbar.active_tap=None
plot_2.toolbar.active_drag=lasso_select
# ----------------- PLOT LAYOUT -------------------------- #
layout_1 = layout(
children=[
[plot_1, plot_2],
],
sizing_mode='fixed',
)
curdoc().add_root(layout_1)
开发者反馈
事实上,Bryan(散景开发者)在聊天中告诉我
I was going to actually answer that default tool activation and grid plots had never been considered together and was not supported yet, tho if you have found something that works for your specific use case that's probably the best possible. As you say it's not generally the case that user's should have to work with toolbars directly, they are finicky for a number of reasons.
如果要为散景图定义活动(默认)工具,可以通过将 "active_drag"、"active_inspect"、...参数传递给图形实例来进行设置 here.
我还没有成功为网格图设置标准活动工具,其中所有单个图共享一个工具栏。这是我代码的相关部分:
tools = [
PanTool(),
BoxZoomTool(),
WheelZoomTool(),
UndoTool(),
RedoTool(),
ResetTool(),
SaveTool(),
HoverTool(tooltips=[
("Value", "$y")
])
]
x_axes_range = Range1d(self.data.index[0], self.data.index[-1])
for plot_type, plot_settings in pcfg.plot_types[self.name].items():
plots.append(figure(x_axis_type="datetime", title=plot_type, plot_height = 400, x_range = x_axes_range,
tools = tools, active_drag = None, active_inspect = None, active_scroll = None, active_tap = None))
...
plots[plot_counter].line(self.data.index, self.data[parameter], color=parameter_settings[1], legend=parameter_settings[0])
...
gp = gridplot(plots, ncols = 1, sizing_mode = "scale_width")
script, div = components(gp)
所以发生的事情是 "BoxZoomTool()" 在我显示它的网站上被选为活动工具,虽然我在图形初始化中将活动工具设置为 None,但是可用工具是我传递给 figure()
inits 的那些。
我确实看到了 "toolbar_option" here,但我不知道如何使用该参数更改活动工具。
2020 年 6 月 4 日更新
嗯,好像有人创造了一个GitHub Issue and the changes were already merged。让我们看看这是否适用于下一个 Bokeh 版本
旧答案
研究
我相信你只能像这样用toolbar_options
改变标志:
toolbar_options=dict(logo='gray')
希望以后有更多选择
我已经检查了如何实现你想要的(我也需要这样做)并且似乎网格图使用一个特殊的工具栏将所有绘图工具栏连接在一起:a ProxyToolbar
# Make the grid
tools = []
rows = []
for row in children:
row_tools = []
row_children = []
for item in row:
if merge_tools:
if item is not None:
for plot in item.select(dict(type=Plot)):
row_tools = row_tools + plot.toolbar.tools
plot.toolbar_location = None
if item is None:
width, height = 0, 0
for neighbor in row:
if isinstance(neighbor, Plot):
width = neighbor.plot_width
height = neighbor.plot_height
break
item = Spacer(width=width, height=height)
if isinstance(item, LayoutDOM):
item.sizing_mode = sizing_mode
if isinstance(item, Plot):
if plot_width:
item.plot_width = plot_width
if plot_height:
item.plot_height = plot_height
row_children.append(item)
else:
raise ValueError("Only LayoutDOM items can be inserted into Grid")
tools = tools + row_tools
rows.append(Row(children=row_children, sizing_mode=sizing_mode))
grid = Column(children=rows, sizing_mode=sizing_mode)
if not merge_tools:
return grid
if toolbar_location:
proxy = ProxyToolbar(tools=tools, **toolbar_options)
toolbar = ToolbarBox(toolbar=proxy, toolbar_location=toolbar_location)
这些工具被收集在一个列表中,以将它们分配给特殊工具栏。我没有看到任何地方都收集了默认的活动元素。
备选方案
所以你可以做的是手动创建一个工具栏和网格图,你可以在其中为工具栏设置你想要的属性 class。检查我构建的这个示例:
from bokeh.models import Button, ColumnDataSource, Range1d, Toolbar, ToolbarBox
from bokeh.models.tools import HoverTool, WheelZoomTool, PanTool, CrosshairTool
from bokeh.layouts import layout
from bokeh.plotting import curdoc, figure
x_range = Range1d(start=0, end=10)
y_range = Range1d(start=0, end=10)
# ------------------- PLOT 1 --------------------------- #
plot_1 = figure(
title='First figure',
width=400,
height=400,
x_range=x_range,
y_range=y_range,
toolbar_location=None,
x_axis_label='x axis',
y_axis_label='y axis',
)
x = [1, 2, 3, 4]
y = [4, 3, 2, 1]
source = ColumnDataSource(data=dict(x=x, y=y))
plot_1.circle(
x='x',
y='y',
source=source,
radius=0.5,
fill_alpha=0.6,
fill_color='green',
line_color='black',
)
# ------------------- PLOT 2 --------------------------- #
plot_2 = figure(
name='plot_2',
title='Second figure',
width=400,
height=400,
x_range=x_range,
y_range=y_range,
toolbar_location=None,
x_axis_label='x axis',
y_axis_label='y axis',
)
plot_2.circle(
x='x',
y='y',
source=source,
radius=0.5,
fill_alpha=0.6,
fill_color='red',
line_color='black',
)
# ---------------- ADD TOOLS TO THE PLOT --------------------- #
wheel_zoom = WheelZoomTool()
pan_tool = PanTool()
hover = HoverTool()
crosshair = CrosshairTool()
tools = (wheel_zoom, pan_tool, hover, crosshair)
toolbar = Toolbar(
tools=[wheel_zoom, pan_tool, hover, crosshair],
active_inspect=[crosshair],
# active_drag = # here you can assign the defaults
# active_scroll = # wheel_zoom sometimes is not working if it is set here
# active_tap
)
toolbar_box = ToolbarBox(
toolbar=toolbar,
toolbar_location='left'
)
plot_1.add_tools(*tools)
plot_2.add_tools(*tools)
# ----------------- PLOT LAYOUT -------------------------- #
layout_1 = layout(
children=[
[toolbar_box, plot_1, plot_2],
],
sizing_mode='fixed',
)
curdoc().add_root(layout_1)
注意:我正在做一些测试,有时效果不佳。这些工具被标记为默认但随机不起作用,恐怕它与 JavaScript 和异步任务有关。所以也许我们应该等待。
第二种替代解决方案
我想我找到了一个始终有效的解决方案。这是一种解决方法。在我的示例中,我使用了两个图,但只显示了第一个图的工具栏。无论如何,您需要将默认工具栏值设置为两个图。
from bokeh.models import Button, ColumnDataSource, Range1d, Toolbar, ToolbarBox
from bokeh.models.tools import HoverTool, WheelZoomTool, PanTool, CrosshairTool, LassoSelectTool
from bokeh.layouts import layout
from bokeh.plotting import curdoc, figure
x_range = Range1d(start=0, end=10)
y_range = Range1d(start=0, end=10)
# ------------------- PLOT 1 --------------------------- #
plot_1 = figure(
title='First figure',
width=400,
height=400,
x_range=x_range,
y_range=y_range,
toolbar_location='left', # show only the toolbar of the first plot
tools='',
x_axis_label='x axis',
y_axis_label='y axis',
)
x = [1, 2, 3, 4]
y = [4, 3, 2, 1]
source = ColumnDataSource(data=dict(x=x, y=y))
plot_1.circle(
x='x',
y='y',
source=source,
radius=0.5,
fill_alpha=0.6,
fill_color='green',
line_color='black',
)
# ------------------- PLOT 2 --------------------------- #
plot_2 = figure(
name='plot_2',
title='Second figure',
width=400,
height=400,
x_range=x_range,
y_range=y_range,
toolbar_location=None,
tools='',
x_axis_label='x axis',
y_axis_label='y axis',
)
plot_2.circle(
x='x',
y='y',
source=source,
radius=0.5,
fill_alpha=0.6,
fill_color='red',
line_color='black',
)
# ---------------- ADD TOOLS TO THE PLOT --------------------- #
wheel_zoom = WheelZoomTool()
lasso_select = LassoSelectTool()
pan_tool = PanTool()
hover = HoverTool()
crosshair = CrosshairTool()
tools = (wheel_zoom, lasso_select, pan_tool, hover, crosshair)
plot_1.add_tools(*tools)
plot_2.add_tools(*tools)
plot_1.toolbar.active_inspect=[crosshair] # defaults added to the first plot
plot_1.toolbar.active_scroll=wheel_zoom
plot_1.toolbar.active_tap=None
plot_1.toolbar.active_drag=lasso_select
plot_2.toolbar.active_inspect=[crosshair] # defaults added to the second plot
plot_2.toolbar.active_scroll=wheel_zoom
plot_2.toolbar.active_tap=None
plot_2.toolbar.active_drag=lasso_select
# ----------------- PLOT LAYOUT -------------------------- #
layout_1 = layout(
children=[
[plot_1, plot_2],
],
sizing_mode='fixed',
)
curdoc().add_root(layout_1)
开发者反馈
事实上,Bryan(散景开发者)在聊天中告诉我
I was going to actually answer that default tool activation and grid plots had never been considered together and was not supported yet, tho if you have found something that works for your specific use case that's probably the best possible. As you say it's not generally the case that user's should have to work with toolbars directly, they are finicky for a number of reasons.