Search code examples
rggplot2yaxis

ggplot2: Move overlayed points according to secondary y-axis's range


The left-hand side y-axis's ranges from 0 to 5000-ish and the right-hand side from 0 to 600. With scale_y_continuous(sec.axis = sec_axis(~. * 0.2, name = "price")), I want to move the dots up, but they seem in the 0-5000 range now, so they all are at the bottom.

This line from How to link the secondary y-axis to the correct variable in ggplot2? doesn't help.

  scale_y_continuous(
    name="Price",
    sec.axis=sec_axis(trans=~ . * 0.2, 
                      name="Price")
  )

How do I change my code? Thanks.

library(ggplot2)
library(tidyverse)

price.avg <- diamonds %>%
  group_by(cut, color) %>%
  summarise(price = 0.1 * mean(price), dummy = "1")

summary(price.avg)
        cut    color     price          dummy          
 Fair     :7   D:5   Min.   :259.8   Length:35         
 Good     :7   E:5   1st Qu.:358.5   Class :character  
 Very Good:7   F:5   Median :423.9   Mode  :character  
 Premium  :7   G:5   Mean   :421.4                     
 Ideal    :7   H:5   3rd Qu.:480.2                     
               I:5   Max.   :629.5                     
               J:5            

   


diamonds %>%
  ggplot() +
  geom_bar(aes(x = cut, fill = clarity)) +
  facet_wrap(~ color) +
  ylab("Count") +
  xlab("Cut") + 
  geom_point(data = price.avg, aes(x = cut, y = price, col = "")) +
  scale_y_continuous(sec.axis = sec_axis(~. * 0.2, name = "price")) + 
  scale_color_manual(name = "", label = "Average price", values = "black")

enter image description here


Solution

  • Transforming the scale isn't sufficient. You also have to transform your data using the inverse transformation, i.e. use y = price / .2 in geom_point:

    library(tidyverse)
    
    price.avg <- diamonds %>%
      group_by(cut, color) %>%
      summarise(price = 0.1 * mean(price), dummy = "1")
    #> `summarise()` has grouped output by 'cut'. You can override using the `.groups`
    #> argument.
    
    diamonds %>%
      ggplot() +
      geom_bar(aes(x = cut, fill = clarity)) +
      facet_wrap(~ color) +
      ylab("Count") +
      xlab("Cut") + 
      geom_point(data = price.avg, aes(x = cut, y = price / .2, col = "")) +
      scale_y_continuous(sec.axis = sec_axis(~. * 0.2, name = "price")) + 
      scale_color_manual(name = "", label = "Average price", values = "black")