Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R - color scatterplot points by z value with legend

Tags:

r

I have a scatterplot and wish to color the points by a z value assigned to each point. Then I want to get the legend on the right hand side of the plot to show what colors correspond to what z values using a nice smooth color spectrum.

Here are some x,y,z values you can use so that this is a reproducible example.

x = runif(50)
y = runif(50)
z = runif(50) #determines color of the (x,y) point

I suppose the best answer would be one that is generalized for any color function, but I do anticipate using rainbow()

like image 336
StanLe Avatar asked Oct 18 '25 17:10

StanLe


2 Answers

Translated from this previous question:

library(ggplot2)
d = data.frame(x=runif(50),y=runif(50),z=runif(50))
ggplot(data = d, mapping = aes(x = x, y = y)) + geom_point(aes(colour = z), shape = 19)
like image 95
Stu Avatar answered Oct 21 '25 09:10

Stu


If you don't want to use ggplot2 I modified a solution to this provided by someone else, I don't remember who.

scatter_fill <- function (x, y, z,xlim=c(min(x),max(x)),ylim=c(min(y),max(y)),zlim=c(min(z),max(z)),
                          nlevels = 20, plot.title, plot.axes, 
                          key.title, key.axes, asp = NA, xaxs = "i", 
                          yaxs = "i", las = 1, 
                          axes = TRUE, frame.plot = axes, ...) 
{
  mar.orig <- (par.orig <- par(c("mar", "las", "mfrow")))$mar
  on.exit(par(par.orig))
  w <- (3 + mar.orig[2L]) * par("csi") * 2.54
  layout(matrix(c(2, 1), ncol = 2L), widths = c(1, lcm(w)))
  par(las = las)
  mar <- mar.orig
  mar[4L] <- mar[2L]
  mar[2L] <- 1
  par(mar = mar)

# choose colors to interpolate
levels <- seq(zlim[1],zlim[2],length.out = nlevels)
col <- colorRampPalette(c("red","yellow","dark green"))(nlevels)  
colz <- col[cut(z,nlevels)]  
#   
plot.new()
plot.window(xlim = c(0, 1), ylim = range(levels), xaxs = "i", yaxs = "i")

rect(0, levels[-length(levels)], 1, levels[-1L],col=col,border=col) 
if (missing(key.axes)) {if (axes){axis(4)}}
       else key.axes
   box()
   if (!missing(key.title)) 
     key.title
   mar <- mar.orig
   mar[4L] <- 1
   par(mar = mar)

   # points
   plot(x,y,type = "n",xaxt='n',yaxt='n',xlab="",ylab="",xlim=xlim,ylim=ylim,bty="n")
   points(x,y,col = colz,xaxt='n',yaxt='n',xlab="",ylab="",bty="n",...)

   ## options to make mapping more customizable

        if (missing(plot.axes)) {
          if (axes) {
            title(main = "", xlab = "", ylab = "")
            Axis(x, side = 1)
            Axis(y, side = 2)
          }
        }
        else plot.axes
        if (frame.plot) 
          box()
        if (missing(plot.title)) 
          title(...)
        else plot.title
        invisible()
 }

Just run the function first and it is ready to be used. It is quite handy.

# random vectors
vx <- rnorm(40,0,1)
vy <- rnorm(40,0,1)
vz <- rnorm(40,10,10)

scatter_fill(vx,vy,vz,nlevels=15,xlim=c(-1,1),ylim=c(-1,5),zlim=c(-10,10),main="TEST",pch=".",cex=8)

As you can notice, it inherits the usual plot function capabilities.

enter image description here

like image 26
JEquihua Avatar answered Oct 21 '25 08:10

JEquihua



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!