ggplot2 — равные расстояния по оси x между гранеными участками

#r #ggplot2 #data-visualization #facet #ggpubr

#r #ggplot2 #визуализация данных #фасет #ggpubr

Вопрос:

Предположим, что три набора данных ( A , B , и C ), каждый из которых представляет фрейм данных с четырьмя столбцами. Данные в каждом наборе данных сопоставляются, причем первая половина всех строк представляет состояние «bf«, а вторая половина всей строки представляет состояние «после«. Количество строк в каждом наборе данных разное, причем набор C содержит столько же или больше строк, чем A и B вместе взятых.

 A = structure(list(marker = c("a", "b", "c", "d", "a", "b", "c", "d", "a", "b", "c", "d", "a", "b", "c", "d"), value = c("0.962", "0.923", "0.921", "0.938", "0.949", "0.898", "0.811", "1", "0.967", "0.944", "0.946", "0.96", "0.889", "0.923", "0.864", "1"), metric = c("rc", "rc", "rc", "rc", "ci", "ci", "ci", "ci", "rc", "rc", "rc", "rc", "ci", "ci", "ci", "ci"), treatment = c("b4", "b4", "b4", "b4", "b4", "b4", "b4", "b4", "after", "after", "after", "after", "after", "after", "after", "after")), row.names = c(NA, -16L), class = "data.frame")
B = structure(list(marker = c("a", "b", "a", "b", "a", "b", "a", "b"), value = c("1", "0.967", "0.966", "0.962", "1", "1", "0.967", "0.965"), metric = c("rc", "rc", "ci", "ci", "rc", "rc", "ci", "ci"), treatment = c("b4", "b4", "b4", "b4", "after", "after", "after", "after")), row.names = c(NA, -8L), class = "data.frame")
C = structure(list(marker = c("a", "b", "c", "d", "e", "f", "a", "b", "c", "d", "e", "f", "a", "b", "c", "d", "e", "f", "a", "b", "c", "d", "e", "f"), value = c("0.944", "0.934", "0.947", "0.944", "0.949", "0.922", "0.909", "0.923", "0.958", "0.857", "0.9", "0.914", "0.944", "0.934", "0.947", "0.944", "0.949", "0.922", "0.909", "0.923", "0.958", "0.857", "0.9", "0.914"), metric = c("rc", "rc", "rc", "rc", "rc", "rc", "ci", "ci", "ci", "ci", "ci", "ci", "rc", "rc", "rc", "rc", "rc", "rc", "ci", "ci", "ci", "ci", "ci", "ci"), treatment = c("b4", "b4", "b4", "b4", "b4", "b4", "b4", "b4", "b4", "b4", "b4", "b4", "after", "after", "after", "after", "after", "after", "after", "after", "after", "after", "after", "after")), row.names = c(NA, -24L), class = "data.frame")
  

Предположим далее, что мы хотим визуализировать изменчивость значения столбца между различными классами.

 library(ggplot2)
library(ggpubr)

Plot_A = ggplot(data=data.frame(A), aes(x=marker, y=as.numeric(value), group=treatment, color=metric))  
    facet_grid(metric ~ .)   
    geom_line(aes(linetype=treatment))   
    theme(axis.text.x=element_text(angle=45, hjust=1),
          legend.position="none",
          axis.title.x=element_blank())  
    ylab("")

Plot_B = ggplot(data=data.frame(B), aes(x=marker, y=as.numeric(value), group=treatment, color=metric))  
    facet_grid(metric ~ .)   
    geom_line(aes(linetype=treatment))   
    theme(axis.text.x=element_text(angle=45, hjust=1),
          legend.position="none",
          axis.title.x=element_blank())  
    ylab("")

Plot_C = ggplot(data=data.frame(C), aes(x=marker, y=as.numeric(value), group=treatment, color=metric))  
    facet_grid(metric ~ .)   
    geom_line(aes(linetype=treatment))   
    theme(axis.text.x=element_text(angle=45, hjust=1),
          legend.position="bottom")   
    xlab("Marker")  
    ylab("Value")
ggarrange(Plot_A, Plot_B, Plot_C, nrow=3,  ncol=1)
  

Как я могу гарантировать, что расстояния по оси x между отдельными маркерами на обоих графиках A и B такие же, как на графике C?

Это то, чего я хочу достичь (без необходимости редактировать ширину отдельных участков вручную):

Иллюстрация желаемого результата

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

1. Я подумал, что пакет patchwork может здесь помочь. (Plot_A | plot_spacer()) / (Plot_B | plot_spacer() | plot_spacer()) / Plot_C получается что-то близкое к тому, что вы хотите, но оси не выровнены идеально. Так что это не решение… но опубликуйте его здесь, если это все равно поможет.

Ответ №1:

Возможно, этот подход может вам помочь. Вы можете добавлять scale_x_discrete(limits=unique(C$marker)) к A B графикам и, чтобы сохранить одинаковые уровни на всех графиках. Вот код. Также вы можете создать независимый вектор для уровней по оси x и использовать его непосредственно как vec=c("a", "b", "c", "d", "e", "f") и тогда scale_x_discrete(limits=vec) . Ключевым моментом является фиксация этого элемента на всех требуемых графиках:

 library(ggplot2)
library(ggpubr)

Plot_A = ggplot(data=data.frame(A), aes(x=marker, y=as.numeric(value), group=treatment, color=metric))  
  facet_grid(metric ~ .)   
  geom_line(aes(linetype=treatment))   
  scale_x_discrete(limits=unique(C$marker)) 
  theme(axis.text.x=element_text(angle=45, hjust=1),
        legend.position="none",
        axis.title.x=element_blank())  
  ylab("")

Plot_B = ggplot(data=data.frame(B), aes(x=marker, y=as.numeric(value), group=treatment, color=metric))  
  facet_grid(metric ~ .)   
  geom_line(aes(linetype=treatment))   
  scale_x_discrete(limits=unique(C$marker)) 
  theme(axis.text.x=element_text(angle=45, hjust=1),
        legend.position="none",
        axis.title.x=element_blank())  
  ylab("")

Plot_C = ggplot(data=data.frame(C), aes(x=marker, y=as.numeric(value), group=treatment, color=metric))  
  facet_grid(metric ~ .)   
  geom_line(aes(linetype=treatment))   
  scale_x_discrete(limits=unique(C$marker)) 
  theme(axis.text.x=element_text(angle=45, hjust=1),
        legend.position="bottom")   
  xlab("Marker")  
  ylab("Value")

ggarrange(Plot_A, Plot_B, Plot_C, nrow=3,  ncol=1)
  

Вывод:

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

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

1. Спасибо, но это не то, что я ищу. Я расширил свой вопрос изображением желаемого результата.

2. @MichaelG Я сейчас проверю!