1

I'm plotting a zoo object with daily rainfall data and some water-temperature measurements every 4 days. While merging the data I get some NA data in the days between and therefore the line does not connect the dots. Here a (very) minimal example with horrible layout:

install.packages('zoo')
library(zoo)

Datum<-as.Date(c("2017-07-01", "2017-07-02", "2017-07-03", "2017-07-04"))
data<-as.data.frame(Datum)
data$Rain<-c(3,5,6,7)
data$Temperature<-c(10, NA, 11, 12)
data.zoo<-read.zoo(data, by=Datum)

plot(data.zoo, type=c("h", "o"), lwd=c(5,1), col=c("blue", "red"))

What I need is a line between the temperature data points. I almost found the answer here Plotting xts objects works with points but not with lines. However, interpolating etc data is not possible (or meaningful) and I know that connecting punctual data is scientifically incorrect but if I do not, the plots are really not intuitiv and a optical comparison between the 25 plots very difficult. This is why I'd like to have the lines between the dots.

Not merging the data and hence not producing the NA is not really possible as otherwise the code block is not working anymore. The code block is kind of complicated (for my coding level) as e.g. the rainfall data and temperature data is on the same screen, fancy axis labelings, and contains a for loop to print out a pdf per group automatically etc.

Thanks a lot in advance, Tina

Tina
  • 13
  • 2
  • How are you supposed to draw a line through the points that aren't missing, if you don't interpolate the missing values? – Joshua Ulrich Dec 13 '17 at 11:40
  • I was thinking about something like "ignoring" the NA value, connecting somehow one point with the next point that is not an NA value. – Tina Dec 13 '17 at 12:58

1 Answers1

0

1) screens Plot the temperature twice -- once as lines using na.approx to fill in the empty NAs to prevent the lines from being broken and again using points so the points are visible. Use screens= to specify that the lines and points are to be superimposed on the same panel.

plot(cbind(data.zoo, na.approx(data.zoo$Temperature)), 
  screens = c("Rain", "Temperature", "Temperature"), 
  type = c("h", "p", "l"),
  lwd = c(5, 1, 1), 
  col = c("red", "blue", "blue"),
  main = "Temperature and Rain")

2) panel This could alternately be done using a custom panel function:

my.panel <- function(x, y, ..., pf = parent.frame()) {
  if (pf$panel.number == 1) {
        lines(x, y, type = "h", col ="red", lwd = 5)
  } else {
        lines(x, na.approx(y), col = "blue")
        points(x, y, col = "blue")
  }
}

plot(data.zoo, panel = my.panel, main = "Temperature and Rain")

Either of these would give this output:

screenshot

G. Grothendieck
  • 254,981
  • 17
  • 203
  • 341
  • Thanks! The second approach was easy to add to my existing pannel. But now I have a follow up question:Most of the plots (20 of 25) which are generated with this code are working now but in 5 there is an error message: 'Error in xy.coords(x, y) : 'x' and 'y' lengths differ'. When I skip the lines() command it works perfectly. As mentioned above, the data is merged within the for-loop producing the figures (with all=TRUE) and it seems to have the same daterange (and consequently same number of entries). Do you have any idea what I'm doing wrong? – Tina Dec 14 '17 at 10:01
  • Without a reproducible example I don't know what you are doing. Put some `print` or `browser()` statements in your panel function to see what is going on and maybe you can figure it out yourself. – G. Grothendieck Dec 14 '17 at 13:16