下面这张吐槽LaTeX的图,太深得我心。

而ggplot2这种文本跑出界的事情,也太常见,以至于我在ggtree的FAQ专门指出来,要用xlim给x轴分配多点空间,这是由于数据是数据空间,而文本是像素空间。你画图的画布由数据空间决定,然后文本就从指定的位置(除了坐标,还取决于你align的方式和adjustment微调)开始打出来,一不小心就打出界了。这一点我在FAQ里,除了告诉你用xlim解决之外,我也给出了上面的解释,所以我一直强调,不要以为我在教ggtree,我其实是在教ggplot2。

后面就有人问了ggplot2字体溢出的事情,他所遇到的溢出,似乎更不应该发生,因为是坐标轴上的字体溢出,然而产生的原因是一样的,解决方案也是一样的,请用力猛戳《ggplot2字体溢出的那点破事》。

事情还可以更复杂些,我们知道ggtree有个facet_plot的函数,可以让你把不同的图层和进化树关联起来,这时候就有用户提出来,画进化树的那个分面tip label的字体溢出了,怎么能够单独给Tree panel设置xlim,于是我就写了xlim_tree这个函数来解决,《xlim_tree: set x axis limits for only Tree panel》。你们又以为我在教ggtree了,其实我又在教ggplot2,这个问题当然因为xlim_tree函数名就已经说明了是用于ggtree的,所以没看出门道来也正常。但我随后就又写了一篇,《facet_plot: 加图层到特定的分面上》,并且给出了xlim_expand函数,可以让你自由地设置任意分面的xlim,大家肯定还是没看出来,这和ggplot2有什么关系。我明说都不一定有人看,更何况没明说,还需要拐弯想一下的,肯定没人会想到。

不要以为ggtree的facet_plot画的是不同的图层,而你用ggplot2分面画的是同一数据的不同子集,没有本质区别。如果你在分面的时候用的是scales="free_x",就有可能会出现有些分面正常,有些分面则会有《ggplot2字体溢出的那点破事》这种情况。这时候xlim()已经不能用了,因为你的scales是free的,你想要的是单独为字体溢出的分面设置xlim,解决方案就是我给出的。

内行看门道,这个expand_xlim,我在《facet_plot: 加图层到特定的分面上》里已经说了,其实就是在特定的分面上加图层,这个图层把画布撑大,但这个图层你看不见。因为它不会出来visible的东西(比如点和线),用的是geom_blank,顾名思义,它啥都不画。

然后虽然我这里讲的是xlim,你应该知道怎么搞ylim了。

沿着这个思路,事情还可以更进一步,在《映射变量给axis上色》一文中,其实我们就是用theme(element_text(color=COLOR_VECTOR))这样来给axis上色。但上色容易,想要给这个上色加个legend却不容易。解决的突破口就在于「一双看不见的手」。我们可以通过某个变量去上色打印文本, geom_text(aes(color=VAR)),这样就可以出来个文本按某个变量上色的legend。然而这个geom_text的图层是我们不愿意有的,我们并不想打印这些字,但我们想要它的legend。应用「看不见的手」的思路,我们打印字,但让这些字看不见,设置alpha=0,得以解决。当然这样legend也会看不见,我们通过修改legend,华丽丽地就给你的图穿上了皇帝的新衣。

电梯