Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get multiple years Y-axis data from a single file on the same plot?

I have gas meter readings over three years which I'm trying to graph in R, to highlight the changing daily usage over the months in a year, and to compare different years' usage.

Data sample:

Date,Gas  
02/01/2010,4460.9  
13/01/2010,4543  
04/02/2010,4656  
16/02/2010,4733  
07/03/2010,4842  
26/03/2010,4933.8  

I can calculate the average daily usage from the periodic readings, and plot the whole of the data across several years as a single data series:

A <- read.table("energy.csv", header=TRUE, fill=TRUE, sep=',')
A$Dates <- as.Date(A$Date, format="%d/%m/%Y")
for (j in 2:length(A$Gas)) {
  A$GasDiff[j-1] = A$Gas[j] - A$Gas[j-1]
}
plot(A$Dates, A$GasDiff, type="o", lty=1, pch=20, ylab="Daily Consumption",
     main="Gas Consumption")

But I can't figure out how to get R to automatically split the data into different ?frames? for each year, so that I can plot separate lines for each year. I can manually create different input files with just the data for each year, but it's inelegant, and will need the code changed every year.

I'm sure it's a simple question, but I've stared at manuals, and can't figure it out.

like image 771
jgc Avatar asked Jan 10 '11 00:01

jgc


People also ask

How do you plot multiple Y-axis?

Select Plot > Multi-Panel/Axis: Multiple Y Axes.... Click the Multiple Y Axes... button on the 2D Graphs toolbar. Origin opens the plotmyaxes dialog box.

What is the Matlab command that lets me create two unique Y axes on a single plot?

Use the yyaxis function to create a plot with two y-axes. For example, you can use two y-axes to plot two lines on different scales.

Can a graph have two different scales?

In an Excel chart, can I have different Y-axis scales (a primary and secondary axis)? Yes, in Excel 2013 and Excel 2016 you can have two axes. Start by creating a chart with just one axis.

How do you put multiple curves on one plot in R?

To draw multiple curves in one plot, different functions are created separately and the curve() function is called repeatedly for each curve function. The call for every other curve() function except for the first one should have added an attribute set to TRUE so that multiple curves can be added to the same plot.


2 Answers

There's no need to split the data into data-frames by year; you can use the ggplot2 package quite easily to differentiate the plots by year. First I'll make up some data:

dts <- as.Date("20050101", '%Y%m%d') + seq(0,1000,15)
A <- data.frame( Dates = dts, Gas = 4000 + cumsum(abs( rnorm(length(dts), 100, 30))))

Next I'll add two columns to A: DayOfYear which is the "day-number" within the year, and the GasDiff column (same as yours but generated more easily, with no loops!):

A <- transform( A,               
               Year = format(Dates, '%Y'),
               DayOfYear = as.numeric( format(Dates, '%j')),
               GasDiff = c(diff( Gas ),NA))

Next we use ggplot2 to first plot all the years one after the other, but with different colors:

require(ggplot2)
ggplot(A, aes(Dates, GasDiff)) + geom_line( aes(colour = Year))

which gives you this: alt text

Alternatively you can plot the different years in a vertical grid:

ggplot(A, aes(DayOfYear, GasDiff)) + geom_line( )  + facet_grid(Year ~ .)

and you get this: alt text

UPDATE: A third way is to plot all the years on the same plot with different colors/points, which may be useful if you are looking for seasonal patterns (but looks bad in my case because I made up random data).

ggplot(A, aes(DayOfYear, GasDiff)) + 
  geom_line( aes(colour = Year) )  + 
  geom_point( aes(shape = Year))

alt text

like image 130
Prasad Chalasani Avatar answered Oct 20 '22 11:10

Prasad Chalasani


Here are the plots corresponding to Prasad's ggplot examples (1) done using xyplot in lattice. (2) After that we show how to do it using xyplot.zoo from the zoo package and then (3) we show how to do each yet again using the plot.zoo which uses the zoo package's classic graphics facilities.

In each of these cases we also show a 4th style which is based on xblocks.

First lets repeat Prasad's setup:

dts <- as.Date("20050101", '%Y%m%d') + seq(0,1000,15)
A <- data.frame( Dates = dts, Gas = 4000 + cumsum(abs( rnorm(length(dts), 100, 30))))

A <- transform( A,               
               Year = format(Dates, '%Y'),
               DayOfYear = as.numeric( format(Dates, '%j')),
               GasDiff = c(diff( Gas ),NA))

Now lets try using lattice

library(lattice) # xyplot
library(latticeExtra) # layer_, panel.xblocks
library(gridExtra) # grid.arrange
library(RColorBrewer) # brewer.pal

png("png1.png")
p1 <- xyplot(GasDiff ~ Dates, group = Year, A, type = "l",
    par.settings = list(superpose.line = list(col = 1:nlevels(A$Year))),
    auto.key = list(lines = TRUE, points = FALSE))

p2 <- xyplot(GasDiff ~ DayOfYear | Year, A, type = "l", layout = c(1, 3))

p3 <- xyplot(GasDiff ~ DayOfYear, A, group = Year, type = "l",
    auto.key = list(lines = TRUE, points = FALSE))

# and here is another style:

myPalette <- brewer.pal(nlevels(A$Year), "Set3")
p4 <- xyplot(GasDiff ~ Dates, A, type = "l", col = 1) + 
    layer_(panel.xblocks(A$Dates, myPalette[A$Year]))

grid.arrange(nrow = 2, p1, p2, p3, p4)
dev.off()

This gives these 4 plots:

alt text

and now lets repeat this using using zoo in conjunction with the lattice and the other packages:

png("png2.png")
library(zoo)
library(lattice)
library(latticeExtra) # layer_, panel.xblocks
library(gridExtra) # grid.arrange
library(RColorBrewer) # brewer.pal

z <- with(A, zoo(GasDiff, Dates))
year <- format(time(z), "%Y")

# split years into separate columns and plot
P1 <- xyplot(do.call("merge", split(z, year)), screen = 1, col = 1:3)

# split years into separate columns and use day.of.year as time
day.of.year <- function(x) as.numeric(format(x, "%j"))
zz <- read.zoo(A[c(1, 5, 3)], FUN = day.of.year, split = 3)
colnames(zz) <- unique(year)
P2 <- xyplot(na.approx(zz, na.rm = FALSE))

P3 <- xyplot(na.approx(zz, na.rm = FALSE), screen = 1, col = 1:3, auto.key = TRUE)

pal <- brewer.pal(nlevels(factor(year)), "Set3")
P4 <- xyplot(z, screen = 1) + layer_(panel.xblocks(time(z), pal[factor(year)]))

grid.arrange(nrow = 2, P1, P2, P3, P4)
dev.off()

Here is the output:

alt text

A third set of ways is to use classic graphics with zoo where we use the same z, zz and pal calculated above:

library(zoo)
library(RColorBrewer) # brewer.pal

png("png3a.png")
plot(do.call("merge", split(z, year)), screen = 1, col = 1:3)
dev.off()
png("png3b.png")
plot(na.approx(zz, na.rm = FALSE))
dev.off()
png("png3c.png")
plot(na.approx(zz, na.rm = FALSE), screen = 1, col = 1:3)
legend("topleft", colnames(zz), lty = 1, col = 1:3, bty = "n")
dev.off()
png("png3d.png")
plot(z, type = "n")
xblocks(time(z), pal[factor(year)])
lines(z)
dev.off()

and here is the output

alt text

alt text

alt text

alt text

like image 24
G. Grothendieck Avatar answered Oct 20 '22 13:10

G. Grothendieck