Formatting legend to have multiple rows or columns or ensure legend fits within plot

Hi,

I have a plot that could have 10’s of lines and having the ability to allow the user to click on the legend and hide some of these lines is a great feature. However, as shown below in my plot the legend can really only show a few of these lines before running off the plot. If I can place the glyphs into multiple rows or columns my problem could be fixed. I have tried to place the legend outside the plot, but I really need the ability to update from a ColumnDataSource and after hacking away for some time I think I determined that is not possible. It would make my day to be proven wrong on that, as placing the legend outside the plot is ideal! In the mean time, if I can at least resize the legend or make it into multiple rows/columns, I will just include a button widget that should be able to set the legend visibility to False or True as the user desires.

Thanks in advance for your help!

Hi,

I agree that this would be a very nice capability, however unfortunately at present it is still an open feature request:
  
  ncol and nrow in Legend object · Issue #3880 · bokeh/bokeh · GitHub

I've added to the 0.12.8 milestone but I'm certainly happy to help or offer guidance to anyone who has the time and wants to work on it earlier. Otherwise, I think the only solution would be to create a custom legend extension. You can find details about extending Bokeh here:

  http://bokeh.pydata.org/en/latest/docs/user_guide/extensions.html

An you can find the implementation of the current Legend here:

  https://github.com/bokeh/bokeh/blob/master/bokehjs/src/coffee/models/annotations/legend.coffee

Fair warning, it's one of the more complicated BokehJS models.

Thanks,

Bryan

···

On Jun 21, 2017, at 23:54, cuxcrider <[email protected]> wrote:

Hi,

I have a plot that could have 10's of lines and having the ability to allow the user to click on the legend and hide some of these lines is a great feature. However, as shown below in my plot the legend can really only show a few of these lines before running off the plot. If I can place the glyphs into multiple rows or columns my problem could be fixed. I have tried to place the legend outside the plot, but I really need the ability to update from a ColumnDataSource and after hacking away for some time I think I determined that is not possible. It would make my day to be proven wrong on that, as placing the legend outside the plot is ideal! In the mean time, if I can at least resize the legend or make it into multiple rows/columns, I will just include a button widget that should be able to set the legend visibility to False or True as the user desires.
<Auto Generated Inline Image 1.png>
Thanks in advance for your help!

