本来没有打算写这一篇的,因为在一幅图表中使用双坐标轴确实不是一个很好地习惯,无论是信息传递的效率还是数据表达的准确性而言。
但是最近有好几个小伙伴儿跟我咨询关于ggplot2的次坐标轴问题,平时的一些业务分析中,有些场景出于数据呈现的需要,或者阅读习惯等,往往需要在一幅图中呈现两个量级不等的坐标。
所以我觉得这一篇推送很有必要,确实在最新版的ggplot2(ggplot 2.2.0以上版本)中,已经加入了次坐标轴参数,通过这个次坐标轴的转换,我们可以模拟出不同数量级的次坐标轴效果。
因为其中用到了英文月份简写,这里对系统日期显示格式做了特殊设置:
1 | 复制代码lct <- Sys.getlocale("LC_TIME") |
生成作图数据
作图数据1——单序列柱形图
1 | 复制代码data1 <- data.frame( |
作图数据2——二分类折线图(带散点)
1 | 复制代码data2 <- data.frame( |
以下是整个过程代码,基本是司空见惯的内容,这里不做过多解释,仅提示其中两处重点,注意第二行geom_line内的y参数赋值以及第四行的scale_y_continuous语句:
1 | 复制代码ggplot() + |
这段代码与我们经常用的有两点不同:
第一次自定义映射——折线度量数据的映射转换:
geom_line(geom_point,因为点图是附属于折线图,仅做修饰之用,这里只重点说折线图层)中的y参数指定的对象使用了一个统计变换函数,rescale函数其实很好理解,就是将一个数值向量按照给定的另一个数值向量的极差(range),等比例标准化。
如果你知道如何将一组向量按照0~1标准化的话,那么这个函数就不难理解 ,其实就是将标准化的尺度给了一个自定义的范围。
因为在ggplot2标度系统中,不容许在一个图形中出现两个量级不等的标度(一山不容二虎),但是想要提供度量不等的次坐标轴,折中的方法就是,将次坐标轴的所有量级按照主坐标轴的量级进行缩放(如果次坐标轴量级大于主坐标轴,那么就是等比例放大,如果比主坐标轴量级大则缩小)。
针对本例而言,就是将折线图的数据源量级(0.00.5)放大到035的区间上,所有的单个指标的缩放比例都是相同的,这样你在图上就不会感受到太大的视角误差。
1 | 复制代码value1<-data1$Value |
这是最终的折现结果,在geom_line中使用rescale函数实际上就是做的这种度量重新自定义映射的过程。
第二次自定义映射——次坐标轴刻度标签转换:
仅仅做以上步骤还不够,因为这只能保障次坐标轴的数据点位置相对于整个坐标系统而言,不会出现太大的视觉误差,但是现在的问题是这个图形对象中有两套不同的度量,所以必须声明不同的y轴度量标准,也就是y轴的刻度线及刻度标签,刻度标签的定义就是本案例的第二个重点,它仍然是通过rescale函数进行了一次度量的重新映射。
不过这次映射的过程刚好是相反的操作,即将之前已经被标准化到050区间内的原始度量标签通过rescale函数再次标准化到00.5区间内,这样保障显示在次坐标轴上的度量是符合原始数据极差范围呢。
说的有些拗口了,实际上以上过程思路很简单,就是先将数据映射到正确的位置,然后将次坐标轴刻度线度量标签再按照真实极差进行分布,一虚一实,正好达到了模拟效果。
1 | 复制代码scale_y_continuous( |
思路大体上就是这样子,希望这一篇文章可以帮到大家!
在线课程请点击文末原文链接:
Hellobi Live | R语言可视化在商务场景中的应用
往期案例数据请移步本人GitHub:
github.com/ljtyduyu/Da…
本文转载自: 掘金