R:改变某些面行的高度,同时保持 y 轴比例

问题描述 投票:0回答:2

我将

ggplot
排列在
facet_grid()
中,导致 6 个图排列为 3 列 x 2 行。我希望每列面都有自己的 y 轴范围。但是,我希望独立的列有自己的 y 轴刻度。为了实现这一点,我将每列面保存为独立的图,然后使用
patchwork
将图缝合在一起。

您会注意到底行中的绘图包含大量空白。我想修剪底行中的图,以便仅显示 y 轴的相关部分,但重要的是,我希望 y 轴的相对比例与其上面的图一致。

例如,假设顶行中的图占据 10 个单位的高度。底行的适当相对高度为 2 个单位,并且每个图的 y 轴范围会有所不同。我可以手动定义新的高度和范围。

我尝试过将所有 6 个面分成单独的图,然后将它们缝合在一起。但是,我仅在某些绘图中包含小面条文本(以在我的示例中重新创建图像),这使得相对绘图高度难以计算。

有没有更简单的方法可以使用 ggplot2 或其他包来做到这一点?

谢谢!

combined_plot_v1

library(tidyverse)
library(patchwork)

set.seed(42)

A1 <- sample(seq(0, 14.5, by = 0.1), 2500, replace=TRUE)
B1 <- sample(seq(0, 19.5, by = 0.1), 2500, replace=TRUE)
C1 <- sample(seq(0, 29.5, by = 0.1), 2500, replace=TRUE)

A2 <- sample(seq(0, 2.9, by = 0.01), 2500, replace=TRUE)
B2 <- sample(seq(0, 3.9, by = 0.01), 2500, replace=TRUE)
C2 <- sample(seq(0, 4.9, by = 0.01), 2500, replace=TRUE)


df <- data.frame(
  Position = rep(seq(1:2500), times = 6),
  Signal = c(A1, A2, B1, B2, C1, C2),
  Sample = factor(rep(c("A", "B", "C"), each = 5000), levels = c("A", "B", "C")),
  Group = factor(rep(c("Treatment", "Control"), each = 2500, times = 3), levels = c("Treatment", "Control"))
  )

df_A <- df %>%
  filter(Sample == "A")

df_B <- df %>%
  filter(Sample == "B")

df_C <- df %>%
  filter(Sample == "C")

fillscale <- c("#0496A3", "#7D3B49", "#869D53")

PlotA <- ggplot() +
  geom_area(data = df_A, aes(x=Position, y=Signal, fill=Sample), col=NA, linewidth=0) +
  facet_grid(Group~Sample) +
  scale_fill_manual(values=c(fillscale[[1]])) +
  scale_x_continuous(breaks = c(1, 1000, 1500, 2500),
                     labels = c("label 1", "ON", "OFF", "label 2")) +
  ylim(0,15) +
  labs(y="Signal", x="") +
  theme_bw() +
  theme(
    legend.position = "none", 
    axis.title.x = element_text(),
    axis.title.y = element_text(size = 10),
    axis.text.x = element_text(size = 10),
    axis.text.y = element_text(size = 10),
    strip.text.y = element_blank(),
    strip.background.y = element_blank(),
    plot.margin = margin(t = 0.194, r = 0.40, b = 0.194, l = 0.194, unit = "cm") # Default is 0.194 cm
  )

PlotB <- ggplot() +
  geom_area(data = df_B, aes(x=Position, y=Signal, fill=Sample), col=NA, linewidth=0) +
  facet_grid(Group~Sample) +
  scale_fill_manual(values=c(fillscale[[2]])) +
  scale_x_continuous(breaks = c(1, 1000, 1500, 2500),
                     labels = c("label 1", "ON", "OFF", "label 2")) +
  ylim(0,20) +
  labs(y="Signal", x="") +
  theme_bw() +
  theme(
    legend.position = "none", 
    axis.title.x = element_text(),
    axis.title.y = element_text(size = 10),
    axis.text.x = element_text(size = 10),
    axis.text.y = element_text(size = 10),
    strip.text.y = element_blank(),
    strip.background.y = element_blank(),
    plot.margin = margin(t = 0.194, r = 0.40, b = 0.194, l = 0.194, unit = "cm")
  )

PlotC <- ggplot() +
  geom_area(data = df_C, aes(x=Position, y=Signal, fill=Sample), col=NA, linewidth=0) +
  facet_grid(Group~Sample) +
  scale_fill_manual(values=c(fillscale[[3]])) +
  scale_x_continuous(breaks = c(1, 1000, 1500, 2500),
                     labels = c("label 1", "ON", "OFF", "label 2")) +
  ylim(0,30) +
  labs(y="Signal", x="") +
  theme_bw() +
  theme(
    legend.position = "none", 
    axis.title.x = element_text(),
    axis.title.y = element_text(size = 10),
    axis.text.x = element_text(size = 10),
    axis.text.y = element_text(size = 10),
    axis.ticks.length.x = unit(0, "cm"),
    plot.margin = margin(t = 0.194, r = 0.194, b = 0.194, l = 0.194, unit = "cm")
  )

combined_plot_v1 <- PlotA | PlotB | PlotC

ggsave("~/Desktop/CombinedPlotv1.pdf", combined_plot_v1, device = "pdf", width = 7.5, height = 2.6)

R 4.3.2
ggplot2 3.5.0
拼布1.2.0

r ggplot2 facet-grid
2个回答
1
投票

如果您删除每个图 A、B 和 C 中的

ylim()
规范,并在
scales="free_y"
调用中使用
facet_grid()
,您将生成如下所示的内容:

using free_y plot


0
投票

您可以在此处使用 ggh4x 包轻松更改各个面的高度(行)和/或宽度(列)。

library(ggh4x)

PlotA <- ggplot() + ... 
  facet_grid(Group~Sample, scales="free_y") + ... # scales="free_y"
 #ylim(0,15) + ...   # You don't want this
  force_panelsizes(rows = c(5, 1))

可以根据每组最大信号的比率计算相对高度(5:1)。

summarise(df_A, max(Signal), .by=Group)
      Group max(Signal)
1 Treatment        14.5
2   Control         2.9

14.5/2.9 # 5

对另外两个执行此操作,您应该得到以下结果:

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.