如何在一个3×3的组合图中添加面板内标签?

huangapple go评论59阅读模式
英文:

patchwork: how to have within-panel tags for a 3x3 combined plot?

问题

与这个问题类似 https://stackoverflow.com/questions/76524971/patchwork-align-tags-inside-panels-for-side-by-side-plots/76525099#76525099,我需要将标签移到面板边框内,但现在是一个3x3的网格。

library(devtools)
library(ggplot2)
library(patchwork)

d1 <- runif(500)
d2 <- rep(c("Treatment", "Control"), each = 250)
d3 <- rbeta(500, shape1 = 100, shape2 = 3)
d4 <- d3 + rnorm(500, mean = 0, sd = 0.1)
plotData <- data.frame(d1, d2, d3, d4)
str(plotData)

此代码用于确保每行显示一个合并的图例:

p1 <- ggplot(data = plotData) + geom_boxplot(aes(x = d2, y = d1, fill = d2)) + theme(legend.position = "none")
p2 <- ggplot(data = plotData) + geom_boxplot(aes(x = d2, y = d1, fill = d2)) + theme(legend.position = "none")
p3 <- ggplot(data = plotData) + geom_boxplot(aes(x = d2, y = d1, fill = d2)) + theme(legend.position =  "right")
p4 <- ggplot(data = plotData) + geom_boxplot(aes(x = d2, y = d1, fill = d2)) + theme(legend.position = "none")
p5 <- ggplot(data = plotData) + geom_boxplot(aes(x = d2, y = d1, fill = d2)) + theme(legend.position = "none")
p6 <- ggplot(data = plotData) + geom_boxplot(aes(x = d2, y = d1, fill = d2)) + theme(legend.position =  "right")
p7 <- ggplot(data = plotData) + geom_boxplot(aes(x = d2, y = d1, fill = d2)) + theme(legend.position = "none")
p8 <- ggplot(data = plotData) + geom_boxplot(aes(x = d2, y = d1, fill = d2)) + theme(legend.position = "none")
p9 <- ggplot(data = plotData) + geom_boxplot(aes(x = d2, y = d1, fill = d2)) + theme(legend.position = "right")

此代码生成一个带有标签的组合图,位于默认位置:

(((p1 + p2 + p3) / 
(p4 + p5 + p6) / 
(p7 + p8 + p9)) + guide_area()) & plot_annotation(tag_levels = "A") 

添加 & plot_annotation(tag_levels = "A") + theme(legend.position = "right", plot.tag.position = c(.15, .95)) 将移除标签。

感谢您的访问。

英文:

Similar to this problem <https://stackoverflow.com/questions/76524971/patchwork-align-tags-inside-panels-for-side-by-side-plots/76525099#76525099>, I need to move tags inside panel borders, but now for a 3x3 grid.

library(devtools)
library(ggplot2)
library(patchwork)

d1 &lt;- runif(500)
d2 &lt;- rep(c(&quot;Treatment&quot;,&quot;Control&quot;),each=250)
d3 &lt;- rbeta(500,shape1=100,shape2=3)
d4 &lt;- d3 + rnorm(500,mean=0,sd=0.1)
plotData &lt;- data.frame(d1,d2,d3,d4)
str(plotData)

This code is to make sure one combined legend is shown per row:

p1 &lt;- ggplot(data=plotData) + geom_boxplot(aes(x=d2,y=d1,fill=d2)) + theme(legend.position = &quot;none&quot;)
p2 &lt;- ggplot(data=plotData) + geom_boxplot(aes(x=d2,y=d1,fill=d2)) + theme(legend.position = &quot;none&quot;)
p3 &lt;- ggplot(data=plotData) + geom_boxplot(aes(x=d2,y=d1,fill=d2)) + theme(legend.position =  &quot;right&quot;)
p4 &lt;- ggplot(data=plotData) + geom_boxplot(aes(x=d2,y=d1,fill=d2)) + theme(legend.position = &quot;none&quot;)
p5 &lt;- ggplot(data=plotData) + geom_boxplot(aes(x=d2,y=d1,fill=d2)) + theme(legend.position = &quot;none&quot;)
p6 &lt;- ggplot(data=plotData) + geom_boxplot(aes(x=d2,y=d1,fill=d2)) + theme(legend.position =  &quot;right&quot;)
p7 &lt;- ggplot(data=plotData) + geom_boxplot(aes(x=d2,y=d1,fill=d2)) + theme(legend.position = &quot;none&quot;)
p8 &lt;- ggplot(data=plotData) + geom_boxplot(aes(x=d2,y=d1,fill=d2)) + theme(legend.position = &quot;none&quot;)
p9 &lt;- ggplot(data=plotData) + geom_boxplot(aes(x=d2,y=d1,fill=d2)) + theme(legend.position = &quot;right&quot;)

This code produced a combined plot with tags, at default locations

(((p1 + p2 + p3) / 
(p4 + p5 + p6) / 
(p7 + p8 + p9)) + guide_area()) &amp; plot_annotation(tag_levels = &quot;A&quot;) 

如何在一个3×3的组合图中添加面板内标签?

Adding &amp; plot_annotation(tag_levels = &quot;A&quot;) + theme(legend.position = &quot;right&quot;, plot.tag.position = c(.15, .95)) removed the tags.

如何在一个3×3的组合图中添加面板内标签?

Thanks for stopping by.

答案1

得分: 1

