前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >R画图y轴范围太大时,如何局部压缩坐标轴?

R画图y轴范围太大时,如何局部压缩坐标轴?

作者头像
实验盒
发布2021-09-22 12:20:39
3.6K1
发布2021-09-22 12:20:39
举报
文章被收录于专栏:实验盒实验盒

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

比如,下面这张 GWAS 曼哈顿图中(来自https://doi.org/10.1371/journal.pgen.1006594.g001),y 轴的值是由每一个 SNP 进行关联分析算出的 p 值再进行 -log10(P) 转换后得到的。图中存在非常多显著的 SNPs,当中最显著的 -log10(P) 甚至达到了 150 左右。不过,这样画图的话,红线附近会有很多显著的 SNPs 会因为 y 轴太大而显得不怎么显著。

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

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

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

代码语言:javascript
复制
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()

得到的图是这样的,不同组别的值差别非常大,y 轴范围很大:

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

代码语言:javascript
复制
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倍:

代码语言:javascript
复制
ggplot(shiyanhe, aes(x = group, y = value))+
  geom_point()+
  coord_trans(y = squash_axis(5, 95, 10))

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

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

代码语言:javascript
复制
ggplot(shiyanhe,aes(x = group, y = value))+
  geom_point()+
  coord_trans(y = squash_axis(1, 99, 30))

备注

注意,参考的 Rpub 原文使用 scale_y_continuous()进行转换:

代码语言:javascript
复制
ggplot(shiyanhe, aes(x = group, y = value))+
  geom_point()+
  scale_y_continuous(trans = squash_axis(5, 95, 10))

然而这样操作会报错:

代码语言:javascript
复制
ERROR while rich displaying an object: Error in x[isq] <- from + (x[isq] - from) * factor: NAs are not allowed in subscripted assignments

使用 coord_trans 的话,就可以画出图。

参考

  1. https://rpubs.com/huanfaChen/squash_remove_y_axix_ggplot
  2. https://stackoverflow.com/questions/61010786/error-nas-are-not-allowed-in-subscripted-assignments-while-using-squash-axis-i
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-03-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 实验盒 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 备注
  • 参考
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档