I have the following chart and I want to annotate the bar with the highest value. The problem is the coordinate of x-axis has no values, it has text.
How to annotated the top of a stacked bar with the greatest height
114 Views Asked by Ayman M At
2
There are 2 best solutions below
0
On
The data + example below demonstrates how to label the tallest bar. However, it assumes that the bars were drawn directly using matplotlib and that the data is a numpy array. If you produced your plot using pandas or some other plotting library, then the approach below would need to be modified.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
#Synthetic data
np.random.seed(0)
month_names = pd.Series(
pd.date_range(start='2023-01', periods=12, freq='M')
).dt.month_name().to_list()
month_names = [name[:3].upper() for name in month_names]
disturbances = np.stack([
np.random.randn(12) * 4 + 50, #orange bars
np.random.randn(12) * 6 + 50], #blue bars
axis=0
)
totals = disturbances.sum(axis=0) #total per month
#Plot
f, ax = plt.subplots(figsize=(10, 4))
bottom = np.zeros(12)
for dist in disturbances:
bars = ax.bar(month_names, dist, bottom=bottom, label='')
bottom += dist + 1.5
ax.xaxis.set_tick_params(rotation=45)
ax.set_xlabel('Month')
ax.set_ylabel('Disturbances')
#Make labels
#All labels empty except the largest value
labels = [''] * 12
labels[totals.argmax()] = totals[totals.argmax()].round()
ax.bar_label(bars, labels=labels);


.pivot_tableto aggregate themeanfor each group, and create a separate variable,totfor the maximum total bar height relative to theindex.pivot_tableindex will be the x-axis and the column headers will be the bar groups.pandas.DataFrame.plotwithkind='bar'andstacked=Trueoffers the easiest option for plotting stacked bars.pandasusesmatplotlibas the default plotting backend..bar_labelas explained in this answer and this answer, to annotate the bars.fmtparameter accepts alambdaexpression, which is used to filter the labels to matchtot. This works frommatplotlib v3.7, otherwise a customlabelparameter must be used, as shown in the linked answers.ax.containers, whereax.containers[0]is the bottom segments andax.containers[1]is the top segments.label_type='edge'is the default, which results in the annotation being the sum of the bar heights.'month'column can be set withpd.Categoricalandordered.from calendar import month_abbrto get an ordered list of abbreviated month names.df.month = pd.Categorical(values=df.month, categories=month_abbr[1:], ordered=True)python 3.12.0,pandas 2.1.2,matplotlib 3.8.1,seaborn 0.13.0df.head()ptpt.sum(axis=1)tot