R ggplot2分面保持比例但覆盖/定义输出图大小

6

我目前正在使用ggplot2比较来自不同地区的不同组的统计数据。这是通过一个Web应用程序(tikiwiki CMS + plugin R)完成的,该应用程序运行R脚本。每个地区可以有2到30个或更多的组。相同的R脚本在唯一的网页中运行所有数据,结果根据所选择的地区 - 作为页面参数而调整。

目前,我的代码如下:

region 1: 12 groups = 12 medium facets
region 2: 3 groups = 3 **HUGE** facets
region 3: 24 groups = 24 **TINY** facets
region 4: 16 groups = 16 medium facets
...

区域2

较少组

区域3

更多组

我想要的结果是:

区域2

在此输入图片描述

区域3 保持不变

我使用facet_wrap(~data, ncol=4)按组进行分面,因此可以有2个或30多个子图。问题在于输出:要么将30个子图塞进一个小盒子中,要么将两个子图放大到相同大小的盒子中——请参见上面的图片... 我找不到如何修复比例(或图像最大宽度)但保持最终图片尺寸自由的方法。

在ggplot2 / R中是否可以固定分面的默认大小,并使所得图片的大小根据子图数量自适应?

如果ggplot2 / R中不可能实现,那么是否有任何JavaScript / jQuery库可以获取代码并正确显示结果(d3,...)?


你能否根据图形的分面数量将其保存为可移植格式(例如使用ggsave),并使用javascript / jQuery进行调用? - Roman Luštrik
谢谢Roman,我会探索这个解决方案(根据facet数量计算ggsave的高度/宽度大小,然后将其用作输出)。 - Joel.O
我在想,2017年是否有更优雅的解决方案。 - tic-toc-choc
1个回答

5

您可以将gtable的高度设置为物理单位(例如厘米)而不是相对值("null")

require(ggplot2)
p = qplot(Sepal.Width, Sepal.Length, data=iris) + facet_wrap(~Species, ncol=1)
g = ggplotGrob(p)

panels = which(sapply(g[["heights"]], "attr", "unit") == "null")
g[["heights"]][panels] = list(unit(4, "cm"), unit(8, "cm"), unit(2, "cm"))

device.height = convertHeight(sum(g[["heights"]]), "in", valueOnly=TRUE)

pdf("test.pdf", height = device.height)
grid.draw(g)
dev.off()

输入图像描述

编辑 作为跟进,这里有一个函数可以将所有面板的高度和宽度设置为固定值,

freeze_panels <- function(p, draw=TRUE,
                          width=unit(5,"cm"),
                          height=unit(1,"in")){
  require(grid)
  g  <-  ggplotGrob(p)

  vertical_panels <-which(sapply(g[["heights"]], "attr", "unit") == "null")
  horizontal_panels <-which(sapply(g[["widths"]], "attr", "unit") == "null")

  g[["heights"]][vertical_panels] <- replicate(length(vertical_panels), 
                                               height, simplify=FALSE)

  g[["widths"]][horizontal_panels] <- replicate(length(horizontal_panels), 
                                               width, simplify=FALSE)

  device.height  <-  convertHeight(sum(g[["heights"]]), "in", valueOnly=TRUE)
  device.width  <-  convertWidth(sum(g[["widths"]]), "in", valueOnly=TRUE)
  if(draw){
    dev.new(height=device.height, width=device.width)
    grid.newpage()
    grid.draw(g)
  }
  invisible(g)
}



require(ggplot2)
d1 <- subset(mtcars, carb != 8)
d2 <- subset(mtcars, carb %in% c(1,2,3))
p = qplot(vs, am, data=d1) + facet_wrap(~carb)

freeze_panels(p)
freeze_panels(p %+% d2)
freeze_panels(p %+% d2 + facet_wrap(~carb, ncol=1))

嗨,Baptiste,我尝试了你的代码,真的很好(我会为其他目的保留它),但实际上我的问题更多地是要找到一种根据 facet_wrap 中的 facets 和 columns 数量定义精确图大小的方法。我将在我的问题中明确说明这一点。 - Joel.O
你的代码让我有可能设置分面的大小/比例,但是它会超出视图:绘图输出仅显示图形的一部分,而不增加/强制输出窗口。 - Joel.O
我不理解你的第二条评论,但我已添加了一些代码,可能可以回答你的问题。 - baptiste
最终我在 PHP 中找到了另一个选项来解决我的问题。但是你的答案很棒,我会将其保留以备将来使用!!! - Joel.O

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接