【跟着CNS来作图1】堆积柱状图的多层注释

后面我们会陆陆续续有个系列,跟着别人好的paper中的图进行学习,试着重复别人图中的效果,来加强自己的学习。

今天就来测试和学习下面这个paper中的一个堆积柱状图,主要是分层注释的练习。

因为,没有paper中的数据,我们做测试就随机生成一点数据。

先分解整个图:

1. 堆积柱状图

2. 2层注释:上面一层注释,没3个一组注释,代表取样部位。下面注释代表取样时期。

3. 3层注释,按样本的宏基因组来源分类。

4. 第4层,3个文本信息


所以先生成一个测试数据,来表征柱状图,从图中看,包含21组样本,每个样本里面5种不同的变量。

library(reshape2)

library(ggnewscale)

library(ggplot2)

library(tidyverse)

#所以我们生成一个21行,5列的矩阵,5列的名称与paper中一样。

df <- as.data.frame(matrix(data = sample(0:50,105,replace = T),ncol = 5))

colnames(df) <- c('Heterogeneous selection','Homogeneous selection',

                  'Dispersal limitation','Homogenizing dispersal',

                  'Undominated')

#因为图中画的是百分比,我们转化成百分比信息

back.data<- data.frame()

for(n in 1:nrow(df))

{

  tmp <- df[n,]/sum(df[n,])

  back.data <- rbind(back.data,tmp)

}

back.data$ID <- rownames(back.data)

df_plot <- melt(back.data,id = "ID")        #转化成短矩阵

df_plot$ID <- factor(df_plot$ID,levels=seq(1:27))        

col <- c("purple","green","gold","red","gray")

#下面我们先画出基本的堆积柱状图框架

p <- ggplot(df_plot)+

geom_col(aes( x = ID, y = value, fill = variable), position = position_fill())+

scale_fill_manual(values = col,name="Ecological process")+

xlab(NULL)+

ylab("Relative Importantce")+

scale_y_continuous(labels = scales::percent_format())+

theme(axis.text.x = element_blank(),

      axis.ticks.x=element_blank(),

      text = element_text(size = 15))

p

下面,我们就要开始添加注释信息,信息我们以矩阵框的形式来添加,前面的散点图和曼哈顿图的例子我们也介绍过这种用法:

geom_rect()和geom_tile()函数的功能是一致的,但是参数有所区别:geom_rect()使用的是矩形四个顶点的位置,即xmin、xmax、ymin和ymax,而geom_tile()使用的是矩形的中心位置及其尺寸,即x、y、width、height。geom_tile()是geom_tile()的特例,其要求所有矩形的尺寸相同。

我们今天使用geom_rect来实现。

第一层的注释信息,应该包含下面的样本:

我们先生成一个矩形框的注释文件,文件包含注释框的ID,以及开始和结束位置:

annotation1 <- data.frame(ID=c("Plastic leaf","Phylloplane","Leaf endosphere","Rhizoplane","Root endosphere","Rhizophere soil","Bulk soil"),

                          xmin=seq(1,19,3),xmax=seq(3,21,3))

annotation1$ID <- factor(annotation1$ID,levels = annotation1$ID)

#然后根据注释信息添加矩形框

ggplot(df_plot)+

geom_col(aes( x = ID, y = value, fill = variable), position = position_fill())+

scale_fill_manual(values = col,name="Ecological process")+

xlab(NULL)+

ylab("Relative Importantce")+

scale_y_continuous(labels = scales::percent_format())+

theme(axis.text.x = element_blank(),

      axis.ticks.x=element_blank(),

      text = element_text(size = 15))+

new_scale('fill') +

geom_rect(data=annotation1,aes(xmin = xmin,xmax = xmax,

                            ymin = -0.06,ymax = -0.02,

                            fill = ID))+

scale_fill_manual(values = c('#FA26A0','#388E3C','#77ACF1',

                              '#FFC947','#B85C38','#AAAAAA','#364547'),

                  name = 'Niche')

