0

I have a plot in R to analyse the functional behaviour of this function : -2.5*log10(x) in different regions , the inputs are like this

 curve(-2.5*log10(x),0,5,main="Behaviour of magnification function",col=2)
 abline(v=0,col=3)
 abline(v=1,col=4)
 abline(h=0,col=8)

Now I would like to shade those regions on the right of the v=1 line and left with two different shades, but can't figure it out how to do. the polygon function not giving the shade , please help thanks, Ayan

Ayan Mitra
  • 497
  • 1
  • 8
  • 20

2 Answers2

1

You can use the panel.first argument to draw in the background.

Define a function to do the drawing:

fnShade = function(v,colL,colR) {
  p = par("usr") # limits of the plot 
  rect(p[1],p[3],v,p[4],col=colL,border=NA)
  rect(v,p[3],p[2],p[4],col=colR,border=NA)
  abline(v=v,col=4)
}

Then use it

curve(-2.5*log10(x),0,5,main="Behaviour of magnification function",col=2,
   panel.first=fnShade(1,5,"grey80"))

You can add your other ablines into the function if you like. And it should be easy to extend to draw 4 rectangles - one for each quardant - if desired.

DaveTurek
  • 1,297
  • 7
  • 8
  • `rect` is vectorized, so you only need one rect in the function if you define it like this `rect(c(p[1], v), p[3], c(v, p[2]), p[4], col=cols, border=NA)`, have one col argument, `cols = seq.int(v + 1)`, and now you can use a vector of `v` instead of having to define a new function for n-number of panels: call it like `curve(-2.5*log10(x),0,5,main="Behaviour of magnification function",col=2, panel.first = fnShade(c(1,2,3), cols = paste0('grey', 9:6 * 10)))` abline is also vectorized so this would work on that part as well – rawr Apr 15 '15 at 18:41
  • Good point @rawr about the vectorization. I think for the single left-right split, the 2 calls to `rect` is probably a bit clearer to illustrate the basic concept, but for flexibility for n panels, I like your approach. It would have to be modified if we want to handle up-down splits as well as left-right. – DaveTurek Apr 15 '15 at 19:47
  • That works thanks a lot. One more question if you dont mind, now if I want to only shade the region under the plot on the right of the line =1 is that possible ? – Ayan Mitra Apr 21 '15 at 19:52
  • Sure it's possible - this is R :). But the approach will be different and it might be better as a separate question. (Sorry, no time to work on it today.) – DaveTurek Apr 21 '15 at 21:05
  • @AyanMitra you might first search here in Stackoverflow for "shade", specifically "[r] shade" for the `R` tag to see if that gets you started. – DaveTurek Apr 23 '15 at 15:28
0

Here is a ggplot solution to the problem, using annotate:

First, save the results from curve in df:

df <- curve(-2.5*log10(x),0,5,main="Behaviour of magnification function",col=2)

Then use geom_vline to add the vertical lines, and annotate to add a rect geom to the data for the shaded areas. We use annotate, because we do not want to use data from the original data frame as suggested in this answer.

plot <- ggplot(data.frame(df)) + 
  geom_line(aes(x, y), size = 1) +
  geom_vline(xintercept  = 1, color = "blue", size = 1) +
  geom_hline(yintercept = 0, color ="grey", size = 1) +
  geom_vline(xintercept = 0, color = "green", size = 1) +
  annotate("rect", xmin = 1, xmax = Inf, ymax = Inf, ymin = -Inf, fill = "blue", alpha = 0.2) + 
  annotate("rect", xmin = -Inf, xmax = 1, ymax = Inf, ymin = -Inf, fill = "green", alpha = 0.2) + 
  labs(title = "Behaviour of magnification function\n") +
  theme_bw()

plot  
Community
  • 1
  • 1
Felix
  • 1,611
  • 13
  • 22