Layer Labels (Annotations) on Waterfall Plot

In [1]:
from lets_plot import *
from lets_plot.bistro import *
LetsPlot.setup_html()
In [2]:
data = {
    'stage': ["A", "B", "C", "D", "E", "F"],
    'count': [598, -264, 156, -4, 330, -85],
    'pct': [100, 44.14, 46.71, 1.81, 67.9, 10.41],
}

Default Labels

In [3]:
waterfall_plot(data, 'stage', 'count')
Out[3]:

Separate Labels for 'Relative' and 'Absolute' Bars

The waterfall_plot() function now supports two additional parameters, relative_labels and absolute_labels, which provide separate control over labeling for relative and absolute bars.

In [4]:
waterfall_plot(
    data, 'stage', 'count',
    relative_labels=layer_labels().line('@pct%').format('@pct', '.0f'),
    absolute_labels=layer_labels().line('$@..label..').size(20),
)
Out[4]:

Multiline Labels

These new parameters also support multiline label configuration.

In [5]:
waterfall_plot(
    data, 'stage', 'count',
    relative_labels=layer_labels()
        .line('@count')    
        .line('@pct%')
        .format('@pct', '.0f'),
    absolute_labels=layer_labels().line('$@..label..').size(20),
)
Out[5]:

label_format parameter and layer_labels().format()

By default, labels are generated from the ..label.. data column. The label_format parameter specifies the display format for this column and is convenient if you are not using relative_labels or absolute_labels.

If you're using relative_labels or absolute_labels, it's recommended to use the layer_labels().format() method instead — it allows you to define formatting for each label line individually.

If needed, you can also override the format of ..label.. explicitly using:

layer_labels().line("@..label..").format("@..label..", ".0f")
In [6]:
waterfall_plot(
    data, 'stage', 'count',
    label_format='.1f',
    relative_labels=layer_labels()
        .line('@..label..')
        .line('@count')
        .line('@pct%')
        .format('@pct', '.0f'),
    absolute_labels=layer_labels().line('$@..label..')
)
Out[6]:

Hiding Labels

The new parameters allow you to hide labels for relative and absolute bars independently.

In [7]:
waterfall_plot(
    data, 'stage', 'count',
    relative_labels='none',
    absolute_labels=layer_labels().line('$@..label..').size(20),
)
Out[7]:

Inheriting the Geometry Color in Labels

In [8]:
waterfall_plot(
    data, 'stage', 'count',
    color='flow_type',          # <--- Apply the 'flow type' color palette the boxes (borders). 
    size=2,
    alpha=0.1,
    relative_labels=layer_labels()
        .line('@..label..')
        .line('@count')
        .line('@pct%')
        .format('@pct', '.0f')
        .inherit_color(),       # <--- Let text in the 'relative boxes' to inherit the box color.
    absolute_labels=layer_labels()
        .line('$@..label..')
        .size(20),
    label=element_text(color='gray30') # <--- Set gray text color to all the labels except the 'relative' (because.. see above)
)
Out[8]:

Another, easier way in most cases to inherit the geometry color in text labels is to use the 'inherit' value in the label parameter.

This affects text in both 'relative' and 'absolute' bars:

In [9]:
waterfall_plot(data, 'stage', 'count',
    color='flow_type',            # <--- Apply the 'flow type' color palette the boxes (borders). 
    size=2,
    alpha=0.1,
    label=element_text(color='inherit')  # <--- Use 'inherit' color for labels.        
)
Out[9]:

When Label doesn't Fit in its Box

  • If a label does not fit vertically inside a bar, it is automatically positioned above or below the bar.
  • If a label does not fit horizontally, it is rendered with a background to improve readability.
  • The text color is automatically adjusted based on the background color to ensure sufficient contrast.
In [10]:
gggrid([
    waterfall_plot(data, 'stage', 'count', width=.2),
    waterfall_plot(data, 'stage', 'count', width=.2) + flavor_darcula()     
]) 
Out[10]: