in the plot below I have data distributed into four groups separated via facet_wrap()
. However, these groups have an uneven distribution of the data, hence, all groups have different bar sizes.
How can I avoid cut the geom_label() of groups one and two ?
Here is my code:
library(tidyverse)
library(RColorBrewer)
###
cor12 <- brewer.pal(12, "Paired")
cor5 <- brewer.pal(7, "Pastel1")
myColors <- c(cor12, cor5)
names(myColors) <- c('Não oferta',
'1h - 3h',
'4h - 5h',
'6h - 8h',
'9h - 10h',
'Mais de 10h', 'Mais de 15h',
'20h', 'Mais de 20h', 'Mais de 30h',
'50% em LA', '100% em LA')
### plot:
df %>%
ggplot(aes(y = prop, x = fct_rev(CH), fill = CH, pattern = Q9)) +
geom_bar(stat = "identity", width = 0.5) +
scale_fill_manual(values = myColors, name = NULL) +
geom_label(aes(label = str_glue('{round(prop, 1.5)}%')),
nudge_y = 15, #15
nudge_x = 0.3, #0.05
colour = 'black',
fill = "yellow",
label.padding = unit(0.125, "lines"),
size = 3.5) +
### FLIP IT:
coord_flip(clip = "off") +
facet_wrap(~Q9, scales = "free_y") +
### SHOW N
geom_label(aes(label= str_glue('n = {n}')),
size = 2,
nudge_x = 0.3,
nudge_y = 30,
fontface = "italic",
show.legend = FALSE) +
### SHOW % IN THE X-AXIS:
scale_y_continuous(limits = c(0,100),
labels=scales::percent_format(scale = 1)) +
### LABELS:
labs(x = "times",
y = '%',
title = "a title") +
### THEME:
cowplot::theme_half_open() +
theme(
text = element_text(family = "sans",
size = 14,
hjust = 0.5),
#plot.margin = margin(t = 0, r = 15, b = 0, l = 0),
legend.position = "bottom",
legend.justification = "center",
legend.background = element_rect(color = "black"), #bloco com legendas
legend.margin = margin(t = 5, r = 5, b = 3, l = 3),
legend.text = element_text(size = 12),
axis.text.x = element_text(hjust = 0.5,
size = 12), # legenda de baixo
axis.title.x = element_text(size = 13.5,
face = "bold",
margin = margin(t = 20, r = 0, b = 0, l = 0)),
axis.text.y = element_text(size = 12),
axis.title.y = element_text(size = 13.5,
face = "bold"),
### Facets:
strip.text.x = element_text(face = "bold",
family = "sans",
size = 18,
colour = 'green'),
strip.background = element_rect(size = 3,
fill = 'yellow'),
strip.switch.pad.grid = unit('10', "cm"),
strip.clip = "off")
1: How can I avoid cut the geom_label()
of groups one and two ?
Bonus : is there a way to dynamically set geom_label()
so that the labels always get stuck to a certain position according to each bar size? (hence, I don't have to set them manually and groups with different amount of data get the labels at the same place) ?
I need a solution to achieve this:
structure(list(CH = structure(c(3L, 2L, 3L, 2L, 3L, 4L, 5L, 6L,
7L, 6L, 7L), .Label = c("Não oferta", "1h - 3h", "4h - 5h", "6h - 8h",
"9h - 10h", "Mais de 10h", "50% em LA"), class = "factor"), Q9 = structure(c(1L,
2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L), .Label = c("one", "two",
"three", "four"), class = "factor"), n = c(1L, 12L, 1L, 8L, 2L,
2L, 2L, 1L, 3L, 2L, 2L), prop = c(100, 92.31, 7.69, 44.44, 11.11,
11.11, 11.11, 5.56, 16.67, 50, 50), sd = c(NA, 0.6, 0.6, 0.14,
0.14, 0.14, 0.14, 0.14, 0.14, 0, 0)), class = c("grouped_df",
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -11L), groups = structure(list(
Q9 = structure(1:4, .Label = c("one", "two", "three", "four"
), class = "factor"), .rows = structure(list(1L, 2:3, 4:9,
10:11), ptype = integer(0), class = c("vctrs_list_of",
"vctrs_vctr", "list"))), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -4L), .drop = TRUE))
Update after clarification: It is not the best solution but it should work for this example. To avoid losing one label because of moving the other to the left, we could stack the labels by changing both (% and n) nudge_x and nudge_y and then we can see all of them:
df %>%
ggplot(aes(y = prop, x = fct_rev(CH), fill = CH, pattern = Q9)) +
geom_bar(stat = "identity", width = 0.5) +
scale_fill_manual(values = myColors, name = NULL) +
geom_label(aes(label = str_glue('{round(prop, 1.5)}%')),
nudge_y = -2, #15
nudge_x = 0.05, #0.05
colour = 'black',
fill = "yellow",
label.padding = unit(0.125, "lines"),
size = 3.5) +
### FLIP IT:
coord_flip(clip = "off") +
facet_wrap(~Q9, scales = "free_y") +
### SHOW N
geom_label(aes(label= str_glue('n = {n}')),
size = 2,
nudge_x = -0.2,
nudge_y = -2,
fontface = "italic",
show.legend = FALSE) +
### SHOW % IN THE X-AXIS:
scale_y_continuous(limits = c(0,100),
labels=scales::percent_format(scale = 1)) +
### LABELS:
labs(x = "times",
y = '%',
title = "a title") +
### THEME:
cowplot::theme_half_open() +
theme(
text = element_text(family = "sans",
size = 14,
hjust = 0.5),
#plot.margin = margin(t = 0, r = 15, b = 0, l = 0),
legend.position = "bottom",
legend.justification = "center",
legend.background = element_rect(color = "black"), #bloco com legendas
legend.margin = margin(t = 5, r = 5, b = 3, l = 3),
legend.text = element_text(size = 12),
axis.text.x = element_text(hjust = 0.5,
size = 12), # legenda de baixo
axis.title.x = element_text(size = 13.5,
face = "bold",
margin = margin(t = 20, r = 0, b = 0, l = 0)),
axis.text.y = element_text(size = 12),
axis.title.y = element_text(size = 13.5,
face = "bold"),
### Facets:
strip.text.x = element_text(face = "bold",
family = "sans",
size = 18,
colour = 'green'),
strip.background = element_rect(size = 3,
fill = 'yellow'),
strip.switch.pad.grid = unit('10', "cm"),
strip.clip = "off")
First answer: This should do what you are after:
To avoid expanding y axis over 100%, we could position the labels in the chart area.
Here we use prop
in a condition to set y position of the labels:
df %>%
ggplot(aes(y = prop, x = fct_rev(CH), fill = CH, pattern = Q9)) +
geom_bar(stat = "identity", width = 0.5) +
scale_fill_manual(values = myColors, name = NULL) +
geom_label(aes(label = str_glue('{round(prop, 1.5)}%'), y = ifelse(prop < 10, prop + 5, prop - 5)),
colour = 'black',
fill = "yellow",
label.padding = unit(0.125, "lines"),
size = 3.5) +
coord_flip(clip = "off") +
facet_wrap(~Q9, scales = "free_y") +
scale_y_continuous(limits = c(0,100), labels=scales::percent_format(scale = 1)) +
theme(
text = element_text(family = "sans", size = 14, hjust = 0.5),
legend.position = "bottom",
legend.justification = "center",
# Other theme elements...
)+
### LABELS:
labs(x = "times",
y = '%',
title = "a title") +
### THEME:
cowplot::theme_half_open() +
theme(
text = element_text(family = "sans",
size = 14,
hjust = 0.5),
#plot.margin = margin(t = 0, r = 15, b = 0, l = 0),
legend.position = "bottom",
legend.justification = "center",
legend.background = element_rect(color = "black"), #bloco com legendas
legend.margin = margin(t = 5, r = 5, b = 3, l = 3),
legend.text = element_text(size = 12),
axis.text.x = element_text(hjust = 0.5,
size = 12), # legenda de baixo
axis.title.x = element_text(size = 13.5,
face = "bold",
margin = margin(t = 20, r = 0, b = 0, l = 0)),
axis.text.y = element_text(size = 12),
axis.title.y = element_text(size = 13.5,
face = "bold"),
### Facets:
strip.text.x = element_text(face = "bold",
family = "sans",
size = 18,
colour = 'green'),
strip.background = element_rect(size = 3,
fill = 'yellow'),
strip.switch.pad.grid = unit('10', "cm"),
strip.clip = "off")