也许有一种更直接的方法来实现您期望的结果,但一个选项是使用 annotateannotation_custom 来伪造您的内部标记,就像我在下面所做的那样,这意味着手动将 "标记" 添加为每个图的注释:

library(ggplot2)
library(patchwork)

plot_list <- lapply(1:9, \(x) {
  legend_position <- if (x %% 3 == 0) {
    "right"
  } else {
    "none"
  }
  ggplot(data = plotData) +
    geom_boxplot(aes(x = d2, y = d1, fill = d2)) +
    theme(legend.position = legend_position)
})

add_tag <- function(label, x = 1, y = 1, padding.x = unit(5, "pt"), padding.y = padding.x, hjust = 1, vjust = 1, size = 13) {
  annotation_custom(
    grid::textGrob(
      x = unit(x, "npc") - padding.x,
      y = unit(y, "npc") - padding.y,
      hjust = hjust, vjust = vjust,
      label = label, gp = grid::gpar(fontsize = size)
    )
  )
}

# 默认位置:右上角
lapply(
  seq_along(plot_list), \(x) plot_list[[x]] + add_tag(LETTERS[x])
) |>
  wrap_plots(ncol = 3)

如何在一个3×3的组合图中添加面板内标签?<!-- -->


# 标记在 "左上角"
lapply(
  seq_along(plot_list), \(x) plot_list[[x]] + add_tag(
    LETTERS[x],
    x = 0, y = 1,
    hjust = 0, vjust = 1,
    padding.x = -unit(5, "pt"), padding.y = unit(5, "pt")
  )
) |>
  wrap_plots(ncol = 3)

如何在一个3×3的组合图中添加面板内标签?<!-- -->

英文:

Perhaps there is a more straightforward approach to achieve your desired result but one option would be to fake your inner tags using annotate or annotation_custom as I do below which means to manually add the "tags" as annotations to each plot:

library(ggplot2)
library(patchwork)

plot_list &lt;- lapply(1:9, \(x) {
  legend_position &lt;- if (x %% 3 == 0) {
    &quot;right&quot;
  } else {
    &quot;none&quot;
  }
  ggplot(data = plotData) +
    geom_boxplot(aes(x = d2, y = d1, fill = d2)) +
    theme(legend.position = legend_position)
})

add_tag &lt;- function(label, x = 1, y = 1, padding.x = unit(5, &quot;pt&quot;), padding.y = padding.x, hjust = 1, vjust = 1, size = 13) {
  annotation_custom(
    grid::textGrob(
      x = unit(x, &quot;npc&quot;) - padding.x,
      y = unit(y, &quot;npc&quot;) - padding.y,
      hjust = hjust, vjust = vjust,
      label = label, gp = grid::gpar(fontsize = size)
    )
  )
}

# Default: topright corner
lapply(
  seq_along(plot_list), \(x) plot_list[[x]] + add_tag(LETTERS[x])
) |&gt;
  wrap_plots(ncol = 3)

如何在一个3×3的组合图中添加面板内标签?<!-- -->


# Tags in &quot;topleft&quot; corner
lapply(
  seq_along(plot_list), \(x) plot_list[[x]] + add_tag(
    LETTERS[x],
    x = 0, y = 1,
    hjust = 0, vjust = 1,
    padding.x = -unit(5, &quot;pt&quot;), padding.y = unit(5, &quot;pt&quot;)
  )
) |&gt;
  wrap_plots(ncol = 3)

如何在一个3×3的组合图中添加面板内标签?<!-- -->

答案2

得分: 1

感谢Stefan提供的提示。这段代码处理不同的子图。

# 列出子图
plot_list <- list(p1, p2, p3, p4, p5, p6, p7, p8, p9)

# 定义一个添加标签到图表的函数
add_tag <- function(label, x = 1, y = 1, padding.x = unit(5, "pt"), padding.y = padding.x, hjust = 1, vjust = 1, size = 13) {
  annotation_custom(
    grid::textGrob(
      x = unit(x, "npc") - padding.x,
      y = unit(y, "npc") - padding.y,
      hjust = hjust, vjust = vjust,
      label = label, gp = grid::gpar(fontsize = size)
    )
  )
}

# 向每个图表添加标签
plot_list <- lapply(
  seq_along(plot_list), 
  \(x) plot_list[[x]] + add_tag(LETTERS[x], x = .15, y = .96)
)

# 将图表组合成一个网格
wrap_plots(plot_list, ncol = 3)
英文:

Many thanks to Stefan for the hints. This code handles unidentical subplots.

# List the subplots
plot_list &lt;- list(p1, p2, p3,p4, p5, p6, p7, p8, p9)

# Define a function to add a tag to a plot
add_tag &lt;- function(label, x = 1, y = 1, padding.x = unit(5, &quot;pt&quot;), padding.y = padding.x, hjust = 1, vjust = 1, size = 13) {
  annotation_custom(
    grid::textGrob(
      x = unit(x, &quot;npc&quot;) - padding.x,
      y = unit(y, &quot;npc&quot;) - padding.y,
      hjust = hjust, vjust = vjust,
      label = label, gp = grid::gpar(fontsize = size)
    )
  )
}

# Add a tag to each plot
plot_list &lt;- lapply(
  seq_along(plot_list), 
  \(x) plot_list[[x]] + add_tag(LETTERS[x], x = .15, y = .96)
)

# Combine the plots into a grid
wrap_plots(plot_list, ncol = 3)

huangapple
  • 本文由 发表于 2023年6月22日 01:42:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/76525899.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定