水平对齐条和面

Horizontally align bars and facets

我有这两个data.frames

df1 <- 
  data.frame(unit = factor(1:20, levels = 20:1),
             value = sample(1:10, 20, replace = T))

df2 <- 
  data.frame(unit = 
               factor(as.vector(sapply(1:20, FUN = function(x) rep(x, 10))).
                      levels = 1:20),
             time = rep(1:10, 20), 
             value = sample(1:100, 10*20, replace = T))

我想像这样并排绘制:

library(ggplot2)
library(cowplot)
plot_grid(ggplot(df1, aes(x=value,y=unit)) +
            geom_bar(stat = 'identity') +
            scale_x_continuous(position = "top"),
          ggplot(df2, aes(x=time,y=value)) +
                   geom_line() +
                   facet_grid(rows = vars(unit), scales = "free_y") +
            scale_x_continuous(position = "top") +
            theme(axis.text.y = element_text(size=6)),
          ncol = 2)

导致此输出

仍然,来自同一 unit 的两个图的行映射变量未完全对齐:

以编程方式对齐它们的最简单方法是什么(以便它也适用于不同数量的 unit)?该解决方案不需要涉及 cowplot 包。

实现此目的的一个简单解决方案是对条形图也使用分面。只要两个图中面板之间的间距相同,就应确保每组的条形图和线图对齐。试试这个:

df1 <- 
  data.frame(unit = factor(1:20, levels = 20:1),
             value = sample(1:10, 20, replace = T))

df2 <- 
  data.frame(unit = factor(as.vector(sapply(1:20, FUN = function(x) rep(x, 10))), levels = 1:20),
             time = rep(1:10, 20), 
             value = sample(1:100, 10*20, replace = T))

library(ggplot2)
library(cowplot)

plot_grid(ggplot(df1, aes(x=value,y=unit)) +
            geom_bar(stat = 'identity') +
            facet_grid(rows = vars(unit), scales = "free_y") +
            scale_x_continuous(position = "top") +
            theme(panel.spacing.y = unit(1, "pt"), strip.text = element_blank()),
          ggplot(df2, aes(x=time,y=value)) +
            geom_line() +
            facet_grid(rows = vars(unit), scales = "free_y") +
            scale_x_continuous(position = "top") +
            theme(axis.text.y = element_text(size=6), panel.spacing.y = unit(1, "pt")),
          ncol = 2)

如果我们查看图的对齐方式,似乎很明显要使条形图与相应的面相匹配,我们必须去掉条形图 y 轴两端的 space .我们可以用 scale_y_discrete(expand = c(0, 0)) 来做到这一点。我们还可以缩放条形的宽度,使其等于每个分面面板在其分配的视口中所占的比例。不幸的是,这在某种程度上取决于设备尺寸。但是,0.8 或 0.9 的宽度会让您非常接近。

plot_grid(ggplot(df1, aes(x=value,y=unit)) +
            geom_bar(stat = 'identity', width = 0.8) +
            scale_x_continuous(position = "top") +
            scale_y_discrete(expand = c(0, 0)),
          ggplot(df2, aes(x=time,y=value)) +
                   geom_line() +
                   facet_grid(rows = vars(unit), scales = "free_y") +
            scale_x_continuous(position = "top") +
            theme(axis.text.y = element_text(size=6)),
          ncol = 2)