使用循环gpplot2导致显示图例时出现问题

时间:2017-05-02 18:54:52

标签: r for-loop ggplot2

我有一个R代码,可以创建线性回归。我在图表中遇到了一些传说问题。我想使用trendDateRange中指定的日期作为不同颜色的图例。由于这些日期是YYYY-MM-DD格式。我只需要YYYY-MM。例如,trendDateRage1 = c("2015-01-01", "2015-12-31")我希望将"2015-01 - 2015-12"显示为任何颜色的图例。当我在for循环中运行它时,它只显示1个图例,该图例使用显示trendDateRange的最后一个trendDateRange3,即"2013-01 - 2013-12"。它不显示其他2个日期的图例。我对图表没有任何问题,尽管他们使用相同的颜色。我想为每个图例看到不同的颜色,即使它们有不同的线型。

如果我运行下面显示单个图表的代码,它就会使用正确的图例。我得到了每个图表的图例。

Month_Names <- c("2010-11","2010-12",
     "2011-01","2011-02","2011-03","2011-04","2011-05","2011-06","2011-07","2011-08","2011-09","2011-10","2011-11","2011-12",
     "2012-01","2012-02","2012-03","2012-04","2012-05","2012-06","2012-07","2012-08","2012-09","2012-10","2012-11","2012-12",
     "2013-01","2013-02","2013-03","2013-04","2013-05","2013-06","2013-07","2013-08","2013-09","2013-10","2013-11","2013-12",
     "2014-01","2014-02","2014-03","2014-04","2014-05","2014-06","2014-07","2014-08","2014-09","2014-10","2014-11","2014-12",
     "2015-01","2015-02","2015-03","2015-04","2015-05","2015-06","2015-07","2015-08","2015-09","2015-10","2015-11","2015-12",
     "2016-01","2016-02","2016-03","2016-04","2016-05","2016-06","2016-07","2016-08","2016-09","2016-10","2016-11","2016-12",
     "2017-01")
Actual_volume <- c(54447,57156,
   52033,49547,58718,53109,56488,60095,54683,60863,56692,55283,55504,56633,
   53267,52587,54680,55569,60013,56985,59709,61281,54188,59832,56489,55819,
   59295,52692,56663,59698,61232,57694,63111,60473,58984,64050,54957,63238,
   59460,54430,58901,61088,60496,62984,66895,62720,65591,67815,58289,72002,
   61054,60329,69283,68002,63196,72267,71058,69539,71379,70925,68704,76956,
   65863,70494,77348,70214,74770,77480,69721,83034,76761,77927,79768,81836,
   75381)

df_data <- data.frame(Month_Names, Actual_volume) 

trendDateRange1 <- c("2010-11-01", "2017-01-31")
trendDateRange2 <- c("2012-01-01", "2012-12-31")
trendDateRange3 <- c("2013-01-01", "2013-12-31")
numoftrends <- 3

list_of_df <- list()

list_of_df<- lapply(1:numoftrends, function(j) {
           trend.period <- get(paste0("trendDateRange", j))
           trend1 <- substr(trend.period[1], 1, 7)
           trend2 <- substr(trend.period[2], 1, 7)

          TRx <- subset(df_data, as.character(Month_Names) >= trend1 & 
                      as.character(Month_Names) <= trend2)

})

i = 1
trend.period <- get(paste0("trendDateRange", i))
trend1 <- substr(trend.period[1], 1, 7)
trend2 <- substr(trend.period[2], 1, 7)
Trend.dates <- paste0(trend1, '-' ,trend2)
plot = ggplot() + 
    geom_line(data = list_of_df[[i]], 
              aes(x = Month_Names, y = Actual_volume, group = 1 , colour = Trend.dates), 
              lty = i + 1)
print(ggplotly(plot)) 