从图中可以发现,对于注释框的其实和结束位置,我们需要在中心位置往前往后添加一半的距离,但是因为不同组之间需要有缝隙,所以我们就添加0.45的距离。

annotation1 <- data.frame(ID=c("Plastic leaf","Phylloplane","Leaf endosphere","Rhizoplane","Root endosphere","Rhizophere soil","Bulk soil"),xmin=seq(1,19,3)-0.45,xmax=seq(3,21,3)+0.45)

annotation1$ID <- factor(annotation1$ID,levels = annotation1$ID)

#在原先其实距离的基础上,望前望后添加了0.45的距离,因为添加0.5,组和组之间就没有缝隙了。

ggplot(df_plot)+

geom_col(aes( x = ID, y = value, fill = variable), position = position_fill())+

scale_fill_manual(values = col,name="Ecological process")+

xlab(NULL)+

ylab("Relative Importantce")+

scale_y_continuous(labels = scales::percent_format())+

theme(axis.text.x = element_blank(),

      axis.ticks.x=element_blank(),

      text = element_text(size = 15))+

new_scale('fill') +

geom_rect(data=annotation1,aes(xmin = xmin,xmax = xmax,

                            ymin = -0.06,ymax = -0.02,

                            fill = ID))+

scale_fill_manual(values = c('#FA26A0','#388E3C','#77ACF1',

                              '#FFC947','#B85C38','#AAAAAA','#364547'),

                  name = 'Niche')

下面添加第二层的注释信息,第二层相当于有27个注释,颜色按发育期来添色。所以,我们先添加一样的27个框,颜色按生育期着色,组之间的位置我们再调整。

annotation2 <- data.frame(ID=rep(c("Seedling stage","Tasseling stage","Mature stage"),7),

                          xmin=seq(0.5,20.5,1),xmax=seq(1.5,21.5,1))

annotation2$ID <- factor(annotation2$ID,levels = c("Seedling stage","Tasseling stage","Mature stage"))

#上面构建了一个关于二层注释框的位置信息,和生育期信息。

ggplot(df_plot)+

geom_col(aes( x = ID, y = value, fill = variable), position = position_fill())+

scale_fill_manual(values = col,name="Ecological process")+

xlab(NULL)+

ylab("Relative Importantce")+

scale_y_continuous(labels = scales::percent_format())+

theme(axis.text.x = element_blank(),

      axis.ticks.x=element_blank(),

      text = element_text(size = 15))+

new_scale('fill') +

geom_rect(data=annotation1,aes(xmin = xmin,xmax = xmax,

                            ymin = -0.06,ymax = -0.02,

                            fill = ID))+

scale_fill_manual(values = c('#FA26A0','#388E3C','#77ACF1',

                              '#FFC947','#B85C38','#AAAAAA','#364547'),

                  name = 'Niche')+

new_scale('fill') +

geom_rect(data=annotation2,aes(xmin = xmin,xmax = xmax,

                            ymin = -0.11,ymax = -0.07,

                            fill = ID))+

scale_fill_brewer(palette = 'Set1',name="Stage")

但是,因为有7个组,所以组和组之间是需要留点空隙的,这样子,我们就需要对比如3-4,6-7,9-10,12-13,15-16,18-19之间需要微调,各自减去0.05。而1和21也各自减去0.05。

这样来说,需要加上0.05的有1,4,7,10,13,16,19。而需要往减去0.05的有3,6,9,12,15,18,21

annotation2 <- data.frame(ID=rep(c("Seedling stage","Tasseling stage","Mature stage"),7),

                          xmin=seq(0.5,20.5,1),xmax=seq(1.5,21.5,1))

annotation2$ID <- factor(annotation2$ID,levels = c("Seedling stage","Tasseling stage","Mature stage"))

index1 <- seq(1,19,3)

annotation2$xmin[index1] <- annotation2$xmin[index1] +0.05

index2 <- seq(3,21,3)

