1

I want to produce individual plot objects based on a factor so that i can plot them together using grid_arrange rather than facet_grid - as i find that clunky.

I imagine I need a for loop but i dont quite understand them - if that is what I need can you detail how it works a little.

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")

I would like multiple plot objects for each month in the data set.

1 Answer 1

1

You can split your data frame by Month (use group_split) then loop through that list using map & plot_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')

Edit: keep only 1 common legend

# 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

Created on 2019-05-10 by the reprex package (v0.2.1)

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you that works with a little tweaking - as i need each month to have the different variables on the x, I changed the aes(x=variable...) - it doesn't label my graphs via month - but i can definitely work that out.
here all the plots are colouring the ship types differently - is there away to make consistent colours through the graphs??
Use scale_fill_manual with predetermined assigned colors. See this stackoverflow.com/a/49989089/786542
Thank you - got there now! Thanks for your input!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.