Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Methods adding Excel-like features to R plots? [closed]

Tags:

r

graphics

I've been poking around with R graphical parameters trying to make my plots look a little more professional (e.g., las=1, bty="n" usually help). Started playing with tikzDevice, which was a huge improvement in my mind. It's amazing how much better things look when the font sizes and styles in the figure match those of the surrounding document.

I would like to add several effects to my plots and am interested in methods of doing so in a reproducible fashion. I realize that these might be considered "chart junk," but I find that in my field adding them is helpful to have output be considered professional.

Specifically, I would like to produce any or all of the following effects:

  1. Gradient shading gradient shading
  2. Rounded corners rounded corners
  3. Shadow effects

shadows

Code, references to appropriate packages, or outlines of strategies for accomplishing these effects would be helpful. Thank you.

like image 512
lowndrul Avatar asked Nov 13 '11 04:11

lowndrul


2 Answers

I couldn't help myself: used this picture and adapted this example from Paul Murrell. People who want do this sort of thing might find this link from the R wiki useful as well, although it's a little older and doesn't take advantage of the new(ish) raster capabilities. This post is an example of putting ggplot graphics in a rounded-corner frame of sorts.

edit: lots of help from Baptiste.

library(png)
library(grid)
imgfile <- "http://upload.wikimedia.org/wikipedia/commons/e/e1/Tie-dye.png"   
download.file(imgfile,dest="tiedye.png")
r <- readPNG("tiedye.png")
rmat <- matrix(rgb(r[,,1],r[,,2],r[,,3],alpha=0.4),
               nrow=dim(r)[1])

Function for shadowed points:

shadow.points <- function(x, y, size=unit(1, "char"), default.units="native", ...) {
 if(!is.unit(x)) {x <- unit(x, default.units) } 
 if(!is.unit(y)) { y <- unit(y, default.units) }
 grid::grid.points(x+0.2*size, y-0.2*size, size=size, gp=gpar(col="black"), pch=20) 
 grid::grid.points(x, y, size=size, default.units=default.units, ...)
} 

Set up mask based on grid.roundrect:

png("mask.png",width=ncol(r), height=nrow(r), res=1)
grid.roundrect(gp=gpar(fill="black"))
dev.off()
m <- readPNG("mask.png", native=FALSE)
mask <- matrix(rgb(m[,,1],m[,,2],m[,,3]),
               nrow=dim(m)[1])
rmat[mask == "#FFFFFF"] <- "#FFFFFF"

(Watch out, I think there is some variation in the support for per-pixel variation in transparency across platforms (e.g. this may not work on Windows??)) warning: there may be artifacts across other platforms, too -- the background didn't show up on a PNG, I had to export as PDF ...

grid.newpage()
pushViewport(plotViewport(),
             viewport(xscale=c(0, 10), yscale=c(0, 10)))

grid.raster(rmat,x=unit(0,"native"),y=unit(0,"native"),
            width=1,height=1,just=c(0,0))
grid.roundrect()  ## frame
grid.xaxis(at=seq(2,8,by=2))  ## axes -- shorter to avoid going beyond end of frame
grid.yaxis(at=seq(2,8,by=2))
shadow.points(x=rnorm(10,mean=5),y=rnorm(10,mean=5),pch=20,
            gp=gpar(col="cyan"))

tiedye

like image 189
Ben Bolker Avatar answered Oct 23 '22 13:10

Ben Bolker


You can make shadow lines by drawing several lines at an offset from the line generating the shadow. Start with a wide line (lwd=30, say) drawn in a pale grey (gray(1)) and then draw thinner lines coloured down to gray(.5). There's one shadow.

package:grid has a function for rounded rectangles. Or you can draw them in base graphics using segment and line and a bit of ancient greek geometry.

Psychedelic backgrounds can be splatted onto a base graphics canvas using 'image'. Generate the image using the 'raster' package in whatever resolution you like.

You could also use a package called something like RGoogleVis to interface with Google's charting, or export to JSON, and use something like D3 to do enterprise interactive graphics:

http://mbostock.github.com/d3/ex/

Or just load the darn data into Excel already.

like image 36
Spacedman Avatar answered Oct 23 '22 15:10

Spacedman