Search code examples
rggplot2reverseaxisyaxis

How to reverse axis y predetermined from scale_y_log10? ggplot [repeated]


Similar here

Im trying plot one graphic with scale_y_log10 already predetermined and at the same time reverse the y axis, but when I did, didn't work, shows a message

Scale for 'y' is already present. Adding another scale for 'y', which will replace the existing scale.

dt = data.table(area= c("BA", "FA", "MI"),
dmean = c(30, 50, 200, 76, 467, 87, 98, 10, 240, 176, 89, 400, 340, 10, 40, 54, 89, 340, 205),
sex = c("F", "M"))


leg<- c("Breeding area", "Migration", "Feeding area") #to rename
dt$area<- factor(dt$area, levels = c("BA", "MI", "FA")) #to reorder

ggplot(dt, mapping = aes(y = dmean, x = area, color = sex, fill=sex))+
  geom_violin(alpha=.5,scale = "width",trim = FALSE, position=position_dodge(1))+
  ggtitle("Dive mean per area and sex")+
  scale_y_log10(breaks = c(10, 30, 50, 100, 200, 300, 400, 500)) +   
  scale_fill_discrete(name="Social class",
                      labels=c("Female", "Male"))+
  xlab("Habitat")+
  ylab("Dive depth (m)")+
  theme_bw()+
  scale_x_discrete(labels= leg)

And I tried a lot of things:

  scale_y_reverse(breaks = c(500, 400, 300, 100, 50,30, 10))+ #1
  scale_y_reverse()+ #2
  scale_y_continuous(trans = scales::reciprocal_trans(), trans= c(600, 500, 400, 300, 100, 50, 10))+ #3
  scale_y_continuous(trans = "reverse", breaks = unique(dt$dmean))+ #4
  scale_y_continuous(trans = "reverse")+ #5
  scale_y_discrete(limits = rev(levels(dt)))+ #6
  scale_y_discrete(limits = rev(levels(dt$dmean)))+ #7
  scale_y_discrete(limits = rev(levels(as.factor(dt$dmean))))+ #8
  scale_y_discrete(drop = FALSE)+ #9
  gplot(dt, mapping = aes(y = reorder(dmean, desc(dmean)), x = area, color = sex, fill=sex))+ #10
  dt<-dt %>% mutate(position = factor(dmean), 
                   position = factor(dmean, levels = rev(levels(dmean)))%>% #11
  ggplot(dt, mapping = aes(y = factor(dmean, levels=c(1:600)), x = area, color = sex, fill=sex))+ #12
  ggplot(dt, mapping = aes(y = forcats::fct_rev(factor(dmean)), x = area, color = sex, fill=sex))+ #13
  dt$dmean <- factor(dt$dmean, levels = rev(levels(dt$dmean)))+ #14

Someone know how to fix this? Thank you!


Solution

  • An answer has been provided here. Applying this to your question I was able to reverse the log axis by applying the transformation function in scale_y_continous:

    library("scales")
    reverselog_trans <- function(base = exp(1)) {
      trans <- function(x) -log(x, base)
      inv <- function(x) base^(-x)
      trans_new(paste0("reverselog-", format(base)), trans, inv, 
                log_breaks(base = base), 
                domain = c(1e-100, Inf))
    }
    
    ggplot(dt, mapping = aes(y = dmean, x = area, color = sex, fill=sex))+
      geom_violin(alpha=.5,scale = "width",trim = FALSE, position=position_dodge(1))+
      ggtitle("Dive mean per area and sex")+
      scale_y_continuous(trans = reverselog_trans(10), breaks = c(10, 30, 50, 100, 200, 300, 400, 500))
      scale_fill_discrete(name="Social class",
                          labels=c("Female", "Male"))+
      xlab("Habitat")+
      ylab("Dive depth (m)")+
      theme_bw()+
      scale_x_discrete(labels= leg)
    

    enter image description here