17

For example if i need to shade two area in plot

x<-rep(1:10)
plot(x,type="h")

I need as an example shade the area from 1 to 3 and from 7 to 10,

I use this commands but it omitted the lines of plot.

usr <- par('usr')
rect(1, usr[3], 3, usr[4], col='green')
user3478697
  • 243
  • 1
  • 3
  • 11
  • 3
    you could redraw the lines after you draw the rectangle (`lines(x,type="h")`); you might also want to use `border=NA` in your `rect()` call to suppress the edges. – Ben Bolker Apr 28 '14 at 21:54
  • 1
    you could use `rect(1, usr[3], 3, usr[4], col="#00FF0070")` instead, since "#00FF00" is green and the last two correspond to transparency, 00 being fully transparent and FF opaque – rawr Apr 28 '14 at 22:02
  • good, do you know any different colour, – user3478697 Apr 28 '14 at 22:47
  • 2
    I know all the colors! just scroll down and copy the function `tcol` from here (line 489 it starts) https://github.com/raredd/rawr/blob/master/R/utils.R – rawr Apr 28 '14 at 22:51
  • Could a vertical `abline` be used here, provided it stops at the height of `x`? – Rich Scriven Apr 28 '14 at 23:01
  • Alternatively, use `plot(x, type="h", lwd=3)`. – jbaums Apr 29 '14 at 00:12
  • Note you can convert any of the named colours (see `colors()`) to hex with `do.call(rgb, c(list(t(col2rgb('tomato'))), max=255))`. Replace `tomato` with your favourite colour. – jbaums Apr 29 '14 at 01:26

2 Answers2

15

If I understand you correctly, you can get what you want by using the little-known panel.first= argument to plot.default():

plot(x,type="h", 
     panel.first = {
         usr <- par('usr')
         rect(c(1,7), usr[3], c(3,10), usr[4], col='green', border=NA)
     })

Or, to avoid any mucking around with par('usr') values, just do:

plot(x, type="h", 
     panel.first = rect(c(1,7), -1e6, c(3,10), 1e6, col='green', border=NA))

enter image description here

Josh O'Brien
  • 159,210
  • 26
  • 366
  • 455
  • 1
    +1 Fantastic! So many times I've plotted with `type='n'` in order to plot shading etc. and subsequently using `lines` or `points`. This is one to remember. I never thought to look under `?plot.default` hence never came across this. – jbaums Apr 29 '14 at 07:53
  • 1
    @jbaums Very glad to hear you like it. I only took the time to answer with the hope that someone else would find it useful, so it's esp. nice to hear that someone did! – Josh O'Brien Apr 29 '14 at 15:24
5

See ?polygon:

polygon( x = c(1,1,3,3,1), y=c( usr[1], x[1], x[3], usr[1], usr[1]) ,col="red")

> polygon( x = c(1,1,3,3,1), y=c( usr[1], x[1], x[3], usr[1], usr[1]) ,col="red")
> polygon( x = c(7,7,10,10,7), y=c( usr[2], x[7], x[10], usr[1], usr[1]) ,col="red")

I chose to close the polygon but seem I remember you can get it to self-close.

enter image description here

IRTFM
  • 258,963
  • 21
  • 364
  • 487
  • 1
    Yup, from the `help(polygon)`: *It is assumed that the polygon is to be closed by joining the last point to the first point.* – r2evans Apr 29 '14 at 00:20
  • 3
    I don't think this actually answers the OP's question (they are using `rect()` successfully), which has to do with obscuring the plot behind the polygon/rectangle. – Ben Bolker Apr 29 '14 at 00:50
  • 2
    The OP was asking for "shade the area from 1 to 3 and from 7 to 10" which I would argue is really quite ambiguous as to what was really desired. I took it to mean the irregular polygon that I demonstrated how to draw. Apparently you and two others believed it was something different. I cannot really comment with authority because the mind-reading dongle for my network interface seem to be on the fritz. – IRTFM Apr 29 '14 at 03:25