Add legend afterwards to bokeh plot

I’m trying to answer this stackoverflow question:
https://stackoverflow.com/questions/59679386/holoviews-remove-variables-names-from-x-axis-on-bar-chart

Basically someone created a grouped barchart and wants to add a legend.
Since this is not possible to do in Holoviews at the moment, one possible solution is to render the holoviews plot as a Bokeh plot and then add the legend.

I tried looking for easy ways to add a legend afterwards to a Bokeh plot, but since I’m not very knowledgeable on that topic, I hope you can help me.

Here’s my code example:

# imports and settings
import pandas as pd
import numpy as np
import holoviews as hv
pd.options.plotting.backend = 'hvplot'
from bokeh.plotting import show

# create sample data
df1 = pd.DataFrame({
    'x': np.random.rand(10), 
    'y': np.random.rand(10),
})

# create holoviews plot
my_holoviews_plot = df1.plot(kind='bar')

# render holoviews plot to bokeh plot
my_bokeh_plot = hv.render(my_holoviews_plot, backend='bokeh')

# apply changes to bokeh plot
# but how can I also add a legend to this plot?
my_bokeh_plot.xaxis.major_label_text_font_size = '0pt'

# visualize plot
show(my_bokeh_plot)

Hi SandervandenOord!

You might try something similar to what’s being done here:
https://docs.bokeh.org/en/latest/docs/user_guide/styling.html?highlight=styling%20visual%20attributes#outside-the-plot-area

where the Legend is created independently and then added via add_layout.

I still found the following, but now I’m missing the orange color for one of my categories.

from bokeh.models import Legend

legend = Legend(
    items=[
        ('x', [my_bokeh_plot.renderers[0]]),
        ('y', [my_bokeh_plot.renderers[0]]),
    ],
    location='center',
)

my_bokeh_plot.add_layout(legend, 'right')

show(my_bokeh_plot)

But now, the problem is I only get the color blue, but not the orange in the grouped bar chart. How can i get a color for the orange category?

@SandervandenOord each LegendItem uses a representative point to determine line, fill color, etc. By default, the representative point is just the first point, i.e. index 0 into the CDS. If you want to show an orange entry in the Legend you will want to find the index (into the CDS) of one fo the orange bars, and set that as the index property of the LegendItem.

1 Like

Ok, thanks gonna give it a try.
I originally started my interactive plotting with Hvplot, but to get better plots I had to revert to HoloViews and now I have to dive into Bokeh :smile:

1 Like