Home > Back-end >  Plot geom_col and geom_line with different x-axis percentage scales on the same graph in r
Plot geom_col and geom_line with different x-axis percentage scales on the same graph in r

Time:05-12

I have created the following example data:

df <- data.frame(list(Category = c("A", "A", "A", "B", "B", 
        "B", "B", "B", "B", "C", "C", "C", "D", "D", "D","E", 
        "E", "E"), Axis2 = c(0.34, 0.34, 0.34, 0.22, 0.22, 0.22, 
        0.29, 0.29, 0.29, 0.53, 0.53, 0.53, 0.67, 0.67, 0.67, 0.42, 
        0.42, 0.42), Offices = c("Office 1", "Office 2", "Office 3", 
        "Office 1", "Office 2", "Office 3", "Office 1", "Office 2", 
        "Office 3", "Office 1", "Office 2", "Office 3", "Office 1", 
        "Office 2", "Office 3", "Office 1", "Office 2", "Office 3"), 
        Axis1 = c(0.03, 0.02, 0.04, 0.1, 0.08, 0.07, 0.12, 0.211, 
        0.18, 0.05, 0.07, 0.08, 0.01, 0.02, 0.03, 0.07, 0.011, 0.012)))

I want to plot the Category column on the y-axis, the Axis1 column as the x-axis for the bar plot and the Axis2 columns as the x-axis for the line plot. The fill of the bar plot is also determined by the Category column. The data is then faceted by Offices.

I have the following code for the plot:

ggplot(df)   theme_minimal()   guides(fill = FALSE)  
  geom_col(aes(x = Axis1, y = Category, fill = Category))    
  geom_line(aes(x = Axis2, y = Category), stat = "identity", group = 1)  
  labs(y = element_blank(), x = "Percentage of Thing 1")  
  facet_wrap(~Offices, ncol = 3)  
  scale_x_continuous(labels = scales::percent_format(accuracy = 1),
                     sec.axis = sec_axis(~./max(data$Compliance), 
                                         label=scales::percent))  
  theme(axis.text.y = element_text(size = 11, color = "black"),
        strip.text = element_text(size = 18, color = "black", 
        face = "bold", margin = margin(c(0.2,0,0.6,0), unit = "in")),
        axis.title.x = element_text(size = 12, color = "black", 
        margin = margin(c(0.2,0,0.1,0), unit = "in")),
        panel.grid.major.x = element_line(color = "gray86"),
        panel.grid.major.y = element_blank(),
        panel.grid.minor = element_blank())

I am facing 3 main issues:

  1. The location of the second x-axis, I want it to be under the facet titles right above the plot.
  2. The second x-axis labels are not showing the data in Axis2 column
  3. Both plots seem to still be using the main x-axis scale because the bar plots are shrunken to accommodate the line plot. I want them to be independent of each other where the y axis is shared but the x-axes are not.

enter image description here

CodePudding user response:

To place the strip labels above the axis use strip.placement= "outside". To get the right scales for your axes you also have to scale the data to be plotted on the secondary scale.

library(ggplot2)

scale <- max(df$Axis1)

ggplot(df)  
  theme_minimal()  
  guides(fill = "none")  
  geom_col(aes(x = Axis1, y = Category, fill = Category))  
  geom_line(aes(x = Axis2 * scale, y = Category), stat = "identity", group = 1)  
  labs(y = element_blank(), x = "Percentage of Thing 1")  
  facet_wrap(~Offices, ncol = 3)  
  scale_x_continuous(
    labels = scales::percent_format(accuracy = 1),
    sec.axis = sec_axis(~ . / scale, label = scales::percent)
  )  
  theme(
    axis.text.y = element_text(size = 11, color = "black"),
    strip.text = element_text(
      size = 18, color = "black",
      face = "bold", margin = margin(c(0.2, 0, 0.6, 0), unit = "in")
    ),
    axis.title.x = element_text(
      size = 12, color = "black",
      margin = margin(c(0.2, 0, 0.1, 0), unit = "in")
    ),
    panel.grid.major.x = element_line(color = "gray86"),
    panel.grid.major.y = element_blank(),
    panel.grid.minor = element_blank(),
    strip.placement = "outside"
  )

  • Related