Here is my fake data:
dat1 <- structure(list(A_B = c("A", "B", "A", "B", "A", "B", "A", "B",
"A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A",
"B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B",
"A", "B", "A", "B", "A", "B"), percentage = c(49.2629769158808,
50.7370230841193, 64.4899165250794, 35.5100834749206, 59.3111128788481,
40.6888871211519, 85.3899516501997, 14.6100483498003, 80.5933773112794,
19.4066226887206, 84.3750256827502, 15.6249743172498, 62.8269574848769,
37.1730425151231, 69.5582018265724, 30.4417981734276, 56.5840999142665,
43.4159000857335, 100, 0, 67.4302746354917, 32.5697253645083,
27.3784794349813, 72.6215205650187, 58.0885854897603, 41.9114145102397,
100, 0, 89.005829015544, 10.994170984456, 57.1694599627561, 42.8305400372439,
100, 0, 54.2251244585246, 45.7748755414754, 74.4838466287125,
25.5161533712875, 74.6413724456935, 25.3586275543065), facet = c("Facet 1",
"Facet 1", "Facet 1", "Facet 1", "Facet 1", "Facet 1", "Facet 1",
"Facet 1", "Facet 1", "Facet 1", "Facet 2", "Facet 2", "Facet 2",
"Facet 2", "Facet 2", "Facet 2", "Facet 2", "Facet 2", "Facet 2",
"Facet 2", "Facet 2", "Facet 2", "Facet 1", "Facet 1", "Facet 2",
"Facet 2", "Facet 2", "Facet 2", "Facet 1", "Facet 1", "Facet 1",
"Facet 1", "Facet 2", "Facet 2", "Facet 1", "Facet 1", "Facet 1",
"Facet 1", "Facet 1", "Facet 1"), id = c(1L, 1L, 2L, 2L, 3L,
3L, 4L, 4L, 5L, 5L, 6L, 6L, 7L, 7L, 8L, 8L, 9L, 9L, 10L, 10L,
11L, 11L, 12L, 12L, 13L, 13L, 14L, 14L, 15L, 15L, 16L, 16L, 17L,
17L, 18L, 18L, 19L, 19L, 20L, 20L)), row.names = c(NA, -40L), class = c("tbl_df",
"tbl", "data.frame"))
Here is the chart:
library(ggplot2)
ggplot(dat1, aes(id, percentage, fill = factor(A_B))) +
geom_col(position = position_fill()) +
scale_fill_manual(values = c("coral", "lightblue"),
breaks=c('A', 'B'))+
coord_flip() +
facet_wrap(. ~ facet, scale= "free")+
geom_text(data = subset(dat1, percentage != 0), aes(label = sprintf("%.1f%%", percentage), group = A_B), position = position_fill(vjust=0.5), size = 5)
When attempting to vertically align text within a single line for both A
and B
by adjusting the vjust argument in position_fill()
, I encounter difficulties achieving a uniform alignment. Using vjust=1
brings me closest to the desired outcome; however, this results in the text exceeding the boundaries. Using any other number in vjust
results in a skewed formation of the percent numbers.
Using the vjust
parameter you can only position both labels at the bottom, top or center. Instead, for what you are trying to achieve I think you are better off using position="idenity"
and setting the y
position and the horizontal alignment using an ifelse
. Also note that I switched to geom_label
to add some padding (I'm not a big fan of using h/vjust
for this task (: ).
library(ggplot2)
ggplot(dat1, aes(id, percentage, fill = factor(A_B))) +
geom_col(position = position_fill()) +
scale_fill_manual(
values = c("coral", "lightblue"),
breaks = c("A", "B")
) +
coord_flip() +
facet_wrap(. ~ facet, scale = "free") +
geom_label(
data = subset(dat1, percentage != 0),
aes(
y = ifelse(A_B == "A", 1, 0),
hjust = ifelse(A_B == "A", 1, 0),
label = sprintf("%.1f%%", percentage)
), size = 3, fill = NA, label.size = 0
)