Repository: bokeh/bokeh

Issue:
Autohide toolbar
Right now, when a Bokeh plot has a toolbar, the toolbar is always visible.  This helps people see the tools that are available, but it is distracting when one is primarily reading through a long document, looking at several plots and not wishing to interact with any one of them.  

To support this usage, I'd prefer that the default behavior is that the tools are visible only when the mouse is actually inside the plot area, and otherwise they are silently hidden (which would then also apply on export, providing a cleaner exported figure). Presumably the tools could be set to be invisible (alpha=0) whenever the mouse is outside the plot area?  

An implementation of this would be to add an option `autohide` to `Toolbar`, and once supported we could debate whether it should be True or False by default.


Discussion:
Just an FYI noting that it is expected @jsignell to work on this after #8085 is merged
This will require more work than just adding an option to a toolbar. Currently toolbar, as a part of a plot, can be only located in side panels, in which case any kind of hiding doesn't make sense. There is no way to add a toolbar to the center layout. In #8085 I stared implementing "anchor layout" to allow this, but this is far from being finished.
@mattpap the example upon which this is based, simply hides the toolbar without altering the layout. That is expressly all that is wanted or being asked for. The toolbar does not need to be in the center layout, it just needs to allocate space as if it were going to draw, but then not actually draw (unless the cursor is inside w hit region).

For that matter, we could even flip things: we could have a div on top of the toolbar that fades to and from transparent (instead of having the toolbar itself fade to and from opaque)
Not actually drawing it is fine, but it's also fine to draw it but using transparent pixels; whatever is easier.  Hopefully we wouldn't have to resort to a div on top of the toolbar, because that would interfere with a page where the background isn't a solid color. 

But yes, ideally the layout would be unchanged regardless of whether the tools are visible or not; it would be very distracting to have the plot jump around and resize when the mouse enters the area.
@mattpap, are you worried about how the tool bar should show up when the mouse is over the plot? Is it hard for an event from the center layout to have an effect in the toolbar?