annotation2$xmax[index2] <- annotation2$xmax[index2] -0.05

这样操作之后,获得我们新的第二层注释文件。

ggplot(df_plot)+

geom_col(aes( x = ID, y = value, fill = variable), position = position_fill())+

scale_fill_manual(values = col,name="Ecological process")+

xlab(NULL)+

ylab("Relative Importantce")+

scale_y_continuous(labels = scales::percent_format())+

theme(axis.text.x = element_blank(),

      axis.ticks.x=element_blank(),

      text = element_text(size = 15))+

new_scale('fill') +

geom_rect(data=annotation1,aes(xmin = xmin,xmax = xmax,

                            ymin = -0.06,ymax = -0.02,

                            fill = ID))+

scale_fill_manual(values = c('#FA26A0','#388E3C','#77ACF1',

                              '#FFC947','#B85C38','#AAAAAA','#364547'),

                  name = 'Niche')+

new_scale('fill') +

geom_rect(data=annotation2,aes(xmin = xmin,xmax = xmax,

                            ymin = -0.11,ymax = -0.07,

                            fill = ID))+

scale_fill_brewer(palette = 'Set1',name="Stage")

这样画出来的图,在第二层注释之间就会有间隙了。

第三层比较简单,就是三组。

annotation3 <- data.frame(ID=c("Air","Plant","Soil"),

                          xmin=c(1,4,16)-0.45,xmax=c(3,15,21)+0.45)

ggplot(df_plot)+

geom_col(aes( x = ID, y = value, fill = variable), position = position_fill())+

scale_fill_manual(values = col,name="Ecological process")+

xlab(NULL)+

ylab("Relative Importantce")+

scale_y_continuous(labels = scales::percent_format())+

theme(axis.text.x = element_blank(),

      axis.ticks.x=element_blank(),

      text = element_text(size = 15))+

new_scale('fill') +

geom_rect(data=annotation1,aes(xmin = xmin,xmax = xmax,

                            ymin = -0.06,ymax = -0.02,

                            fill = ID))+

scale_fill_manual(values = c('#FA26A0','#388E3C','#77ACF1',

                              '#FFC947','#B85C38','#AAAAAA','#364547'),

                  name = 'Niche')+

new_scale('fill') +

geom_rect(data=annotation2,aes(xmin = xmin,xmax = xmax,

                            ymin = -0.11,ymax = -0.07,

                            fill = ID))+

scale_fill_brewer(palette = 'Set1',name="Stage")+

new_scale('fill') +

geom_rect(data=annotation3,aes(xmin = xmin,xmax = xmax,

                            ymin = -0.13,ymax = -0.12),fill="black",

          show.legend = F)

第4层就是三个文本信息,位置其实就是第3层的中间位置。

所以基本就是x轴的2,9.5,18.5

所以我们添加文本信息:

ggplot(df_plot)+

geom_col(aes( x = ID, y = value, fill = variable), position = position_fill())+

scale_fill_manual(values = col,name="Ecological process")+

xlab(NULL)+

ylab("Relative Importantce")+

scale_y_continuous(labels = scales::percent_format())+

theme(axis.text.x = element_blank(),

      axis.ticks.x=element_blank(),

      text = element_text(size = 15))+

new_scale('fill') +

geom_rect(data=annotation1,aes(xmin = xmin,xmax = xmax,

                            ymin = -0.06,ymax = -0.02,

                            fill = ID))+

scale_fill_manual(values = c('#FA26A0','#388E3C','#77ACF1',

                              '#FFC947','#B85C38','#AAAAAA','#364547'),

                  name = 'Niche')+

new_scale('fill') +

geom_rect(data=annotation2,aes(xmin = xmin,xmax = xmax,

                            ymin = -0.11,ymax = -0.07,

                            fill = ID))+

scale_fill_brewer(palette = 'Set1',name="Stage")+

new_scale('fill') +

