Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

plotting monthly and yearwise weather data in r

I am trying to develop a weather plot like that appears in weather data - something like.

enter image description here

I want to plot daily value (although average value can appear in circle). I am using ggplot2 as it need multifaceted (for each month and year).

st <- as.Date ("2009-1-1")
en <- as.Date ("2011-12-28")
date1 <- seq(st, en, "1 day")
year <- format(date1, "%Y")
month <- format (date1, "%b")
day <- as.numeric (format(date1, "%d"))

avgtm <- round (rnorm (length(date1), 50,5), 1)
maxtm <- avgtm + abs(rnorm (length (avgtm), 0, 5))
mintm <-  avgtm - abs(rnorm (length (avgtm), 0, 5))

myd <- data.frame ( year, month, day, avgtm, maxtm, mintm)
require(ggplot2)
qplot(day, avgtm, data = myd, geom = "line", col = "red") +
facet_grid(year ~ month) + theme_bw()

enter image description here

There is one major problem here, line will connect between months.

Each month is plotted to maximum (although one month can end in 28, leaving blank at the month). enter image description here

Is there a smart way to achieve what I want to achieve. I tried ggplot2 but there might be other nice options.

Edit:

I am trying to add vertical line at the first day of month to demark the months. Here is I tried to find the first day of month:

 td = as.Date (seq(as.Date("2009/1/1"), as.Date("2011/12/28"), "months"))

I tried to use this to plot line:

qplot(date, avgtm, data = myd, geom = "line", col = "red") +
  facet_wrap(~year, scales='free_x', ncol=1, nrow=3) +

   geom_vline(xintercept=td, linetype="dotted") + theme_bw()

But running an error: Error : Invalid intercept type: should be a numeric vector, a function, or a name of a function

How can plot the vertical line with the date ?

like image 822
SHRram Avatar asked Dec 22 '25 10:12

SHRram


2 Answers

There is a solution with panel.xblocks from latticeExtra:

st <- as.Date("2009-1-1")
en <- as.Date("2011-12-28")
date1 <- seq(st, en, "1 day")

avgtm <- round (rnorm (length(date1), 50,5), 1)

myd <- data.frame(date1, avgtm)

I define two functions to extract month and year values instead of including them in the data.frame. This approach is useful with panel.xblocks in the panel function of xyplot:

month <- function(x)format(x, '%m')
year <- function(x)format(x, '%Y')

I use year(date1) as conditioning variable to produce three panels. Each of these panels will display the time series for that year (panel.xyplot) and a sequence of contiguous blocks with alternating colors to highlight months (panel.xblocks). You should note that the y argument in panel.xblocks is the function month previously defined:

xyplot(avgtm ~ date1 | year(date1), data=myd,
       type='l', layout=c(1, 3),
       scales=list(x=list(relation='free')),
       xlab='', ylab='',
       panel=function(x, y, ...){
           panel.xblocks(x, month,
                         col = c("lightgray", "white"),
                         border = "darkgray")
           panel.xyplot(x, y, lwd = 1, col='black', ...)
           })

xblocks

like image 181
Oscar Perpiñán Avatar answered Dec 24 '25 01:12

Oscar Perpiñán


How about making a date column, then faceting on year only

myd$date <- as.Date(paste(myd$year, myd$month, myd$day), format='%Y %b %d')

qplot(date, avgtm, data = myd, geom = "line", col = "red") +
  facet_wrap(~year, scales='free_x', ncol=1, nrow=3)

enter image description here

You could add scales='free_x' to your plot as well, but will find it makes interpretation difficult.

By faceting on month and year you are telling the viewer and the plotting tool that the variables plotted are not continuous. This is incorrect as you've pointed out in your question. Thus, no faceting... You can add tick marks for each month or each day if you want.

library(scales)
qplot(date, avgtm, data = myd, geom = "line", col = "red") +
      facet_wrap(~year, scales='free_x', ncol=1, nrow=3) +
      scale_x_date(breaks=date_breaks("month"), labels=date_format("%b"))

Alternatively you could extract day of year and plot everything on one plot, coloring by year:

myd$doy <- format(myd$date, '%j')
p <- ggplot(myd, aes(x=doy, y=avgtm, color=year, group=year))

p + geom_line()

or

p + geom_smooth()
like image 41
Justin Avatar answered Dec 24 '25 02:12

Justin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!