【问题标题】:R - Using par() to create a grid of ggplot plots - Not working as expected [duplicate]R - 使用 par() 创建 ggplot 图网格 - 未按预期工作 [重复]
【发布时间】:2020-08-17 17:10:55
【问题描述】:

我有一些看起来像这样的数据

# Generate example data
exampleData <- data.frame(Month = sample(1:5, 500, replace = T),
                          Product = sample(LETTERS[1:10], 500, replace = T),
                          Site = sample(letters[1:5], 500, replace = T),
                          Used = sample(1:100, 500, replace = T))
exampleData <- aggregate(. ~ Month + Product + Site, data = exampleData, sum)      # Consolidating any duplicates
exampleData <- exampleData[order(exampleData$Month, exampleData$Product, exampleData$Site, exampleData$Used),]

我想看看不同网站不同产品的趋势,所以创建了这个功能

# Funciton to retrieve info about a product and site
productSiteInfo <- function(p, s) {
  return(exampleData[intersect(which(exampleData$Product == p), which(exampleData$Site == s)),])
}

为了使我的比较更容易,我想制作一个线图网格,其中网格由所有站点上特定产品的图组成。所以我尝试了这段代码

# Plotting the data
prods <- unique(exampleData$Product)  # All products
prod <- sample(prods,1)      # Select a product of interest
sites <- unique(exampleData$Site)     # All sites
par(mfrow=c(3,2))       # Create grid
lapply(head(sites), function(site) {      # Plot trend of prod at all sites
  aDF <- productSiteInfo(prod, site)
  ggplot() +
           geom_line(data = aDF, aes(x = Month, y = Used), color = "black") +
           xlab("Month") +
           ylab("Units") + 
           ggtitle(paste("Consumption of", prod, "at", site))
})

但它没有按预期工作。我没有得到一个地块网格,而只是单个地块。我想知道为什么会这样,以及我能做些什么来获得那个网格。我的实际数据有大约 10 个产品和大约 160 个网站,所以它会比这个例子大得多。

感谢您的帮助!

【问题讨论】:

  • par(mfrow=...) 仅与基本图形兼容,而不与任何基于 grid 的图形兼容(例如,latticeggplot2)。如果你想组合,你可以尝试gridExtra::grid.arrangecowplot 包。如果数据兼容,另一种选择是使用ggplot::facet_*
  • @r2evans 感谢您的提示。我最终将我的 lapply 保存到一个变量 lst,并尝试使用 grid.extra 安排 lst 中的图。但它看起来只有在我做grid.arrange(lst[[1]], lst[[2]], lst[[3]], lst[[4]], lst[[5]], ncol = 3) 时才会起作用,这实际上并不可行,因为我有大约 160 个地块。我不想在上述函数中写出所有 160 个参数。你知道我如何用 grid.arrange 来排列它们而不必写出每个 ysingle plot 参数吗?谢谢
  • 哦,现在我看到了 160,我的答案可能并不完全适合……奥利弗的答案可能比我的更接近。

标签: r ggplot2


【解决方案1】:

这不起作用的一个原因是ggplot 不遵守标准绘图规则。 通常使用facet_gridfacet_wrap 在网格中创建多个图,您可以使用数据中的现有变量将数据集拆分为多个图。如果您的分组变量驻留在您的数据中,则绝对推荐这种方法。

@r2evans 建议使用grid.extra,这也是将任何给定的一系列情节安排成小节的经典方法(类似于cowplot)。 但是,对于我称之为ultimate 的便利,我建议使用patchwork 并查看他们写得很好的简短指南。对于您的具体示例,它可以像将图添加在一起一样简单。

plots <- lapply(head(sites), function(site) {      # Plot trend of prod at all sites
  aDF <- productSiteInfo(prod, site)
  ggplot() +
           geom_line(data = aDF, aes(x = Month, y = Used), color = "black") +
           xlab("Month") +
           ylab("Units") + 
           ggtitle(paste("Consumption of", prod, "at", site))
})
library(patchwork)
library(purrr) #for reduce
reduce(plots, `+`)

正如您在此处所指出的,我只是将图添加在一起,而我可以使用- 删除图/ 将图排列在彼此之上等等。

【讨论】:

  • 我“支持”patchwork 的推荐,我在评论中忘记了这一点。
  • 这似乎工作得很好。谢谢!
【解决方案2】:

使用构面试试这个视图:

set.seed(42)
exampleData <- data.frame(Month = sample(1:5, 500, replace = T),
                          Product = sample(LETTERS[1:10], 500, replace = T),
                          Site = sample(letters[1:5], 500, replace = T),
                          Used = sample(1:100, 500, replace = T))
exampleData <- aggregate(. ~ Month + Product + Site, data = exampleData, sum)      # Consolidating any duplicates
exampleData <- exampleData[order(exampleData$Month, exampleData$Product, exampleData$Site, exampleData$Used),]

ggplot() +
  geom_line(data = exampleData, aes(x = Month, y = Used, color = Product)) +
  facet_wrap("Site", nrow=3, ncol=2,
             labeller = labeller(Site = function(x) paste("Site", x))) +
  xlab("Month") +
  ylab("Units")

所做的更改:

  • set.seed(42) 开头,这样我们都有相同的数据:-) ;
  • 使用整个数据,无需lapply 跨越它;
  • 添加color=Product 作为美学,以便 (1) 线条可以正确分组,但更重要的是 (2) 您的“产品 x 在站点 y”的标签将是可辨别的(并且在各个方面之间具有可比性);
  • 添加了facet_wraplabeller 函数以将Site 添加到每个标签标题;和
  • 删除了ggtitle,因为标签标题做同样的事情。

【讨论】:

  • 虽然与这个问题并不完全相关,但我会为其他数据集较小且仍然认为par(mfrow=) 是一个选项的人保留答案。
猜你喜欢
  • 2014-06-23
  • 2019-01-20
  • 2021-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多