在多面板ggplot2中标记各个面板

Posted

技术标签:

【中文标题】在多面板ggplot2中标记各个面板【英文标题】:Label individual panels in a multi-panel ggplot2 【发布时间】:2013-07-08 17:19:11 【问题描述】:

我有兴趣尝试为我在 ggplot 中准备的多面板图形创建简单的角标签。 This is similar to this previously asked question,但答案只解释了如何在图的顶部包含一个标签,而不是产生许多期刊要求的格式的角标签。我希望在ggplot2 中复制类似于plotrix 函数corner.label() 的东西。

这是一个使用plottrix 的示例,我想在ggplot2 中重新创建。

require(plotrix)

foo1<-rnorm(50,25,5)
foo2<-rpois(50,25)
foo3<-rbinom(50,25,0.5)
foo4<-rnbinom(50,25,0.5)

par(mfrow=c(2,2))
hist(foo1)
corner.label(label='a',figcorner=T)
hist(foo2)
corner.label(label='b',figcorner=T)
hist(foo3)
corner.label(label='c',figcorner=T)
hist(foo4)
corner.label(label='d',figcorner=T)

这会产生以下内容:

提前感谢您的帮助!

【问题讨论】:

你能澄清一下标签应该是什么样子吗?您只需要将分面标签全部推到左侧吗?还是您需要完全去除刻面标签色带? 我只需要将标签对齐到每个面板的左上角。我不知道你说的去掉刻面标签色带是什么意思.. 好的,然后查看?theme并将hjust设置为strip.text 【参考方案1】:

最近的两项更改使这变得更加容易:

最新版本的ggplot2 增加了tag 标题,可用于标记子图。 patchwork 包使绘制多个 ggplot 对象变得非常容易。 https://github.com/thomasp85/patchwork

这意味着不需要更改 grobs。改编 Kev 提供的可重现示例:

library(ggplot2)
# install.package("patchwork")
library(patchwork)

a <- 1:20
b <- sample(a, 20)
c <- sample(b, 20)
d <- sample(c, 20)
mydata   <- data.frame(a, b, c, d)

myplot1  <- ggplot(mydata, aes(x=a, y=b)) + geom_point() + labs(tag = "A")
myplot2  <- ggplot(mydata, aes(x=b, y=c)) + geom_point() + labs(tag = "B")
myplot3  <- ggplot(mydata, aes(x=c, y=d)) + geom_point() + labs(tag = "C")
myplot4  <- ggplot(mydata, aes(x=d, y=a)) + geom_point() + labs(tag = "D")

myplot1 + myplot2 + myplot3 + myplot4

扩展:改变风格:

如果您想更改标签样式,您可以为每个图单独设置或设置主题默认值。我会推荐第二种方法。在构建绘图之前添加以下行以使字体 boldblue

ggplot2::theme_update(plot.tag = element_text(face = "bold", colour = "blue"))

有关自定义ggplot2主题的更多信息,请参阅here。

【讨论】:

您可以将tag 加粗、更改大小等吗?那要怎么做呢? 好问题:在原始答案中添加了更多内容以涵盖您的观点。 ggplot2 的几乎每个组件都可以通过 theme 参数进行自定义。 谢谢!我正在尝试查找文档,但似乎没有很多人使用它!【参考方案2】:

我遇到了同样的问题,想出了以下解决方案,有点不同:

加载 r 包

library(ggplot2)
library(grid)
library(gridExtra)

示例数据

a <- 1:20
b <- sample(a, 20)
c <- sample(b, 20)
d <- sample(c, 20)

创建数据框

mydata   <- data.frame(a, b, c, d)

创建示例图

myplot1  <- ggplot(mydata, aes(x=a, y=b)) + geom_point()
myplot2  <- ggplot(mydata, aes(x=b, y=c)) + geom_point()
myplot3  <- ggplot(mydata, aes(x=c, y=d)) + geom_point()
myplot4  <- ggplot(mydata, aes(x=d, y=a)) + geom_point()

设置角标签

myplot1 <- arrangeGrob(myplot1, top = textGrob("A", x = unit(0, "npc")
         , y   = unit(1, "npc"), just=c("left","top"),
         gp=gpar(col="black", fontsize=18, fontfamily="Times Roman")))

myplot2 <- arrangeGrob(myplot2, top = textGrob("B", x = unit(0, "npc")
         , y = unit(1, "npc"), just=c("left","top"),
         gp=gpar(col="black", fontsize=18, fontfamily="Times Roman")))

myplot3 <- arrangeGrob(myplot3, top = textGrob("C", x = unit(0, "npc")
        , y  = unit(1, "npc"), just=c("left","top"),
        gp=gpar(col="black", fontsize=18, fontfamily="Times Roman")))

myplot4 <- arrangeGrob(myplot4, top = textGrob("D", x = unit(0, "npc")
        , y = unit(1, "npc"), just=c("left","top"),
        gp=gpar(col="black",    fontsize=18, fontfamily="Times Roman")))

在一页上绘制所有图

grid.arrange(myplot1, myplot2, myplot3, myplot4, ncol = 2)

【讨论】:

这很棒。这比公认的解决方案 IMO 更简单、更普遍适用和更容易实施。谢谢!【参考方案3】:

一个例子:

d <- data.frame(x = runif(16),
                y = runif(16),
                grp = rep(letters[1:4],each = 4))

ggplot(d,aes(x = x,y = y)) + 
facet_wrap(~grp) + 
geom_point() + 
theme(strip.text = element_text(hjust = -0.05),
      strip.background = element_blank())

【讨论】:

有没有办法让标签在绘图/轴区域之外?类似于corner.label()中的'figcorner=T'选项? @Thraupidae 您可以将hjust 设置为负数,但随后 b 和 d 会漂移到其他面板中。 @Thraupidae 查看我的编辑。我认为这更接近你所追求的。 (并且应该解释我为什么询问刻面丝带。) 好的,为了防止漂移到其他面板我想你只需要使用 plot.margin 来弄乱间距? 啊,是的,这看起来非常接近我希望去掉刻面色带后的样子。谢谢!【参考方案4】:

这是使用自定义贴标机功能的解决方案。这不涉及对数据的任何操作。目前它仅适用于一维构面(facet_wrap)。我仍在研究如何沿二维网格递增...

    定义贴标函数

    make_labelstring <- function(mypanels) 
      mylabels <- sapply(mypanels, 
                         function(x) LETTERS[which(mypanels == x)])
    
      return(mylabels)
    
    
    label_panels <- ggplot2::as_labeller(make_labelstring)
    

    label_panels 作为贴标者传递给facet_wrap

    library(ggplot2)
    data("diamonds")
    
    # create a faceted plot
    ggplot(data = diamonds, aes(x = depth, y = price)) +
      geom_point() +
      facet_wrap(~cut, labeller = label_panels) +
      theme(strip.text = element_text(hjust = -0),
            strip.background = element_blank())
    

【讨论】:

以上是关于在多面板ggplot2中标记各个面板的主要内容,如果未能解决你的问题,请参考以下文章

ggplot2中的每个面板平滑

R语言可视化包ggplot2包使用facet_wrap绘制多面板图(子图)实战

ggplot2中的角标签

ggplot2 移动构面布局

ggplot2 png文件没有背景

ggplot2:3路交互堆积条形图的分组条形图