跟着Molecular Cancer学作图 -- 分半小提琴图

跟着Molecular Cancer学作图 -- 分半小提琴图.png

从这个系列开始,师兄就带着大家从各大顶级期刊中的Figuer入手,从仿照别人的作图风格到最后实现自己游刃有余的套用在自己的分析数据上!这一系列绝对是高质量!还不赶紧点赞+在看,学起来!

示例数据和代码获取

生信常用分析图形+跟着高分SCI学作图

参考文献

话不多说,直接上图!

读图

原图

这张图理解起来没什么复杂的,就是一个分组提琴图,然后将两个组的小提琴分别显示一半,这样更方便读者直观比较。本小节我们介绍两种实现方法,一种是基于gghalves包中的geom_half_violin函数,另一种是借助github大佬编写的geom_split_violin函数。

效果展示

效果展示

由于本次使用的数据分布并不是很好,所以提琴的形状并不是很美观,但是图形的外观和细节都基本复现了原文。本次复现完全在R语言中进行,请大家放心食用!

数据构建

####################### 分半提琴图 ####################
library(ggplot2)
library(gghalves)
library(tidyverse)

# 读取测试数据:此数据集来源于GSE142651,随机挑选25个基因:
data <- read.csv("data.csv")
data <- data[sample(1:nrow(data), 10),]


# 宽数据转长数据:
data_new <- data %>% 
  pivot_longer(cols = !X, 
               names_to = "Samples", 
               values_to = "Values")

colnames(data_new)[1] <- "Genes"

# 添加分组信息:
data_new$group <- str_split(data_new$Samples, "_", simplify = T)[,4]
# 查看数据
head(data_new)
# # A tibble: 6 x 4
# Genes Samples                     Values group    
# <chr> <chr>                        <dbl> <chr>    
# 1 MCM5  Chip91481_r20_c71_Untreated   7.84 Untreated
# 2 MCM5  Chip91481_r47_c21_Untreated   5.12 Untreated
# 3 MCM5  Chip91484_r0_c62_Untreated    5.67 Untreated
# 4 MCM5  Chip91481_r16_c70_Untreated   5.12 Untreated
# 5 MCM5  Chip91484_r0_c35_Treated      6.67 Treated  
# 6 MCM5  Chip91484_r37_c38_Untreated   5.12 Untreated

绘图代码

geom_half_violin函数

# 绘图:
ggplot()+
  geom_half_violin(
    data = data_new %>% filter(group == "Treated"),
    aes(x = Genes,y = Values),colour="white",fill="#1ba7b3",side = "l"
  )+
  geom_half_violin(
    data = data_new %>% filter(group == "Untreated"),
    aes(x = Genes,y = Values),colour="white",fill="#dfb424",side = "r"
  )+
  theme_bw()+
  xlab("")+
  ylab("log2(CPM)")+
  geom_point(data = data_new, aes(x = Genes,y = Values, fill = group),
             stat = 'summary', fun=mean,
             position = position_dodge(width = 0.2))+
  stat_summary(data = data_new, aes(x = Genes,y = Values, fill = group),
               fun.min = function(x){quantile(x)[2]},
               fun.max = function(x){quantile(x)[4]},
               geom = 'errorbar', color='black',
               width=0.01,size=0.5,
               position = position_dodge(width = 0.2))+
  stat_compare_means(data = data_new, aes(x = Genes,y = Values, fill = group),
                     # 修改显著性标注:
                     symnum.args=list(cutpoints = c(0, 0.001, 0.01, 0.05, 1),
                                      symbols = c("***", "**", "*", "-")),
                     label = "p.signif",
                     label.y = max(data_new$Values),
                     hide.ns = F)+
  theme(axis.text.x = element_text(angle = 45, hjust = 1), 
        legend.position = "top",
        legend.justification = "right")
  

ggsave("violin_plot.pdf", height = 5, width = 10)
效果1

方法二

