I'm trying to plot a very simple dataframe which contains 7 categories (var
) and their respective proportions (prop
), but I wanted to plot it with gradients within bars. I was able to do so, but now I cannot display my proportions on the plot anymore. How can I display proportions on this self-made gradient in ggplot2 ?
- The simpler plot is this:
- I want it to look like this, but with the proportions and Ns on it:
Note: it should return 7 categories, not 4
I tried with geom_text
and with annotate()
, but I couldn't find a solution.
Questions :
Q1: How can I plot the proportions and ns on the second plot?
Q2: I've never used
geom_tile()
before, so I've read its documentation. Still, I still didn't understand how it understands that I only have 7 groups and displays the bars according to ther proportions. Thanks in adv.
Code and data are below:
- Plot 1 code:
library(tidyverse)
library(forcats)
library(stringr)
## This is the original dataframe:
> df
# A tibble: 7 x 4
# Groups: var [7]
var x n prop
<fct> <fct> <int> <dbl>
1 VAR_A yes 7 13.7
2 VAR_B yes 30 58.8
3 VAR_C yes 49 96.1
4 VAR_D yes 48 94.1
5 VAR_E yes 47 92.2
6 VAR_F yes 39 76.5
7 VAR_G yes 21 41.2
# plot it:
df %>%
ggplot(aes(y = prop, x = fct_rev(var),
fill = as.integer(df$var))) + ## HACK to convert discrete to cont
geom_bar(stat = "identity", width = 0.3) +
scale_fill_gradient2(name = "category",
low = "#F1B454",
mid= "#F1EF54",
high = "green",
space = "Lab",
midpoint = 4,
guide= 'legend') +
coord_flip(clip = "off") +
geom_text(aes(label = str_glue('{round(prop, 1.5)}% ')),
nudge_y = 1,
nudge_x = 0.05,
size = 1.5) +
geom_label(aes(label= str_glue('n = {n}')),
size = 1.3,
nudge_x = 0.3,
show.legend = FALSE)
- Plot 2 code: (adapted from here)
## df transformation:
df_expanded2 <- df %>%
rowwise() %>%
summarise(group = var,
value = list(0:n)) %>%
unnest(cols = value)
## to recalculate proportions (if needed):
df_expanded2 %>%
group_by(var) %>%
mutate(prop = round(value * 100/51, 2))
## plot it:
df_expanded2 %>%
ggplot() +
geom_tile(aes(
x = fct_rev(var),
y = value,
fill = value),
width = 0.9) + ## adds space between bars
coord_flip() +
scale_fill_gradient2(name = "category",
low = "#F1B454",
mid= "#F1EF54",
high = "green",
space = "Lab",
midpoint = 4,
guide= 'legend') ## it should be 7, not 4
- data:
structure(list(var = structure(1:7, .Label = c("VAR_A", "VAR_B",
"VAR_C", "VAR_D", "VAR_E", "VAR_F", "VAR_G"), class = "factor"),
x = structure(c(2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("no",
"yes"), class = "factor"), n = c(7L, 30L, 49L, 48L, 47L,
39L, 21L), prop = c(13.73, 58.82, 96.08, 94.12, 92.16, 76.47,
41.18)), class = c("grouped_df", "tbl_df", "tbl", "data.frame"
), row.names = c(NA, -7L), groups = structure(list(var = structure(1:7, .Label = c("VAR_A",
"VAR_B", "VAR_C", "VAR_D", "VAR_E", "VAR_F", "VAR_G"), class = "factor"),
.rows = structure(list(1L, 2L, 3L, 4L, 5L, 6L, 7L), ptype = integer(0), class = c("vctrs_list_of",
"vctrs_vctr", "list"))), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -7L), .drop = TRUE))
- edit:
# putting back original names (not working)
library(forcats)
df <- df %>%
mutate(var = fct_collapse(var,
'Berçário' = 'VAR_A',
'Maternal' = 'VAR_B',
'Educação Infantil' = 'VAR_C',
'Anos Iniciais do E.F.' = 'VAR_D',
'Anos Finais do E.F.' = 'VAR_E',
'Fundamental 2' = 'VAR_F',
'Médio' = 'VAR_G'))