基于因子循环多个图对象

时间:2019-05-10 20:59:26

标签: r loops ggplot2 facet

我想基于一个因子生成单独的绘图对象,以便我可以使用grid_arrange而不是facet_grid将它们一起绘制-因为我发现那笨拙。

我想我需要一个for循环,但是我不太了解它们-如果那是我所需要的,您能否详细说明一下它的工作原理。

p <- ggplot(All, aes(x=variable, y=value, fill = Type))
p <- p + geom_bar(stat="identity" ) + facet_grid(~ Month)
p   


#dummy data
All <- structure(list(Type = structure(c(5L, 5L, 5L, 5L, 5L, 5L, 
5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 7L, 7L, 
7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L), .Label = c("Cargo ship", "Cargo ship:DG,HS,MP(A)", 
"Cargo ship:DG,HS,MP(B)", "Cargo ship:DG,HS,MP(D)", "Fishing", 
"Other:DG,HS,MP(B)", "Tanker", "Tanker:DG,HS,MP(B)"), class = 
"factor"), 
 Month = c("Jan", "Jan", "Jan", "Nov", "Jan", "Jan", "Jan", 
"Nov", "Jan", "Mar", "Jan", "Jan", "Jan", "Jan", "Jan", "Nov", 
 "Jan", "Mar", "Nov", "Mar", "Mar", "Feb", "Mar", "Mar", "Nov", 
 "Nov", "Jan", "Feb", "Mar", "Mar", "Nov", "Nov", "Dec", "Dec", 
 "Dec", "Dec", "Jan", "Jan", "Jan", "Jan", "Jan", "Jan", "Jan"
 ), Year = c(2019, 2019, 2019, 2018, 2019, 2019, 2019, 2018, 
2019, 2019, 2019, 2019, 2019, 2019, 2019, 2018, 2019, 2019, 
2018, 2019, 2019, 2019, 2019, 2019, 2018, 2018, 2019, 2019, 
2019, 2019, 2018, 2018, 2018, 2018, 2018, 2018, 2019, 2019, 
2019, 2019, 2019, 2019, 2019), variable = structure(c(4L, 
4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("0-12", 
"0-25", "0-50", "0-100"), class = "factor"), value = c(1, 
0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 
0, 0, 0, 0)), row.names = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 
9L, 10L, 360L, 361L, 362L, 363L, 364L, 365L, 366L, 367L, 368L, 
369L, 370L, 3300L, 3301L, 3302L, 3303L, 3304L, 3305L, 3306L, 
3307L, 3308L, 3309L, 3310L, 2460L, 2461L, 2462L, 2463L, 2464L, 
2465L, 2466L, 2467L, 2468L, 2469L, 2470L), class = "data.frame")

我想要数据集中每个月有多个绘图对象。

1 个答案:

答案 0 :(得分:1)

您可以按Month(使用group_split)分割数据帧,然后使用mapplot_function()遍历该列表

library(tidyverse)
theme_set(theme_minimal(base_size = 14))

plot_function <- function(df) {
  p <- ggplot(df, aes(x = Month, y = value, fill = Type))
  p <- p + geom_col() +
    scale_fill_manual("",
                       values = c('Cargo ship' = '#7570b3',
                                  'Fishing' = '#1b9e77',
                                  'Tanker'='#d95f02'))
  return(p)
}

# Save all plots in a list
plot_list <- All %>% 
  mutate(Month = factor(Month, levels = c("Jan", "Feb", "Mar", "Nov", "Dec"))) %>% 
  group_split(Month) %>% 
  map(~ plot_function(.x))

# Combine all plots into one
cowplot::plot_grid(plotlist = plot_list, 
                   nrow  = 3,
                   align = 'hv',
                   axis  = 'tblr')

修改:仅保留1个常见图例

# remove all legends
all_plot <- cowplot::plot_grid(plotlist = 
  lapply(seq_along(plot_list), function(x) {plot_list[[x]] + theme(legend.position = 'none')}), 
                   nrow = 3,
                   align = 'hv',
                   axis = 'tblr')

# extract legend from one plot              
common_legend <- cowplot::get_legend(plot_list[[1]] + theme(legend.position = 'bottom'))

# combine plot and legend
p <- cowplot::plot_grid(all_plot, common_legend, 
                        nrow = 2,
                        rel_heights = c(3, .3))
p

reprex package(v0.2.1)于2019-05-10创建