Roope
Roope

Reputation: 4507

How to achieve a graph like this in R

This sample from a study is very close to what I need. The question is, how do I achieve the conditional background color like in the chart below. This chart has two categories, I have three, so I would use some texture for the third.

The categories for the condition that changes over time are in a vector with names CL, C, and CR.

sample graph

Here's some sample data. So there's the index and then there's the categories that are government types (center-left, center, center-right). In the data there are 72 government terms so there are 72 consecutive runs, therefore doing it by hand with rects is kind of cumbersome at least. I do understand that first I need to plot the categories and then add the line to the plot, I'll worry about axes after the fact and add them last.

shareindex    categ
100           C
103           C
104           C
102           CL
99            CL
98            CR
99            CR
101           CL
104           CL
105           CR
104           CR
102           C
103           C

Upvotes: 0

Views: 152

Answers (2)

alko989
alko989

Reputation: 7928

You can use rect to make rectangles and plot lines on top of that

For your data example:

set.seed(1)
x <- 1:100
y <- cumsum(rnorm(100))
z <- c(rep(1, 10), rep(2,20), rep(1,40), rep(3,30))
plot(x, y, type="n")
rect(xleft = x - 1, xright = x, ybottom=par("usr")[3], ytop=par("usr")[4], col=z, border=NA )
lines(x, y, col="white")

Example plot

Edit for your data:

## Data frame with the data
dat <- data.frame(shareindex=c(100,103,104,102, 99,98,99,101,104,105,104,102,103),
                  categ=c("C","C","C","CL","CL","CR","CR", "CL", "CL","CR", "CR","C", "C"))

## Add index column
dat$id <- seq(along.with=dat$shareindex) 

# Add your background colors here
cols <- c("lightgray","grey", "lightblue") 

## Just an empty plot
plot(dat$id, dat$shareindex, type="n", ylab="Share index", xlab="id")

## Plot the rectangles for the background
rect(xleft =dat$id - 1 , xright = dat$id, 
     ybottom=par("usr")[3], ytop=par("usr")[4], 
     col=cols[dat$categ], border=NA )

## Plot the line
lines(dat$id, dat$shareindex, lwd=2)

The output looks like this:

Plot of your data

Cheers,

alex

Upvotes: 0

Thomas
Thomas

Reputation: 44555

Here's some example data and a call to plot using the panel.first argument to draw the rectangles. I've suggested here using an lapply call to simply the drawing the many rectangles.

# data
set.seed(1)
x <- rnorm(1000)
x2 <- cumsum(x)
y <- rnorm(1000)
y2 <- cumsum(y)-5
ranges <- list(c(5,10), c(20,100), c(200,250), c(500,600), c(800,820), c(915,930))

# expression to be used for plotting gray boxes
boxes <- expression(lapply(ranges, function(z) rect(z[1],-100,z[2],100, col='gray', border=NA)))

# the actual plotting
plot(1:1000, x2, type='l', xlab='time', panel.first = eval(boxes))
lines(1:1000, y2, col='red')

enter image description here

Upvotes: 2

Related Questions