Create a translucency barplot


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:

The target image

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

Let's try it

The background picture

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.

Make a barplot

Making a barplot with R is easy. One could query1) the RGG about 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 :MACOS: 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")

Bring the image to R

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.

x <- read.pnm('tomCruise.pnm')

Mix image and barplot

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

Make a png file

So far, we have a really weighty PDF file. Using ImageMagick we can do that

$ convert -size 600x400 out.pdf -resize 600x400 out.png

Second shot

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.

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")
# 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)
abline(h = 5, lty = 2, col = "gray", lwd = 2)

tips/graphics-misc/translucency.txt · Last modified: 2008/02/01
Recent changes RSS feed R Wiki powered by Driven by DokuWiki and optimized for Firefox Creative Commons License