0

I would like to generate plot titles and filenames for ggsave from the data frame that I am using, for every plot that the for loop generates.

And I would like the months to be written as January, February, March etc rather than 1, 2, 3 in my plot titles. How can I do this in an elegant way?

For example, if I plot A1 and B1 for January, I would like the title to be A1 and B1, January 2016 and for the next month : A1 and B1 for February 2016 and so on. and I want something similar for the filename of each plot every month. For the title the months is shown as "1" and the year 2016 is not shown at all. For the filename it works as it is but I have to change it every time I change the AA och BB, and I would love it if I didn't have to do that.

I would also want this to be generated from whatever data i filter, so if I filter A1 and B1 for January 2016 I want it to transfer into the title without me having to type it in for every month.

I made up a dataframe that will do for the purpose of this question (the real data frame is huge, of course, and my R script is very long).

crs <- CRS("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs") 

Number <- 1:48 

AA <-  c(rep("A1", 12), rep("A2", 12), rep("A3", 12),rep("A4", 12))

BB <- c(rep("B4", 12), rep("B3", 12), rep("B2", 12),rep("B1", 12))

Long <- c(-46.25, -45.85,-45.85,-45.65, -45.983, -45.95,-45.85, -47.116,-47.1,-47.65, -47.116,-47.65, 
          -47.1,-47.633,-47.116,-47.65, -47.1, -47.65, -47.116, -47.666, -46.866, -47.116, -47.783, -47,
          -46.25, -45.85, -45.85, -45.65, -45.983, -45.95, -45.85, -47.116, -47.1, -47.65, -47.116, -47.65
          -47.1, -47.633, -47.116, -47.65, -47.1, -47.65, -47.116, -47.666, -46.866, -47.116, -47.783, -47, -47)

Lat <- c(46.55, 46.416, 46.533, 46.45, 46.433, 46.433, 46.45, 48.116, 48.083, 48.133, 48.1, 48.133, 
         48.1, 48.133, 48.116, 48.15, 48.1, 48.133, 48.1, 48.133, 48.133, 48.116, 48, 47.683, 
         46.55, 46.416, 46.533, 46.45, 46.433, 46.433, 46.45, 48.116, 48.083, 48.133, 48.1, 48.133,
         48.1, 48.133, 48.116, 48.15, 48.1, 48.133, 48.1, 48.133, 48.133, 48.116, 48, 47.683)

End_month <-  sample(1:12, size=48, replace = TRUE)

Category1 <- c(rep("Yes", 16), rep("No", 16), rep("Maybe", 16))
Category <- sample(x = Category1, size = 48)

Year<- c(rep("2016", 48))


dfAllData2 <- data.frame(Number, Long, Lat, End_month, Year, Category,
                           AA, BB )

#

newdata2 <- c("Lat", "Long", "End_month","Year", "AA", "BB", "Category" ) # select the column names of the columns in the plot

dfSubsets <- dfAllData2[newdata2] 


# filter and create 2 layers of data----


Month_list <- (unique(dfSubsets$End_month))                   



for (i in seq_along(Months_list)){

dfFiltered1 <- dfSubsets %>%
               filter(AA=="A1"& BB=="B1")



  #create 2 sets of data


  dfLayer1 <- dfFiltered1 %>%
    filter(Category %in% c("Yes","No" ))


  dfLayer2 <- dfFiltered1 %>%
    filter(Category == "Maybe" )


  #Plot ----

myPlot <- plot(dfFiltered1$Long, dfFiltered1$Lat)

ggplot(myPlot) +
    geom_point(data = dfLayer1, aes(Long, Lat, color=Category, shape = Category), size = 2 ) + guides(size= FALSE)+
    geom_point (data = dfLayer2, aes(Long, Lat, color=Category, shape = Category), size = 2 ) + guides(size= FALSE)


  myPlot <- ggplot(myPlot) +
    geom_point(data = dfLayer1, aes(Long, Lat, color=Category, shape = Category), size = 2 ) + guides(size= FALSE)+
    geom_point (data = dfLayer2, aes(Long, Lat, color=Category, shape = Category), size = 2 ) + guides(size= FALSE)


  print(myPlot + coord_cartesian(xlim = c(-43, -55), ylim = c(39, 49)) + 
          theme_bw()+
          theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(), 
                plot.title = element_text(hjust = 0, face = "bold", size = 14), 
                legend.justification = c(0,1), legend.position = c(0,1), legend.background = element_rect(color = "black"))+
          ggtitle("A1, and B1,", Month_list[i], "2016")+
          labs(x = "Longitude", y = "Latitude"))

  ggsave(paste("A1_B1_", Month_list[i],"_2016", ".png"))
}




1 Answer 1

1
+50

Try this. The code loops over all months. But I included only the first three plots. Besides: I also tidied up the code.

library(tidyverse)
library(sp)

crs <-sp::CRS("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs") 

Number <- 1:48 

AA <-  c(rep("A1", 12), rep("A2", 12), rep("A3", 12),rep("A4", 12))

BB <- c(rep("B4", 12), rep("B3", 12), rep("B2", 12),rep("B1", 12))

Long <- c(-46.25, -45.85,-45.85,-45.65, -45.983, -45.95,-45.85, -47.116,-47.1,-47.65, -47.116,-47.65, 
          -47.1,-47.633,-47.116,-47.65, -47.1, -47.65, -47.116, -47.666, -46.866, -47.116, -47.783, -47,
          -46.25, -45.85, -45.85, -45.65, -45.983, -45.95, -45.85, -47.116, -47.1, -47.65, -47.116, -47.65
          -47.1, -47.633, -47.116, -47.65, -47.1, -47.65, -47.116, -47.666, -46.866, -47.116, -47.783, -47, -47)

Lat <- c(46.55, 46.416, 46.533, 46.45, 46.433, 46.433, 46.45, 48.116, 48.083, 48.133, 48.1, 48.133, 
         48.1, 48.133, 48.116, 48.15, 48.1, 48.133, 48.1, 48.133, 48.133, 48.116, 48, 47.683, 
         46.55, 46.416, 46.533, 46.45, 46.433, 46.433, 46.45, 48.116, 48.083, 48.133, 48.1, 48.133,
         48.1, 48.133, 48.116, 48.15, 48.1, 48.133, 48.1, 48.133, 48.133, 48.116, 48, 47.683)

End_month <-  sample(1:12, size=48, replace = TRUE)

Category1 <- c(rep("Yes", 16), rep("No", 16), rep("Maybe", 16))
Category <- sample(x = Category1, size = 48)

Year<- c(rep("2016", 48))

dfAllData2 <- data.frame(Number, Long, Lat, End_month, Year, Category,
                         AA, BB )

newdata2 <- c("Lat", "Long", "End_month","Year", "AA", "BB", "Category" ) # select the column names of the columns in the plot

dfSubsets <- dfAllData2[newdata2] 

# filter and create 2 layers of data----

Month_list <- unique(dfSubsets$End_month)

## BUG: when using seq_along this way, `i` no longer is the number of the month
#for (i in seq_along(Month_list)){
# Therefore: simply use  for (i in Month_list)
##
for (i in Month_list) {

  print(i)
  print(month.name[i])

  dfFiltered1 <- dfSubsets %>%
    filter(AA=="A1"& BB=="B4") %>% 
    filter(End_month == i)

  #create 2 sets of data

  dfLayer1 <- dfFiltered1 %>%
    filter(Category %in% c("Yes","No" ))

  dfLayer2 <- dfFiltered1 %>%
    filter(Category == "Maybe" )

  #Plot ----

  myPlot <- ggplot(mapping = aes(Long, Lat)) +
    geom_point(data = dfFiltered1)+
    geom_point(data = dfLayer1, aes(color=Category, shape = Category), size = 2 ) + 
    geom_point (data = dfLayer2, aes(color=Category, shape = Category), size = 2 ) + guides(size= FALSE)

  myPlot <- myPlot + 
    coord_cartesian(xlim = c(-43, -55), ylim = c(39, 49)) + 
    theme_bw()+
    theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(), 
          plot.title = element_text(hjust = 0, face = "bold", size = 14), 
          legend.justification = c(0,1), legend.position = c(0,1), legend.background = element_rect(color = "black"))+
    ggtitle(paste("A1, and B1,", month.name[[i]], "2016"))+
    labs(x = "Longitude", y = "Latitude")
  print(myPlot)

  ggsave(paste("A1_B1_", month.name[[i]],"_2016", ".png"))
}
#> [1] 11
#> [1] "November"
#> Saving 7 x 5 in image

#> [1] 5
#> [1] "May"
#> Saving 7 x 5 in image

#> [1] 1
#> [1] "January"
#> Saving 7 x 5 in image

Created on 2020-03-16 by the reprex package (v0.3.0)

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

3 Comments

Thank you for your answer, and for tidying up my code, that is helpful! I tried your improvements, but it produces the exact same plot for every month, so I'll have to figure out why it does that. The months in the title still come out as 1, 2, 3 rather than January, February, March. is there a way to fix that maybe?
We get the same plot as we always use the same data. So i guess the filter condition should include something like End_month == i. And yes. Of course can it be easily fixed to have the name of the month. I check it out. And edit my answer.
I just edited the code. Now both in the title and the filename the month.name is used. Second. I also filter for the End_month == i. Finally there was bug in the loop. for (i in Month_list) is what we want, not for (i in seq.along(Month_list)). Using the latter has the effect that `i' does not correpsond to the number of the month.

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.