Bakaburg
Bakaburg

Reputation: 3311

Area plot with missing values in base R

I want to draw an area plot for which the base of the polygon is zero and the data lines are connected to the base by vertical segments at every data break (that is the beginning, the end and possible NAs/NaN).

I drew this:

time serie

I had to force vertical down ward segments where the serie is interrupted with NAs, and I did this transforming NAs in 0s. But that doesn't produce vertical segments but polygon lines that reach the following 0s. I solved the problem for the beginning and the end of the series, adding a (y = 0, x = 0) point on both sides on the serie.

But this doesn't fix the problem if the NAs are inside the serie.

Any idea?

here's an example code (different image):

pollen <- c(45, 257.4, 24.67, 54.6, 89.4, 297, 471.25, 1256.5, 312.25, 969.2, 787.5, 425, NaN, 76.6, 42.67, 38.5, 20.2, 5.67, 15.8, 13.2, 11, 6.25, 6.67, 2.3, 0.5, 30.8, 3.75, 3, 2, 2.2, 3.25, 4.5, 9.6, 15.8, 200.2, NaN)

weeks.vec <- c(5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40)

plot.ts(y = pollen, x = weeks.vec, col = 'red', ylab = 'Pollen',  xlab = 'Weeks', lwd = 3, xy.labels = F, xy.lines = T)
pollen[is.na(pollen)] <- 0

poly.y <- c(0,pollen,0)
poly.x <- c(weeks.vec[1], weeks.vec, weeks.vec[length(weeks.vec)])

polygon(y = poly.y, x = poly.x, density = NA,border = NA, col = rgb(1,0,0, .3))

Upvotes: 2

Views: 772

Answers (1)

Roland
Roland

Reputation: 132706

I'd use ggplot2:

pollen <- c(45, 257.4, 24.67, 54.6, 89.4, 297, 471.25, 1256.5, 312.25, 969.2, 787.5, 425, NaN, 76.6, 42.67, 38.5, 20.2, 5.67, 15.8, 13.2, 11, 6.25, 6.67, 2.3, 0.5, 30.8, 3.75, 3, 2, 2.2, 3.25, 4.5, 9.6, 15.8, 200.2, NaN)

weeks.vec <- c(5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40)


DF <- data.frame(pollen, weeks.vec)

library(ggplot2)
ggplot(DF, aes(x = weeks.vec, y = pollen)) +
  geom_ribbon(aes(ymin = 0, ymax = pollen), 
              colour = NA, fill = "red", alpha = 0.3) +
  geom_line(colour = "red") + 
  geom_point(colour = "red", size = 3) +
  xlab("Week") + ylab("Pollen") +
  theme_bw()

resulting plot

But if you must use base plots:

plot.ts(y = pollen, x = weeks.vec, col = 'red', 
        ylab = 'Pollen',  xlab = 'Weeks', lwd = 3, 
        xy.labels = F, xy.lines = T)

g <- cumsum(!is.finite(pollen))
for (i in unique(g)) {
  y <- pollen[g == i]
  x <- weeks.vec[g == i]
  x <- x[is.finite(y)]
  y <- y[is.finite(y)]
  x <- c(x, rev(x))
  y <- c(y, y * 0)
  polygon(y = y, x = x, density = NA,border = NA, col = rgb(1,0,0, .3))
}

resulting plot

Upvotes: 2

Related Questions