在 R 中调用 ggMarginal 后正确调整多个 ggExtraPlot objects 的大小
Properly size multiple ggExtraPlot objects after calling ggMarginal in R
我想用 ggExtra::ggMarginal
绘图创建 facet-like 效果。这是not yet directly possible,所以我尝试用patchwork::wrap_plots
、cowplot::plot_grid
和egg::ggarrange
自己做。我已经正确地开发了一切——除了情节大小。 patchwork
和 egg
使 ggplot
objects 的 面板 大小相同,但是此行为不适用于 ggMarginal
创建的 ggExtraPlot
objects。
例如,考虑以下 patchwork
of ggplot
s(下面的代码):
但是一旦我添加了边缘密度,排列就变成了这样:
如您所见,每个地块的 面板 大小不再相等;相反,整个 objects 都是。我希望第二个图中每个 ggplot
的面板大小与第一个图中的相同。
尝试的解决方案:
- 我试图确定轴相对于面板的宽度和高度,因为这样我就可以使用
wrap_plot
中的 widths
和 heights
参数来设置适当的相对大小ggMarginal
化的 objects;不幸的是,我花了很多时间没有成功地挖掘 ggplotGrob
输出。例如,我使用 grid::convertWidth(sum(ggplotGrob(p1)$widths), "in", TRUE)
和 grid::convertWidth(sum(ggplotGrob(p2)$widths), "in", TRUE)
来尝试以英寸为单位计算地块的宽度(p1
有 y-axis,p2
没有) ,但结果却大不相同:0.87 和 0.19。简单地删除轴标题、文本和刻度会大大减少宽度,这对我来说没有意义。当然,将相对宽度设置为 4.5 和 1 左右不会生成正确的 patchwork
图!
- 我尝试使用
patchwork::get_dim
和 patchwork::set_dim
手动设置每个子图的区域(使用 patchwork::area
)但无法弄清楚。
- 我也试过先创建拼图,然后将
ggMarginal
应用到拼图中的每个地块,但这没有用。
我很感激关于保证四个图的面板大小相等的建议,理想情况下不依赖于组件的实际大小(即以像素为单位)。看到 ggMarginal
允许分面并看到 patchwork
超越简单 ggplot
objects!
会很棒
b <- ggplot(mtcars, aes(x = disp, y = mpg)) +
geom_point() +
labs(x = "some\nlines",
y = "many\nnew\nlines")
p1 <- b +
theme(axis.title.x = element_blank(),
axis.text.x = element_blank(),
axis.ticks.x = element_blank())
p1m <- ggExtra::ggMarginal(p1, margins = "y")
p2 <- b +
theme(axis.title = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank())
p2m <- ggExtra::ggMarginal(p2, margins = "y")
p3 <- b
p3m <- ggExtra::ggMarginal(p3, margins = "y")
p4 <- b +
theme(axis.title.y = element_blank(),
axis.text.y = element_blank(),
axis.ticks.y = element_blank())
p4m <- ggExtra::ggMarginal(p4, margins = "y")
patchwork::wrap_plots(p1, p2, p3, p4, nrow = 2) # this looks great!
patchwork::wrap_plots(p1m, p2m, p3m, p4m, nrow = 2) # this doesn't :(
与其依赖 ggMarginal
,一种选择是手动创建密度图并使用 patchwork
:
将主图和密度图粘合在一起
library(ggplot2)
library(patchwork)
dp <- ggplot(mtcars, aes(y = mpg)) +
geom_density() +
theme_void()
list(p1, dp, p2, dp, p3, dp, p4, dp) |>
wrap_plots(nrow = 2, widths = c(5, 1, 5, 1))
我想用 ggExtra::ggMarginal
绘图创建 facet-like 效果。这是not yet directly possible,所以我尝试用patchwork::wrap_plots
、cowplot::plot_grid
和egg::ggarrange
自己做。我已经正确地开发了一切——除了情节大小。 patchwork
和 egg
使 ggplot
objects 的 面板 大小相同,但是此行为不适用于 ggMarginal
创建的 ggExtraPlot
objects。
例如,考虑以下 patchwork
of ggplot
s(下面的代码):
但是一旦我添加了边缘密度,排列就变成了这样:
如您所见,每个地块的 面板 大小不再相等;相反,整个 objects 都是。我希望第二个图中每个 ggplot
的面板大小与第一个图中的相同。
尝试的解决方案:
- 我试图确定轴相对于面板的宽度和高度,因为这样我就可以使用
wrap_plot
中的widths
和heights
参数来设置适当的相对大小ggMarginal
化的 objects;不幸的是,我花了很多时间没有成功地挖掘ggplotGrob
输出。例如,我使用grid::convertWidth(sum(ggplotGrob(p1)$widths), "in", TRUE)
和grid::convertWidth(sum(ggplotGrob(p2)$widths), "in", TRUE)
来尝试以英寸为单位计算地块的宽度(p1
有 y-axis,p2
没有) ,但结果却大不相同:0.87 和 0.19。简单地删除轴标题、文本和刻度会大大减少宽度,这对我来说没有意义。当然,将相对宽度设置为 4.5 和 1 左右不会生成正确的patchwork
图! - 我尝试使用
patchwork::get_dim
和patchwork::set_dim
手动设置每个子图的区域(使用patchwork::area
)但无法弄清楚。 - 我也试过先创建拼图,然后将
ggMarginal
应用到拼图中的每个地块,但这没有用。
我很感激关于保证四个图的面板大小相等的建议,理想情况下不依赖于组件的实际大小(即以像素为单位)。看到 ggMarginal
允许分面并看到 patchwork
超越简单 ggplot
objects!
b <- ggplot(mtcars, aes(x = disp, y = mpg)) +
geom_point() +
labs(x = "some\nlines",
y = "many\nnew\nlines")
p1 <- b +
theme(axis.title.x = element_blank(),
axis.text.x = element_blank(),
axis.ticks.x = element_blank())
p1m <- ggExtra::ggMarginal(p1, margins = "y")
p2 <- b +
theme(axis.title = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank())
p2m <- ggExtra::ggMarginal(p2, margins = "y")
p3 <- b
p3m <- ggExtra::ggMarginal(p3, margins = "y")
p4 <- b +
theme(axis.title.y = element_blank(),
axis.text.y = element_blank(),
axis.ticks.y = element_blank())
p4m <- ggExtra::ggMarginal(p4, margins = "y")
patchwork::wrap_plots(p1, p2, p3, p4, nrow = 2) # this looks great!
patchwork::wrap_plots(p1m, p2m, p3m, p4m, nrow = 2) # this doesn't :(
与其依赖 ggMarginal
,一种选择是手动创建密度图并使用 patchwork
:
library(ggplot2)
library(patchwork)
dp <- ggplot(mtcars, aes(y = mpg)) +
geom_density() +
theme_void()
list(p1, dp, p2, dp, p3, dp, p4, dp) |>
wrap_plots(nrow = 2, widths = c(5, 1, 5, 1))