# 方法二:使用geom_split_violion函数:
# 函数来源:https://github.com/tidyverse/ggplot2/blob/eecc450f7f13c5144069705ef22feefe0b8f53f7/R/geom-violin.r#L102
GeomSplitViolin <- ggproto("GeomSplitViolin", GeomViolin, 
                           draw_group = function(self, data, ..., draw_quantiles = NULL) {
                             data <- transform(data, xminv = x - violinwidth * (x - xmin), xmaxv = x + violinwidth * (xmax - x))
                             grp <- data[1, "group"]
                             newdata <- plyr::arrange(transform(data, x = if (grp %% 2 == 1) xminv else xmaxv), if (grp %% 2 == 1) y else -y)
                             newdata <- rbind(newdata[1, ], newdata, newdata[nrow(newdata), ], newdata[1, ])
                             newdata[c(1, nrow(newdata) - 1, nrow(newdata)), "x"] <- round(newdata[1, "x"])
                             
                             if (length(draw_quantiles) > 0 & !scales::zero_range(range(data$y))) {
                               stopifnot(all(draw_quantiles >= 0), all(draw_quantiles <=
                                                                         1))
                               quantiles <- ggplot2:::create_quantile_segment_frame(data, draw_quantiles)
                               aesthetics <- data[rep(1, nrow(quantiles)), setdiff(names(data), c("x", "y")), drop = FALSE]
                               aesthetics$alpha <- rep(1, nrow(quantiles))
                               both <- cbind(quantiles, aesthetics)
                               quantile_grob <- GeomPath$draw_panel(both, ...)
                               ggplot2:::ggname("geom_split_violin", grid::grobTree(GeomPolygon$draw_panel(newdata, ...), quantile_grob))
                             }
                             else {
                               ggplot2:::ggname("geom_split_violin", GeomPolygon$draw_panel(newdata, ...))
                             }
                           })

geom_split_violin <- function(mapping = NULL, data = NULL, stat = "ydensity", position = "identity", ..., 
                              draw_quantiles = NULL, trim = TRUE, scale = "area", na.rm = FALSE, 
                              show.legend = NA, inherit.aes = TRUE) {
  layer(data = data, mapping = mapping, stat = stat, geom = GeomSplitViolin, 
        position = position, show.legend = show.legend, inherit.aes = inherit.aes, 
        params = list(trim = trim, scale = scale, draw_quantiles = draw_quantiles, na.rm = na.rm, ...))
}

ggplot(data_new, aes(x = Genes,y = Values, fill = group))+
  geom_split_violin(trim = T,colour="white")+
  geom_point(stat = 'summary',fun=mean,
             position = position_dodge(width = 0.2))+
  scale_fill_manual(values = c("#1ba7b3","#dfb424"))+
  stat_summary(fun.min = function(x){quantile(x)[2]},
               fun.max = function(x){quantile(x)[4]},
               geom = 'errorbar',color='black',
               width=0.01,size=0.5,
               position = position_dodge(width = 0.2))+
  stat_compare_means(data = data_new, aes(x = Genes,y = Values),
                     # 修改显著性标注:
                     symnum.args=list(cutpoints = c(0, 0.001, 0.01, 0.05, 1),
                                      symbols = c("***", "**", "*", "-")),
                     label = "p.signif",
                     label.y = max(data_new$Values),
                     hide.ns = F)+
  theme_bw()+
  xlab("")+
  ylab("log2(CPM)")+
  theme(axis.text.x = element_text(angle = 45, hjust = 1), 
        legend.position = "top",
        #legend.key = element_rect(fill = c("#1ba7b3","#dfb424")),
        legend.justification = "right")

ggsave("violin_plot2.pdf", height = 5, width = 10)
效果2

结果展示

效果展示

示例数据和代码获取

生信常用分析图形+跟着高分SCI学作图

以上就是本期的全部内容啦!欢迎点赞,点在看!师兄会尽快更新哦!制作不易,你的打赏将成为师兄继续更新的十足动力!

往期文章

  1. 跟着Nature Medicine学作图--箱线图+散点图
  2. 跟着Nature Communications学作图--渐变火山图
  3. 跟着Nature Communications学作图--气泡图+相关性热图
  4. 跟着Nature Communications学作图 -- 复杂提琴图
  5. 跟着Nature Communications学作图 -- 复杂热图
  6. 跟着Nature Communications学作图--复杂散点图
  7. 跟着Nature Communications学作图 -- 复杂百分比柱状图
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335

推荐阅读更多精彩内容