为什么 ggplot2 不支持两个 y 轴?

时间:2022-07-28
本文章向大家介绍为什么 ggplot2 不支持两个 y 轴?,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

在前面

大猫终于毕业了!!!

emmm……你们是不是还在怀疑为什么关注列表中还有一个这样的up主。在这里和大家汇报一下,大猫前几个月在奋斗自己的博士毕业论文,现在终于通关啦,而且再过十几天就要迎来毕业典礼!所以这个不靠谱的up主现在又可以重启这个公众号啦。

在这里要感谢所有给大猫留言和加大猫微信的读者,和你们的讨论让我受益良多~毕业之后等大猫发毕业照23333

题:为什么ggplot2有这个硬伤?

稍微对ggplot2有所了解的小伙伴都知道,ggplot2中是无法同一张图中画出两个y轴的,也即,下面这张图用“正常”的ggplot是画不出来的(大猫会在最后给出一个奇技淫巧的实现办法):

为什么强大的ggplot2无法做到这种看似简单的任务呢?毕竟在几乎所有其他的统计软件中,两个y轴都很好的支持。例如SAS中,不仅可以画两个y轴,通过offset参数,这两个轴还可以拥有不同的起始高度!如下:

ggplot2的作者 Hadley 能力有限吗 ?当然不是,实际上,ggplot2的这个功能缺失是 Hadley 有意为之的。

W

hy ?

StackOverflow 中有一个帖子,名字就叫作“请问如何在一幅图中左侧和右侧各画一个y轴?”如下:

非常幸运的,这个问题得到了 Hadley 本人的回答,他说道:

Hadley: 我认为在同一个图中画两个分开的y轴是“具有严重缺陷”的(fundamentally flawed)。具体而言:

  • 它们是不可逆的。给定在图中的一点,你无法把它映射回原有的数据空间中。
  • 和其他选项相比,它们阅读起来更加困难。具体可以参考“ A Study on Dual-scale Data Charts”这篇文章。
  • 它们很容易受人操控、很容易误导他人,因为不同量纲之间的转换是主观的。
  • 它们太arbitrary了。为什么是2个轴呢?难道3个、4个不行吗?

Hadley 说的似乎很有道理,并且得到了题主的认可!我们可以看看最终题主接受的这个答案是怎么样的:

有时候客户想要两个y轴,但是这样做只会让他们的论证变得千疮百孔。我尊重并喜欢ggplot2对于“正确作图理念”的坚持。我相信ggplot2正在向大家普及什么是符合规范的数据可视化技巧。

B

ut ...

但是故事没完!虽然上面这个答案得到了非常多的票数,但也不乏反对的声音,例如下面的这四个评论:

“你(Hadley)能再具体阐释下你的观点吗?我认为把许多独立的变量画在同一个图中是一种特别简洁的方法(a compact way)。这也是一项被许多人所要求,并且广为使用的功能。” “@hadley。你说的大多数我都同意,但是确实有种情况必须要同时用到两个y轴:当一个变量拥有两个metric的时候。例如对于温度,我想同时显示摄氏和华氏。” “你(Hadley)的这个回答并不对大家有什么帮助,因为你没有解释什么是“重大缺陷”(fundamental flow)。如果有文献,请你引用起来。” “如果一个绘图包强制用户必须遵守某个规则,那么他就是“重大缺陷”的” “(Hadley)的回答是胡说八道(nonsense)。我被这个他的这个答案还有那么多支持给震惊了。Hadley 严重误解了 API 的设计原则,即任何 API 都应该是可选的。也就是说,我认为,能够同时画两个y轴是非常有用的功能。”

确实上面的这些批评意见很有道理——我可以不给客户看,但我自己在做数据分析的时候画给自己总行了吧?毕竟很多时候在做时间序列分析的时候,我们需要把多个不同量纲的变量画在同一个图中来快速获得变量之间的联动关系。退一万步讲:我可以不用,但你不能没有。

S

o ...

毕竟广大网友的智慧是无穷的,最终还是有人想出了一套使用ggplo2来画dual-y-scales的方法。只不过这个办法需要用到gtablegrid两个包,而且代码非常非常的长。其中涉及到很多ggplot2底层的知识,反正大猫自己是没有耐心看完全部代码,只是本着拿来主义直接就用。

由于代码比较复杂,大猫把代码不做讲解直接粘贴到文章中,感兴趣的小伙伴可以根据关键字在 StackOverflow 上搜索相关资料。