首页 > 解决方案 > 将base和ggplot图形合并到图形设备的子图形中

问题描述

我想使用base R生成一个图数组,每个图都有自己的基于ggplot的插入图,向右对齐,略低于右上角,以便我可以在上面添加一些文本。像这样的东西(我已经使用 MS Paint 手绘了 ggplot 插入)。

在此处输入图像描述

我认为这可能使用viewports- 类似于这个问题。

# ggplot code for inserts
library(tidyverse)
g1 <- ggplot(data = mtcars, mapping = aes(x = cyl)) +
  geom_density(colour = "red") +
  theme_void()
g2 <- ggplot(data = mtcars, mapping = aes(x = disp)) +
  geom_density(colour = "red") +
  theme_void()
g3 <- ggplot(data = mtcars, mapping = aes(x = hp)) +
  geom_density(colour = "red") +
  theme_void()
g4 <- ggplot(data = mtcars, mapping = aes(x = drat)) +
  geom_density(colour = "red") +
  theme_void()
g5 <- ggplot(data = mtcars, mapping = aes(x = wt)) +
  geom_density(colour = "red") +
  theme_void()
g6 <- ggplot(data = mtcars, mapping = aes(x = qsec)) +
  geom_density(colour = "red") +
  theme_void()

我尝试过使用视口功能,但是,我无法将插入相对于每个子图放置(我认为它们都是基于整个图形设备放置的)...

library(grid)
par(mfrow = c(2, 3))
vps <- baseViewports()
plot(x = mtcars$mpg, y = mtcars$cyl)
pushViewport(vps$figure)
print(g1, vp = viewport(height = unit(0.2, "npc"), width = unit(0.2, "npc"), x = 1, y = 0.8, just  = 1))
plot(x = mtcars$mpg, y = mtcars$disp)
pushViewport(vps$figure)
# upViewport()
# popViewport()
print(g2, vp = viewport(height = unit(0.2, "npc"), width = unit(0.2, "npc"), x = 1, y = 0.8, just  = 1))
plot(x = mtcars$mpg, y = mtcars$hp)
print(g3, vp = viewport(height = unit(0.2, "npc"), width = unit(0.2, "npc"), x = 1, y = 0.8, just  = 1))
plot(x = mtcars$mpg, y = mtcars$drat)
print(g4, vp = viewport(height = unit(0.2, "npc"), width = unit(0.2, "npc"), x = 1, y = 0.8, just  = 1))
plot(x = mtcars$mpg, y = mtcars$wt)
print(g5, vp = viewport(height = unit(0.2, "npc"), width = unit(0.2, "npc"), x = 1, y = 0.8, just  = 1))
plot(x = mtcars$mpg, y = mtcars$qsec)
print(g6, vp = viewport(height = unit(0.2, "npc"), width = unit(0.2, "npc"), x = 1, y = 0.8, just  = 1))

在此处输入图像描述

标签: rggplot2plotviewport

解决方案


一种解决方案(不涉及在您想要制作的图上妥协)是使用layout参数 inviewpoint()为子图设置一个网格,该网格覆盖par(mfrow)/par(mfcol)网格。

将视点网格设置为多个par(mfrow)维度可以让您将子图很好地放置在所需的网格位置。视点网格的比例将决定子图的大小 - 因此更大的网格将导致更小的子图。

# base R plots
par(mfrow = c(2, 3))
plot(x = mtcars$mpg, y = mtcars$cyl)
plot(x = mtcars$mpg, y = mtcars$disp)
plot(x = mtcars$mpg, y = mtcars$hp)
plot(x = mtcars$mpg, y = mtcars$drat)
plot(x = mtcars$mpg, y = mtcars$wt)
plot(x = mtcars$mpg, y = mtcars$qsec)

# set up viewpoint grid
library(grid)
pushViewport(viewport(layout=grid.layout(20, 30)))

# add ggplot subplots (code for these objects in question) at `layout.pos.row`, `layout.pos.col` 
print(g1, vp = viewport(height = unit(0.2, "npc"), width = unit(0.05, "npc"), 
                        layout.pos.row = 2, layout.pos.col = 9))
print(g2, vp = viewport(height = unit(0.2, "npc"), width = unit(0.05, "npc"), 
                        layout.pos.row = 2, layout.pos.col = 19))
print(g3, vp = viewport(height = unit(0.2, "npc"), width = unit(0.05, "npc"), 
                        layout.pos.row = 2, layout.pos.col = 29))
print(g4, vp = viewport(height = unit(0.2, "npc"), width = unit(0.05, "npc"), 
                        layout.pos.row = 12, layout.pos.col = 9))
print(g5, vp = viewport(height = unit(0.2, "npc"), width = unit(0.05, "npc"), 
                        layout.pos.row = 12, layout.pos.col = 19))
print(g6, vp = viewport(height = unit(0.2, "npc"), width = unit(0.05, "npc"), 
                        layout.pos.row = 12, layout.pos.col = 29))

在此处输入图像描述

如果您有简单的基础 R 图,那么另一条路线是使用ggplotify将基础图转换为 ggplot,然后使用 cowplot 或拼凑进行放置。我无法让这适用于我想要的绘图,它使用了一组比上面的虚拟示例更复杂的绘图函数(在基础 R 中)。


推荐阅读