使用 coord_fixed 后从 ggplot 中删除空 space

Removing empty space from ggplot after coord_fixed is used

我正在尝试将三个不同的地块绘制在一起以形成一个更大的图。问题是 plot.margin(c(0,0,0,0), "cm") 没有按预期删除空格。如果我删除 coord_fixed.

,这些数字会按预期靠在一起

示例数据集、生成数据集的代码以及用于生成示例的代码。

数据集代码。

library(tidyverse)
library(cowplot)
n_pat <- 25
patient <- 1:n_pat
censoring <- ceil(rexp(n_pat, 1/30))
tumour_shrink <- (rbeta(n_pat, 2, 2) - 0.5) * 100

n_params <- 15
parameters <- paste("Parameter", 1:n_params)

response <- sample(c("PR", "NE", "CR", "PD", "SD"), size=n_pat,
                   replace = T)

missing_combination <- sample(c(TRUE, FALSE), size=n_pat, replace=T)

changes <- matrix(runif(n_pat * n_params, 1, 100), nrow=n_pat, ncol=n_cytokines)
changes[sample(1:dim(changes)[1], 4, replace = FALSE), sample(1:dim(changes)[2], 5, replace = F)] <- NA

df <- data.frame(patient, censoring, tumour_shrink, changes, missing_combination)
colnames(df) <- c("patient", "censoring", "tumour_shrink", cytokines, "missing_combination")

地块代码:

p1 <- df %>%
  mutate(color = case_when(
    response == "PR" ~ "lightgreen",
    response == "NE" ~ "white",
    response == "CR" ~ "darkgreen",
    response == "PD" ~ "red",
    response == "SD" ~ "yellow"
  )) %>% 
  arrange(tumour_shrink) %>% 
  mutate(patient = factor(patient, levels=patient)) %>% 
  ggplot(aes(x=patient, y=1, fill=color)) +
  geom_raster() +
  coord_fixed() +
  geom_tile(color="black", size=1) +
  geom_text(aes(label=response), size=3) +
  theme(axis.text = element_blank(),
        axis.ticks = element_blank(),
        legend.position = "none",
        axis.ticks.length = unit(0, "mm"),
        axis.title.y = element_text(angle = 0, vjust=0.57, size = 12),
        plot.margin = unit(c(0, 0, 0, 0), "cm")) +
  scale_fill_identity() +
  labs(y="Best ov. resp", x=NULL)

p2 <- df %>%
  arrange(tumour_shrink) %>% 
  mutate(patient = factor(patient, levels=patient)) %>% 
  mutate(color = ifelse(missing_combination, "white", "gray")) %>% 
  ggplot(aes(x=patient, y=1, fill=color)) +
  geom_raster() +
  geom_tile(color="black", size=1) +
  geom_text(aes(label=censoring), size=3) +
  scale_fill_identity() + 
  labs(y="Censoring", x=NULL) +
  coord_fixed() +
  theme(axis.text = element_blank(),
        axis.title = element_blank(),
        axis.ticks = element_blank(),
        axis.ticks.length = unit(0, "mm"),
        legend.position = "none",
        axis.title.y = element_text(angle = 0, vjust=0.57, size=12),
        plot.margin = unit(c(0, 0, 0, 0), "pt"))

p3 <- df %>% 
  arrange(tumour_shrink) %>% 
  mutate(patient = factor(patient, levels=patient)) %>% 
  ggplot(aes(x=factor(patient), y=1, fill=tumour_shrink)) +
  geom_raster(alpha=0.8) +
  geom_tile(color="black", size=1) +
  coord_fixed() +
  geom_text(aes(label=formatC(tumour_shrink, 0, format="f")), 
            size=3) +
  theme(axis.text = element_blank(),
        axis.title = element_blank(), 
        axis.ticks = element_blank(),
        axis.ticks.length = unit(0, "mm"),
        axis.title.y = element_text(angle = 0, vjust=0.57, size=12),
        plot.margin = unit(c(0, 0, 0, 0), "cm"),
        legend.position = "none") +
  scale_fill_gradient(low="green", high="red") +
  labs(y="Tumour shrink", x=NULL)

plot_grid(p1, p2, p3, ncol=1, align="v", axis="lr")

patchwork 包提供了一个简单的解决方案:

library(patchwork)
wrap_plots(p1, p2, p3, ncol=1)

另一种选择:将所有内容绘制在一个图中。这样做的好处是您可以完全控制间距,并且减少了对 cowplot/patchwork.

的需求

