Search code examples
rplotbar-chartoverlap

How to overlay bar chart with another bar chart but smaller bar width?


I want to plot four dimensions in one plot. For each decile I want income and expenditures side by side.

In addition, the rural values should then be displayed in the background with a normal bar width and the urban values as an overlay in the foreground with a thinner bar width.

Income bars refer to the left Y-axis and expenditures to the right Y-axis. The colors of the ones in the back (rural domain) should have an alpha value of 0.5.

I have tried the following:

# Creates N colors for Viridis
n <- 22
color <- viridis(n)

# See and compare color scales:
show_col(viridis_pal()(n))

# Plot
ggplot(data, aes(fill = Decile, alpha = Divide)) + 
geom_col(data=data, aes(x=Decile, y=Avg.q.hou.inc), position = position_dodge(width = 0.9)) +
geom_col(data=data, aes(x=Decile, y=Avg.q.hou.exp), position = position_dodge(width = 0.9)) +
scale_fill_manual(values = c(color[1:10])) +
scale_alpha_manual(values = c(0.5, 1)) +
scale_y_continuous(labels = comma,
                   name = "Average quarterly household income",
                   sec.axis = sec_axis(~ ., 
                                       name = "Average quarterly household expenditure",
                                       labels = comma))

Resulting in the following graphic:

graphic

The data is available here: https://drive.google.com/file/d/1pyFAWZ2CU7bUkzpCm-QjfsqFUAe47bFI/view?usp=sharing

An example of the graph is here:

enter image description here


Solution

  • Well, in the end I manage to do the graph I needed with the following code:

      ggplot(data, aes(alpha=Divide, linetype=Divide)) + 
      geom_col(data=data, 
               aes(x=Decile, y=Avg.q.hou.inc, color=Divide, fill=Decile), 
               position = position_dodge(1)) +
      geom_col(data=data, 
               aes(x=Decile, y=Avg.q.hou.exp, color=Divide, fill=Decile), 
               position = position_dodge(1)) +
      scale_fill_manual(values = c(color[1:10])) +
      scale_alpha_manual(values = c(0.5, 1), name="Domain") +
      scale_color_manual(values = c("black", "black")) +
      scale_y_continuous(labels = comma,
                         name="USD") +
      theme_classic(base_size = 15) +
      theme(legend.position = c(0.5, 1), 
            legend.box = 'vertical', 
            legend.direction = 'horizontal',
            legend.justification = c(0.5, 1),
            axis.text.x = element_text(size=15, color="black"),
            axis.text.y = element_text(size=15, color="black"),
            axis.title.x = element_text(size=15, color="black", vjust=-1),
            axis.title.y = element_text(size=15, color="black")) +
      guides(color="none",   # https://datavizpyr.com/selectively-remove-legends-with-ggplot2/
             linetype = "none",
             fill = guide_legend(title.position = "top", 
                                 title.hjust = 0.5, 
                                 label.hjust = 0.5,
                                 nrow=1, 
                                 byrow=TRUE,
                                 order=1),
             alpha = guide_legend(name="Domain",
                                  title.position = "top",
                                  title.hjust = 0.5, 
                                  label.hjust = 0.5,
                                  nrow=1, 
                                  byrow=TRUE,
                                  order=2))
    

    The resulting figure:

    enter image description here