Resolving patch:
diff --git a/bokeh/models/tools.py b/bokeh/models/tools.py
--- a/bokeh/models/tools.py
+++ b/bokeh/models/tools.py
@@ -112,6 +112,11 @@ class ToolbarBase(Model):
     set to None, no logo will be displayed.
     """)
 
+    autohide = Bool(default=False, help="""
+    Whether the toolbar will be hidden by default. Default: False.
+    If True, hides toolbar when cursor is not in canvas.
+    """)
+
     tools = List(Instance(Tool), help="""
     A list of tools to add to the plot.
     """)
diff --git a/examples/plotting/file/toolbar_autohide.py b/examples/plotting/file/toolbar_autohide.py
new file mode 100644
--- /dev/null
+++ b/examples/plotting/file/toolbar_autohide.py
@@ -0,0 +1,20 @@
+import numpy as np
+
+from bokeh.layouts import row
+from bokeh.plotting import figure, show, output_file
+
+N = 1000
+x = np.random.random(size=N) * 100
+y = np.random.random(size=N) * 100
+radii = np.random.random(size=N) * 1.5
+colors = ["#%02x%02x%02x" % (int(r), int(g), 150) for r, g in zip(50+2*x, 30+2*y)]
+
+def make_plot(autohide=None):
+    p = figure(width=300, height=300, title='Autohiding toolbar' if autohide else 'Not autohiding toolbar')
+    p.scatter(x, y, radius=radii, fill_color=colors, fill_alpha=0.6, line_color=None)
+    p.toolbar.autohide = autohide
+    return p
+
+output_file("toolbar_autohide.html", title="toolbar_autohide example")
+
+show(row(make_plot(True), make_plot(False)))
diff --git a/sphinx/source/docs/user_guide/examples/styling_toolbar_autohide.py b/sphinx/source/docs/user_guide/examples/styling_toolbar_autohide.py
new file mode 100644
--- /dev/null
+++ b/sphinx/source/docs/user_guide/examples/styling_toolbar_autohide.py
@@ -0,0 +1,12 @@
+from bokeh.plotting import figure, output_file, show
+
+output_file("styling_toolbar_autohide.html")
+
+# Basic plot setup
+plot = figure(width=400, height=400, title='Toolbar Autohide')
+plot.line([1,2,3,4,5], [2,5,8,2,7])
+
+# Set autohide to true to only show the toolbar when mouse is over plot
+plot.toolbar.autohide = True
+
+show(plot)


Test patch:
diff --git a/bokeh/models/tests/test_tools.py b/bokeh/models/tests/test_tools.py
--- a/bokeh/models/tests/test_tools.py
+++ b/bokeh/models/tests/test_tools.py
@@ -15,8 +15,17 @@ def test_Toolbar():
     assert tb.active_inspect == 'auto'
     assert tb.active_scroll == 'auto'
     assert tb.active_tap == 'auto'
+    assert tb.autohide is False
 
 
+def test_Toolbar_with_autohide():
+    tb = Toolbar(autohide=True)
+    assert tb.active_drag == 'auto'
+    assert tb.active_inspect == 'auto'
+    assert tb.active_scroll == 'auto'
+    assert tb.active_tap == 'auto'
+    assert tb.autohide is True
+
 #
 # ToolbarBox
 #
diff --git a/tests/integration/tools/test_toolbar_autohide.py b/tests/integration/tools/test_toolbar_autohide.py
new file mode 100644
--- /dev/null
+++ b/tests/integration/tools/test_toolbar_autohide.py
@@ -0,0 +1,70 @@
+#-----------------------------------------------------------------------------
+# Copyright (c) 2012 - 2017, Anaconda, Inc. All rights reserved.
+#
+# Powered by the Bokeh Development Team.
+#
+# The full license is in the file LICENSE.txt, distributed with this software.
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# Boilerplate
+#-----------------------------------------------------------------------------
+from __future__ import absolute_import, division, print_function, unicode_literals
+
+import pytest ; pytest
+
+#-----------------------------------------------------------------------------
+# Imports
+#-----------------------------------------------------------------------------
+
+# Standard library imports
+
+# External imports
+from selenium.webdriver.common.action_chains import ActionChains
+
+# Bokeh imports
+from bokeh.plotting import figure
+
+#-----------------------------------------------------------------------------
+# Tests
+#-----------------------------------------------------------------------------
+
+pytest_plugins = (
+    "bokeh._testing.plugins.bokeh",
+)
+
+@pytest.mark.integration
+@pytest.mark.selenium
+class Test_Toobar_Autohide(object):
+
+    def test_toolbar_is_visible_by_default_and_stays_visible(self, single_plot_page):
+        plot = figure(height=800, width=1000)
+        plot.rect(x=[1, 2], y=[1, 1], width=1, height=1)
+
+        page = single_plot_page(plot)
+
+        assert (page.driver.find_element_by_class_name('bk-toolbar')
+                           .value_of_css_property('visibility')) == 'visible'
+
+        ActionChains(page.driver).move_to_element(page.canvas).perform()
+
+        assert (page.driver.find_element_by_class_name('bk-toolbar')
+                           .value_of_css_property('visibility')) == 'visible'
+
+        assert page.has_no_console_errors()
+
+    def test_toolbar_with_autohide_becomes_visible_when_cursor_is_over_plot(self, single_plot_page):
+        plot = figure(height=800, width=1000)
+        plot.toolbar.autohide = True
+        plot.rect(x=[1, 2], y=[1, 1], width=1, height=1)
+
+        page = single_plot_page(plot)
+        assert (page.driver.find_element_by_class_name('bk-toolbar')
+                           .value_of_css_property('visibility')) == 'hidden'
+
+        ActionChains(page.driver).move_to_element(page.canvas).perform()
+
+        assert (page.driver.find_element_by_class_name('bk-toolbar')
+                           .value_of_css_property('visibility')) == 'visible'
+
+        assert page.has_no_console_errors()