28
$\begingroup$

While I know that there are a series of functions for generating heat maps in R, the problem is that I'm unable to produce visually appealing maps. For example, the images below are good examples of heat maps I want to avoid. The first clearly lacks detail, while the other one (based on the same points) is too detailed to be useful. Both plots have been generated by the density() function in the spatstat R package.

How can I get more "flow" into my plots? What I'm aiming for is more of the look the results of the commercial SpatialKey (screenshot) software is able to produce.

Any hints, algorithms, packages or lines of code that could take me in this direction?

enter image description here

$\endgroup$
1
  • $\begingroup$ have you looked at the image() function? Increasing the number of breaks increases resolution. $\endgroup$
    – Macro
    Apr 18, 2012 at 13:37

4 Answers 4

29
$\begingroup$

There are two things that will impact the smoothness of the plot, the bandwidth used for your kernel density estimate and the breaks you assign colors to in the plot.

In my experience, for exploratory analysis I just adjust the bandwidth until I get a useful plot. Demonstration below.

library(spatstat)
set.seed(3)
X <- rpoispp(10)
par(mfrow = c(2,2))
plot(density(X, 1))
plot(density(X, 0.1))
plot(density(X, 0.05))
plot(density(X, 0.01))

enter image description here

Simply changing the default color scheme won't help any, nor will changing the resolution of the pixels (if anything the default resolution is too precise, and you should reduce the resolution and make the pixels larger). Although you may want to change the default color scheme for aesthetic purposes, it is intended to be highly discriminating.

Things you can do to help the color are change the scale level to logarithms (will really only help if you have a very inhomogenous process), change the color palette to vary more at the lower end (bias in terms of the color ramp specification in R), or adjust the legend to have discrete bins instead of continuous.

Examples of bias in the legend adapted from here, and I have another post on the GIS site explaining coloring the discrete bins in a pretty simple example here. These won't help though if the pattern is over or under smoothed though to begin with.

Z <- density(X, 0.1)
logZ <- eval.im(log(Z))
bias_palette <- colorRampPalette(c("blue", "magenta", "red", "yellow", "white"), bias=2, space="Lab")
norm_palette <- colorRampPalette(c("white","red"))
par(mfrow = c(2,2))
plot(Z)
plot(logZ)
plot(Z, col=bias_palette(256))
plot(Z, col=norm_palette(5))

enter image description here


To make the colors transparent in the last image (where the first color bin is white) one can just generate the color ramp and then replace the RGB specification with transparent colors. Example below using the same data as above.

library(spatstat)
set.seed(3)
X <- rpoispp(10)
Z <- density(X, 0.1)
A <- rpoispp(100) #points other places than density


norm_palette <- colorRampPalette(c("white","red"))
pal_opaque <- norm_palette(5)
pal_trans <- norm_palette(5)
pal_trans[1] <- "#FFFFFF00" #was originally "#FFFFFF" 

par(mfrow = c(1,3))
plot(A, Main = "Opaque Density")
plot(Z, add=T, col = pal_opaque)
plot(A, Main = "Transparent Density")
plot(Z, add=T, col = pal_trans)


pal_trans2 <- paste(pal_opaque,"50",sep = "")
plot(A, Main = "All slightly transparent")
plot(Z, add=T, col = pal_trans2)

enter image description here

$\endgroup$
6
  • $\begingroup$ Thank you, very clearly resented answer. This combined with the "spatstat.options(npixel=c(100,100))" command you lined to did the trick. If I can bother you some more: Do you know how I can make the "background" color transparent? $\endgroup$
    – Figaro
    Apr 19, 2012 at 7:34
  • 1
    $\begingroup$ @Figaro, I have updated with an example of making the colors semi-transparent. $\endgroup$
    – Andy W
    Apr 19, 2012 at 12:20
  • $\begingroup$ Thank you. One more thing. While this might be slightly off topic: How do I export these heatmaps into a Shape file? Or am I required to treat them as rasters only? $\endgroup$
    – Figaro
    Apr 19, 2012 at 12:37
  • $\begingroup$ I've never had to do that, so I can't say offhand. Probably a good question for the R guru's on stackoverflow. $\endgroup$
    – Andy W
    Apr 19, 2012 at 12:49
  • $\begingroup$ Can a heatmap be presented as anything else than a raster? $\endgroup$
    – Figaro
    Apr 19, 2012 at 12:53
2
$\begingroup$

You may benefit from the interp function from the akima package. This will let you interpolate your matrix to another resolution if need be. To make something like your linked example, you would need to interpolate to a pretty fine grid (perhaps with the arguments xo and yo being ~ 1000 in length). This will give you a new matrix that you can plot with image(). If you want transparency, this will take some additional work. It's not easy to do that with a color palette, so you may end up having to plot each grid as a polygon with an assigned color.

$\endgroup$
4
  • $\begingroup$ Do you have experience with creating the transparency? Are there examples? That would be the next step. $\endgroup$
    – Figaro
    Apr 19, 2012 at 6:04
  • $\begingroup$ How do I create the x, y, z values needed for the interp()? For example, if density() uses a 100x100 grid, I have the z values for each point, but I do not have the x & y in the required vector format (I only have the coordinates of the axles). $\endgroup$
    – Figaro
    Apr 19, 2012 at 7:31
  • $\begingroup$ Made a loop to get the coordinate pairs, but is there a function for this? $\endgroup$
    – Figaro
    Apr 19, 2012 at 8:26
  • 2
    $\begingroup$ Looks like image can accept transparent colors after all. See: menugget.blogspot.de/2012/04/… . In case you still want to use interp, you can generate your xy coordinate combinations for your z levels with : "grid <- expand.grid(x=x,y=y)" $\endgroup$ Apr 19, 2012 at 10:59
1
$\begingroup$

You may want to look into ggplot2. It seems like the package you've tried doesn't have a great color schemes or "flow" -- take a look at RColorBrewer. There is a blog where it implemented these package with a simple example.

I'm not sure if you are trying to plot geographical data as shown in your linked example, but if you do I know that Google offers "Static Maps API V2 Developer Guide" and you can combine Google and R with a package called, RgoogleMaps.

Good luck with your research.

$\endgroup$
1
  • $\begingroup$ Sorry if I was unclear, but right now the issue isn't the color scheme itself. I did however try RColorBrewer earlier today: a great little pacakge! It is spatial data, I'm not sure I want to use Google APIs, but I might have a look. $\endgroup$
    – Figaro
    Apr 18, 2012 at 17:45
0
$\begingroup$

Have you tried cranking up the resolution in density? Try argument dimyx=c(512, 512) or higher.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.