Bokeh: Customizing Bar Plot Legends
In this article, we will explore how to customize a bar plot legend in Bokeh using a single-index labeled legend for a grouped Pandas DataFrame with two categorical columns.
Introduction
Bokeh is an interactive visualization library that provides elegant and concise ways to create web-based interactive plots. One of the features of Bokeh is its ability to customize the appearance of various elements, including legends. In this article, we will demonstrate how to set a single-index labeled legend for a bar plot with a double-indexed Pandas grouped DataFrame.
Background
Before diving into the solution, let’s review some background information on Bokeh and Pandas DataFrames.
Bokeh provides several ways to customize the appearance of legends, including using the legend_location
parameter, which allows us to specify the location of the legend. However, when working with grouped DataFrames, we need a more customized approach to achieve our desired single-index labeled legend.
Pandas DataFrames are powerful data structures that provide various methods for grouping and reshaping data. When grouping DataFrames, it’s common to create double-indexed DataFrames, which can lead to complex legends if not handled properly.
Example Use Case
Let’s consider an example use case where we want to plot a bar chart using a Pandas DataFrame with two categorical columns: weekday
and daytime
. We group the data by these two columns and plot a histogram. Our goal is to customize the legend to show only four colors, one for each time of day.
import pandas as pd
from bokeh.models import FactorCmap
from bokeh.transform import factor_cmap
from bokeh.plotting import figure
# Create sample data
df = pd.DataFrame(dict(
weekday=['Monday', 'Monday', 'Tuesday', 'Tuesday', 'Tuesday', 'Sunday', 'Sunday'],
daytime=['morning', 'evening', 'night', 'afternoon', 'afternoon', 'morning', 'night'],
value=[12,13,15,5,14,12,11]
))
# Group data by weekday and daytime
groupby_datetime = df.groupby(['weekday', 'daytime'], as_index=True)
# Define a colormap for the plot
daytime_cmap = FactorCmap('weekday_daytime', palette=['orange','darkviolet','yellow','darkblue'],
factors=sorted(df.daytime.unique()), start=1)
Solution
To create a single-index labeled legend, we need to use a combination of Bokeh’s FactorCmap
and custom styling. Here’s how we can achieve this:
# Create the plot
p = figure(x_range=groupby_datetime)
# Use FactorCmap to define the colormap
daytime_cmap = FactorCmap('weekday_daytime', palette=['orange','darkviolet','yellow','darkblue'],
factors=sorted(df.daytime.unique()), start=1)
# Customize the legend
custom_legend = [
{'label': 'Weekday Labels', 'location': 'right',
'orientation': 'horizontal', 'text_align': 'left'},
{'label': 'Daytime Labels', 'location': 'center_right',
'orientation': 'vertical', 'text_align': 'left'}
]
# Add a legend to the plot
p.add_layout(BokehModels Legends('weekday_daytime', custom_legend, location='right'))
# Customize the appearance of each bar in the plot
for i, row in groupby_datetime.iterrows():
p.vbar(x=row['weekday_daytime'], top=row['value_mean'], width=0.9,
line_color=None, fill_color=daytime_cmap, legend_field='weekday_daytime')
# Add custom styling to the plot
p.xaxis.formatter = PrintfTickFormatter(format='')
show(p)
Explanation
In this solution, we define a custom_legend
list that includes two elements: one for weekday labels and one for daytime labels. We specify the location of each legend using the location
, orientation
, and text_align
parameters.
We then use the add_layout
method to add the custom legend to the plot. Note that we pass in the 'weekday_daytime'
field as the legend_field
parameter, which tells Bokeh to associate the colors with this specific column.
Finally, we customize the appearance of each bar in the plot by using the daytime_cmap
colormap and specifying the legend_field
parameter. This ensures that only four colors are displayed in the legend: one for each time of day.
Conclusion
In this article, we demonstrated how to set a single-index labeled legend for a bar plot with a double-indexed Pandas grouped DataFrame using Bokeh’s custom styling capabilities. By defining a custom legend and specifying the legend_field
parameter, we can achieve our desired result – a simple and elegant legend that shows only four colors.
Additional Resources
If you’re interested in learning more about Bokeh or Pandas DataFrames, here are some additional resources to get you started:
Last modified on 2023-10-01