2

Goal: I have an adjusted pairs plot in R and I would like to add a color key to it. The panel backgrounds in the pairs plot show certain colors determined from a matrix of numbers. I would like to have a color key to the right of the pairs plot which shows these colors and some labels indicating the numbers.

I found some ways how to add color keys to image() plots (for example, image.plot in the fields package; colorbar in the matlab package; color.legend in the plotrix package). So, in principle, I would like to do something similar for my adjusted pairs plot. However, I already run into trouble with reserving some space for the color key to be plotted to (can [or even should?] this be done with grid?).

Here is a minimal example of a pairs plot that has colored backgrounds. I also tried to adapt the example of color.legend in plotrix but this is more or less nonsense at the moment. Any ideas of how to do this in an elegant/flexible way?

count <- 0
color <- c("yellow", "orange", "red", "lightgreen", "darkgreen", "cyan", "lightblue",
           "darkblue", "brown", "gray", "transparent", "transparent")
mypanel <- function(x, y, ...){
   count <<- count+1
   bg <- color[count]
   ll <- par("usr")
   rect(ll[1], ll[3], ll[2], ll[4], col=bg)
   points(x, y, cex=0.5)
}

U <- matrix(runif(4*500), ncol=4)

## require(plotrix)
## par(mar=c(7,4,4,14)) # (bottom, left, top, right)
pairs(U, panel=mypanel, gap=0)
## color.legend(xl=10.2, yb=2, xr=11, yt=5,
##              legend=c("bright","normal","dark"), rect.col=color, align="rb",
##              gradient="y")

Info: The colors chosen above are determined from numbers (a vector of the same length). The numbers are all in between 0 and 1 and 0 (1) corresponds to the darkest (brightest) color. Those numbers should then determine the ticks and numbers printed at the color key (I don't need actual text labels -- I just tried that since the example of color.legend used it). So a vector of numbers for colors above could be c(0.95, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 1, 1) (the larger the number the brighter the column). To be more precise: These values are p-values determined by goodness-of-fit tests for each pair and the dark color should point out small p-values. Indeed, the colors are not that evenly spaced, I only use some colors above the significance level of (for example) 0.05, and most of the colors below 0.05, so one can directly see which tests lead to rejection.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Marius Hofert
  • 6,546
  • 10
  • 48
  • 102
  • Your legend values are length 3 but you color values are length 12. Is your hope to have the legend values recycled? – IRTFM Mar 24 '12 at 14:19
  • Actually, I don't even need to have text-labels, I rather would like to have numbers with ticks indicating the value based on which the color was determined. So typically, the number of colors is large (it could be up to d*(d-1) many (for each panel differently)), but the ticks/numbers/labels is small. I'll add some words concerning the "numbers" above in a minute. – Marius Hofert Mar 24 '12 at 14:29
  • Adjusting the layout to make room for a colorbar will be a challenge. `pairs` calls `par(mfrow = ...)` which will override any attempt on your part to adjust the layout. The easiest route would likely be to place the colorbar in one of the diagonal boxes. Otherwise I think grid may indeed be better suited to this. – joran Mar 24 '12 at 16:42
  • That's no problem. As I wrote, I created a new function pairs2 based on pairs (but for a specific plot and with some adjustments -- just can't post it here), so I can change anything I like. The line you mention is line 106 in pairs.R (R 2.14): `opar <- par(mfrow = c(nc, nc), mar = rep.int(gap/2, 4), oma = oma)` where `nc` is the number of columns to plot. What's the best way to adjust this? Shall I adjust `mfrow`, `mar` or `oma`? Since the tick labels are between 0 and 1, I have a fixed width of the color key. This means to adjust `mfrow` I would have to scale by `nc` – Marius Hofert Mar 24 '12 at 17:00
  • 1
    Actually, the reason I think it's going to be a challenge is that I don't think that `mfrow` is going to suit your needs at all. You may have to rewrite it completely to employ `layout` instead. – joran Mar 24 '12 at 17:35
  • I got the whole plot to work (after some days of work). I then wanted to apply it to visualize a data set in 30 dimensions. I obtained an error from `layout`: `too many cells in layout, limit 500`... highly frustrating – Marius Hofert Apr 11 '12 at 22:29
  • Marius, you may want to consider learning the base 'grid' package if you do much custom visualization. Spending a few days of work is ridiculous. At most, I spend about 4 hours doing highly customized visualizations with the 'grid' functions, and it has full flexibility to do whatever you want. My answer on http://stackoverflow.com/questions/13081310/combining-multiple-complex-plots-as-panels-in-a-single-figure/14567298#14567298 may help you get started. – Dinre Mar 05 '13 at 14:37
  • Thanks, Dinre, in the meanwhile I did :-) – Marius Hofert Mar 05 '13 at 15:45

0 Answers0