R - Smoothing color and adding a legend to a scatterplot

heatmap, interpolation, legend, r, scatter-plot

Solution

Here are some solutions using the `ggplot2` package.

# Load library
library(ggplot2)

# Recreate the scatterplot from the example with default colours
ggplot(df) +
  geom_point(aes(x=x, y=y, col=dens))

# Recreate the scatterplot with a custom set of colours. I use rainbow(100)
ggplot(df) +
  geom_point(aes(x=x, y=y, col=dens)) +
  scale_color_gradientn(colours=rainbow(100))

# A 2d density plot, using default colours
ggplot(df) +
  stat_density2d(aes(x=x, y=y, z=dens, fill = ..level..), geom="polygon") +
  ylim(-0.2, 1.2) + xlim(-30, 180) # I had to twiddle with the ranges to get a nicer plot

# A better density plot, in my opinion. Tiles across your range of data
ggplot(df) +
  stat_density2d(aes(x=x, y=y, z=dens, fill = ..density..), geom="tile", 
                 contour = FALSE)

# Using custom colours. I use rainbow(100) again.
ggplot(df) +
  stat_density2d(aes(x=x, y=y, z=dens, fill = ..density..), geom="tile", 
                 contour = FALSE) +
  scale_fill_gradientn(colours=rainbow(100))

# You can also plot the points on top, if you want
ggplot(df) +
  stat_density2d(aes(x=x, y=y, z=dens, fill = ..density..), geom="tile", 
                 contour = FALSE) +
  geom_point(aes(x=x, y=y, col=dens)) +
  scale_colour_continuous(guide=FALSE) # This removes the extra legend

I attach the plots as well:

Problem

I have a scatterplot in R. Each `(x,y)` point is colored according to its `z` value. So you can think of each point as `(x,y,z)`, where `(x,y)` determines its position and `z` determines its color along a color gradient. I would like to add two things - A legend on the right side showing the color gradient and what `z` values correspond to what colors - I would like to smooth all the color using some type of interpolation, I assume. In other words, the entire plotting region (or at least most of it) should become colored so that it looks like a huge heatmap instead of a scatterplot. So, in the example below, there would be lots of orange/yellow around and then some patches of purple throughout. I'm happy to further clarify what I'm trying to explain here, if need be. Here is the code I have currently, and the image it makes. ``` x <- seq(1,150) y <- runif(150) z <- c(rnorm(mean=1,100),rnorm(mean=20,50)) colorFunction <- colorRamp(rainbow(100)) zScaled <- (z - min(z)) / (max(z) - min(z)) zMatrix <- colorFunction(zScaled) zColors <- rgb(zMatrix[,1], zMatrix[,2], zMatrix[,3], maxColorValue=255) df <- data.frame(x,y) x <- densCols(x,y, colramp=colorRampPalette(c("black", "white"))) df$dens <- col2rgb(x)[1,] + 1L plot(y~x, data=df[order(df$dens),],pch=20, col=zColors, cex=1) ```

Original source