画圈圈

问题来自于技能树的公众号,简书和知乎上也有,可见链接:

使用ggplot画出带圆圈的tsne聚类图 - 简书

在PCA,单细胞的降维聚类分析中,我们将高维的数值映射到二维散点上,如果结果够好,我们会看到几群相互分离的散点群,而为了能够更好的展示,我们想尝试把这些分为一类的散点,用一个圈给他框起来。

在上面的示例中我们能看到可以用stat_ellipse来给这些散点画圈。

比如:我们对IRIS的数据做tsne

1
2
3
4
5
6
7
8
9
10
11
library(Rtsne)
iris_unique <- unique(iris) # Remove duplicates
iris_matrix <- as.matrix(iris_unique[,1:4])
set.seed(42) # Set a seed if you want reproducible results
tsne_out <- Rtsne(iris_matrix) # Run TSNE


# Show the objects in the 2D tsne representation
library(ggplot2)
tsne_plot <- data.frame(x = tsne_out$Y[,1], y = tsne_out$Y[,2], col = iris_unique$Species)

用来绘图的数据tsne_plot有三列:

1
> tsne_plot[1:6,1:3]
          x         y    col
1 -15.79436 -6.776711 setosa
2 -18.12043 -6.231470 setosa
3 -18.26108 -7.311696 setosa
4 -18.52094 -7.087130 setosa
5 -15.77855 -7.221474 setosa
6 -14.00867 -7.269801 setosa

前两列是tsne的坐标,第三列是分类变量,类似于单细胞中的cluster

因此,很容易就能发现,我们可以这样绘制:

1
2
3
ggplot(tsne_plot, aes(x, y, color = col)) +
geom_point() +
stat_ellipse(level = 0.9)

调整stat_ellipse中的level可以让圈更大或者更小。

但是,假如我们只想对某些cluster画圈?又不想直接给原始数据删了怎么弄?

答:很容易,熟悉ggplot多类型绘图拼图映射的一定第一时间就能想到,那就是在stat_ellipse中修改映射,同时,还可以对每个特定群修改参数,还能加上颜色覆盖和透明。

1
2
3
4
5
6
7
8
ggplot(tsne_plot, aes(x, y, color = col)) +
geom_point() +
stat_ellipse(level = 0.9,geom = "polygon",alpha = 1/5,data = subset(tsne_plot,col=="setosa")) +
stat_ellipse(level = 0.8,geom = "polygon",alpha = 1/5,data = subset(tsne_plot,col=="versicolor")) +
stat_ellipse(level = 0.7,geom = "polygon",alpha = 1/5,data = subset(tsne_plot,col=="virginica")) +
theme_classic() +
theme(panel.background = element_blank(),
panel.grid = element_blank())

由此,在单细胞的降维聚类里面,手动提取umap坐标和cluster,就能想给哪个群画圈,就给哪个群画圈了,再也不用去PPT或者AI里面手动框了。