获取更好阅读体验:
单细胞Seurat DimPlot优化,添加迷你坐标轴、添加注释标签、手动调整标签位置。
前言
前面有篇文章 爆改DimPlot, 解决label.box背景色不统一的问题。
目前我还存在几个问题:
- 第一,标签框如何设置透明背景;
- 第二,对于同一亚群却分布多个区域的情况,标签往往被计算在多个区域之间,但标签附近可能没有它对应的细胞;
- 第三:如何支持手动修改标签位置。
- 第四,如何将坐标轴改为迷你坐标轴。
- 第四五没有支持tSNE降维
今天解决这些问题,所有测试数据和代码文末获取。
开发过程
载入数据和函数,需要安装我编写的工具包。
# remotes::install_github("JiahaoWongg/bioinfobaidu.utils")
library(bioinfobaidu.utils)
loadp(Seurat)
load2("data/obj.RData")
source("DimPlot2.R")
先看看原版的图片:
DimPlot(obj, group.by = "Celltype", label = TRUE, label.box = TRUE)
加个色板,色板见文章开始提到的那篇文章里。
DimPlot(obj,
group.by = "Celltype",
label = TRUE,
label.box = TRUE,
cols = col.cluster2.1
)
存在一些问题:
- 细胞颜色跟标签框背景颜色不统一(忽视这一条,现在其实是统一的,之前不统一是因为我把色板只给了
color
而没有给fill
😅,原函数直接给参数cols
就行了) - 标签框背景无法设置透明,如果亚群细胞太少就直接覆盖掉了
- 标签出界
为了解决标签出界的问题,我先把坐标轴换为迷你坐标轴。思路就是先清空所有坐标轴,再提取降维数据,根据数据范围确定轴标签和箭头的位置。分别使用geom_segment
和annotate
来实现。
另外,为了防止在设置图片长宽时迷你坐标轴xy轴长度变得不一样,将坐标长宽比进行锁定:
p <- p + theme_blank() + coord_fixed(ratio = 1)
替换为迷你标签功能也包装为函数sc_mini_axis
:
# 更换迷你坐标轴
p <- DimPlot(obj,
group.by = "Celltype",
label = TRUE,
label.box = TRUE,
cols = col.cluster2.1
)
sc_mini_axis(p, obj)
接下来设置透明标签框背景,搜了一下,貌似没有直接设置透明背景的方法,但是有人提出可以设置透明度。天才!随便设个颜色,透明度设为0就行!
但是无法基于DimPlot修改了,因此需要重新手动绘制这张图,这在上篇文章DimPlot2
也已展示,因此直接展示标签框背景相关的代码。
并且,这次把sc_mini_axis
功能也加入到DimPlot2
里,但是默认不绘制迷你坐标轴,因为不排除某些情况下坐标轴位置出错。
if(label.fill == "auto"){
p <- p + geom_label(data = label.data, aes(label = Cluster, x = x.center, y = y.center, fill = Cluster), size = label.cex)
} else if(label.fill == "none"){
p <- p + geom_label(data = label.data, aes(label = Cluster, x = x.center, y = y.center), size = label.cex, fill = alpha(c("red"), 0))
} else {
p <- p + geom_label(data = label.data, aes(label = Cluster, x = x.center, y = y.center), size = label.cex, fill = label.fill)
}
这里有三个选项:
auto
:自动跟随细胞亚群的颜色,相当于也设置为默认的情况;并且标题也增加统计细胞数的功能,默认标题为All
加统计值,细胞类型可通过参数title
修改。
DimPlot2(obj, group.by = "Celltype", mini.axis = TRUE)
none
:背景不添加颜色,即透明色。
DimPlot2(obj, group.by = "Celltype", mini.axis = TRUE, label.fill = "none", title = "Macrophages")
看起来还蛮好看了,细胞也不被遮挡了。
特定颜色
: 除此之外,背景还可以设置为特定的颜色,一般就是白色了。
DimPlot2(obj, group.by = "Celltype", mini.axis = TRUE, label.fill = "white")
也怪好看的。
接下来解决后面两个问题:
- 第二,对于同一亚群却分布多个区域的情况,标签往往被计算在多个区域之间,但标签附近可能没有它对应的细胞;
- 第三:如何支持手动修改标签位置。
对于第二个问题,比如上图的两大B细胞亚群,就是这个情况。目前没想到合适的解决办法,实现起来比较麻烦。所以索性直接以解决第三个问题的方式解决第二个问题。
实现起来也简单,在绘图前已经生成了包含标签位置信息的数据框,直接进行修改就行了。
传入一个列表参数,每个元素为对应亚群的坐标位置。
DimPlot2(obj2,
group.by = "Celltype",
mini.axis = TRUE,
label.fill = "none",
pos.manual = list("B cell" = c(-6.8, 14.3))
)
不仅如此,这也直接解决了添加细胞类型标签时标签重叠的问题,有时为了不重叠只能放弃标签,实则可惜。
最后也支持了tSNE降维,也支持去除图例。
DimPlot2(obj,
group.by = "Celltype",
reduction = "tsne",
mini.axis = TRUE,
label.fill = "white"
)
DimPlot2(obj,
group.by = "Celltype",
reduction = "tsne",
mini.axis = TRUE,
label.fill = "white",
legend = FALSE)
除此之外,迷你坐标轴默认是在降维图的外侧的,也可以移动位置使得离中心更近,图片更紧凑。通过参数pos.just
调节,默认为1,越大离中心越近。
DimPlot2(obj,
group.by = "Celltype",
reduction = "tsne",
mini.axis = TRUE,
label.fill = "white",
legend = FALSE,
pos.just = 2
)
接下来使用deepseek
详细解释下和
这两个函数的功能。
提示词:详细解释和评价以下函数。
以下是对 sc_mini_axis
和 DimPlot2
两个函数的详细解释和评价。这两个函数主要用于单细胞数据的可视化,特别是在降维空间(如 UMAP 或 t-SNE)中绘制细胞群,并添加小型坐标轴以增强可读性。
1. sc_mini_axis
函数
功能概述
sc_mini_axis
函数用于在降维可视化图中添加一个小型坐标轴,以指示降维空间(如 UMAP 或 t-SNE)的方向。它通过绘制箭头和标签来表示坐标轴的方向,并允许用户自定义箭头长度、标签大小等参数。
参数解释
p
: 输入的ggplot
对象。obj
: 单细胞数据对象(如 Seurat 对象),包含降维嵌入信息。reduction
: 降维方法,默认为 “umap”,也可以是 “tsne”。pos.just
: 坐标轴位置的调整参数,默认为 1。label.just
: 标签位置的调整参数,默认为 0.92。axis.len
: 坐标轴的长度比例,默认为 0.2。axis.label.cex
: 坐标轴标签的字体大小,默认为 3。arrow.len
: 箭头的长度,默认为 0.3。arrow.size
: 箭头的粗细,默认为 0.5。
函数逻辑
- 初始化图形:
- 使用
theme_blank()
移除默认的主题样式。 - 使用
coord_fixed(ratio = 1)
确保图形的纵横比为 1,避免坐标轴变形。
- 使用
- 提取降维坐标:
- 从
obj
中提取降维嵌入信息(如 UMAP 或 t-SNE 的二维坐标)。
- 从
- 计算坐标轴位置:
- 根据数据的范围(
range_x
和range_y
)计算坐标轴的起点和终点。 - 使用
segTable
数据框存储坐标轴的起点、终点以及箭头的方向。
- 根据数据的范围(
- 绘制坐标轴:
- 使用
geom_segment()
绘制坐标轴线段。 - 使用
arrow()
函数添加箭头。
- 使用
- 添加坐标轴标签:
- 根据降维方法(UMAP 或 t-SNE)添加对应的坐标轴标签。
- 使用
annotate("text")
在适当位置添加标签。
- 返回图形:
- 返回添加了小型坐标轴的
ggplot
对象。
- 返回添加了小型坐标轴的
评价
- 优点:
- 增强了降维图的可读性,特别是在没有默认坐标轴的情况下。
- 提供了丰富的参数,允许用户自定义坐标轴的长度、箭头大小和标签位置。
- 代码结构清晰,易于扩展和修改。
- 缺点:
- 坐标轴的位置和长度是固定的,可能不适用于所有数据集。
- 对于非 UMAP 或 t-SNE 的降维方法,需要手动修改代码。
2. DimPlot2
函数
功能概述
DimPlot2
函数用于在降维空间(如 UMAP 或 t-SNE)中绘制单细胞数据的分群结果。它支持自定义颜色、标签、图例等,并可以调用 sc_mini_axis
函数添加小型坐标轴。
参数解释
obj
: 单细胞数据对象(如 Seurat 对象)。group.by
: 用于分群的元数据列名。title
: 图形的标题,默认为 “All”。cols
: 分群的颜色映射,默认为col.cluster2.1
。reduction
: 降维方法,默认为 “umap”。cex
: 图形中文本的全局缩放比例,默认为 20。size
: 点的大小,默认为 0.3。label.fill
: 标签的背景填充,默认为 “auto”label.cex
: 标签的字体大小,默认为 3。mini.axis
: 是否添加小型坐标轴,默认为FALSE
。legend
: 是否显示图例,默认为TRUE
。pos.manual
: 手动指定标签位置的列表,默认为NULL
。
函数逻辑
- 加载依赖包:
- 使用
loadp()
加载所需的 R 包(如Seurat
、dplyr
、ggplot2
等)。
- 使用
- 提取降维坐标和分群信息:
- 从
obj
中提取降维嵌入信息和分群信息,并存储在pdata
数据框中。
- 从
- 计算分群中心:
- 使用
kmeans
算法计算每个分群的中心点,并存储在label.data
数据框中。 - 如果提供了
pos.manual
,则手动调整标签位置。
- 使用
- 绘制图形:
- 使用
ggplot()
创建基础图形。 - 使用
geom_point()
绘制散点图,颜色由分群信息决定。 - 使用
scale_color_manual()
设置颜色映射。 - 添加坐标轴标签和标题。
- 使用
- 添加分群标签:
- 根据
label.fill
参数的值,使用geom_label()
添加分群标签。 - 如果
label.fill
为 “auto”,则使用分群颜色填充标签背景。 - 如果
label.fill
为 “none”,则使用透明背景。
- 根据
- 调整图例和主题:
- 使用
guides()
调整图例样式。 - 如果
legend
为FALSE
,则隐藏图例。
- 使用
- 添加小型坐标轴:
- 如果
mini.axis
为TRUE
,则调用sc_mini_axis()
函数添加小型坐标轴。
- 如果
- 返回图形:
- 返回最终的
ggplot
对象。
- 返回最终的
评价
- 优点:
- 提供了高度可定制的单细胞数据可视化功能。
- 支持自动和手动调整分群标签位置,适应不同的数据分布。
- 集成了
sc_mini_axis
函数,增强了图形的可读性。 - 代码结构清晰,易于扩展和修改。
- 缺点:
- 对于大规模数据集,
kmeans
计算分群中心可能会较慢。 - 部分参数(如
cols
和label.fill
)的默认值可能需要根据具体数据集调整。
- 对于大规模数据集,
可见deepseek
描述的非常清晰,当然前提你代码写的可读性和逻辑非常高(傲娇脸😉)。
它提到的缺点也是我担心的地方,就是迷你坐标轴和轴标签的位置有时候可能会错位,不过我都提供了手动修改的参数,可以参考默认值进行多次调整即可。
整合这么多功能实属不易,不过也终于解决了所有我对DimPlot
不满意的地方,再也不膈应了。
推荐以下我的R语言直播课
有些R语言基础比较薄弱的同学可以对代码不太熟悉,也鉴于很多找我做分析的同学很多都想学R语言,因此我打算以后每月开一期零基础R语言直播课
-零基础R语言直播课第一期,欢迎咨询!.
3月份的开班时间是19号这周三
,优惠非常多,感兴趣的可以直接联系我。
关注公众号 【生信摆渡】,后台回复 【DimPlot2】 即可获取所有代码和测试数据。