在同一张图中使用ggplot2将两个变量绘制为线


305

一个非常新奇的问题,但请说我有这样的数据:

test_data <-
  data.frame(
    var0 = 100 + c(0, cumsum(runif(49, -20, 20))),
    var1 = 150 + c(0, cumsum(runif(49, -10, 10))),
    date = seq(as.Date("2002-01-01"), by="1 month", length.out=100)
  )

如何使用x在x轴上绘制时间序列var0var1同一张图?如果您制作和使用不同的颜色,则可获得加分,并可包含图例!dateggplot2var0var1

我敢肯定这很简单,但是我找不到任何示例。

Answers:


373

对于少量变量,您可以自己手动构建图:

ggplot(test_data, aes(date)) + 
  geom_line(aes(y = var0, colour = "var0")) + 
  geom_line(aes(y = var1, colour = "var1"))

3
一个很好的例子,但是如何自定义我自己的颜色(例如黑色和橙色)?,因为似乎您使用的colour=是变量名。
达尔文PC

1
甚至colour='var_names'按照hadley的规定也可以。但是@DaveX-如果要选择特定颜色而不是通过该功能自动选择颜色,则将更加具体。
I_m_LeMarque

如何添加图例?
user1700890

361

通用方法是将数据转换为长格式(melt()从包reshape或中使用reshape2)或gather()/ pivot_longer()tidyr包中:

library("reshape2")
library("ggplot2")

test_data_long <- melt(test_data, id="date")  # convert to long format

ggplot(data=test_data_long,
       aes(x=date, y=value, colour=variable)) +
       geom_line()

ggplot2输出

另请参阅有关从宽到长整形数据的问题


8
您还可以使用打包gather()功能tidyr来融合数据:gather(test_data, variable, value, -date)
janosdivenyi 2015年

33

对于ggplot2,您需要数据采用“高”格式,而不是“宽”格式。“宽”表示每行都有一个观察值,每个变量作为不同的列(就像您现在拥有的那样)。您需要将其转换为“高大”格式,其中有一列告诉您变量名称,而另一列告诉您变量值。从宽到高的过渡过程通常称为“熔化”。您可以tidyr::gather用来融化数据框:

library(ggplot2)
library(tidyr)

test_data <-
  data.frame(
    var0 = 100 + c(0, cumsum(runif(49, -20, 20))),
    var1 = 150 + c(0, cumsum(runif(49, -10, 10))),
    date = seq(as.Date("2002-01-01"), by="1 month", length.out=100)
  )
test_data %>%
    gather(key,value, var0, var1) %>%
    ggplot(aes(x=date, y=value, colour=key)) +
    geom_line()

多个系列ggplot2

只是要清楚的dataggplot在消费通过管道之后gather看起来像这样:

date        key     value
2002-01-01  var0    100.00000
2002-02-01  var0    115.16388 
...
2007-11-01  var1    114.86302
2007-12-01  var1    119.30996

13

使用数据:

test_data <- data.frame(
var0 = 100 + c(0, cumsum(runif(49, -20, 20))),
var1 = 150 + c(0, cumsum(runif(49, -10, 10))),
Dates = seq.Date(as.Date("2002-01-01"), by="1 month", length.out=100))

我创建了一个堆叠版本,该版本可以ggplot()使用:

stacked <- with(test_data,
                data.frame(value = c(var0, var1),
                           variable = factor(rep(c("Var0","Var1"),
                                                 each = NROW(test_data))),
                           Dates = rep(Dates, 2)))

在这种情况下,生成stacked非常容易,因为我们只需要执行几次操作即可,但是如果您需要处理更复杂的实际数据集reshape(),则reshapereshape2可能会很有用。

一旦数据在这个堆叠形式,只需要一个简单的ggplot()通话产生你所有的演员想要的情节(原因之一更高级别的绘图包,比如latticeggplot2是如此有用):

require(ggplot2)
p <- ggplot(stacked, aes(Dates, value, colour = variable))
p + geom_line()

我会留给您整理轴标签,图例标题等。

高温超导


1
我认为您在其中的代码中放置了错误的括号。我想这就是您要追求的:堆叠<-with(test_data,data.frame(value = c(var0,var1),variable = factor(rep(c(“ Var0”,“ Var1”)))),每个= NROW(test_data),日期= rep(date,2)))。另外,“每个”列的目的是什么?而且这不仅是一种更复杂,效率更低的融化rcs所示数据的方法吗?我想我可以想象一个实例,在这种情况下,融化无法完成工作,但是除非我缺少某些东西,否则几乎可以肯定这是完成这项工作的正确工具?
大通

1
@chase,对不起,这是Emacs ESS缩进错误。每个都是一个论点rep(),所以我们实际上只得到3个列stacked。我将编辑代码以使缩进更清晰。
加文·辛普森

1
@追; 您的评论melt()已被采纳,我注意到reshape [2]包在这里很有用。我对reshape2不太熟悉,因为这样简单的操作手工制作起来比打电话要复杂得多melt(),因为我不需要阅读如何使用它花费的精力更少melt()。在我生产矿井的时候,rcs潜入他的回答。当我开始回复时,没有任何答案。正如他们所说,不只一种为猫皮的方法!;-)
加文·辛普森

7

我对R还是陌生的,但是试图了解ggplot的工作原理,我想我有另一种方法。我只是分享可能不是一个完整的完美解决方案,而是要添加一些不同的观点。

我知道ggplot可以更好地与数据帧一起使用,但是知道不使用数据帧就可以直接绘制两个向量有时也许对您很有用。

加载数据中。原始日期向量的长度为100,而var0和var1的长度为50,因此我仅绘制可用数据(前50个日期)。

var0 <- 100 + c(0, cumsum(runif(49, -20, 20)))
var1 <- 150 + c(0, cumsum(runif(49, -10, 10)))
date <- seq(as.Date("2002-01-01"), by="1 month", length.out=50)    

绘图

ggplot() + geom_line(aes(x=date,y=var0),color='red') + 
           geom_line(aes(x=date,y=var1),color='blue') + 
           ylab('Values')+xlab('date')

在此处输入图片说明

但是,我无法使用这种格式添加正确的图例。有人知道吗?


1
这增加了一个传说 ggplot() + geom_line(aes(x=date,y=var0, group=1, colour = 'red')) + geom_line(aes(x=date,y=var1, group = 2, colour = 'blue')) + ylab('Values')+xlab('date')
flurbius 19/12/6
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.