Download notebook (.ipynb)

Custom Legend with manual_key Option#

In Lets-Plot, as in ggplot2, legends are automatically generated based on the aesthetic mappings in the plot.

Sometimes, however, this automatic generation doesn’t provide the precise control needed for complex visualizations.

The manual_key option allows you to create custom legend entries specific to individual plot layers.

The manual_key option can be used in two ways:

  • Simple case: pass a string to serve as the label for the legend entry.

  • Advanced case: use the layer_key() function for more detailed customization:

    • label - text for the legend element

    • group - key used to group elements in the legend

    • index - position of the element within its legend group

    • kwargs - dictionary of aesthetic parameters to be applied in the legend

import pandas as pd

from lets_plot import *
LetsPlot.setup_html()
df = pd.read_csv("https://raw.githubusercontent.com/JetBrains/lets-plot-docs/master/data/mpg.csv")
print(df.shape)
df.head(3)
(234, 12)
Unnamed: 0 manufacturer model displ year cyl trans drv cty hwy fl class
0 1 audi a4 1.8 1999 4 auto(l5) f 18 29 p compact
1 2 audi a4 1.8 1999 4 manual(m5) f 21 29 p compact
2 3 audi a4 2.0 2008 4 manual(m6) f 20 31 p compact
# Default plot
ggplot(df, aes("displ", "hwy")) + \
    geom_point(color="#878787") + \
    geom_smooth(method='loess', se=False, color="#2166ac") + \
    geom_smooth(method='lm', se=False, color="#b2182b")

1. Simple Custom Legend#

ggplot(df, aes("displ", "hwy")) + \
    geom_point(color="#878787",
               manual_key="Observed Data"                   # label for the legend entry
              ) + \
    geom_smooth(method='loess', se=False, color="#2166ac",
                manual_key="LOESS Trend Line") + \
    geom_smooth(method='lm', se=False, color="#b2182b",
                manual_key="Linear Model Trend Line") + \
    ggsize(800, 400)

2. The layer_key() Function#

All constants for the visual representation of the legend key are inherited from the geometry. Use the layer_key() function to override these values. You can also specify the legend group in which the element is displayed and the position of the element within the legend group.

p = ggplot(df, aes("displ", "hwy")) + \
    geom_point(color="#878787",
               manual_key=layer_key("Observed Data",          # <-- label for the legend entry
                                    color='pen', size=8)      # <-- override aesthetics
              ) + \
    geom_smooth(method='loess', se=False, color="#2166ac",
                manual_key=layer_key("LOESS", 
                                     group="Methods",         # <-- assign a group (note the same group in the layer below)
                                     index=1,                 # <-- position of the element
                                     size=4)) + \
    geom_smooth(method='lm', se=False, color="#b2182b",
                manual_key=layer_key("LM", group="Methods", index=0, size=4)) + \
    ggsize(800, 400)
p

3. Change Title of Custom Legends#

p + labs(
    manual="Scatter Plot",  # <-- "manual" is a default 'key' referring to a custom legend
    Methods="Trend Lines"   # <-- "Methods" is the group name referring to the second custom legend
)

4. Compound Legend Entries in Custom Legend#

ggplot(mapping=aes(as_discrete('class', order_by='..y..'), 'hwy')) + \
    stat_summary(data=df[df.year == 1999], fun='mean', # <-- 1999
                 geom='line', size=2, color='#D87093',
                 manual_key="1999"                     # <-- label for the legend entry
                ) + \
    stat_summary(data=df[df.year == 1999], fun='mean',
                 geom='point', size=5, shape=22,
                 fill='#D87093', color='paper',
                 manual_key=layer_key("1999",          # <-- Using the same label as above results in a composite entry in the legend
                                      size=3)) + \
    stat_summary(data=df[df.year == 2008], fun='mean', # <-- 2008
                 geom='line', size=2, color='#708090',
                 manual_key="2008") + \
    stat_summary(data=df[df.year == 2008], fun='mean',
                 geom='point', size=7, shape=23, fill='#708090', color='paper',
                 manual_key=layer_key("2008", size=5)) + \
    guides(manual=guide_legend(
               override_aes=dict(stroke=0,             # <-- remove `stroke` in the "manual" legend
                                 size=1)               # <-- update `size` if not specified otherwise in the layer itself
          )) + \
    ggsize(800, 400) + \
    theme(legend_position=[0.9, 0.95], legend_justification=[1, 1],
          legend_direction='horizontal',
          legend_background=element_rect(size=1, linetype='dotted'))