1

I am trying to display a 2-D colored scatter plot -- i.e, Y as function of X with point colors driven by Z.

I would like the Z color-gradient legend to be on top, ideally below the main plot title.

I inspired myself from this SO with Z color-gradient on the right to derive the following function:

library(grDevices)
library(colorRamps)

# 2-dim scatter plot with color gradient legend on top.
scatterPlot2DWithColorLegend <- function(x, y, z, colorGradient, legendTitle=""
                                         , main="", xlab="", ylab="", pch=16, cex=1)
{
  parPrev <- par()
  nColorGradient <- length(colorGradient)
  labelRange <- zRange <- range(z)
  layout(matrix(1:2, nrow=2), widths = c(1), heights = c(1, 2), FALSE) # 2 plots, one above the other.
  # Plot legend first on top.
  plot(c(0, 1), c(0, 0.05), type = 'n', axes = F, xlab = '', ylab = '', main = legendTitle, cex.main=0.5)
  legend_image <- as.raster(matrix(colorGradient, nrow = 1))
  text(x = seq(0, 1, l = 5), y = 0.1 , labels = seq(labelRange[1], labelRange[2], l = 5), pos=1)
  rasterImage(legend_image, 0, 0, 1, 1)
  # Main plot second on bottom.
  if (1 < length(unique(zRange)))
    colVec = colorGradient[as.numeric(cut(z, nColorGradient))]
  else
    colVec = colorGradient[1]
  plot(x, y, col = colVec
       ,    main = main, xlab = xlab, ylab = ylab, pch = pch, cex = cex)
  par(parPrev)
}

This is a simple test code:

# Test data.
mdf <- data.frame(X=c(0:10))
mdf$Y <- mdf$X * 3
mdf$Z <- (mdf$X-5)^2

# Color gradient function.
colorGradient <- colorRampPalette(c("blue", "green", "yellow", "red"))(4)

# 2-D colored scatter plot.
scatterPlot2DWithColorLegend(mdf$X, mdf$Y, mdf$Z, colorGradient
                             , legendTitle="Z", main="Y vs. X with Z-Color", ylab="Y", xlab="X"
                             , pch=16, cex=0.7)

With my scatterPlot2DWithColorLegend function as above, I get:

enter image description here

I desire something like:

enter image description here

Can someone quickly offer an enhanced version of the scatterPlot2DWithColorLegend function or point me to an existing package/function that would get me what I want? Namely:

  1. Main title above the color-gradient legend (Y vs. X with Z-Color).
  2. Z-color gradient image smaller, height and width.
  3. Z-color gradient Z-range on bottom (the Z-range does not currently show).
  4. Z-color gradient legend to the left of Z-color gradient image as opposed to top (i.e., legendTitle="Z").
  5. Significantly reduce spacing between main title, color-gradient legend, and the main scatter plot.

Obviously, I don't understand well R graphics. I am not familiar with the lattice, ggplot and the kinds either - the number of options appears overwhelming. I would like something simple that works I can reuse to get over this specific hump as this seems very basic.

Thanks in advance for any help.

Community
  • 1
  • 1
Patrick
  • 1,561
  • 2
  • 11
  • 22
  • You've got some good `ggplot` answers below, but this has also been similarly covered at this [previous question](http://stackoverflow.com/questions/13355176/gradient-legend-in-base/13389693#13389693). – thelatemail Jan 27 '14 at 22:52

1 Answers1

2

Here's a ggplot alternative:

ggplot(data = mdf, aes(x = X, y = Y, col = Z)) +
  geom_point() +
  scale_colour_gradientn(colours = colourGradient) +
  theme_bw() +
  theme(legend.position = "top") +
  ggtitle("Y vs. X with Z-Color")

enter image description here

Henrik
  • 65,555
  • 14
  • 143
  • 159
  • 1
    Thanks for your feedback. Yes, it is definitely worth to give `ggplot` a try. [This **tutorial**](http://www.cookbook-r.com/Graphs/) may be a good start. As well as the official help pages with output for all examples [**here**](http://docs.ggplot2.org/current/). Good luck! – Henrik Jan 27 '14 at 23:36