jjAnno 重大更新强势来袭!
向死而生
1引言
前面刚发布的 jjAnno 添加各种注释,无论是自动添加和自定义添加都需要用户提供具体的坐标信息,似乎看起来并不是那么 优雅。
局限:
尤其是当你给具有不同数量的不同组别添加注释时只能自己一个个去指定对应的坐标。还是非常的不方便的。
改进:
这里于是进行了改进,提供了一种类似于 映射(mapping) 的形式,可以自动进行分组注释, 你 只需要提供一列分组信息 即可。这样可以节约你的大量时间和精力。主要参数为 aesGroup 和 aesGroName, 前者为
逻辑变量
,判断你是否开启自动按组别注释,后者则是映射的变量名(列名)
。
Note 1:
首先确保你的分组顺序和图的顺序保持一致。 关闭参数 clip (coord_cartesian(clip = 'off'))
。如果遇到图显示不完全,你可以扩展图形边缘区域来解决。
Note 2:
mapping operation 可以用在以下函数中:
annoPoint2 annoRect annoSegment
Others:
此外 jjAnno 还增加了 annoPoint2 函数和 annoTriangle 函数以及其它有趣的功能,前者是基于 annoPoint 函数做的一些改进和升级,后者可以添加三角形注释。
参考手册见:
https://junjunlab.github.io/jjAnno-manual/mapping-introduction.html
以下将详细介绍新的功能的使用示例。
2Basic plot
Let's make a simple dot plot:
# load data
dot_data <- read.delim('gene-dot.txt',header = T) %>%
arrange(class)
# check
head(dot_data,3)
# cell gene class mean.expression percentage
# 1 1b CoelEpi GATA4 DMRT1 Early supporting 0.3749122 36.03614
# 2 1b CoelEpi GATA4 CPA2 Early supporting 0.7495705 95.82235
# 3 1b CoelEpi GATA4 GPR37 Early supporting 0.1604790 95.79420
# colnames
colnames(dot_data)
# [1] "cell" "gene" "class" "mean.expression" "percentage"
unique(dot_data$cell)
# [1] "1b CoelEpi GATA4" "2a Early somatic" "2b ESGC male" "2b ESGC female"
# [5] "2c PreGC-I" "2d Sertoil" "3a Early sPAX8" "3b Gi"
# add cell group
dot_data$cellGroup <- case_when(
dot_data$cell %in% c("1b CoelEpi GATA4", "2a Early somatic", "2b ESGC male") ~ "cell type1",
dot_data$cell %in% c("2b ESGC female", "2c PreGC-I", "2d Sertoil") ~ "cell type2",
dot_data$cell %in% c("3a Early sPAX8", "3b Gi") ~ "cell type3"
)
We should make the order to be shown correctly:
# order
dot_data$gene <- factor(dot_data$gene,levels = unique(dot_data$gene))
Plot:
# plot
pdot <-
ggplot(dot_data,aes(x = gene,y = cell)) +
geom_point(aes(fill = mean.expression,size = percentage),
color = 'black',
shape = 21) +
theme_bw(base_size = 14) +
xlab('') + ylab('') +
scale_fill_gradient2(low = 'white',mid = '#EB1D36',high = '#990000',
midpoint = 0.5,
name = 'Mean expression') +
scale_size(range = c(1,13)) +
theme(panel.grid = element_blank(),
axis.text = element_text(color = 'black'),
aspect.ratio = 0.5,
plot.margin = margin(t = 1,r = 1,b = 1,l = 1,unit = 'cm'),
axis.text.x = element_text(angle = 90,hjust = 1,vjust = 0.5,
face = 'italic')) +
coord_cartesian(clip = 'off')
pdot
Or you can load the test data in jjAnno package:
library(jjAnno)
data("pdot")
Here we use column "class" and "cellGroup" to annotate X and Y axis.
3Annotate with annoSegment
Some segment annotation examples:
Reference: Single-cell roadmap of human gonadal development
Add segment with aesGroup = T and aesGroName = 'class', we do not need to supply x coordinate and set annoManual = T anymore:
# add segment
annoSegment(object = pdot,
annoPos = 'top',
aesGroup = T,
aesGroName = 'class',
yPosition = 8.8,
segWidth = 0.5)
Add branch:
# add branch
annoSegment(object = pdot,
annoPos = 'top',
aesGroup = T,
aesGroName = 'class',
yPosition = 8.8,
segWidth = 0.5,
addBranch = T,
lwd = 2,
branDirection = -1,
pCol = rep('black',11))
Add text label:
# add text
annoSegment(object = pdot,
annoPos = 'top',
aesGroup = T,
aesGroName = 'class',
yPosition = 8.8,
segWidth = 0.5,
addText = T,
textRot = 45,
hjust = 0)
Mapping with cellGroup:
# mapping cell group
annoSegment(object = pdot,
annoPos = 'left',
aesGroup = T,
aesGroName = 'cellGroup',
xPosition = -3.5,
segWidth = 0.5,
addText = T,
textRot = 90,
textHVjust = -0.5,
textSize = 14)
4Annotate with annoRect
Some rect annotation examples:
Reference: Single-cell roadmap of human gonadal development
Mapping with class:
# mapping by group
annoRect(object = pdot,
annoPos = 'top',
aesGroup = T,
aesGroName = 'class',
yPosition = c(9,9.5),
rectWidth = 0.8)
Use roundRect to add roundCorner rect:
# add round rect
annoRect(object = pdot,
annoPos = 'top',
aesGroup = T,
aesGroName = 'class',
yPosition = c(9,9.5),
rectWidth = 0.8,
roundRect = T)
You can change the corner radius:
# change corner radius
annoRect(object = pdot,
annoPos = 'top',
aesGroup = T,
aesGroName = 'class',
yPosition = c(9,9.5),
rectWidth = 0.8,
roundRect = T,
roundRadius = 0.5)
Add to botomn:
# add to botomn
annoRect(object = pdot,
annoPos = 'botomn',
aesGroup = T,
aesGroName = 'class',
yPosition = c(-2,0.25),
rectWidth = 0.8,
alpha = 0.35)
annoRect can also add text label now:
# add text label
annoRect(object = pdot,
annoPos = 'top',
aesGroup = T,
aesGroName = 'class',
yPosition = c(9,9.5),
rectWidth = 0.8,
addText = T,
textRot = 45,
hjust = 0,
textCol = rep('black',11),
textHVjust = 0.5)
Mapping with cellGroup:
# mapping cell group
annoRect(object = pdot,
annoPos = 'left',
aesGroup = T,
aesGroName = 'cellGroup',
xPosition = c(-3.5,0.25),
alpha = 0.3,
rectWidth = 0.8,
addText = T,
textRot = 90,
textSize = 14,
textCol = rep('black',3),
textHVjust = -2.3)
5Annotate with rotated Rect
If you have rotated the axis text before annotatation, the text labels will do not match the rect region when you add rect annotations. Here I supply a rotateRect parameter to rotate the rect with a matched degree to produce a will-matched plot.
First we move the text label to the top:
# rotate the x text label(top)
pdot_test <-
pdot +
scale_x_discrete(position = 'top') +
theme(axis.text.x = element_text(angle = 60,hjust = 0))
pdot_test
Let's add a rect annotation:
# normal rect annotation
annoRect(object = pdot_test,
annoPos = 'top',
aesGroup = T,
aesGroName = 'class',
yPosition = c(8.6,10.5))
Now rotate the rect:
# rotate rect
annoRect(object = pdot_test,
annoPos = 'top',
aesGroup = T,
aesGroName = 'class',
yPosition = c(8.6,10.4),
rotateRect = T)
Ajust the rect width:
# ajust width
annoRect(object = pdot_test,
annoPos = 'top',
aesGroup = T,
aesGroName = 'class',
yPosition = c(8.6,10.4),
rotateRect = T,
alpha = 0.5,
rectWidth = 0.8)
You can specify a degree you want:
# supply a rotate degree
annoRect(object = pdot_test,
annoPos = 'top',
aesGroup = T,
aesGroName = 'class',
yPosition = c(8.6,10.4),
rotateRect = T,
alpha = 0.5,
rectWidth = 0.9,
rectAngle = 20)
Ypu can also shift the rect with horizotal
or vertical
direction:
# shift the rotated rect
annoRect(object = pdot_test,
annoPos = 'top',
aesGroup = T,
aesGroName = 'class',
yPosition = c(8.6,10.4),
rotateRect = T,
alpha = 0.5,
rectWidth = 0.9,
rectAngle = 50,
normRectShift = 0.3)
Adding the group text label if you want:
# add group label
annoRect(object = pdot_test,
annoPos = 'top',
aesGroup = T,
aesGroName = 'class',
yPosition = c(8.6,10.4),
rotateRect = T,
alpha = 0.5,
rectWidth = 0.9,
rectAngle = 50,
normRectShift = 0.15,
addText = T,
textHVjust = 1,
textRot = 60,
hjust = 0,
textShift = 0.5)
Adding to the bottom:
# rotate the x text label(bottom)
pdot_test <-
pdot +
theme(axis.text.x = element_text(angle = 45,hjust = 1,vjust = 1))
# add to bottom
annoRect(object = pdot_test,
annoPos = 'botomn',
aesGroup = T,
aesGroName = 'class',
yPosition = c(-1.3,0.3),
rotateRect = T,
alpha = 0.5,
rectWidth = 0.9)
Adding to the left, you should ajust the rectAngle and rotatedRectShift for several times to get a perfect preference:
# rotate the y text label(left)
pdot_test <-
pdot +
theme(axis.text.y = element_text(angle = 45,hjust = 1))
# rotate the rect
annoRect(object = pdot_test,
annoPos = 'left',
aesGroup = T,
aesGroName = 'cellGroup',
xPosition = c(-3.5,0.3),
rotateRect = T,
alpha = 0.5,
rectWidth = 0.8,
rectAngle = 20,
rotatedRectShift = 2.8)
6Annotate with annoPoint2
Some point annotation examples:
Reference: Molecular logic of cellular diversification in the mouse cerebral cortex
Here I have made some improvements on the annoPoint function which make it upgrade into annoPoint2. But the annoPoint function still in this package and works well. The annoPoint2 can also be used to annotate plot with your group columns. The follwing examples show you:
# mapping with class
annoPoint2(object = pdot,
annoPos = 'top',
aesGroup = T,
aesGroName = 'class')
You can also turn on the shape mapping:
# turn on shape mapping
annoPoint2(object = pdot,
annoPos = 'top',
aesGroup = T,
aesGroName = 'class',
yPosition = 9,
aesShape = T,
ptSize = 2)
Add text label:
# add text label
annoPoint2(object = pdot,
annoPos = 'top',
aesGroup = T,
aesGroName = 'class',
ptSize = 2,
yPosition = 9,
addText = T,
textRot = 45,
hjust = 0,
textHVjust = 0.4)
Mapping with cellGroup:
# mapping with cellGroup
annoPoint2(object = pdot,
annoPos = 'left',
aesGroup = T,
aesGroName = 'cellGroup',
xPosition = -2.8)
If you want to put the point annotation between the text and aixs, you should first expand the space between axis text and axis line:
library(ggplot2)
# expand y axis text space
pdot1 <-
pdot +
theme(axis.text.y = element_text(margin = margin(r = 1,unit = 'cm')))
# add point
annoPoint2(object = pdot1,
annoPos = 'left',
aesGroup = T,
aesGroName = 'cellGroup',
xPosition = -0.2,
pCol = rep(c('#488FB1','#4FD3C4','#C1F8CF'),c(3,3,2)))
7Annotate with annoTriangle
I also supply an annoTriangle to add triangle annotation in plot which is familiar with the following dotplot here:
This figure shows the different celltype numbers' variation along continues reaearch time point.
Let's add an triangle:
# add triangle
annoTriangle(object = pdot,
annoPos = 'top',
xPosition = c(1,21),
yPosition = c(8.8,9.3))
Add a border on it:
# add border
annoTriangle(object = pdot,
annoPos = 'top',
xPosition = c(1,21),
yPosition = c(8.8,9.3),
addBorder = T,
lwd = 2)
You can also remove the triangle annotation:
# remove triangle
annoTriangle(object = pdot,
annoPos = 'top',
xPosition = c(1,21),
yPosition = c(8.8,9.3),
addBorder = T,
lwd = 2,
addTriangle = F)
There are four types triangle(RU/RD/LU/LD)
which can be choosed to show:
# change triangle type(4 types)
annoTriangle(object = pdot,
annoPos = 'top',
xPosition = c(1,21),
yPosition = c(8.8,9.3),
addBorder = T,
lwd = 2,
triangleType = 'LD')
Supply colors:
# change color
annoTriangle(object = pdot,
annoPos = 'top',
xPosition = c(1,21),
yPosition = c(8.8,9.3),
addBorder = T,
lwd = 2,
triangleType = 'LD',
fillCol = useMyCol('paired',10))
Add to botomn:
# add to bottomn
annoTriangle(object = pdot,
annoPos = 'botomn',
xPosition = c(1,21),
yPosition = c(-1.7,-1.2),
addBorder = T,
lwd = 2,
triangleType = 'RU',
fillCol = useMyCol('paired',10))
8Example
Let's draw a correlation plot:
library(jjAnno)
library(ggplot2)
# 加载内置数据集
data('mtcars')
# 计算相关性系数
corda <- data.frame(cor(mtcars))
# 上三角操作
corda[upper.tri(corda)] <- NA
# 加载R包
library(reshape2)
library(tidyverse)
# 增加行名列
corda$y <- rownames(corda)
# 宽数据转长数据
da <- melt(data = corda) %>% na.omit()
# 因子化
da$variable <- factor(da$variable,levels = unique(da$variable))
da$y <- factor(da$y,levels = rev(unique(da$y)))
# plot
p <-
ggplot(da) +
# 矩形图层
geom_tile(aes(x = variable,y = y),fill = 'white',
show.legend = F,
color = 'black') +
# 点图层
geom_point(aes(x = variable,y = y,fill = value,size = value),
show.legend = T,
shape = 21,color = 'black') +
theme_minimal(base_size = 16) +
# 主题调整
theme(panel.grid = element_blank(),
aspect.ratio = 1,
axis.text.x = element_text(angle = 45,hjust = 1),
plot.margin = margin(t = 2,unit = 'cm')) +
# 点颜色
scale_fill_gradientn(colors = colorRampPalette(c("#F6E3C5", "#A0D995", "#4CACBC"))(10)) +
# 点大小范围
scale_size(range = c(7,14)) +
xlab('') + ylab('') +
coord_cartesian(clip = 'off')
P
Add two layers point annotation:
# annotate
p1 <- annoPoint2(object = p,
annoManual = T,
xPosition = c(1:11),
yPosition = c(12:2))
# anno to left
annoPoint2(object = p1,
annoPos = 'left',
yPosition = c(1:11),
xPosition = -0.8)
9End
More paremeters see:
?useMyCol
?annoPoint
?annoPoint2
?annoRect
?annoSegment
?annoImage
?annoTriangle
?annoLegend
欢迎加入生信交流群。加我微信我也拉你进 微信群聊 老俊俊生信交流群
(微信交流群需收取20元入群费用(防止骗子和便于管理)
)。
老俊俊微信:
知识星球:
所以今天你学习了吗?
今天的分享就到这里了,敬请期待下一篇!
最后欢迎大家分享转发,您的点赞是对我的鼓励和肯定!
如果觉得对您帮助很大,赏杯快乐水喝喝吧!
往期回顾
◀...