如何为散景网格图设置默认/活动工具?

时间:2018-03-14 16:12:12

标签: python python-3.x plot bokeh

如果想要为散景图定义活动(默认)工具,可以通过将" 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,但我看不出如何使用该参数更改活动工具。

1 个答案:

答案 0 :(得分:2)

研究

我相信您只能使用toolbar_options更改徽标:

toolbar_options=dict(logo='gray')

我希望将来有更多的选择。

我已经检查了如何实现你想要的东西(我也需要这样做)并且似乎网格图使用一个特殊的工具栏将所有的绘图工具栏连接在一起: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)

工具收集在列表中,以将它们分配到特殊工具栏。我没有看到默认的活动元素是在任何地方收集的。

替代解决方案

因此,您可以手动创建工具栏和网格图,您可以在其中设置工具栏类所需的属性。查看我已构建的示例:

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(散景开发者)在聊天中告诉我

  

我打算实际回答默认工具激活和网格图从未被一起考虑过,并且还没有得到支持,如果你找到了适合你特定用例的东西,那可能是最好的。正如你所说,一般情况下用户不应该直接使用工具栏,但由于种种原因,它们很挑剔。