4

I want to skip part of my y-axis for a dataset with most values between -10 and 100, and then a few at 400 again. So I want to squeeze this empty area. I already am using facet grid in my plot for 3 different scenario's, so I would prefer to just "squash" the Y axis and not create mutltiple plots.

I found the "squash_axis" function on RPubs (https://rpubs.com/huanfaChen/squash_remove_y_axix_ggplot_), which may be able to help me. But I can not get it to work with my own dataset, and not even with the example dataset.

Example dataset (mine looks quite similar except that there is another column with time)

dat <- data.frame(group=rep(c('A', 'B', 'C', 'D'), each = 10), 
                 value=c(rnorm(10), rnorm(10)+100)
                 )

Then the Squash axis function:

require(ggplot2)
squash_axis <- function(from, to, factor) { 
    # A transformation function that squashes the range of [from, to] by factor on a given axis 

    # Args:
    #   from: left end of the axis
    #   to: right end of the axis
    #   factor: the compression factor of the range [from, to]
    #
    # Returns:
    #   A transformation called "squash_axis", which is capsulated by trans_new() function

  trans <- function(x) {    
      # get indices for the relevant regions
      isq <- x > from & x < to
      ito <- x >= to

      # apply transformation
      x[isq] <- from + (x[isq] - from)/factor
      x[ito] <- from + (to - from)/factor + (x[ito] - to)

      return(x)
  }

  inv <- function(x) {

      # get indices for the relevant regions
      isq <- x > from & x < from + (to - from)/factor
      ito <- x >= from + (to - from)/factor

      # apply transformation
      x[isq] <- from + (x[isq] - from) * factor
      x[ito] <- to + (x[ito] - (from + (to - from)/factor))

      return(x)
  }

# return the transformation
  return(trans_new("squash_axis", trans, inv))
}

And the plot from the example:

ggplot(dat,aes(x=group,y=value))+
  geom_point()+
  scale_y_continuous(trans = squash_axis(5, 95, 10))

I then get the error: Error in x[isq] <- from + (x[isq] - from) * factor : NAs are not allowed in subscripted assignments

I don't understand because there are no NAs in my data and not in the example data either.

What is going on?

1 Answers1

4

Using browser() if figured out that the problem arises in the inv part of the squish transformation. But I could only guess what the reason is, probably has to do with how the breaks are set (??). However, instead of applying the transformation inside scale_y_continuous I tried applying it via coord_trans ... et voila, worked:

library(ggplot2)

dat <- data.frame(group=rep(c('A', 'B', 'C', 'D'), each = 10), 
                  value=c(rnorm(10), rnorm(10)+100)
)

squash_axis <- function(from, to, factor) { 
  # A transformation function that squashes the range of [from, to] by factor on a given axis 

  # Args:
  #   from: left end of the axis
  #   to: right end of the axis
  #   factor: the compression factor of the range [from, to]
  #
  # Returns:
  #   A transformation called "squash_axis", which is capsulated by trans_new() function

  trans <- function(x) {    
    # get indices for the relevant regions
    isq <- x > from & x < to
    ito <- x >= to

    # apply transformation
    x[isq] <- from + (x[isq] - from)/factor
    x[ito] <- from + (to - from)/factor + (x[ito] - to)

    return(x)
  }

  inv <- function(x) {

    # get indices for the relevant regions
    isq <- x > from & x < from + (to - from)/factor
    ito <- x >= from + (to - from)/factor

    # apply transformation
    x[isq] <- from + (x[isq] - from) * factor
    x[ito] <- to + (x[ito] - (from + (to - from)/factor))

    return(x)
  }

  # return the transformation
  return(scales::trans_new("squash_axis", trans, inv, domain = c(from, to)))
}

ggplot(dat,aes(x=group, y = value))+
  geom_point()+
  coord_trans(y = squash_axis(5, 95, 10))

Created on 2020-04-03 by the reprex package (v0.3.0)

stefan
  • 20,714
  • 3
  • 13
  • 26