【问题标题】:Plotting multiple time series on the same plot using ggplot()使用 ggplot() 在同一图上绘制多个时间序列
【发布时间】:2013-11-24 04:03:22
【问题描述】:

我对 R 相当陌生,我正在尝试使用 ggplot2 同时绘制两条时间序列线(当然使用不同的颜色)。

我有 2 个数据框。第一个具有“X 的百分比变化”和“日期”列。第二个也有“Y 的百分比变化”和“日期”列,即两者都有一个具有相同值的“日期”列,而“百分比变化”列具有不同的值。

我想在单个图上使用 ggplot2 将“百分比变化”列与“日期”(两者通用)绘制出来。

我在网上找到的示例使用具有不同变量的相同数据框来实现这一点,我一直无法找到任何使用 2 个数据框来达到情节的东西。我不想将两个数据框绑定在一起,我想将它们分开。这是我正在使用的代码:

ggplot(jobsAFAM, aes(x=jobsAFAM$data_date, y=jobsAFAM$Percent.Change)) + geom_line() +
  xlab("") + ylab("")

但是这段代码只产生一行,我想在上面添加另一行。 任何帮助将非常感激。 TIA。

【问题讨论】:

    标签: r plot ggplot2


    【解决方案1】:

    如果两个数据框具有相同的列名,那么您应该在 ggplot() 调用中添加一个数据框,并在 aes() 的 ggplot() 调用中命名 x 和 y 值。然后为第一行添加第一个 geom_line() 并添加第二个 geom_line() 调用 data=df2 (其中 df2 是您的第二个数据框)。如果您需要不同颜色的线条,请在每个 geom_line() 的 aes() 中添加 color= 和 eahc 线条的名称。

    df1<-data.frame(x=1:10,y=rnorm(10))
    df2<-data.frame(x=1:10,y=rnorm(10))
    
    ggplot(df1,aes(x,y))+geom_line(aes(color="First line"))+
      geom_line(data=df2,aes(color="Second line"))+
      labs(color="Legend text")
    

    【讨论】:

    • 非常感谢您的回答,它完全达到了我的期望。
    • @Didzi 是一个很好的例子,但是如果我想应用我自定义的颜色(例如黑色和橙色)和名称怎么办?看起来您使用 color= 作为“y”名称。
    • @DarwinPC 如果您需要更改图例中的颜色和标签,则可以使用scale_color_manual()
    • @DidzisElferts 如果 df2 中的 x 和 y 值不同怎么办?
    【解决方案2】:

    ggplot 允许您拥有多个层,这就是您应该在这里利用的优势。

    在下面创建的图中,您可以看到有两个 geom_line 语句针对您的每个数据集并将它们一起绘制在一个图上。如果您希望添加任何其他数据集、绘图甚至图表的特征(例如轴标签),您可以扩展该逻辑。

    library(ggplot2)
    
    jobsAFAM1 <- data.frame(
      data_date = runif(5,1,100),
      Percent.Change = runif(5,1,100)
    )
    
    jobsAFAM2 <- data.frame(
      data_date = runif(5,1,100),
      Percent.Change = runif(5,1,100)
    )
    
    ggplot() + 
      geom_line(data = jobsAFAM1, aes(x = data_date, y = Percent.Change), color = "red") +
      geom_line(data = jobsAFAM2, aes(x = data_date, y = Percent.Change), color = "blue") +
      xlab('data_date') +
      ylab('percent.change')
    

    【讨论】:

    • 谢谢@TheComeOnMan!!这太棒了;有没有办法合并图例?
    【解决方案3】:

    我更喜欢使用ggfortify 库。它是一个ggplot2 包装器,可识别 autoplot 函数内的对象类型并选择最佳的 ggplot 方法进行绘图。至少我不必记住ggplot2的语法。

    library(ggfortify)
    ts1 <- 1:100
    ts2 <- 1:100*0.8
    autoplot(ts( cbind(ts1, ts2)  , start = c(2010,5), frequency = 12 ),
             facets = FALSE)
    

    【讨论】:

      【解决方案4】:

      另一种方法是绑定数据框,并为它们分配它们所代表的变量类型。这将允许您在 tidier way

      中使用完整的数据集
      library(ggplot2)
      library(dplyr)
      
      df1 <- data.frame(dates = 1:10,Variable = rnorm(mean = 0.5,10))
      df2 <- data.frame(dates = 1:10,Variable = rnorm(mean = -0.5,10))
      
      df3 <- df1 %>%
        mutate(Type = 'a') %>%
        bind_rows(df2 %>%
                    mutate(Type = 'b'))
      
      
      ggplot(df3,aes(y = Variable,x = dates,color = Type)) + 
        geom_line()
      

      【讨论】:

        【解决方案5】:

        我知道这是旧的,但它仍然是相关的。您可以利用 reshape2::melt 将数据框更改为对 ggplot2 更友好的结构。

        优点:

        • 允许您绘制任意数量的线
        • 每一行都有不同的颜色
        • 为每一行添加一个图例
        • 只调用一次 ggplot/geom_line

        缺点:

        • 需要一个额外的包(reshape2)
        • 一开始熔化并不那么直观

        例如:

        jobsAFAM1 <- data.frame(
          data_date = seq.Date(from = as.Date('2017-01-01'),by = 'day', length.out = 100),
          Percent.Change = runif(5,1,100)
        )
        
        jobsAFAM2 <- data.frame(
          data_date = seq.Date(from = as.Date('2017-01-01'),by = 'day', length.out = 100),
          Percent.Change = runif(5,1,100)
        )
        
        jobsAFAM <- merge(jobsAFAM1, jobsAFAM2, by="data_date")
        
        jobsAFAMMelted <- reshape2::melt(jobsAFAM, id.var='data_date')
        
        ggplot(jobsAFAMMelted, aes(x=data_date, y=value, col=variable)) + geom_line()
        

        【讨论】:

        • reshape2 已经过时了,最好立即使用它的继任者 dplyr
        • 嗨@FranzPlumpton。你介意用 dplyr 举个例子吗?
        【解决方案6】:

        这是旧的,只是更新上面没有提到的新的 tidyverse 工作流。

        library(tidyverse)
        
        jobsAFAM1 <- tibble(
            date = seq.Date(from = as.Date('2017-01-01'),by = 'day', length.out = 5),
            Percent.Change = runif(5, 0,1)
            ) %>% 
            mutate(serial='jobsAFAM1')
        jobsAFAM2 <- tibble(
            date = seq.Date(from = as.Date('2017-01-01'),by = 'day', length.out = 5),
            Percent.Change = runif(5, 0,1)
            ) %>% 
            mutate(serial='jobsAFAM2')
        jobsAFAM <- bind_rows(jobsAFAM1, jobsAFAM2)
        
        ggplot(jobsAFAM, aes(x=date, y=Percent.Change, col=serial)) + geom_line()
        

        @Chris Njuguna

        tidyr::gather() 是 tidyverse 工作流程中的一个,用于将宽数据帧转换为长整齐的布局,然后 ggplot 可以绘制多个序列。

        【讨论】:

        • @visitanz 向更新的方法发展似乎是保持这个问题开放的一个很好的理由。你会像之前的答案/cmets 那样创建一个玩具示例吗?
        • @Chris Njuguna,我在 tidyverse 工作流程中更改了您的示例代码。
        • @visitanz 整洁!
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-10-30
        • 1970-01-01
        • 2020-03-30
        • 1970-01-01
        • 1970-01-01
        • 2022-01-13
        • 2021-11-08
        相关资源
        最近更新 更多