当然是ggplot2画,才好和ggtree兼容,你首先问自己,抛开树,你能右边吗?本身你有个矩阵,row的顺序要跟着树来,你可以先不管,先随意,这是y轴。那x轴呢?你矩阵里的数字,打点你总该会的,而点连线,同样column的数字打出来的点,就连在一起,你先按这个思路画出来,再来问后续的。

这是我在「知识星球」中的回答,然而小伙伴表示还是不懂。那么我来详细讲解一下:

首先我们读入一个FASTA数据:

require(treeio)

fasta <- system.file("examples/FluA_H3_AA.fas", package="ggtree")
aa <- read.fasta(fasta)

数据用treeio包里的read.fasta去读这个氨基酸序列,它有个好处是你直接as.character(aa[[i]])就是个字母的向量,方便比较。

n = length(aa)
d = matrix(NA, ncol=n, nrow=n)
nm = labels(aa)
rownames(d) = colnames(d) = nm

for (i in seq_len(n)) {
    for (j in seq_len(i)) {
        d[i, j] = mean(as.character(aa[[i]]) != as.character(aa[[j]]))
        d[j, i] = d[i, j]
    }
} 

这段代码生成了pairwise distance矩阵,你可以搞其它的统计量,都OK的。大家可以想一想,一般这种矩阵怎么可视化?用热图!热图用数字来填充颜色,而现在我们把数字当成x轴上的变量,然后打点,仅此而已,我们有没有办法画出来,当然可以。同样row的数值会在同一y轴上,如果是热图,同一column的数值会在同一x轴上,方便横向和纵向比较,而现在同一column的数值不在同一直线一了,因为我们打的点的位置使用了矩阵中的数值,同一column的点被拉扯到不同的位置上去了,所以为了能够比较或者是看清楚同一column上的点的走势,我们把同一column上的点用线条连接在一起。这就是小伙伴提问的图,就是这么画出来的,非常简单。我在「知识星球」里其实已经解答得很清楚了。


Continue reading

小伙伴说他写个CSV文件,名字就变了,无缘无故|就被改了,还有些名字被强加了X。我注意到了他写的对象是data.frame(d),这锅绝对是data.frame的。

我们可以试一下:

> d = matrix(rnorm(4), ncol=2)
> colnames(d) = c("A|B", "123")
> write.csv(data.frame(d))
"","A.B","X123"
"1",-0.601247669017546,0.802654193340092
"2",-0.128752028398414,0.430829592244036

没错,自己给变了。


Continue reading

小伙伴提出了上面的问题,点不能够打到violin里面去,即使加了aes(group=color)强行分组也不行。这个照理第一感觉都会觉得可以,但试一下都会发现不行。

library(ggplot2)
d = subset(diamonds, color %in% c("D", "E"))
ggplot(d, aes(cut, carat, fill=color, color=color)) + 
    geom_violin(alpha=.3) + geom_jitter(width=.05, alpha=.5)


Continue reading

大家是否还记得我写的文章《画个小圈圈》?里面吐槽了ggpubr这个包的存在是制造混乱,徒增学习成本。我们知道ggplot2包里有个qplot函数,而在《ggplot2》的第一版中,hadley先用了一章介绍qplot,再介绍grammar of graphics,然后这个qplot就被吐槽,先入为主,给学习grammar of graphics,学习ggplot2语法制造了不必要的麻烦。然后如果你看《ggplot2》第二版,你就会发现qplot这一章被删掉了。我说ggpubr制造混乱,徒增学习成本并不是为了吐槽某公众号,而是实事求是。

我并不反对封装,我并没有强迫症说大家一定要用ggplot2图形语法,而不能封装函数,我想我在《画个小圈圈》已经说得很清楚了,封装画图的包,按我的观点是要么卖了数据处理的专业知识,要么卖了画图的专业知识。如果一个包做的封装太过于简单,像ggpubr这种,数据必须是用户整理好的data.frame,而画图只是简单的两三个图层的叠加,那么当然可以减少你敲键盘输入,然而影响了初级用户学习ggplot2,复杂的东西,我们当然想要用封装好的函数,等你自己啥都搞懂了,老板都要跟你掀桌子了。简单的东西也可以封装,减少输入嘛,只是特别不适用于ggplot2的图层,简单的设定你写个主题,我都举双手赞成,但两三个图层的简单拼凑我不支持,因为图层是积木,大家学习就是要对积木熟悉,然后才能搭出复杂的东西出来。特别简单的图层叠加正是你熟悉积木的时候,你不多敲点键盘,做为练习,又怎么能做出稍复杂点的东西呢?


Continue reading

很多人都在学ggplot2,也有很多「高手」,比如你搜索「精通ggplot2」,你甚至会看到各种「从入门到精通」的课程,然而都是各种照猫画老虎的入门菜谱而已,当然广大群众去上课也可能只是为了求菜谱好在需要的时候,可以copy-paste而已。

ggplot2学习容易,因为无非是图层叠加,而图层的参数一致性非常好,网上也有很全的文档。然而要深入很难,比如你想干点什么是ggplot2自身没有支持的,你需要自己去hack,需要用到更底层的东西的时候,一般情况下,会无从入手,尝试之后才知道什么叫绝望!因为ggplot2套路实在是太深。

正如我在《听说你还不会画热图》吐槽的,有些所谓的「高手」实际上连ggplot2底层是什么都不知道!然后可以把ggplot2吹上天。很多人根本不知道当你打下ggplot这个命令的时候,到底发生了什么?要理解ggplot2并不容易,正如前面所说「套路太深」,没有金钢钻,读不了它的代码,有没有一个简单点的包,能够读懂代码,并且有助于理解ggplot2呢?我想我的meme包就非常好,虽然仿的有点肤浅,然而胜在简单,看过下面这两篇文章的,都知道这个包在做什么。


Continue reading

I am trying to add a scale to an unrooted tree with geom_treescale, but when I use it, the tree completely collapses and I am not able to set anything that fix it. Anybody has any idea on how to do it ?

google group里的问题,说他加geom_treescale之后,树被压缩了,由于他没有给出可重复性的例子,所以我们并不知道情况到底有多么糟糕,但这种情况是可能发生的,因为加treescale这种东西,默认情况下geom_treescale会自己去计算该加多大的scale bar,该放在什么位置上,而这种默认情况是基于rectangular布局来的,在假设的情况下,都不可能尽善尽美,假设不成立的情况下当然有可能搞得很差。


Continue reading

有小伙伴在说可以用par(mar)来设置画图的margin,但不能应用于ggplot2,这个可能很多新手都会很困扰,可能需要一段时间的探索之后,才能发现原来是用theme来设定。

这当然你可以归结于说ggplot2和base plot是不同的东西,但从实质画图参数这一点而言,并没有什么同与不同,无非是设置的方式不同而已,而这种方式都是人定义的,我们完全可以人为定义它们兼容。


Continue reading

Author's picture

Guangchuang Yu

a senior-in-age-but-not-senior-in-knowledge bioinformatician

Postdoc researcher

Hong Kong