Jair
Jair

Reputation: 15

Is there a way to plot 2 or more series with ggplot2 from an xts object?

Is basically the problem described here Plotting an xts object using ggplot2

But I can not adapt it to plot two series, the code is the following:

dates <- c("2014-10-01", "2014-11-01", "2014-12-01", "2015-01-01", "2015-02-01")
values1 <- as.numeric(c(1,2,3,4,5))
values2 <- as.numeric(c(10,9,8,7,6))
new_df <- data_frame(dates, values1, values2)
new_df$dates <- as.Date(dates)
new_df <- as.xts(new_df[, -1], order.by = new_df$dates)

Now I use ggplot:

ggplot(new_df, aes(x = Index, y = c(values1, values2))) 
+ geom_point()
   

but I get the following error:

Error: Aesthetics must be either length 1 or the same as the data (5): y Run rlang::last_error() to see where the error occurred.

It is possible to have both series of this object on the same plot?

Upvotes: 0

Views: 478

Answers (2)

G. Grothendieck
G. Grothendieck

Reputation: 269654

Regarding the creation of new_df we revise the calculation in the Note at the end giving the same value but with less code:

  • new_df is an xts object, not a data.frame, so let us use x as a more descriptive name
  • there is no real point in creating a data frame and then converting it to xts -- just create an xts object directly
  • we don't need as.numeric. Both instances of c(...) are already numeric.
  • the ggplot2 command takes data frames, not xts objects. For an xts object use autoplot instead.

Note that x in the Note is identical in contents to new_df in the question. We have just used a different name.

Now use autoplot. Omit the geom="point" argument if you want lines and omit the facet=NULL argument if you want separate panels. See ?autoplot.zoo for more examples.

library(ggplot2)
library(xts)

autoplot(x, geom = "point", facet = NULL) + ggtitle("My Plot")

screenshot

Note

Input used above.

library(xts)
dates <- c("2014-10-01", "2014-11-01", "2014-12-01", "2015-01-01", "2015-02-01")
values1 <- c(1,2,3,4,5)
values2 <- c(10,9,8,7,6)
x <- xts(cbind(values1, values2), as.Date(dates))

Upvotes: 1

Jon Spring
Jon Spring

Reputation: 66500

Option 1: specify each series as a layer:

 ggplot(new_df, aes(x = Index)) + 
  geom_point(aes(y = values1, color = "values1")) +
  geom_point(aes(y = values2, color = "values2"))

enter image description here

Option 2: convert to a longer shape of tibble, with series name as a column:

library(tidyverse)
new_df %>%
  zoo::fortify.zoo() %>%
  as_tibble() %>%
  pivot_longer(-Index, names_to = "series", values_to = "values") %>%
  ggplot(aes(x = Index, y = values, color = series)) + 
  geom_point()

enter image description here

Upvotes: 2

Related Questions