这需要对您的绘图方法进行一些更改:

  • 为每一行定义不同的 color,facilitated/enabled 通过使用 scale_fill_identity;
  • 每个几何体分开 y=
  • 使用 rank(-tumour_shrink) 作为 x 值而不是 patient;
  • 删除 axis.ticks 主题,因为我(滥用)将它们用于“审查”(等)y 轴标签(并手动分配这些标签);和
  • 添加更多主题元素以移除背景网格。

为了可重复性,我将ceil替换为ceiling,并设置了随机种子:

set.seed(42)
# df <- ...
head(df)
#   patient censoring tumour_shrink Cytokine 1 Cytokine 2 Cytokine 3 Cytokine 4 Cytokine 5
# 1       1         6     -4.554208   45.73676  78.626829   57.88910  56.582358   87.05652
# 2       2        20     42.752870   32.38828  13.758344   35.98169   8.001468   21.29991
# 3       3         9     10.031523         NA  13.779839   55.19518         NA         NA
# 4       4         2      8.484090   19.42411   8.153058   89.37914  55.412421   88.78861
# 5       5        15    -11.012928   73.24328   6.259819   49.50907  48.716163   14.49329
# 6       6        44     21.390972   41.77534  53.655569   17.99158  16.787516   78.74959
#   Cytokine 6 Cytokine 7 Cytokine 8 Cytokine 9 Cytokine 10 Cytokine 11 Cytokine 12 Cytokine 13
# 1  73.439052   30.38779  10.000912  61.971232    52.95427   26.663044    92.21165   32.736054
# 2  32.210819   65.66861  80.061067  92.588889    66.02428   78.010740    36.89758   19.686203
# 3  39.258947   90.20598         NA  39.612267          NA   43.220164    85.65836   39.989134
# 4  33.912153   99.08878   5.008270  29.504049    72.40138    6.944785    30.78971   86.340576
# 5   9.888019   43.60299   5.067548   9.982861    49.58429   12.368421    47.10058   35.443229
# 6  75.948505   39.98392  95.488990  32.881356    96.56030   48.792933    15.13034    1.141956
#   Cytokine 14 Cytokine 15 missing_combination
# 1    48.93261    16.28906                TRUE
# 2    84.69391    27.37059               FALSE
# 3    42.21307    35.72471                TRUE
# 4    49.44491    58.26738                TRUE
# 5    19.14549    81.05158                TRUE
# 6    76.15699    93.39376               FALSE

我任意使用 1、3 和 5 作为 y 值,您显然可以更改它们以满足您的需要。

library(dplyr)
library(ggplot2)
df %>%
  arrange(tumour_shrink) %>% 
  mutate(
    xval = rank(-tumour_shrink),
    patient = factor(patient),
    color1 = case_when(
      response == "PR" ~ "lightgreen",
      response == "NE" ~ "white",
      response == "CR" ~ "darkgreen",
      response == "PD" ~ "red",
      response == "SD" ~ "yellow"
    ),
    color2 = if_else(missing_combination, "white", "gray"),
    color3 = do.call(rgb, asplit(colorRamp(colors = c("green", "red"))(
      (tumour_shrink - min(tumour_shrink)) / diff(range(tumour_shrink))
    )/255, 2))
  ) %>%
  ggplot(aes(x = xval)) +
  coord_fixed() +
  # plot 1
  geom_tile(aes(y = 5, fill = color1), color="black") +
  geom_text(aes(y = 5, label = response), size=3) +
  # plot 2
  geom_tile(aes(y = 3, fill=color2), color="black") +
  geom_text(aes(y = 3, label=response), size=3) +
  # plot 3
  geom_tile(aes(y = 1, fill = color3), color = "black") +
  geom_text(aes(y = 1, label = formatC(tumour_shrink, 0, format="f")), 
            size=3) +
  theme(
    legend.position = "none",
    axis.ticks.length = unit(0, "mm"),
    axis.title.y = element_text(angle = 0, vjust=0.57, size = 12),
    plot.margin = unit(c(0, 0, 0, 0), "cm"),
    panel.background = element_blank(),
    panel.grid.major = element_blank(),
    panel.grid.minor = element_blank()) +
  scale_fill_identity() +
  scale_y_continuous(
    name = NULL, breaks = c(5,3,1),
    labels = c("Best ov. resp", "Censoring", "Tumour shrink")) +
  scale_x_discrete(name = NULL)

我承认 do.call(rgb, ...) 有点过头了,但它提供了相同的效果,而且我从来没有真正喜欢过矩阵 return - [=23 的值=]. (同样,该部分是通过使用 scale_fill_identity 启用的,没有它就不会是 easy/feasible。)