1

I am trying to create a figure in ggplot2, whereby there are three bars in a stacked bar chart, one of which I want to highlight (i.e. make bigger than the other two to draw out the findings of that bar over the other two).

To make the bar chart I do as follows:

df <- data.frame(var = c("var1", "var1", "var1", "var2", "var2", "var2", "var3", "var3", "var3"),
                 change = c("better", "same", "worse","better", "same", "worse","better", "same", "worse"),
                 freq = sample(100:500, 9, replace = T))

df <- df %>% group_by(change) %>%
  mutate(per= prop.table(freq) * 100) %>%
  mutate(across(per, ~ round(., 1)))

fig1 <- ggplot(df, aes(x=change, y=freq, fill=var)) + 
  geom_bar(position="fill", stat="identity", alpha = 0.8) + 
  scale_y_continuous(labels = scales::percent) +
  theme_classic() + 
  theme(legend.position = "right") + 
  guides(fill = guide_legend(reverse = TRUE)) +
  coord_flip()

I have tried to change the width of the bars by doing the following:

fig2 <- ggplot(df, aes(x=change, y=freq, fill=var)) + 
  geom_bar(position="fill", stat="identity", alpha = 0.8, width = c(0.3, 0.3, 1)) + 
  scale_y_continuous(labels = scales::percent) +
  theme_classic() + 
  theme(legend.position = "right") + 
  guides(fill = guide_legend(reverse = TRUE)) +
  coord_flip()

That changes the width of the bar I want to change, but I would like the gaps between each bar to be of equal distance. The effect I want is to draw the reader's eye towards the top bar over the other two.

itsapuntis
  • 35
  • 5
  • Similar question [at this link](https://stackoverflow.com/questions/20688376/how-to-make-variable-bar-widths-in-ggplot2-not-overlap-or-gap) where the chosen answer was to use a continuous axis. – aosmith Oct 27 '21 at 18:50

1 Answers1

2

You can use a discrete variable to index into a continuous one. You can use that to match up the discrete variable with positions of where you want to place the bars.

library(ggplot2)
#> Warning: package 'ggplot2' was built under R version 4.1.1

df <- data.frame(var = c("var1", "var1", "var1", "var2", "var2", "var2", "var3", "var3", "var3"),
                 change = c("better", "same", "worse","better", "same", "worse","better", "same", "worse"),
                 freq = sample(100:500, 9, replace = T))

df <- df %>% group_by(change) %>%
  mutate(per= prop.table(freq) * 100) %>%
  mutate(across(per, ~ round(., 1)))
#> Error in df %>% group_by(change) %>% mutate(per = prop.table(freq) * 100) %>% : could not find function "%>%"

positions <- c(1, 1.7, 2.8)

ggplot(df, aes(x= positions[match(change, sort(unique(change)))], 
               y=freq, fill=var)) + 
  geom_col(position="fill", alpha = 0.8, 
           width = c(0.3, 0.3, 1)) + 
  scale_y_continuous(labels = scales::percent) +
  scale_x_continuous(breaks = positions,
                     labels = sort(unique(df$change))) +
  theme_classic() + 
  theme(legend.position = "right") + 
  guides(fill = guide_legend(reverse = TRUE)) +
  coord_flip()

Created on 2021-10-27 by the reprex package (v2.0.1)

teunbrand
  • 33,645
  • 4
  • 37
  • 63