3

As of matplotlib 3.4.0, Axes.bar_label method allows for labelling bar charts.

However, the labelling format option works with old style formatting, e.g. fmt='%g'

How can I make it work with new style formatting that would allow me to do things like percentages, thousands separators, etc: '{:,.2f}', '{:.2%}', ...

The first thing that comes to my mind is somehow taking the initial labels from ax.containers and then reformatting them but it also needs to work for different bar structures, grouped bars with different formats and so on.

tdy
  • 26,545
  • 9
  • 43
  • 50
Konstantin
  • 354
  • 1
  • 15

1 Answers1

4

How can I make it work with new style formatting like percentages, thousands separators, etc?

With the new bar_label method, use the labels param. Format the bar container's datavalues with the desired f-string and set those as the labels.


For example:

  • Thousands separator f-string

    bars = plt.bar(list('ABC'), [12344.56, 23456.78, 34567.89])
    
    plt.bar_label(bars, labels=[f'${x:,.2f}' for x in bars.datavalues])
    

  • Percentage f-string

    bars = plt.bar(list('ABC'), [0.123456, 0.567890, 0.789012])
    
    plt.bar_label(bars, labels=[f'{x:.2%}' for x in bars.datavalues])
    

  • Stacked percentage f-string

    x = list('ABC')
    y = [0.7654, 0.6543, 0.5432]
    
    fig, ax = plt.subplots()
    ax.bar(x, y)
    ax.bar(x, 1 - np.array(y), bottom=y)
    
    # now 2 bar containers: white labels for blue bars, black labels for orange bars
    colors = list('wk')
    for bars, color in zip(ax.containers, colors):
        labels = [f'{x:.1%}' for x in bars.datavalues]
        ax.bar_label(bars, labels=labels, color=color, label_type='center')
    

tdy
  • 26,545
  • 9
  • 43
  • 50