【问题标题】:Adding customized axis label to faceted ggplot将自定义轴标签添加到多面 ggplot
【发布时间】:2025-11-29 13:10:01
【问题描述】:

我正在尝试在多面 ggplot 的 x 轴文本的左侧添加一个带有更多信息的文本元素(一次)(不要在每个方面都重复):

到目前为止,我尝试了几种方法都失败了:

  • geom_text(出现在图中)
  • 注释功能(出现在图中的每个方面)
  • axis.title.x(不能随意自定义位置,即x=-1和y=-1或多或少)
  • mtext(不适合ggplot)

我的代码:

#1.1 create labels for x-axis:
cfutypes_labels <- c("native\n-\n-", "native\n-\n+",
                     "aliquot\n-\n-", "aliquot\n-\n+",
                     "aliquot\n+\n-", "aliquot\n+\n+")

names(cfutypes_labels) <- c("no.0.native", "yes.0.native", 
                            "no.0.aliquot","yes.0.aliquot", 
                            "no.20.aliquot", "yes.20.aliquot")

extra_axis <- c("storagetype\nglycerol\nfreeze-thaw-cycle")

#1.2 plotting

plot_t1calc1 <- thawcycles_long %>%
  filter(dilution_potency<5,
         count >0, cfutype =="cfuperml") %>%
  ggplot(aes(x=interaction(thawcycle,
                           glycerol_content,
                           storagetype), 
             y=count,
             color=interaction(thawcycle,
                               glycerol_content,
                               storagetype))) +
  geom_jitter(width=0.2,
              alpha=0.8,
              show.legend = FALSE)+
  stat_summary(geom = "crossbar",
               fun = "geometric.mean",
               width = 0.3,
               show.legend = FALSE)+
  scale_y_log10(breaks = trans_breaks("log10", function(x) 10^(x+1)),
                labels = trans_format("log10", math_format(10^.x))) +
  scale_x_discrete(labels = cfutypes_labels)+
  ylab("CFU per mL") + 
  xlab("")+
  facet_grid(~timepoint,
             scales="free_x",
             space="free")+
  theme_minimal()+
  theme(panel.background = element_rect(fill = "white"),
      #  axis.title.x = element_text(hjust = -0.5, 
       #                             vjust= 0.9,
        #                            size=9),
        axis.line = element_line(color="black",
                                 size=0.2),
        strip.text = element_text(face="bold"))

我的数据集的一小部分:

> tibble(thawcycles_long)
# A tibble: 567 x 9
     sid timepoint storagetype thawcycle glycerol_content dilution_potency cfutype       dotnumber    count
   <dbl> <chr>     <chr>       <chr>                <dbl>            <dbl> <chr>         <chr>        <dbl>
 1     4 t0        native      no                       0                3 dill1_cfu     1              104
 2     4 t0        native      no                       0                3 dill1_cfu     2               83
 3     4 t0        native      no                       0                3 dill1_cfu     3              106
 4     4 t0        native      no                       0                3 cfuperml      1         10400000
 5     4 t0        native      no                       0                3 cfuperml      2          8300000
 6     4 t0        native      no                       0                3 cfuperml      3         10600000
 7     4 t0        native      no                       0                3 auxv_cfuperml 1         10400000
 8     4 t0        native      no                       0                3 auxv_cfuperml 2          8300000
 9     4 t0        native      no                       0                3 auxv_cfuperml 3         10600000
10     4 t0        native      no                       0                4 dill1_cfu     1                7

有人知道如何解决这个问题吗? 非常感谢!

【问题讨论】:

    标签: r ggplot2 text annotations axis-labels


    【解决方案1】:

    一种选择是像这样使用geom_text

    重要的是添加coord_cartesian(clip = "off", ylim = c(1, NA))来固定y标度,防止标签被剪掉。

    此外,您必须通过增加绘图边距为标签腾出一些空间。

    extra_axis <- c("storagetype\nglycerol\nfreeze-thaw-cycle")
    
    library(ggplot2)
    
    ggplot(thawcycles_long, aes(x = var, y = count, color = var)) +
      geom_jitter(width = 0.2, alpha = 0.8, show.legend = FALSE) +
      scale_x_discrete(labels = cfutypes_labels) +
      scale_y_log10(breaks = scales::trans_breaks("log10", function(x) 10^(x+1)),
                    labels = scales::trans_format("log10", scales::math_format(10^.x))) +
      labs(y = "CFU per mL", x = NULL) +
      facet_grid(~timepoint, scales = "free_x",  space = "free") +
      theme_minimal() +
      theme(
        panel.background = element_rect(fill = "white"),
        axis.line = element_line(color = "black",size = 0.2),
        strip.text = element_text(face = "bold"),
        plot.margin = margin(5.5, 5.5, 16.5, 55, unit = "pt")
      ) +
      geom_text(data = data.frame(timepoint = "t0"), aes(label = extra_axis), x = -1, y = -.1, 
                inherit.aes = FALSE, color = "red", hjust = .5, vjust = 1, size = 8 / .pt) +
      coord_cartesian(clip = "off", ylim = c(1, NA))
    

    数据

    set.seed(42)
    
    thawcycles_long <- data.frame(
      thawcycle = sample(c("yes", "no"), 20, replace = TRUE),
      glycerol_content = sample(c(0, 20), 20, replace = TRUE),
      storagetype = sample(c("native", "aliquot"), 20, replace = TRUE),
      count = 1:20,
      timepoint = sample(c("t0", "t1"), 20, replace = TRUE)
    )
    thawcycles_long$var <- interaction(
      thawcycles_long$thawcycle,
      thawcycles_long$glycerol_content,
      thawcycles_long$storagetype
    )
    

    【讨论】:

    • 感谢@stefan 的快速回复您知道如何使coord_cartesian(clip = "off", ylim = c(0, NA)) 适应对数刻度吗?接受您建议的代码会给我一条错误消息:grid.Call.graphics 中的错误(C_setviewport,vp,TRUE):非有限位置或/和视口大小。
    • 嗨,安妮卡。没什么大不了的。问题当然是没有日志(0)。我刚刚进行了编辑,添加了对数刻度并设置ylim = c(1, NA)。根据您想要的结果和数据范围,您可能已经调整了限制的下限。
    • 嗨斯特凡,谢谢!很抱歉打扰你,还有一个问题:当我按照建议设置 ylim 时,我的图变得不必要地大,因为第一个值从大约 10^5 开始出现。因此,我调整了 geom_text 元素的 coord_cartesian 限制和 x/y 值。不幸的是,我在这里收到一条错误消息: grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : Polygon edge not found" 知道如何处理吗?跨度>
    • 嗯。不幸的是,我无法重现该问题。我尝试将示例数据的范围增加到 10^5 * c(1:20)。然后我设置ylim = c(10^5, NA)y = 4.9 (= 5 -.1)。工作正常。