# More Elaborate Legend Example

**URL:** <https://discourse.bokeh.org/t/more-elaborate-legend-example/156>\
**Category:** Community Support\
**Created:** [August 16, 2014, 12:35am UTC](https://discourse.bokeh.org/t/more-elaborate-legend-example/156 "2014-08-16T00:35:55Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Armen\_Alexanian](https://discourse.bokeh.org/letter_avatar_proxy/v4/letter/a/da6949/32.png) [@Armen\_Alexanian](https://discourse.bokeh.org/u/Armen_Alexanian)\
**Post date:** [August 16, 2014, 12:35am UTC](https://discourse.bokeh.org/t/more-elaborate-legend-example/156/1 "2014-08-16T00:35:55Z")

</div>

Hi,

I’m trying to experiment with plotting glyphs and text together to try to create a legend that looks like the picture attached. I need to create a legend which also functions as a mini report describing the associated graph with colors corresponding to data items (in this case, people).

Would using a rect() be the best approach or is there another way (like an HTML table?) to create something like the attached image? The ability to do this would be really awesome because rich text and numeric data would perfectly compliment the graph and summarize key elements.

Thanks very much!

Armen

![](https://discourse-uploads.bokeh.org/original/1X/11905f3a7fa706a9862006cb4fe234ad5f8f586f.png)

---

<div class="post-metadata">

**Author:** ![Armen\_Alexanian](https://discourse.bokeh.org/letter_avatar_proxy/v4/letter/a/da6949/32.png) [@Armen\_Alexanian](https://discourse.bokeh.org/u/Armen_Alexanian)\
**Post date:** [August 16, 2014, 12:44am UTC](https://discourse.bokeh.org/t/more-elaborate-legend-example/156/2 "2014-08-16T00:44:15Z")

</div>

To clarify, it wouldn’t technically be the type of legend that is connected to a graph. It would be another separate graph below the first graph. Thanks!

> **···**
>
> On Friday, August 15, 2014 5:35:55 PM UTC-7, Armen Alexanian wrote:
> 
> > Hi,
> 
> > I’m trying to experiment with plotting glyphs and text together to try to create a legend that looks like the picture attached. I need to create a legend which also functions as a mini report describing the associated graph with colors corresponding to data items (in this case, people).
> 
> > 
> 
> > Would using a rect() be the best approach or is there another way (like an HTML table?) to create something like the attached image? The ability to do this would be really awesome because rich text and numeric data would perfectly compliment the graph and summarize key elements.
> 
> > 
> 
> > Thanks very much!
> 
> > Armen

---

<div class="post-metadata">

**Author:** ![Bryan](https://discourse.bokeh.org/user_avatar/discourse.bokeh.org/bryan/32/3625_2.png) [@Bryan](https://discourse.bokeh.org/u/Bryan)\
**Post date:** [August 17, 2014, 11:40am UTC](https://discourse.bokeh.org/t/more-elaborate-legend-example/156/3 "2014-08-17T11:40:35Z")

</div>

Hi Armen,

You could absolutely draw this sort of legend in Bokeh using the rect() or quad() glyph functions together with text() and line() functions (all in bokeh.plotting). However it would also be fairly simple to do with pure HTML. Whether it is worthwhile to do as a plot vs HTML probably depends upon more details of what you are doing. An advantage for doing it in Bokeh would be that if you set it up properly, it should update whenever the data updates. If your data is not updating once the plot is renderers, then it is probably simpler to go the HTML route.

Bryan

> **···**
>
> On Aug 15, 2014, at 7:44 PM, Armen Alexanian \<armenalexanian@gmail.com\> wrote:
> 
> > To clarify, it wouldn't technically be the type of legend that is connected to a graph. It would be another separate graph below the first graph. Thanks!
> > 
> > On Friday, August 15, 2014 5:35:55 PM UTC-7, Armen Alexanian wrote:  
> > Hi,
> > 
> > I'm trying to experiment with plotting glyphs and text together to try to create a legend that looks like the picture attached. I need to create a legend which also functions as a mini report describing the associated graph with colors corresponding to data items (in this case, people).
> > 
> > Would using a rect() be the best approach or is there another way (like an HTML table?) to create something like the attached image? The ability to do this would be really awesome because rich text and numeric data would perfectly compliment the graph and summarize key elements.
> > 
> > Thanks very much!  
> > Armen
> > 
> > --  
> > You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.  
> > To unsubscribe from this group and stop receiving emails from it, send an email to bokeh+unsubscribe@continuum.io.  
> > To post to this group, send email to bokeh@continuum.io.  
> > To view this discussion on the web visit [https://groups.google.com/a/continuum.io/d/msgid/bokeh/169052b3-21cc-4190-911e-cb6e4b69a47a%40continuum.io\](https://groups.google.com/a/continuum.io/d/msgid/bokeh/169052b3-21cc-4190-911e-cb6e4b69a47a%40continuum.io%5C).  
> > For more options, visit [https://groups.google.com/a/continuum.io/d/optout\](https://groups.google.com/a/continuum.io/d/optout%5C).

---

<div class="post-metadata">

**Author:** ![Armen\_Alexanian](https://discourse.bokeh.org/letter_avatar_proxy/v4/letter/a/da6949/32.png) [@Armen\_Alexanian](https://discourse.bokeh.org/u/Armen_Alexanian)\
**Post date:** [August 17, 2014, 11:41pm UTC](https://discourse.bokeh.org/t/more-elaborate-legend-example/156/4 "2014-08-17T23:41:36Z")

</div>

Hi Bryan,

Thanks so much for the encouragement this morning, and for working on the weekend! I got as far as the code below and the image attached. Such as it is, it will still be a huge bonus for my project to have this legend. I ended up using a rectangle because I couldn’t figure out how to make colored boxes (table background color) using df.to\_html().

By the way, I added the xaxis and yaxis code to plotting.py, and was then able to hide the axes again. Thanks!

However, there were several things I wasn’t able to figure out:

1. How to print column headers (or totals) or insert a line separator below them.

2. An easy way to format numbers (I couldn’t get ‘{0:,}’.format() or the locale module to work).

3. How to concatenate df[‘a’] with df[‘b’] in order to avoid having to use multiple text() functions.

Also, how would I insert some HTML, like a table or image, directly under a Bokeh plot?

Thanks so much for your help! I’m still very new to Python and Bokeh so I’m sure the way I did things in the code below could be much improved.

Cheers!

Armen

import numpy as np

from numpy.random import randn

from pandas import \*

from bokeh.plotting import \*

‘’’

I had some trouble in the past in which newer plots would print on top

of older plots so this reset\_output() command clears away old plots

from memory.

‘’’

reset\_output()

# Set an output file.

output\_file(“C:/Users/Armen/Desktop/legend.html”, title=“Legend Example”)

# Plotting all on the same plot.

hold()

# There will be another plot above this one so instantiate a new figure.

figure(

title = “”,

tools = “” # Title and tools not needed for the legend.

)

# Make some series, including one to color the rectangles.

sx = Series([.5,.5,.5,.5,.5,.5,.5])

sy = Series([1,2,3,4,5,6,7])

sc = Series([‘red’,‘orange’,‘green’,‘blue’,‘black’,‘darkred’,‘darkviolet’])

s1 = Series([

‘Robert Smith’,

‘George Jones’,

‘Sally Rogers’,

‘Lenny Walters’,

‘Gene Williams’,

‘Sue Peters’,

‘Jane Maxwell’

])

s2 = Series(range(1000, 7001, 1000))

# Create a dict putting the series above together.

d = {

‘x’: sx,

‘y’: sy,

‘color’: sc,

‘one’: sy,

‘two’: s1,

‘three’: s2

}

# Create a pandas data frame from the dict.

df = DataFrame(d)

# Print the data frame in the Spyder console.

print(df)

# Create x and y axis ranges.

x\_axis\_range = [str(x) for x in sorted(set(df[‘x’]))]

y\_axis\_range = [str(x) for x in sorted(set(df[‘y’]))]

‘’’

The plot height should only be as tall as needed.

Get the max of the y axis for setting the height.

‘’’

max\_y\_axis\_range = int(str(max(y\_axis\_range)))

# Print the rectangles

rect(

x = df[‘x’],

y = df[‘y’],

x\_range = x\_axis\_range,

y\_range = y\_axis\_range,

width = .1,

height = .7,

fill\_color = df[‘color’],

line\_color = df[‘color’],

plot\_width = 600,

# Set the plot height based on how many rows there will be.

plot\_height = max\_y\_axis\_range \* 45

)

# For all the text properties that should be the same.

text\_props = {

“angle”: 0,

“text\_align”: “left”,

“text\_baseline”: “middle”,

“text\_font\_size”: “12pt”,

}

# Print the name a little bit after the rectangles.

text(

df[‘x’] + .07,

df[‘y’],

text = df[‘two’],

\*\*text\_props

)

# Print the number a little after the name.

text(

df[‘x’] + .30,

df[‘y’],

text = df[‘three’],

\*\*text\_props

)

# Hide the grid lines inside the big rectangle box.

grid().grid\_line\_color = None

# Hide elements of the plot.

plot = curplot()

plot.outline\_line\_color = None

axis().axis\_line\_color = None

axis().major\_label\_text\_color = None

axis().major\_tick\_line\_color = None

# Show in browser.

show()

 ![](https://discourse-uploads.bokeh.org/original/1X/ab5ff50ed41cd8adb87db6f6ff3e998ba93c2476.png)

> **···**
>
> On Sunday, August 17, 2014 4:40:37 AM UTC-7, Bryan Van de ven wrote:
> 
> > Hi Armen,
> > 
> > You could absolutely draw this sort of legend in Bokeh using the rect() or quad() glyph functions together with text() and line() functions (all in bokeh.plotting). However it would also be fairly simple to do with pure HTML. Whether it is worthwhile to do as a plot vs HTML probably depends upon more details of what you are doing. An advantage for doing it in Bokeh would be that if you set it up properly, it should update whenever the data updates. If your data is not updating once the plot is renderers, then it is probably simpler to go the HTML route.
> > 
> > Bryan
> > 
> > On Aug 15, 2014, at 7:44 PM, Armen Alexanian [armenal...@gmail.com](mailto:armenal...@gmail.com) wrote:
> > 
> > > To clarify, it wouldn’t technically be the type of legend that is connected to a graph. It would be another separate graph below the first graph. Thanks!
> > 
> > > On Friday, August 15, 2014 5:35:55 PM UTC-7, Armen Alexanian wrote:
> > 
> > > Hi,
> > 
> > > I’m trying to experiment with plotting glyphs and text together to try to create a legend that looks like the picture attached. I need to create a legend which also functions as a mini report describing the associated graph with colors corresponding to data items (in this case, people).
> > 
> > > Would using a rect() be the best approach or is there another way (like an HTML table?) to create something like the attached image? The ability to do this would be really awesome because rich text and numeric data would perfectly compliment the graph and summarize key elements.
> > 
> > > Thanks very much!
> > 
> > > Armen
> > 
> > > –  
> > > You received this message because you are subscribed to the Google Groups “Bokeh Discussion - Public” group.
> > 
> > > To unsubscribe from this group and stop receiving emails from it, send an email to [bokeh+un...@continuum.io](mailto:bokeh+un...@continuum.io).
> > 
> > > To post to this group, send email to [bo...@continuum.io](mailto:bo...@continuum.io).
> > 
> > > To view this discussion on the web visit [https://groups.google.com/a/continuum.io/d/msgid/bokeh/169052b3-21cc-4190-911e-cb6e4b69a47a%40continuum.io](https://groups.google.com/a/continuum.io/d/msgid/bokeh/169052b3-21cc-4190-911e-cb6e4b69a47a%40continuum.io).
> > 
> > > For more options, visit [https://groups.google.com/a/continuum.io/d/optout](https://groups.google.com/a/continuum.io/d/optout).

---

<div class="post-metadata">

**Author:** ![Bryan](https://discourse.bokeh.org/user_avatar/discourse.bokeh.org/bryan/32/3625_2.png) [@Bryan](https://discourse.bokeh.org/u/Bryan)\
**Post date:** [August 23, 2014, 9:14pm UTC](https://discourse.bokeh.org/t/more-elaborate-legend-example/156/5 "2014-08-23T21:14:31Z")

</div>

Armen,

Sorry for the delayed reply. A few comments:

1) These are some things you would have to do "by hand" with Bokeh. You can use the text(...) and line(...) renderer functions from bokeh.plotting, respectively.

2) I'm not sure? If you are first formatting the numbers in python you should be able to do what ever you like to them.

3) I'm unfortunately not a pandas expert. There is a good tutorial at: [http://pandas.pydata.org/pandas-docs/stable/tutorials.html](http://pandas.pydata.org/pandas-docs/stable/tutorials.html)

For the last question, there are alot of ways to embed Bokeh plots. Is this in a standalone document that has all the data inside it? Then file\_html(...) in bokeh.embed will accept an optional Jinja2 template and that is probably easiest. If the document will be hosted, then there is also components(...) and autoload\_static(...) in bokeh.embed. There is more information here:

&nbsp;&nbsp;[http://bokeh.pydata.org/docs/user\_guide.html#embedding](http://bokeh.pydata.org/docs/user_guide.html#embedding)  
&nbsp;&nbsp;[https://github.com/ContinuumIO/bokeh/blob/master/bokeh/embed.py](https://github.com/ContinuumIO/bokeh/blob/master/bokeh/embed.py)

Bryan

> **···**
>
> On Aug 17, 2014, at 6:41 PM, Armen Alexanian \<armenalexanian@gmail.com\> wrote:
> 
> > Hi Bryan,
> > 
> > Thanks so much for the encouragement this morning, and for working on the weekend! I got as far as the code below and the image attached. Such as it is, it will still be a huge bonus for my project to have this legend. I ended up using a rectangle because I couldn't figure out how to make colored boxes (table background color) using df.to\_html().
> > 
> > By the way, I added the xaxis and yaxis code to plotting.py, and was then able to hide the axes again. Thanks!
> > 
> > However, there were several things I wasn't able to figure out:  
> > 1. How to print column headers (or totals) or insert a line separator below them.  
> > 2. An easy way to format numbers (I couldn't get '{0:,}'.format() or the locale module to work).  
> > 3. How to concatenate df['a'] with df['b'] in order to avoid having to use multiple text() functions.
> > 
> > Also, how would I insert some HTML, like a table or image, directly under a Bokeh plot?
> > 
> > Thanks so much for your help! I'm still very new to Python and Bokeh so I'm sure the way I did things in the code below could be much improved.
> > 
> > Cheers!  
> > Armen
> > 
> > import numpy as np  
> > from numpy.random import randn  
> > from pandas import \*  
> > from bokeh.plotting import \*
> > 
> > '''  
> > I had some trouble in the past in which newer plots would print on top  
> > of older plots so this reset\_output() command clears away old plots  
> > from memory.  
> > '''
> > 
> > reset\_output()
> > 
> > # Set an output file.
> > 
> > output\_file("C:/Users/Armen/Desktop/legend.html", title="Legend Example")
> > 
> > # Plotting all on the same plot.  
> > hold()
> > 
> > # There will be another plot above this one so instantiate a new figure.
> > 
> > figure(  
> > title = "",  
> > tools = "" # Title and tools not needed for the legend.  
> > )
> > 
> > # Make some series, including one to color the rectangles.
> > 
> > sx = Series([.5,.5,.5,.5,.5,.5,.5])  
> > sy = Series([1,2,3,4,5,6,7])  
> > sc = Series(['red','orange','green','blue','black','darkred','darkviolet'])  
> > s1 = Series([  
> > 'Robert Smith',  
> > 'George Jones',  
> > 'Sally Rogers',  
> > 'Lenny Walters',  
> > 'Gene Williams',  
> > 'Sue Peters',  
> > 'Jane Maxwell'  
> > ])  
> > s2 = Series(range(1000, 7001, 1000))
> > 
> > # Create a dict putting the series above together.  
> > d = {  
> > 'x': sx,  
> > 'y': sy,  
> > 'color': sc,  
> > 'one': sy,  
> > 'two': s1,  
> > 'three': s2  
> > }
> > 
> > # Create a pandas data frame from the dict.  
> > df = DataFrame(d)
> > 
> > # Print the data frame in the Spyder console.  
> > print(df)
> > 
> > # Create x and y axis ranges.  
> > x\_axis\_range = [str(x) for x in sorted(set(df['x']))]  
> > y\_axis\_range = [str(x) for x in sorted(set(df['y']))]
> > 
> > '''  
> > The plot height should only be as tall as needed.  
> > Get the max of the y axis for setting the height.  
> > '''
> > 
> > max\_y\_axis\_range = int(str(max(y\_axis\_range)))
> > 
> > # Print the rectangles  
> > rect(  
> > x = df['x'],  
> > y = df['y'],  
> > x\_range = x\_axis\_range,  
> > y\_range = y\_axis\_range,  
> > width = .1,  
> > height = .7,  
> > fill\_color = df['color'],  
> > line\_color = df['color'],  
> > plot\_width = 600,  
> > # Set the plot height based on how many rows there will be.  
> > plot\_height = max\_y\_axis\_range \* 45  
> > )
> > 
> > # For all the text properties that should be the same.
> > 
> > text\_props = {  
> > "angle": 0,  
> > "text\_align": "left",  
> > "text\_baseline": "middle",  
> > "text\_font\_size": "12pt",  
> > }
> > 
> > # Print the name a little bit after the rectangles.
> > 
> > text(  
> > df['x'] + .07,  
> > df['y'],  
> > text = df['two'],  
> > \*\*text\_props  
> > )
> > 
> > # Print the number a little after the name.  
> > text(  
> > df['x'] + .30,  
> > df['y'],  
> > text = df['three'],  
> > \*\*text\_props  
> > )
> > 
> > # Hide the grid lines inside the big rectangle box.
> > 
> > grid().grid\_line\_color = None
> > 
> > # Hide elements of the plot.
> > 
> > plot = curplot()  
> > plot.outline\_line\_color = None  
> > axis().axis\_line\_color = None  
> > axis().major\_label\_text\_color = None  
> > axis().major\_tick\_line\_color = None
> > 
> > # Show in browser.
> > 
> > show()
> > 
> > On Sunday, August 17, 2014 4:40:37 AM UTC-7, Bryan Van de ven wrote:  
> > Hi Armen,
> > 
> > You could absolutely draw this sort of legend in Bokeh using the rect() or quad() glyph functions together with text() and line() functions (all in bokeh.plotting). However it would also be fairly simple to do with pure HTML. Whether it is worthwhile to do as a plot vs HTML probably depends upon more details of what you are doing. An advantage for doing it in Bokeh would be that if you set it up properly, it should update whenever the data updates. If your data is not updating once the plot is renderers, then it is probably simpler to go the HTML route.
> > 
> > Bryan
> > 
> > On Aug 15, 2014, at 7:44 PM, Armen Alexanian \<armenal...@gmail.com\> wrote:
> > 
> > \> To clarify, it wouldn't technically be the type of legend that is connected to a graph. It would be another separate graph below the first graph. Thanks!  
> > \>  
> > \> On Friday, August 15, 2014 5:35:55 PM UTC-7, Armen Alexanian wrote:  
> > \> Hi,  
> > \>  
> > \> I'm trying to experiment with plotting glyphs and text together to try to create a legend that looks like the picture attached. I need to create a legend which also functions as a mini report describing the associated graph with colors corresponding to data items (in this case, people).  
> > \>  
> > \> Would using a rect() be the best approach or is there another way (like an HTML table?) to create something like the attached image? The ability to do this would be really awesome because rich text and numeric data would perfectly compliment the graph and summarize key elements.  
> > \>  
> > \> Thanks very much!  
> > \> Armen  
> > \>  
> > \> --  
> > \> You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.  
> > \> To unsubscribe from this group and stop receiving emails from it, send an email to bokeh+un...@continuum.io.  
> > \> To post to this group, send email to bo...@continuum.io.  
> > \> To view this discussion on the web visit [https://groups.google.com/a/continuum.io/d/msgid/bokeh/169052b3-21cc-4190-911e-cb6e4b69a47a%40continuum.io\](https://groups.google.com/a/continuum.io/d/msgid/bokeh/169052b3-21cc-4190-911e-cb6e4b69a47a%40continuum.io%5C).  
> > \> For more options, visit [https://groups.google.com/a/continuum.io/d/optout\](https://groups.google.com/a/continuum.io/d/optout%5C).
> > 
> > --  
> > You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.  
> > To unsubscribe from this group and stop receiving emails from it, send an email to bokeh+unsubscribe@continuum.io.  
> > To post to this group, send email to bokeh@continuum.io.  
> > To view this discussion on the web visit [https://groups.google.com/a/continuum.io/d/msgid/bokeh/bbdd36db-0e30-4c77-a10a-8314b06c7f36%40continuum.io\](https://groups.google.com/a/continuum.io/d/msgid/bokeh/bbdd36db-0e30-4c77-a10a-8314b06c7f36%40continuum.io%5C).  
> > For more options, visit [https://groups.google.com/a/continuum.io/d/optout\](https://groups.google.com/a/continuum.io/d/optout%5C).  
> > \<Sample\_Legend.PNG\>

---

<div class="post-metadata">

**Author:** ![system](https://discourse-uploads.bokeh.org/original/2X/1/14eb24f9e10e4e9b78e3f10f66c04ffa96446e5a.svg) [@system](https://discourse.bokeh.org/u/system)\
**Post date:** [July 21, 2021, 9:04pm UTC](https://discourse.bokeh.org/t/more-elaborate-legend-example/156/6 "2021-07-21T21:04:19Z")

</div>