i = 2
trend.period <- get(paste0("trendDateRange", i))
trend1 <- substr(trend.period[1], 1, 7)
trend2 <- substr(trend.period[2], 1, 7)
Trend.dates <- paste0(trend1, '-' ,trend2)
plot = ggplot() + 
    geom_line(data = list_of_df[[i]], 
              aes(x=Month_Names, y = Actual_volume, group = 1 , colour = Trend.dates), 
              lty = i + 1)
print(ggplotly(plot)) 

i = 3
trend.period <- get(paste0("trendDateRange", i))
trend1 <- substr(trend.period[1], 1, 7)
trend2 <- substr(trend.period[2], 1, 7)
Trend.dates <- paste0(trend1, '-' ,trend2)
plot = ggplot() + 
    geom_line(data = list_of_df[[i]], 
              aes(x = Month_Names, y = Actual_volume, group = 1 , colour = Trend.dates), 
              lty = i+1)
print(ggplotly(plot)) 

但是当我把它放在循环中以使其成为每个图例的一个图形时它不起作用

plot = ggplot()
for (i in seq_along(list_of_df)) {
    trend.period = get(paste0("trendDateRange", i))
    trend1 = substr(trend.period[1], 1, 7)
    trend2 = substr(trend.period[2], 1, 7)
    Trend.dates = paste0(trend1, '-' ,trend2)
    plot = plot + geom_line(aes(x = Month_Names, y = Actual_volume, group = 1 , colour = Trend.dates), 
                            data = list_of_df[[i]], lty = i + 1)
}
print(ggplotly(plot))

3 个答案:

答案 0 :(得分:3)

如果将三个数据集合并为一个具有分隔它们的美学的数据集,而不是将它们一起添加到for循环中,那么使用ggplot2可以更轻松地

您可以通过多种方式执行此操作,但这是使用dplyr和tidyr软件包的示例。它会替换df_data <-行之后的所有内容。

library(ggplot2)
library(dplyr)
library(tidyr)

trends <- data_frame(Start = c("2010-11", "2012-01", "2013-01"),
                     End = c("2017-01", "2012-12", "2013-12"))

combined_data <- df_data %>%
  crossing(trends) %>%
  mutate(Month_Names = as.character(Month_Names),
         TrendName = paste(Start, End, sep = "-")) %>%
  filter(Month_Names >= Start,
         Month_Names <= End)

# rotated x-axes to make plot slightly more readable
ggplot(combined_data, aes(Month_Names, y = Actual_volume,
                          group = TrendName,
                          color = TrendName)) +
  geom_line() +
  theme(axis.text.x = element_text(angle = 90, hjust = 1))

答案 1 :(得分:3)

如果你将你的列表组合成一个data.frame,其中一个ID表示观察来自哪个元素并解析日期,那么获得一个不错的情节非常简单:

library(dplyr)
library(ggplot2)

list_of_df %>% 
    bind_rows(.id = 'id') %>% 
    mutate(date = as.Date(paste0(Month_Names, '-01'))) %>% 
    ggplot(aes(date, Actual_volume, color = id)) + 
    geom_line()

split line plot

或没有dplyr,

df <- do.call(rbind, 
              Map(function(df, i){df$id <- i; df}, 
                  df = list_of_df, 
                  i = as.character(seq_along(list_of_df))))

df$date <- as.Date(paste0(df$Month_Names, '-01'))

ggplot(df, aes(date, Actual_volume, color = id)) + geom_line()

返回同样的东西。

如果您想要更多描述性组标签,请设置列表元素的名称或将id定义为从格式化的最小值和已解析日期的最大值粘贴在一起的字符串。

答案 2 :(得分:1)

以下是使用ggplotly的解决方案。

nrows <- unlist(lapply(list_of_df,nrow))
df <- data.frame(do.call(rbind,list_of_df), Grp = factor(rep(1:3, nrows)))

plot <- ggplot(aes(x=Month_Names, y=Actual_volume, group = Grp, 
        colour=Grp), data=df) + geom_line()
print(ggplotly(plot))

enter image description here

相关问题