Добавление настраиваемой метки оси в граненую диаграмму ggplot

#r #ggplot2 #text #annotations #axis-labels

Вопрос:

Я пытаюсь добавить текстовый элемент с дополнительной информацией по оси x (один раз) в левой части моего текста по оси x граненого ggplot (не повторяйте его каждую грань).:

введите описание изображения здесь

До сих пор я терпел неудачу, перепробовав несколько подходов:

  • geom_text (отображается внутри графика)
  • функция аннотирования (отображается внутри графика в каждом аспекте)
  • axis.title.x (не удается настроить позицию по желанию, а именно x=- 1 и y=-1 более или менее)
  • mtext (не подходит для ggplot)

Мой код:

 #1.1 create labels for x-axis:
cfutypes_labels <- c("nativen-n-", "nativen-n ",
                     "aliquotn-n-", "aliquotn-n ",
                     "aliquotn n-", "aliquotn 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("storagetypenglycerolnfreeze-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
 

У кого-нибудь есть идеи, как это исправить?
Заранее большое спасибо!

Ответ №1:

Одним из вариантов было бы использовать geom_text примерно так:

Важно добавить coord_cartesian(clip = "off", ylim = c(1, NA)) , чтобы исправить шкалу y и предотвратить обрезку этикетки.

Кроме того, вам нужно освободить немного места для метки, что я и сделал, увеличив поля графика.

 extra_axis <- c("storagetypenglycerolnfreeze-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
)
 

Комментарии:

1. Спасибо за быстрый ответ @stefan Вы знаете, как адаптировать coord_cartesian(clip = "off", ylim = c(0, NA)) его к логарифмической шкале? Принимая предложенный вами код, я получаю сообщение об ошибке: Ошибка в grid.Call.graphics(C_setviewport, vp, TRUE) : не конечное местоположение или/и размер окна просмотра.

2. Привет, Аника. Ничего особенного. Проблема, конечно, в том, что нет журнала(0). Я просто внес правку, добавил масштаб журнала и установил ylim = c(1, NA) . В зависимости от желаемого результата и диапазона ваших данных вы, вероятно, скорректируете нижнюю границу для ограничений.

3. Привет, Стефан, спасибо тебе! извините, что беспокою вас, еще один вопрос: когда я устанавливаю ylim, как было предложено, мой график становится излишне большим, так как первые значения появляются примерно с 10^5. Поэтому я адаптировал пределы coord_cartesian и значения x/y для элемента geom_text. К сожалению, я получаю сообщение об ошибке здесь: Ошибка в сетке. Вызов(C_textBounds, как.graphicsAnnot(x$label), x$x, x$y, : Край полигона не найден» Есть идеи, как с этим справиться?

4. Хм. К сожалению, я не могу воспроизвести проблему. Я попытался увеличить диапазон данных моего примера до 10^5 * c(1:20). Затем я устанавливаю ylim = c(10^5, NA) и y = 4.9 (= 5-.1). Сработало отлично.