0

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
Roope
  • 4,469
  • 2
  • 27
  • 51
  • 3
    Could you please provide a sample dataset, so we don't have to generate the sample *and* the solution for you? Also, what did you try, and what part of the graph is difficult for you to do? – Jealie Apr 14 '14 at 17:22
  • 1
    You could use `rect` for the gray areas. – Karsten W. Apr 14 '14 at 17:38
  • To understand the ideas behind scaling your data & plotting a 2nd dataset (ie, volatility & price), it may help you to read my answer here: [Plotting multiple datasets on the same figure with 2 y axes](http://stackoverflow.com/a/18875822/1217536). – gung - Reinstate Monica Apr 14 '14 at 17:52
  • I guess my main question here is, how to plot the `rect`s automatically and not manually, since there are quite a few of them. Would I need to make a `rect` for each individual value? – Roope Apr 14 '14 at 18:49
  • I edited my answer with your data. I hope it is more clear now. – alko989 Apr 14 '14 at 21:18

2 Answers2

2

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

Thomas
  • 43,637
  • 12
  • 109
  • 140
0

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

alko989
  • 7,688
  • 5
  • 39
  • 62