用 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