I would like to make a barplot with different categories of appointments as different colors, and appointment for each color, partially filled based on whether it was cancelled or not.
library(tidyverse) df <- tribble( ~ apt, ~ count, ~ attended, "Consult", 5, 3, "Follow Up", 3, 2, "Procedure", 6, 6 ) %>% mutate(apt = factor(apt)) df %>% ggplot(aes(x = "Appointments", y = count, fill = apt)) + geom_bar(stat = "identity", position = "stack")
I would like the Green "Follow Up" bar to be "filled" only 2/3 of the way and the red "Consult" bar to be "filled" only 3/5 of the way based on the 3rd variable "attended"
Is there a way to do that with the existing ggplot parameters? I was trying to come up with a way using color and fill parameters creatively but it introduces a lot of headaches
You can achieve this by counting the missed appointments for each appointment type, then pivoting into long format. You can then assign attended vs missed appointments to the alpha aesthetic.
df %>% mutate(DNA = count - attended) %>% select(-count) %>% pivot_longer(attended:DNA) %>% ggplot(aes(x = "Appointments", y = value, fill = apt, alpha = name)) + geom_col(position = "stack", color = 'gray60') + scale_alpha_manual(NULL, values = c(1, 0.2))
If I may make a suggestion however, it would be a much easier plot to understand (and therefore better from a data-viz perspective) if you had the appointment type on the x axis and used fill color to represent the attended / missed groups. It is better to use color to highlight some important aspect about the information on display rather than using it gratuitously.
For example, if the reason for creating the plot is to highlight the number of missed appointments in each appointment type, we could do:
df %>% mutate(DNA = count - attended) %>% select(-count) %>% pivot_longer(attended:DNA) %>% ggplot(aes(x = apt, y = value, fill = name)) + geom_col(position = position_stack(reverse = TRUE), width = 0.5, alpha = 0.8) + theme_minimal(base_size = 16) + labs(y = 'Number of appointments', x = 'Appointment type') + scale_fill_manual('Outcome', values = c('gray50', 'red4'), labels = c('Attended', 'Did not attend')) + theme(panel.grid.major.x = element_blank())
This is a plot which needs very little, if any, explanation, and to my eye looks more professional and elegant.