This page is based on a question on R-help by Gabor Grothendieck.
Does anyone have an idea of how to make a chart in R like the ones here that use a graphic: http://bigpicture.typepad.com/comments/images/slide1.gif
Let’s start by acknowledging that this kind of picture would have been easier to do with any image manipulation program (such as Gimp) that support layers. But, it has been fun to try doing it with R.
Moreover, that kind of sexy graphic should not be advised in real life situations. See Friendly (2000).
We will try to mimic the graphic on top left of the image above. The background is a picture from War of the worlds. Googling for la guerre des mondes gives a pretty accurate candidate.
Making a barplot with R is easy. One could query1) the RGG about barplot
http://addictedtor.free.fr/graphiques/search.php?q=barplot
This one (though not returned by the query) uses barplot just like we want. I don’t have the data used in the original picture, so I maked it up :
y <- c(6, 6.5, 7, 8, 8.5, 8.2, 10, 9.6, 9.7, 9) #x11(width = 12, height = 8) # same ratio than picture op <- par(mar = c(2, 3, 2, 2), las = 1) barplot(y, space = 0, col = "#FF0000A3") par(op) # reset the parameters
The color #FFFFFFA3 is red2) with an alpha-channel set to 70%. If you try that code from the command line, you won’t get red rectangles at all because the screen devices doesn’t support Translucency.
At least the Cairo and
Aqua devices support transparency.
The PDF device supports translucency, but only with version 1.4, so you should tell R that
pdf('out.pdf', width = 12, height = 8, version = "1.4")
To bring the image into R, the package pixmap may be used3). The image should have been transformed into the PNM format to be readable fo pixmap. Kindly, GIMP did that for me. The resulting picture is here, you will need it to run the later chunks of code.
require(pixmap) x <- read.pnm('tomCruise.pnm') plot(x)
What we want to do now is superimpose the background image and the barplot, using translucency so that the barplot covers the background image but not too much.
You need that file
y <- c(6, 6.5, 7, 8, 8.5, 8.2, 10, 9.6, 9.7, 9) require(pixmap) pdf('out.pdf', width = 12, height = 8, version = "1.4") #first the background image op <- par(mar = rep(0, 4)) # we want it to fill the file x <- read.pnm("tomCruise.pnm") plot(x) #and now the barplot par(mar = rep(2, 4), new = TRUE, las = 1) barplot(y, space = 0, col = "#FFFFFFA3") # #FFFFFFA3 is white with an alpha channel set to 0.7 # A3 / FF = 0.7 par(op) # reset dev.off()
So far, we have a really weighty PDF file. Using ImageMagick we can do that
$ convert -size 600x400 out.pdf -resize 600x400 out.png
Some might say:
The Tom Cruise R example on wiki does not look like the original example. The R one is just a barplot with the image in the background but the original one has the image in the barplot only.
You need that file to run the code below.
require(pixmap) pdf("out_2.pdf", width = 14, height = 10, version = "1.4") par(mai = rep(1,4)) y <- c(6, 6.5, 7, 8, 8.5, 8.2, 10, 9.6, 9.7, 9) x <- read.pnm("tomCruise.pnm") plot(x) # Prepare the space par(new = TRUE) plot(0, type = "n", ann = FALSE, xlim = c(0, 10), ylim = c(0, 10), xaxs = "i", yaxs = "i", axes = FALSE) rect(xleft = 0:9, xright = 1:10, ybottom = y, ytop = 10, col = "white", border = NA) rect(xleft = 0:9, xright = 1:10, ybottom = 0, ytop = y, col = "#FFFFFFA3") par(las = 1) axis(2) abline(h = 5, lty = 2, col = "gray", lwd = 2) dev.off()
Then
convert -size 700x500 out_2.pdf -resize 700x500 out_2.png
make a picture inspired by that page for RGG, maybe using that picture of the maunga whau. Peter Dalgaard says it’s ok. Does somebody have an idea of what kind of picture to do using that mechanism ?
this should be reconsidered using the material from Paul Murrell’s talk on useR! 2006 conference. Roughly the idea is to clip inside a bar of the barplot and then draw the entire image.