Posted on

用 R 画图的时候,如果 y 轴存在个别非常大或非常小的值,或者当中的数值存在非常大差异的时候,画出的图很容易产生误导效果,使人忽略当中某一部分信息。

针对这种 y 轴范围太大、有一部分点与其他点差距非常大的情况,可以考虑压缩/压扁 y 轴。删除 y 轴中没有点的部分也是可以,但个人更倾向于直接对 y 轴进行缩放,把偏离比较大的区域压扁。

RPub 上有一篇文章介绍了一个缩放的函数(https://rpubs.com/huanfaChen/squash_remove_y_axix_ggplot) ,但当中有个小问题。这里小修改了一下。

首先生成一个示例数据,直接用 ggplot2 画图:

library(ggplot2)

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

ggplot(shiyanhe, aes(x=group, y=value)) + geom_point()

接下来构建一个 squash_axis 函数来实现坐标轴压缩功能,这个函数需要使用 scales 包:

library(scales)

squash_axis <- function(from, to, factor) { 
    # Args:
    #   from: left end of the axis
    #   to: right end of the axis
    #   factor: the compression factor of the range [from, to]

  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))
}

然后就可以在 ggplot 画图时的 coord_trans 使用这个函数。参数 from 和 to 是要压缩的范围, factor 是要压缩的倍率。比如要把 5 到 95 范围的 y 轴压缩 10倍:

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

这样画出的图,就能看清每个组别中各个点的分布:

把 1 到 99 范围的 y 轴压缩 30 倍:

ggplot(shiyanhe, aes(x=group, y = value))+
  geom_point()+
  coord_trans(y = squash_axis(1, 99, 30))

转自:https://zhuanlan.zhihu.com/p/358781655

发表评论

邮箱地址不会被公开。 必填项已用*标注