Repository: bokeh/bokeh

Issue:
Legend is too tall (and maybe too wide) if more than two items
See `examples/charts/file/scatter_multi.py` - at two or three legend items, the legend height is correct, but as number of legend items increases, the legend height increases inappropriately (but seemingly in proportion to the increase) 



Discussion:
@birdsarah Looked into it. Problem is not that legend is too hight, but that the items are not correctly divided in the available space. 

One thing that surprises me is that the `legend_spacing` is _also_ used as padding. I.e.  the total padding is a combination of spacing and padding. This seems not how it is supposed to be. I am halfway in fixing that, but it seems so consistently applied that before I continue, I'd like to make sure we're on the same page about this.

For reference, our docs say on `legend_spacing`: "Amount of spacing between legend entries."

This line also doesn't work as intended: https://github.com/bokeh/bokeh/blob/master/bokehjs/src/coffee/models/annotations/legend.coffee#L22-L24

`get_text_height(@visuals.label_text.font_value())` returns an object not a number

Thanks for looking into this. I needed to make a couple of changes for off-canvas to work, then thought I'd make a couple of changes for styling defaults, the found the code a little messy and un-tested and realized I shouldn't get sucked into it. I can't remember if i'm responsible for padding and spacing being the same (which i agree they shouldn't be). I think all clean-up would be great. The main thing i was hoping the new defaults would do is to give legend entries a little more breathing room than they had before.

Thanks @canavandl, nice catch. I will fix that while I am in there.

Also, the padding seems to be used as the margin as well ...


Resolving patch:
diff --git a/bokeh/models/annotations.py b/bokeh/models/annotations.py
--- a/bokeh/models/annotations.py
+++ b/bokeh/models/annotations.py
@@ -74,16 +74,16 @@ class Legend(Annotation):
 
     label_text_font_size = Override(default={ 'value' : '10pt' })
 
-    label_standoff = Int(15, help="""
+    label_standoff = Int(5, help="""
     The distance (in pixels) to separate the label from its associated glyph.
     """)
 
     label_height = Int(20, help="""
-    The height (in pixels) of the area that legend labels should occupy.
+    The minimum height (in pixels) of the area that legend labels should occupy.
     """)
 
-    label_width = Int(50, help="""
-    The width (in pixels) of the area that legend labels should occupy.
+    label_width = Int(20, help="""
+    The minimum width (in pixels) of the area that legend labels should occupy.
     """)
 
     glyph_height = Int(20, help="""
@@ -94,8 +94,12 @@ class Legend(Annotation):
     The width (in pixels) that the rendered legend glyph should occupy.
     """)
 
+    legend_margin = Int(10, help="""
+    Amount of margin around the legend.
+    """)
+
     legend_padding = Int(10, help="""
-    Amount of padding around the legend.
+    Amount of padding around the contents of the legend.
     """)
 
     legend_spacing = Int(3, help="""


Test patch:
diff --git a/bokeh/models/tests/test_annotations.py b/bokeh/models/tests/test_annotations.py
--- a/bokeh/models/tests/test_annotations.py
+++ b/bokeh/models/tests/test_annotations.py
@@ -55,9 +55,9 @@ def test_Legend():
     legend = Legend()
     assert legend.plot is None
     assert legend.location == 'top_right'
-    assert legend.label_standoff == 15
+    assert legend.label_standoff == 5
     assert legend.label_height == 20
-    assert legend.label_width == 50
+    assert legend.label_width == 20
     assert legend.glyph_height == 20
     assert legend.glyph_width == 20
     assert legend.legend_padding == 10
@@ -75,6 +75,7 @@ def test_Legend():
         "label_width",
         "glyph_height",
         "glyph_width",
+        "legend_margin",
         "legend_padding",
         "legend_spacing",
         "legends",