Home > Back-end >  Use free_y scale on first axis and fixed on second facet_grid ggplot2
Use free_y scale on first axis and fixed on second facet_grid ggplot2

Time:05-12

Is there any method to set scale = 'free_y' on the left hand (first) axis in ggplot2 and use a fixed axis on the right hand (second) axis?

I have a dataset where I need to use free scales for one variable and fixed for another but represent both on the same plot. To do so I'm trying to add a second, fixed, y-axis to my data. The problem is I cannot find any method to set a fixed scale for the 2nd axis and have that reflected in the facet grid.

This is the code I have so far to create the graph -

#plot weekly seizure date 
p <- ggplot(dfspw_all, aes(x=WkYr, y=Seizures, group = 1))    geom_line()   
  xlab("Week Under Observation")   ggtitle("Average Seizures per Week - To Date")   
  geom_line(data = dfsl_all, aes(x =WkYr, y = Sleep), color = 'green')  
  scale_y_continuous(
    # Features of the first axis
    name = "Seizures",
    # Add a second axis and specify its features
    sec.axis = sec_axis(~.[0:20], name="Sleep")
  )

p   facet_grid(vars(Name), scales = "free_y")  
  theme(axis.ticks.x=element_blank(),axis.text.x = element_blank())

This is what it is producing (some details omitted from code for simplicity) -

enter image description here

What I need is for the scale on the left to remain "free" and the scale on the right to range from 0-24.

CodePudding user response:

Secondary axes are implemented in ggplot2 as a decoration that is a transformation of the primary axis, so I don't know an elegant way to do this, since it would require the secondary axis formula to be aware of different scaling factors for each facet.

Here's a hacky approach where I scale each secondary series to its respective primary series, and then add some manual annotations for the secondary series. Another way might be to make the plots separately for each facet like enter image description here

...we could scale each secondary series to its primary series, and add custom annotations for that secondary series:

fake2 <- fake %>%
  group_by(facet) %>%
  mutate(y_sec_scaled = y_sec/max(y_sec) * (max(y_prim))) %>%
  ungroup()

fake2_labels <- fake %>% 
  group_by(facet) %>%
  summarize(max_prim = max(y_prim), baseline = 0, x_val = 10.5)

ggplot(fake2, aes(x, y_prim))  
  geom_line()   
  geom_line(aes(y= y_sec_scaled), color = "green")  
  facet_wrap(~facet, ncol = 1, scales = "free_y")  
  geom_text(data = fake2_labels, aes(x = x_val, y = max_prim, label = "100%"),
            hjust = 0, color = "green")  
  geom_text(data = fake2_labels, aes(x = x_val, y = baseline, label = "0%"),
            hjust = 0, color = "green")  
  coord_cartesian(xlim = c(0, 10), clip = "off")  
  theme(plot.margin = unit(c(1,3,1,1), "lines"))

enter image description here

  • Related