geom_rect(data=annotation3,aes(xmin = xmin,xmax = xmax,

                            ymin = -0.13,ymax = -0.12),fill="black",

          show.legend = F)+

geom_text(aes(x = 2,y = -0.18,label = 'Air'),size = 8) +

geom_text(aes(x = 9.5,y = -0.18,label = 'Plant'),size = 8) +

geom_text(aes(x = 18.5,y = -0.18,label = 'Soil'),size = 8)

下面,我们来调整一下legend的位置,用cowplot::plot_grid来实现。

main_plot <- ggplot(df_plot)+

geom_col(aes( x = ID, y = value, fill = variable), position = position_fill())+

scale_fill_manual(values = col,name="Ecological process")+

xlab(NULL)+

ylab("Relative Importantce")+

scale_y_continuous(labels = scales::percent_format())+

theme(axis.text.x = element_blank(),

      axis.ticks.x=element_blank(),

      text = element_text(size = 15))+

new_scale('fill') +

geom_rect(data=annotation1,aes(xmin = xmin,xmax = xmax,

                            ymin = -0.06,ymax = -0.02,

                            fill = ID),show.legend = F)+

scale_fill_manual(values = c('#FA26A0','#388E3C','#77ACF1',

                              '#FFC947','#B85C38','#AAAAAA','#364547'),

                  name = 'Niche')+

new_scale('fill') +

geom_rect(data=annotation2,aes(xmin = xmin,xmax = xmax,

                            ymin = -0.11,ymax = -0.07,

                            fill = ID),show.legend = F)+

scale_fill_brewer(palette = 'Set1',name="Stage")+

new_scale('fill') +

geom_rect(data=annotation3,aes(xmin = xmin,xmax = xmax,

                            ymin = -0.13,ymax = -0.12),fill="black",

          show.legend = F)+

geom_text(aes(x = 2,y = -0.18,label = 'Air'),size = 8) +

geom_text(aes(x = 9.5,y = -0.18,label = 'Plant'),size = 8) +

geom_text(aes(x = 18.5,y = -0.18,label = 'Soil'),size = 8)


lg1 <- ggplot(df_plot)+

geom_col(aes( x = ID, y = value, fill = variable), position = position_fill(),show.legend = F)+

scale_fill_manual(values = col,name="Ecological process")+

xlab(NULL)+

ylab("Relative Importantce")+

scale_y_continuous(labels = scales::percent_format())+

theme(axis.text.x = element_blank(),

      axis.ticks.x=element_blank(),

      text = element_text(size = 15))+

new_scale('fill') +

geom_rect(data=annotation1,aes(xmin = xmin,xmax = xmax,

                            ymin = -0.06,ymax = -0.02,

                            fill = ID))+

scale_fill_manual(values = c('#FA26A0','#388E3C','#77ACF1',

                              '#FFC947','#B85C38','#AAAAAA','#364547'),

                  name = 'Niche')+

new_scale('fill') +

geom_rect(data=annotation2,aes(xmin = xmin,xmax = xmax,

                            ymin = -0.11,ymax = -0.07,

                            fill = ID))+

scale_fill_brewer(palette = 'Set1',name="Stage")+

new_scale('fill') +

geom_rect(data=annotation3,aes(xmin = xmin,xmax = xmax,

                            ymin = -0.13,ymax = -0.12),fill="black",

          show.legend = F)+

geom_text(aes(x = 2,y = -0.18,label = 'Air'),size = 8) +

geom_text(aes(x = 9.5,y = -0.18,label = 'Plant'),size = 8) +

geom_text(aes(x = 18.5,y = -0.18,label = 'Soil'),size = 8) +

theme(legend.direction = "horizontal", legend.position = "bottom")


niche_legend <- cowplot::get_legend(lg1)   #获取采样部位和时期的legend信息


cowplot::plot_grid(plotlist = list(main_plot,niche_legend),ncol = 1, nrow = 2,

          rel_heights = c(5, 1))

多个图的话,可以一起合。

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

推荐阅读更多精彩内容