Skip to content

Instantly share code, notes, and snippets.

@zx8754
Created April 8, 2025 09:31
Show Gist options
  • Save zx8754/85d0c669a3048eb58d7c58a11eaef9a2 to your computer and use it in GitHub Desktop.
Save zx8754/85d0c669a3048eb58d7c58a11eaef9a2 to your computer and use it in GitHub Desktop.
stacked_bar_alternative
# https://bsky.app/profile/dm-p.nz/post/3lmbrf7axt22t
# https://deneb.guide/blog/stacked-bar-alternative
library(ggplot2)
library(data.table)
library(scales)
library(ggthemes)
d <- fread("
Country Segment Sales
Canada Channel Partners 19752468
Canada Enterprise 144752736
Canada Government 428829833
Canada Midmarket 21616940
Canada Small Business 361203792
France Channel Partners 15178124
France Enterprise 150182723
France Government 432792397
France Midmarket 25395919
France Small Business 274034856
Germany Channel Partners 9807620
Germany Enterprise 146362549
Germany Government 307773485
Germany Midmarket 12452545
Germany Small Business 281729079
Mexico Channel Partners 8887825
Mexico Enterprise 130960356
Mexico Government 413892255
Mexico Midmarket 16428775
Mexico Small Business 308830851
United States of America Channel Partners 12059458
United States of America Enterprise 166894624
United States of America Government 362146299
United States of America Midmarket 21890524
United States of America Small Business 463176030")
#background bar totals data
db <- d[, .(ymax = sum(Sales)), by = Country ]
db[, xmin := -Inf ]
db[, xmax := Inf ]
db[, ymin := 0 ]
db[, label := paste0(Country, "\n", prettyNum(round(ymax/1e6), big.mark = ",")) ]
#set order based on sales total
db[, Country := factor(Country, levels = db$Country[ order(-db$ymax) ]) ]
d[, Country := factor(Country, levels = levels(db$Country)) ]
#set order based on segment total
x <- d[, .(totalSegment = sum(Sales)), by = Segment]
d[, Segment := factor(Segment, levels = x[ order(-totalSegment), Segment ])]
#find mid point
x <- levels(d$Segment)
midPoint <- x[ ceiling(length(x)/2) ]
ggplot(db) +
geom_rect(aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax), fill = "#d4d4d4") +
geom_text(aes(x = midPoint,
y = ymax * 1.05, label = label), nudge_y = 0) +
geom_col(aes(Segment, Sales, fill = Segment), d, colour = "white") +
geom_text(aes(Segment, Sales, label = round(Sales/1e6)), d, vjust = -0.5) +
facet_wrap(vars(Country), nrow = 1) +
scale_y_continuous(labels = label_currency()) +
scale_fill_manual(values = tableau_color_pal(palette = "Tableau 10")(10)) +
labs(title = "Country Revenue by Segment ($M)", fill = "") +
theme_void() +
theme(strip.text = element_blank(),
legend.position = "top",
legend.key.size = unit(10, "points"),
legend.justification = "left",
legend.title.position = "top")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment