Methods adding Excel-like features to R plots? [cl

2019-03-15 11:33发布

问题:

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
  2. Rounded corners
  3. Shadow effects

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

回答1:

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.



回答2:

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"))



回答3:

Using rounded rectangles as a clip mask in @Ben Bolker's example,

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"
grid.raster(rmat)
grid.roundrect()


回答4:

Adding a shadow to Ben Bolker's example,

grid.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, ...)
} 


标签: r graphics