3

我正在尝试使用特定坐标将多个图(不同大小)绘制到网格上。为此,我正在使用treemap包创建一个树形图以获取坐标,然后使用这些坐标,我试图放置我的个人图。希望我下面的例子能更好地解释我的问题。

首先,我创建了一些条形图,然后创建了一个树形图,如下所示:

library(ggplot2)
library(treemap)
#create data
df <- data.frame(var1 = c("A", "B", "C"),
             var2 = runif(3),
             var3 = runif(3),
             var4 = runif(3),
             size = c(10, 5, 3),
             labels = c(1:3))
# Basic barplot
p1 <- ggplot(data=df, aes(x=var1, y=var2)) +
   geom_bar(stat="identity")
p2 <- ggplot(data=df, aes(x=var1, y=var3)) +
   geom_bar(stat="identity")
p3 <- ggplot(data=df, aes(x=var1, y=var4)) +
  geom_bar(stat="identity")

#create treemap
tm <- treemap(df,
       index = "labels",
       vSize = "size",
       palette = "Set2")

如果我们看一下 treemap 对象tm,我们可以看到它提供了如下所示的 treemap 的坐标,其中x0y0wh是坐标。

> tm$tm
  labels vSize vColor stdErr vColorValue level        x0    y0         w     h   color
1      1    10      1     10          NA     1 0.0000000 0.000 0.5555556 1.000 #66C2A5
2      2     5      1      5          NA     1 0.5555556 0.375 0.4444444 0.625 #FC8D62
3      3     3      1      3          NA     1 0.5555556 0.000 0.4444444 0.375 #8DA0CB

树状图

所以,我想做的是把我的三个条形图p1p2并将p3它们放入树形图中,以便在树形图p1的位置1......p2将在适当的位置2等......

为了清楚起见,我想要的结果看起来像这样: 地块树状图

关于我如何做到这一点的任何建议?我尝试使用该patchwork软件包,但遇到了地块重叠的问题......但我愿意接受使用任何软件包的建议(例如gridExtra或只是ggplot

编辑 澄清一些事情,根据下面彼得给出的关于patchwork包的答案,我不能手动输入坐标作为绘图布局(我最初使用area函数patchwork并将树形图的坐标输入到area函数中) . 但是,正如下面评论中提到的,如果我有很多条形图,并且树形图的大小和形状发生了变化,那么我不能手动输入布局值。我正在尝试找到一种方法来自动化该过程

4

2 回答 2

3

这需要一些算术,并不完美,但应该是使用patchwork's 更复杂的布局选项的开始。有几个技巧可以解决:

  • treemap根据视口缩放其尺寸,这意味着它计算的位置取决于例如 RStudio 的绘图窗格中的查看器。相反,这不是绝对必要的,但您可能应该决定纵横比以确保框的位置是您想要的。
  • 您需要将小数位和大小转换为整数,而不是简单地乘以某个数字并四舍五入,而是通过找到它们的小数等价物的分母并乘以它。例如,第一个框的宽度为 0.55555,即 5/9;要获得整数,我们需要知道这个盒子应该是 9 个单位中的 5 个单位宽。取最大宽度和高度是任意的;关键是要得到一个不等于 1.0 的值。
  • 从不同的维度加减 1 并不是最好的,但它是一种足够简单的方法来获得例如一个从 1 到 5 的盒子,下一个从 6 到 9 的盒子。
  • 情节的顺序不对,但大小是......还没有弄清楚为什么,但为了尝试诊断这个我为每个情节添加了标签。
library(ggplot2)
library(treemap)
library(dplyr)

asp <- 1.25
tm <- treemap(df, index = "labels", vSize = "size", palette = "Set2", sortID = "labels",
              aspRatio = asp)
denoms <- tm$tm %>%
  tidyr::pivot_longer(w:h, names_to = "direction") %>%
  filter(value < 1) %>%
  group_by(direction) %>%
  slice_max(value, n = 1) %>%
  mutate(denom = MASS::fractions(value) %>%
           stringr::str_extract("\\d+$") %>%
           as.numeric()) %>%
  select(direction, denom) %>%
  tibble::deframe()
denoms
#> h w 
#> 8 9
areas <- tm$tm %>%
  mutate(across(c(x0, w), ~. * denoms[["w"]]),
         across(c(y0, h), ~. * denoms[["h"]]),
         top = y0 + 1,
         left = x0 + 1,
         bottom = top + h - 1,
         right = left + w - 1) %>%
  select(top:right) %>%
  purrr::pmap(function(top, left, bottom, right) patchwork::area(top, left, bottom, right)) %>%
  purrr::reduce(c)

patchwork::wrap_plots(p1, p2, p3, design = areas)

于 2021-11-29T01:23:49.510 回答
2

patchwork似乎工作正常:

library(patchwork)
library(ggplot2)


design <- "
  11122
  11122
  11133
"
p1 + p2 + p3 + plot_layout(design = design)

reprex 包于 2021-11-28 创建(v2.0.1)

于 2021-11-28T21:56:33.717 回答