在调用r中调用ggmarginal后,适当尺寸多个ggextraplot对象

发布于 2025-02-03 10:11:13 字数 2811 浏览 3 评论 0原文

我想使用ggextra :: ggmarginal图创建类似facet的效果。这是尚未直接可能,所以我尝试使用patchwork :::::::: wrap_plotscowplot :: plot_gridegg :: ggarrange自己做。我拥有正确开发的所有东西 - 除了情节尺寸。 patchworkegg制作 ggplotggplot 对象相同的大小,但是此行为不适用于ggextraplot ggmarginal创建的对象。

例如,考虑ggplot s(代码下)的以下patchwork

但是一旦我添加了边缘密度,安排就会如下:

如您所见,每个图的 不再同样尺寸 相反,整个对象是。我希望第二个图中的每个ggplot的面板大小与第一个图相同。

尝试的解决方案:

  • 我尝试确定相对于面板的轴的宽度和高度,因为那时我可以使用widths and heights wrap_plot 设置ggmarginal -ized对象的适当相对尺寸;不幸的是,我花了很多时间在ggplotgrob输出中挖掘失败。例如,我使用grid :: convertwidth(sum(ggplotgrob(p1)$ widths),“ in”,true)grid :: convertwidth(sum(ggplotgrob(p2)$ widths $ widths ),“ in”,true)尝试以英寸为单位计算图的宽度(p1具有y轴,p2 not) ,但结果大不相同:0.87和0.19。对我来说,简单地删除轴标题,文字和滴答就不会大大降低宽度,这对我来说是没有意义的。当然,将相对宽度设置为4.5左右,而1不会生成适当的patchwork图!
  • 我尝试使用patchwork :: get_dimpatchwork :: set_dim来手动设置每个子图的区域(使用patchwork :: afeartwork :: reage)但是无法弄清楚。
  • 我还尝试首先创建拼布,然后将ggmarginal应用于拼布中的每个图,但这无效。

我很感谢您保证为四个图提供相同面板尺寸的建议,理想情况下,不依赖组件的实际尺寸(即,以像素为单位)。看到ggmarginal允许faceting并查看patchwork扩展超越简单ggplot对象,这将是很棒的!

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 :(

I want to create a facet-like effect with ggExtra::ggMarginal plots. This is not yet directly possible, so I tried to use patchwork::wrap_plots, cowplot::plot_grid, and egg::ggarrange to do it myself. I have everything properly developed—except for the plot sizing. patchwork and egg make the panels of ggplot objects the same size, but this behavior does not apply to the ggExtraPlot objects that ggMarginal creates.

For example, consider the following patchwork of ggplots (code below):
four ggplots correctly sized

But once I add the marginal densities, the arrangement looks like this:
four ggplots incorrectly sized

As you can see, the panels of each plot are no longer equally sized; rather, the entire objects are. I want the panel sizes of each ggplot in the second plot to be the same, as in the first plot.

Attempted solutions:

  • I tried to determine the width and height of the axes relative to the panel, because then I could use the widths and heights arguments in wrap_plot to set proper relative sizes of the ggMarginal-ized objects; unfortunately, I spent many hours unsuccessfully digging through the ggplotGrob output. For instance, I used grid::convertWidth(sum(ggplotGrob(p1)$widths), "in", TRUE) and grid::convertWidth(sum(ggplotGrob(p2)$widths), "in", TRUE) to attempt to calculate the widths of the plots in inches (p1 has a y-axis, p2 doesn't), but the results were vastly different: 0.87 and 0.19. It didn't make sense to me that simply removing the axis title, text, and ticks would so heavily decrease the width. Certainly setting the relative widths at around 4.5 and 1 wouldn't generate the proper patchwork plot!
  • I tried to use patchwork::get_dim and patchwork::set_dim to manually set the area for each subplot (using patchwork::area) but couldn't figure it out.
  • I also tried to create the patchwork first and then apply ggMarginal to each plot in the patchwork, but this didn't work.

I would appreciate advice on guaranteeing equal panel sizes for the four plots, ideally without relying on the actual size (i.e., in pixels) of the components. It would be awesome to see ggMarginal allow faceting and to see patchwork extend beyond simple 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 :(

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

苏辞 2025-02-10 10:11:13

而不是依靠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))

”“

Instead of relying on ggMarginal one option would be to manually create your density plots and glue both your main and the density plots together using 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))

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文