You should open an issue in StatsPlots.jl.
Meanwhile, you may check this wrapping function (not fully tested):
Code
function annotated_groupedbar(xx, yy, group; series_annotations="", legend=:top_right, bar_width=0.8, color=:blue, font_size=10)
gp = groupedbar(xx, yy, group=group, series_annotations="", legend=legend, bar_width=bar_width)
m = length(unique(group)) # number of items per group
n = length(unique(xx)) # number of groups
xt = (1:n) .- 0.5 # plot x-coordinate of groups' centers
dx = bar_width/m # each group occupies bar_width units along x
dy = diff([extrema(yy)...])[1]
x2 = [xt[i] + (j - m/2 - 0.5)*dx for j in 1:m, i in 1:n][:]
k = 1
for i in 1:n, j in 1:m
y0 = gp[1][2j][:y][i] + 0.04*dy
if isfinite(y0)
annotate!(x2[(i-1)*m + j], y0, text(series_annotations[k], :center, color, font_size))
k += 1
end
end
gp
end
For your example it produces:
using StatsPlots
x, y = ["A","A","B","B"], [1,2,3,4]
year = ["2020","2021","2020","2021"]
annotated_groupedbar(x, y, year; series_annotations=y, legend=:topleft, bar_width=0.7, color=:blue, font_size=10)
And for other more interesting groupings with gaps:
using StatsPlots
x, y = ["D","A","A","B","B","C","C","C","D"], collect(1:9)
year = ["2020","2021","2022","2020","2022","2020","2021","2022","2021"]
annotated_groupedbar(x, y, year; series_annotations=y, legend=:topleft, bar_width=0.7, color=:blue, font_size=10)
annotated_groupedbar(year, y, x; series_annotations=y, legend=:topleft, bar_width=0.7, color=:blue, font_size=10)