Repository: bokeh/bokeh

Issue:
Warn when sticky toolbars might visually overlap other components
Currently with `toolbar_sticky == True` the toolbar can potentially overlap with annotations on the sides of plots, e.g. axes. The default configuration is designed to avoid this possibility, and some cases of sticky toolbars and axes on the same side can be desirable (e.g., internal-only ticks). However, sticky toolbars and axes on the same side will often produce less than desirable results, and so to help users diagnose this outcome, we will issue a validation warning in cases when visual overlap is possible. 

Note: `toolbar_sticky` will like be renamed/changed. 



Discussion:

Resolving patch:
diff --git a/bokeh/core/validation/check.py b/bokeh/core/validation/check.py
--- a/bokeh/core/validation/check.py
+++ b/bokeh/core/validation/check.py
@@ -25,7 +25,7 @@ def check_integrity(models):
         logger.error("E-%d (%s): %s: %s" % msg)
 
     for msg in sorted(messages['warning']):
-        logger.error("W-%d (%s): %s: %s" % msg)
+        logger.warning("W-%d (%s): %s: %s" % msg)
 
     # This will be turned on in a future release
     # if len(messages['error']) or (len(messages['warning']) and settings.strict()):
diff --git a/bokeh/core/validation/warnings.py b/bokeh/core/validation/warnings.py
--- a/bokeh/core/validation/warnings.py
+++ b/bokeh/core/validation/warnings.py
@@ -21,12 +21,13 @@
 '''
 
 codes = {
-    1000: ("MISSING_RENDERERS",         "Plot has no renderers"),
-    1001: ("NO_DATA_RENDERERS",         "Plot has no data renderers"),
-    1002: ("EMPTY_LAYOUT",              "Layout has no children"),
-    1003: ("MALFORMED_CATEGORY_LABEL",  "Category labels cannot contain colons"),
-    1004: ("BOTH_CHILD_AND_ROOT",       "Models should not be a document root if they are in a layout box"),
-    9999: ("EXT",                       "Custom extension reports warning"),
+    1000: ("MISSING_RENDERERS",           "Plot has no renderers"),
+    1001: ("NO_DATA_RENDERERS",           "Plot has no data renderers"),
+    1002: ("EMPTY_LAYOUT",                "Layout has no children"),
+    1003: ("MALFORMED_CATEGORY_LABEL",    "Category labels cannot contain colons"),
+    1004: ("BOTH_CHILD_AND_ROOT",         "Models should not be a document root if they are in a layout box"),
+    1005: ("SNAPPED_TOOLBAR_ANNOTATIONS", "Snapped toolbars and annotations on the same side MAY overlap visually"),
+    9999: ("EXT",                         "Custom extension reports warning"),
 }
 
 for code in codes:
diff --git a/bokeh/models/plots.py b/bokeh/models/plots.py
--- a/bokeh/models/plots.py
+++ b/bokeh/models/plots.py
@@ -10,8 +10,8 @@
 from ..core import validation
 from ..core.validation.errors import REQUIRED_RANGE
 from ..core.validation.warnings import (
-    MISSING_RENDERERS, NO_DATA_RENDERERS,
-    EMPTY_LAYOUT, MALFORMED_CATEGORY_LABEL)
+    MISSING_RENDERERS, NO_DATA_RENDERERS, EMPTY_LAYOUT, MALFORMED_CATEGORY_LABEL,
+    SNAPPED_TOOLBAR_ANNOTATIONS)
 from ..core.enums import Location
 from ..core.property_mixins import LineProps, TextProps, FillProps
 from ..model import Model
@@ -375,6 +375,15 @@ def _check_colon_in_category_label(self):
                                  for field, value in broken)
             return '%s [renderer: %s]' % (field_msg, self)
 
+    @validation.warning(SNAPPED_TOOLBAR_ANNOTATIONS)
+    def _check_snapped_toolbar_and_axis(self):
+        if not self.toolbar_sticky: return
+        if self.toolbar_location is None: return
+
+        objs = getattr(self, self.toolbar_location)
+        if len(objs) > 0:
+            return str(self)
+
     __deprecated_attributes__ = (
         'background_fill', 'border_fill', 'logo', 'tools',
         'title_text_baseline', 'title_text_align', 'title_text_alpha', 'title_text_color',


Test patch: