【问题标题】:How can I generate plot titles from dataframe in a for loop using ggplot2?如何使用 ggplot2 在 for 循环中从数据框生成绘图标题?
【发布时间】:2020-03-04 12:22:04
【问题描述】:

我想从我正在使用的数据框中为 for 循环生成的每个图生成 ggsave 的图标题和文件名。

我希望在我的情节标题中将月份写成一月、二月、三月等,而不是 1、2、3。我怎样才能以优雅的方式做到这一点?

例如,如果我为 1 月绘制 A1 和 B1,我希望标题为 A1 和 B1,2016 年 1 月,下个月:A1 和 B1 表示 2016 年 2 月 等等。我希望每个月的每个情节的文件名都有类似的东西。对于标题,月份显示为“1”,根本不显示 2016 年。对于文件名,它按原样工作,但每次更改 AA och BB 时我都必须更改它,如果我不必这样做,我会很高兴的。

我还希望从我过滤的任何数据中生成它,所以如果我过滤 2016 年 1 月的 A1 和 B1,我希望它转移到标题中,而无需我每个月都输入它。

我制作了一个数据框来解决这个问题(实际的数据框当然很大,而且我的 R 脚本很长)。

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




【问题讨论】:

    标签: for-loop ggplot2


    【解决方案1】:

    试试这个。代码在整个月份循环。但我只包括了前三个地块。另外:我还整理了代码。

    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
    

    reprex package (v0.3.0) 于 2020-03-16 创建

    【讨论】:

    • 感谢您的回答,以及整理我的代码,这很有帮助!我尝试了你的改进,但它每个月都会产生完全相同的情节,所以我必须弄清楚为什么会这样。标题中的月份仍然显示为 1、2、3,而不是一月、二月、三月。有没有办法解决这个问题?
    • 我们得到相同的图,因为我们总是使用相同的数据。所以我想过滤条件应该包括End_month == i之类的东西。是的。当然可以很容易地固定有月份的名称。我检查一下。并编辑我的答案。
    • 我刚刚编辑了代码。现在在标题和文件名中都使用了month.name。第二。我还过滤了End_month == i。最后在循环中有错误。 for (i in Month_list) 是我们想要的,而不是 for (i in seq.along(Month_list))。使用后者的效果是 `i' 与月份不对应。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-28
    • 2019-04-24
    • 1970-01-01
    相关资源
    最近更新 更多