--
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 [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/1ecefd0b-ad9f-4200-b8b0-1fd7196c07ee%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.
<Auto Generated Inline Image 1.png>

Another idea, that would be much simpler than creating a legend extension: Just make something legend-like with standard HTML, and put that in a Bokeh Div next to your plot, along the lines of:

  legend = Div(text="some HTML that makes a legend-like table")

  plot = figure()

  show(row(plot, legend)

Thanks,

Bryan

···

On Jun 22, 2017, at 19:03, Bryan Van de ven <[email protected]> wrote:

Hi,

I agree that this would be a very nice capability, however unfortunately at present it is still an open feature request:
  
  ncol and nrow in Legend object · Issue #3880 · bokeh/bokeh · GitHub

I've added to the 0.12.8 milestone but I'm certainly happy to help or offer guidance to anyone who has the time and wants to work on it earlier. Otherwise, I think the only solution would be to create a custom legend extension. You can find details about extending Bokeh here:

  http://bokeh.pydata.org/en/latest/docs/user_guide/extensions.html

An you can find the implementation of the current Legend here:

  https://github.com/bokeh/bokeh/blob/master/bokehjs/src/coffee/models/annotations/legend.coffee

Fair warning, it's one of the more complicated BokehJS models.

Thanks,

Bryan

On Jun 21, 2017, at 23:54, cuxcrider <[email protected]> wrote:

Hi,

I have a plot that could have 10's of lines and having the ability to allow the user to click on the legend and hide some of these lines is a great feature. However, as shown below in my plot the legend can really only show a few of these lines before running off the plot. If I can place the glyphs into multiple rows or columns my problem could be fixed. I have tried to place the legend outside the plot, but I really need the ability to update from a ColumnDataSource and after hacking away for some time I think I determined that is not possible. It would make my day to be proven wrong on that, as placing the legend outside the plot is ideal! In the mean time, if I can at least resize the legend or make it into multiple rows/columns, I will just include a button widget that should be able to set the legend visibility to False or True as the user desires.
<Auto Generated Inline Image 1.png>
Thanks in advance for your help!

--
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 [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/1ecefd0b-ad9f-4200-b8b0-1fd7196c07ee%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.
<Auto Generated Inline Image 1.png>

Hi Bryan,

Thanks for the message. Developing the extension is outside my skillset at the moment, but perhaps I can learn enough to at least give it a shot. The HTML is a workable idea, but having the ability to click the legend and turn on/off the line plots is what I am really after.

I thought maybe I could make a dummy plot that would be really tall and skinny and could contain just a legend that was linked to my real plot, but at least in my initial attempt at that, I only got a ValueError.

I was hoping I could make a legend for s1, and then set legend s2 = s1.legend[0]. Below is the code I used, but the s2 legend is not happy with this: ValueError: expected an element of either String, Dict(String, Either(String, Instance(Transform), Instance(ColorMapper), List(String))) or List(String), got Legend(id=‘6e317fd8-d63b-425e-ac61-6951015117b9’, …)

···

On Thu, Jun 22, 2017 at 6:06 PM, Bryan Van de ven [email protected] wrote:

Another idea, that would be much simpler than creating a legend extension: Just make something legend-like with standard HTML, and put that in a Bokeh Div next to your plot, along the lines of:

    legend = Div(text="some HTML that makes a legend-like table")



    plot = figure()



    show(row(plot, legend)

Thanks,

Bryan

On Jun 22, 2017, at 19:03, Bryan Van de ven [email protected] wrote:

Hi,

I agree that this would be a very nice capability, however unfortunately at present it is still an open feature request:

  [https://github.com/bokeh/bokeh/issues/3880](https://github.com/bokeh/bokeh/issues/3880)

I’ve added to the 0.12.8 milestone but I’m certainly happy to help or offer guidance to anyone who has the time and wants to work on it earlier. Otherwise, I think the only solution would be to create a custom legend extension. You can find details about extending Bokeh here:

  [http://bokeh.pydata.org/en/latest/docs/user_guide/extensions.html](http://bokeh.pydata.org/en/latest/docs/user_guide/extensions.html)

An you can find the implementation of the current Legend here:

  [https://github.com/bokeh/bokeh/blob/master/bokehjs/src/coffee/models/annotations/legend.coffee](https://github.com/bokeh/bokeh/blob/master/bokehjs/src/coffee/models/annotations/legend.coffee)

Fair warning, it’s one of the more complicated BokehJS models.

Thanks,

Bryan

On Jun 21, 2017, at 23:54, cuxcrider [email protected] wrote:

Hi,

I have a plot that could have 10’s of lines and having the ability to allow the user to click on the legend and hide some of these lines is a great feature. However, as shown below in my plot the legend can really only show a few of these lines before running off the plot. If I can place the glyphs into multiple rows or columns my problem could be fixed. I have tried to place the legend outside the plot, but I really need the ability to update from a ColumnDataSource and after hacking away for some time I think I determined that is not possible. It would make my day to be proven wrong on that, as placing the legend outside the plot is ideal! In the mean time, if I can at least resize the legend or make it into multiple rows/columns, I will just include a button widget that should be able to set the legend visibility to False or True as the user desires.

<Auto Generated Inline Image 1.png>

Thanks in advance for your help!

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 [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/1ecefd0b-ad9f-4200-b8b0-1fd7196c07ee%40continuum.io.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.

<Auto Generated Inline Image 1.png>

You received this message because you are subscribed to a topic in the Google Groups “Bokeh Discussion - Public” group.

To unsubscribe from this topic, visit https://groups.google.com/a/continuum.io/d/topic/bokeh/Psqhz-yGlyI/unsubscribe.

To unsubscribe from this group and all its topics, send an email to [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/A317BFB5-A4CD-4FDE-950A-6EAC0393FB14%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.

There's one more possibility:

* Legends are configured by a collection of LegendItems
* It's possible to have more than one legend

So, it should be possible to split the LegendItems from the default legend up in to two or three groups and add them to Legends that you explicitly create and position for each group. Doing this would have the effect of a "multi-colunm" legend. Check out this example for some idea:

  https://github.com/bokeh/bokeh/blob/master/examples/models/file/synthetic.py#L63-L68

Thanks,

Bryan

···

On Jun 22, 2017, at 20:09, Collin Becker <[email protected]> wrote:

Hi Bryan,

Thanks for the message. Developing the extension is outside my skillset at the moment, but perhaps I can learn enough to at least give it a shot. The HTML is a workable idea, but having the ability to click the legend and turn on/off the line plots is what I am really after.

I thought maybe I could make a dummy plot that would be really tall and skinny and could contain just a legend that was linked to my real plot, but at least in my initial attempt at that, I only got a ValueError.

I was hoping I could make a legend for s1, and then set legend s2 = s1.legend[0]. Below is the code I used, but the s2 legend is not happy with this: ValueError: expected an element of either String, Dict(String, Either(String, Instance(Transform), Instance(ColorMapper), List(String))) or List(String), got Legend(id='6e317fd8-d63b-425e-ac61-6951015117b9', ...)
#################################
from bokeh.io import output_file, show
from bokeh.layouts import gridplot
from bokeh.plotting import figure

output_file("panning.html")

x = list(range(11))
y0 = x
y1 = [10-xx for xx in x]
y2 = [abs(xx-5) for xx in x]

# create a new plot
s1 = figure(plot_width=250, plot_height=250, title=None)
s1.circle(x, y0, size=10, color="navy", alpha=0.5, legend = "hi")

# create a new plot and share both ranges
s2 = figure(plot_width=250, plot_height=250, x_range=s1.x_range, y_range=s1.y_range, title=None)
s2.triangle(x, y1, size=10, color="firebrick", alpha=0.5, legend = s1.legend[0])

# create a new plot and share only one range
s3 = figure(plot_width=250, plot_height=250, x_range=s1.x_range, title=None)
s3.square(x, y2, size=10, color="olive", alpha=0.5)

p = gridplot([[s1, s2, s3]], toolbar_location=None)

# show the results
show(p)

On Thu, Jun 22, 2017 at 6:06 PM, Bryan Van de ven <[email protected]> wrote:
Another idea, that would be much simpler than creating a legend extension: Just make something legend-like with standard HTML, and put that in a Bokeh Div next to your plot, along the lines of:

        legend = Div(text="some HTML that makes a legend-like table")

        plot = figure()

        show(row(plot, legend)

Thanks,

Bryan

> On Jun 22, 2017, at 19:03, Bryan Van de ven <[email protected]> wrote:
>
> Hi,
>
> I agree that this would be a very nice capability, however unfortunately at present it is still an open feature request:
>
> ncol and nrow in Legend object · Issue #3880 · bokeh/bokeh · GitHub
>
> I've added to the 0.12.8 milestone but I'm certainly happy to help or offer guidance to anyone who has the time and wants to work on it earlier. Otherwise, I think the only solution would be to create a custom legend extension. You can find details about extending Bokeh here:
>
> http://bokeh.pydata.org/en/latest/docs/user_guide/extensions.html
>
> An you can find the implementation of the current Legend here:
>
> https://github.com/bokeh/bokeh/blob/master/bokehjs/src/coffee/models/annotations/legend.coffee
>
> Fair warning, it's one of the more complicated BokehJS models.
>
> Thanks,
>
> Bryan
>
>> On Jun 21, 2017, at 23:54, cuxcrider <[email protected]> wrote:
>>
>> Hi,
>>
>> I have a plot that could have 10's of lines and having the ability to allow the user to click on the legend and hide some of these lines is a great feature. However, as shown below in my plot the legend can really only show a few of these lines before running off the plot. If I can place the glyphs into multiple rows or columns my problem could be fixed. I have tried to place the legend outside the plot, but I really need the ability to update from a ColumnDataSource and after hacking away for some time I think I determined that is not possible. It would make my day to be proven wrong on that, as placing the legend outside the plot is ideal! In the mean time, if I can at least resize the legend or make it into multiple rows/columns, I will just include a button widget that should be able to set the legend visibility to False or True as the user desires.
>> <Auto Generated Inline Image 1.png>
>> Thanks in advance for your help!
>>
>> --
>> 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 [email protected].
>> To post to this group, send email to [email protected].
>> To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/1ecefd0b-ad9f-4200-b8b0-1fd7196c07ee%40continuum.io\.
>> For more options, visit https://groups.google.com/a/continuum.io/d/optout\.
>> <Auto Generated Inline Image 1.png>
>

--
You received this message because you are subscribed to a topic in the Google Groups "Bokeh Discussion - Public" group.
To unsubscribe from this topic, visit https://groups.google.com/a/continuum.io/d/topic/bokeh/Psqhz-yGlyI/unsubscribe\.
To unsubscribe from this group and all its topics, send an email to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/A317BFB5-A4CD-4FDE-950A-6EAC0393FB14%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.

--
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 [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/CABGVw9s%3Dxd2aeNKT1fBh0%3DBBucbb6RQVKGsWy13Lb1Vp_NxfyA%40mail.gmail.com\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.

Hi Bryan,

That seems like a good idea to me. However, can this still be implemented to update with a ColumnDataSource? After reading and my own experimenting, it seems the only way to update a legend is to create it with the renderer as shown here: https://stackoverflow.com/questions/39049622/bokeh-interact-with-legend-label-text

Thanks!

···

On Thu, Jun 22, 2017 at 7:19 PM, Bryan Van de ven [email protected] wrote:

There’s one more possibility:

  • Legends are configured by a collection of LegendItems

  • It’s possible to have more than one legend

So, it should be possible to split the LegendItems from the default legend up in to two or three groups and add them to Legends that you explicitly create and position for each group. Doing this would have the effect of a “multi-colunm” legend. Check out this example for some idea:

    [https://github.com/bokeh/bokeh/blob/master/examples/models/file/synthetic.py#L63-L68](https://github.com/bokeh/bokeh/blob/master/examples/models/file/synthetic.py#L63-L68)

Thanks,

Bryan

On Jun 22, 2017, at 20:09, Collin Becker [email protected] wrote:

Hi Bryan,

Thanks for the message. Developing the extension is outside my skillset at the moment, but perhaps I can learn enough to at least give it a shot. The HTML is a workable idea, but having the ability to click the legend and turn on/off the line plots is what I am really after.

I thought maybe I could make a dummy plot that would be really tall and skinny and could contain just a legend that was linked to my real plot, but at least in my initial attempt at that, I only got a ValueError.

I was hoping I could make a legend for s1, and then set legend s2 = s1.legend[0]. Below is the code I used, but the s2 legend is not happy with this: ValueError: expected an element of either String, Dict(String, Either(String, Instance(Transform), Instance(ColorMapper), List(String))) or List(String), got Legend(id=‘6e317fd8-d63b-425e-ac61-6951015117b9’, …)

#################################

from bokeh.io import output_file, show

from bokeh.layouts import gridplot

from bokeh.plotting import figure

output_file(“panning.html”)

x = list(range(11))

y0 = x

y1 = [10-xx for xx in x]

y2 = [abs(xx-5) for xx in x]

create a new plot

s1 = figure(plot_width=250, plot_height=250, title=None)

s1.circle(x, y0, size=10, color=“navy”, alpha=0.5, legend = “hi”)

create a new plot and share both ranges

s2 = figure(plot_width=250, plot_height=250, x_range=s1.x_range, y_range=s1.y_range, title=None)

s2.triangle(x, y1, size=10, color=“firebrick”, alpha=0.5, legend = s1.legend[0])

create a new plot and share only one range

s3 = figure(plot_width=250, plot_height=250, x_range=s1.x_range, title=None)

s3.square(x, y2, size=10, color=“olive”, alpha=0.5)

p = gridplot([[s1, s2, s3]], toolbar_location=None)

show the results

show(p)

On Thu, Jun 22, 2017 at 6:06 PM, Bryan Van de ven [email protected] wrote:

Another idea, that would be much simpler than creating a legend extension: Just make something legend-like with standard HTML, and put that in a Bokeh Div next to your plot, along the lines of:

    legend = Div(text="some HTML that makes a legend-like table")
    plot = figure()
    show(row(plot, legend)

Thanks,

Bryan

On Jun 22, 2017, at 19:03, Bryan Van de ven [email protected] wrote:

Hi,

I agree that this would be a very nice capability, however unfortunately at present it is still an open feature request:

  [https://github.com/bokeh/bokeh/issues/3880](https://github.com/bokeh/bokeh/issues/3880)

I’ve added to the 0.12.8 milestone but I’m certainly happy to help or offer guidance to anyone who has the time and wants to work on it earlier. Otherwise, I think the only solution would be to create a custom legend extension. You can find details about extending Bokeh here:

  [http://bokeh.pydata.org/en/latest/docs/user_guide/extensions.html](http://bokeh.pydata.org/en/latest/docs/user_guide/extensions.html)

An you can find the implementation of the current Legend here:

  [https://github.com/bokeh/bokeh/blob/master/bokehjs/src/coffee/models/annotations/legend.coffee](https://github.com/bokeh/bokeh/blob/master/bokehjs/src/coffee/models/annotations/legend.coffee)

Fair warning, it’s one of the more complicated BokehJS models.

Thanks,

Bryan

On Jun 21, 2017, at 23:54, cuxcrider [email protected] wrote:

Hi,

I have a plot that could have 10’s of lines and having the ability to allow the user to click on the legend and hide some of these lines is a great feature. However, as shown below in my plot the legend can really only show a few of these lines before running off the plot. If I can place the glyphs into multiple rows or columns my problem could be fixed. I have tried to place the legend outside the plot, but I really need the ability to update from a ColumnDataSource and after hacking away for some time I think I determined that is not possible. It would make my day to be proven wrong on that, as placing the legend outside the plot is ideal! In the mean time, if I can at least resize the legend or make it into multiple rows/columns, I will just include a button widget that should be able to set the legend visibility to False or True as the user desires.

<Auto Generated Inline Image 1.png>

Thanks in advance for your help!

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 [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/1ecefd0b-ad9f-4200-b8b0-1fd7196c07ee%40continuum.io.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.

<Auto Generated Inline Image 1.png>

You received this message because you are subscribed to a topic in the Google Groups “Bokeh Discussion - Public” group.

To unsubscribe from this topic, visit https://groups.google.com/a/continuum.io/d/topic/bokeh/Psqhz-yGlyI/unsubscribe.

To unsubscribe from this group and all its topics, send an email to [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/A317BFB5-A4CD-4FDE-950A-6EAC0393FB14%40continuum.io.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.

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 [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/CABGVw9s%3Dxd2aeNKT1fBh0%3DBBucbb6RQVKGsWy13Lb1Vp_NxfyA%40mail.gmail.com.

For more options, visit https://groups.google.com/a/continuum.io/d/optout.

You received this message because you are subscribed to a topic in the Google Groups “Bokeh Discussion - Public” group.

To unsubscribe from this topic, visit https://groups.google.com/a/continuum.io/d/topic/bokeh/Psqhz-yGlyI/unsubscribe.

To unsubscribe from this group and all its topics, send an email to [email protected].

To post to this group, send email to [email protected].

To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/6BCD73B8-6479-45E8-9F3D-C24F0ED488F1%40continuum.io.
For more options, visit https://groups.google.com/a/continuum.io/d/optout.

Collin Becker
[email protected]

Hi,

Unfortunately I don't think it will work with the auto-grouping feature. In that instance there is only a single LegendItem, configured with a column name, responsible for creating multiple legend rows for that column. So there is no list of legend items to split up. I think until #3880 is done the HTML "legend" in a div may be your best bet, although the second plot idea might work out as well. Sorry I don't have better immediate news.

Thanks,

Bryan

···

On Jun 22, 2017, at 20:28, Collin Becker <[email protected]> wrote:

Hi Bryan,

That seems like a good idea to me. However, can this still be implemented to update with a ColumnDataSource? After reading and my own experimenting, it seems the only way to update a legend is to create it with the renderer as shown here: python - Bokeh: Interact with legend label text - Stack Overflow
Thanks!

On Thu, Jun 22, 2017 at 7:19 PM, Bryan Van de ven <[email protected]> wrote:
There's one more possibility:

* Legends are configured by a collection of LegendItems
* It's possible to have more than one legend

So, it should be possible to split the LegendItems from the default legend up in to two or three groups and add them to Legends that you explicitly create and position for each group. Doing this would have the effect of a "multi-colunm" legend. Check out this example for some idea:

        https://github.com/bokeh/bokeh/blob/master/examples/models/file/synthetic.py#L63-L68

Thanks,

Bryan

> On Jun 22, 2017, at 20:09, Collin Becker <[email protected]> wrote:
>
> Hi Bryan,
>
> Thanks for the message. Developing the extension is outside my skillset at the moment, but perhaps I can learn enough to at least give it a shot. The HTML is a workable idea, but having the ability to click the legend and turn on/off the line plots is what I am really after.
>
> I thought maybe I could make a dummy plot that would be really tall and skinny and could contain just a legend that was linked to my real plot, but at least in my initial attempt at that, I only got a ValueError.
>
> I was hoping I could make a legend for s1, and then set legend s2 = s1.legend[0]. Below is the code I used, but the s2 legend is not happy with this: ValueError: expected an element of either String, Dict(String, Either(String, Instance(Transform), Instance(ColorMapper), List(String))) or List(String), got Legend(id='6e317fd8-d63b-425e-ac61-6951015117b9', ...)
> #################################
> from bokeh.io import output_file, show
> from bokeh.layouts import gridplot
> from bokeh.plotting import figure
>
> output_file("panning.html")
>
> x = list(range(11))
> y0 = x
> y1 = [10-xx for xx in x]
> y2 = [abs(xx-5) for xx in x]
>
> # create a new plot
> s1 = figure(plot_width=250, plot_height=250, title=None)
> s1.circle(x, y0, size=10, color="navy", alpha=0.5, legend = "hi")
>
> # create a new plot and share both ranges
> s2 = figure(plot_width=250, plot_height=250, x_range=s1.x_range, y_range=s1.y_range, title=None)
> s2.triangle(x, y1, size=10, color="firebrick", alpha=0.5, legend = s1.legend[0])
>
> # create a new plot and share only one range
> s3 = figure(plot_width=250, plot_height=250, x_range=s1.x_range, title=None)
> s3.square(x, y2, size=10, color="olive", alpha=0.5)
>
> p = gridplot([[s1, s2, s3]], toolbar_location=None)
>
> # show the results
> show(p)
>
>
> On Thu, Jun 22, 2017 at 6:06 PM, Bryan Van de ven <[email protected]> wrote:
> Another idea, that would be much simpler than creating a legend extension: Just make something legend-like with standard HTML, and put that in a Bokeh Div next to your plot, along the lines of:
>
> legend = Div(text="some HTML that makes a legend-like table")
>
> plot = figure()
>
> show(row(plot, legend)
>
> Thanks,
>
> Bryan
>
> > On Jun 22, 2017, at 19:03, Bryan Van de ven <[email protected]> wrote:
> >
> > Hi,
> >
> > I agree that this would be a very nice capability, however unfortunately at present it is still an open feature request:
> >
> > ncol and nrow in Legend object · Issue #3880 · bokeh/bokeh · GitHub
> >
> > I've added to the 0.12.8 milestone but I'm certainly happy to help or offer guidance to anyone who has the time and wants to work on it earlier. Otherwise, I think the only solution would be to create a custom legend extension. You can find details about extending Bokeh here:
> >
> > http://bokeh.pydata.org/en/latest/docs/user_guide/extensions.html
> >
> > An you can find the implementation of the current Legend here:
> >
> > https://github.com/bokeh/bokeh/blob/master/bokehjs/src/coffee/models/annotations/legend.coffee
> >
> > Fair warning, it's one of the more complicated BokehJS models.
> >
> > Thanks,
> >
> > Bryan
> >
> >> On Jun 21, 2017, at 23:54, cuxcrider <[email protected]> wrote:
> >>
> >> Hi,
> >>
> >> I have a plot that could have 10's of lines and having the ability to allow the user to click on the legend and hide some of these lines is a great feature. However, as shown below in my plot the legend can really only show a few of these lines before running off the plot. If I can place the glyphs into multiple rows or columns my problem could be fixed. I have tried to place the legend outside the plot, but I really need the ability to update from a ColumnDataSource and after hacking away for some time I think I determined that is not possible. It would make my day to be proven wrong on that, as placing the legend outside the plot is ideal! In the mean time, if I can at least resize the legend or make it into multiple rows/columns, I will just include a button widget that should be able to set the legend visibility to False or True as the user desires.
> >> <Auto Generated Inline Image 1.png>
> >> Thanks in advance for your help!
> >>
> >> --
> >> 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 [email protected].
> >> To post to this group, send email to [email protected].
> >> To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/1ecefd0b-ad9f-4200-b8b0-1fd7196c07ee%40continuum.io\.
> >> For more options, visit https://groups.google.com/a/continuum.io/d/optout\.
> >> <Auto Generated Inline Image 1.png>
> >
>
> --
> You received this message because you are subscribed to a topic in the Google Groups "Bokeh Discussion - Public" group.
> To unsubscribe from this topic, visit https://groups.google.com/a/continuum.io/d/topic/bokeh/Psqhz-yGlyI/unsubscribe\.
> To unsubscribe from this group and all its topics, send an email to [email protected].
> To post to this group, send email to [email protected].
> To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/A317BFB5-A4CD-4FDE-950A-6EAC0393FB14%40continuum.io\.
> For more options, visit https://groups.google.com/a/continuum.io/d/optout\.
>
>
>
>
>
> --
> 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 [email protected].
> To post to this group, send email to [email protected].
> To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/CABGVw9s%3Dxd2aeNKT1fBh0%3DBBucbb6RQVKGsWy13Lb1Vp_NxfyA%40mail.gmail.com\.
> For more options, visit https://groups.google.com/a/continuum.io/d/optout\.

--
You received this message because you are subscribed to a topic in the Google Groups "Bokeh Discussion - Public" group.
To unsubscribe from this topic, visit https://groups.google.com/a/continuum.io/d/topic/bokeh/Psqhz-yGlyI/unsubscribe\.
To unsubscribe from this group and all its topics, send an email to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/6BCD73B8-6479-45E8-9F3D-C24F0ED488F1%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.

--
Collin Becker
[email protected]

--
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 [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/CABGVw9uqi701NFQFwRt8%2BZJ1-z04TO2DP-2gQxQUuh6fmCcYAg%40mail.gmail.com\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.

Although this topic is a couple years old now, just thought I would add what worked for me, since the feature request for ncol and nrow in Legend object is still open.

As @Bryan mentioned above, if you have a list of Legend items, you can split the list into two parts and add a separate positioned legend for each. This works well for me, and both legends are connected to the same Column Data Source and function as expected for toggling visibility in the plot.

Here’s an example that adds two rows of legends below the figure, with visibility toggling enabled. In this case, using a Column Data Source built from a datetime-indexed Pandas dataframe:

from bokeh.plotting import figure
from bokeh.models import Legend, ColumnDataSource

p = figure(title="Fig1", name="Fig1", x_axis_type="datetime")    

cds = ColumnDataSource(data=my_df, name="my_name")

labels = ['foo1','bar1','foo2','bar2','foo3','bar3']
items = []
legenddict = {}
for label in labels:
    legenddict[label] = p.line(x='Date', y=label, source=cds)
    items.append((label,[legenddict[label]]))

legend1 = Legend(
    items=items[0:2],
    location=(0, 15))

legend2 = Legend(
    items=items[2:],
    location=(0, 10))

p.add_layout(legend1, 'below')
p.add_layout(legend2, 'below')
p.legend.click_policy="hide"
5 Likes