0

I have data consisting of (x,y,z) values, and I would like to plot it as a heatmap in ggplot2. However, these points are not evenly spaced (i.e, the x and y datapoints do not fall nicely onto a regular grid), which prevents the data from being displayed normally. I have found this post regarding a similar question, in which they suggest using the interp function to interpolate the data to an evenly-spaced grid. I have included some example code below that accomplishes this

library(akima)

data <- data.frame("x" = c(1, 3, 5), "y" = c(-1, 2, 8), "z" = c(5, 1, 2))
resolution <- 0.1
a <- interp(x=data$x, y=data$y, z=data$z, 
  xo=seq(min(data$x),max(data$x),by=resolution),
  yo=seq(min(data$y),max(data$y),by=resolution), duplicate="mean")

the resulting variable a can be displayed automatically using the image function, but I would like to use ggplot2. I cannot understand how a is structured - it appears to be a list of lists, but each of the lists are of different lengths and I am unsure how to cast it into a form suitable for ggplot2. I have not been able to find an answer to this in the documentation for interp. Can someone explain how to recast a in a way that it can be plotted using ggplot2?

Henry Shackleton
  • 351
  • 2
  • 11

1 Answers1

1

a$x contains the x coordinates

a$y contains the y coordinates

a$z contains the actual matrix

library(akima)
library(data.table)

data <- data.frame("x" = c(1,3,5,7), "y" = c(-1,2,8,5), "z" = c(5,1,2,7))
resolution <- 0.1
a <- interp(x=data$x, y=data$y, z=data$z, 
            xo=seq(min(data$x),max(data$x),by=resolution),
            yo=seq(min(data$y),max(data$y),by=resolution), duplicate="mean")

x.coordinate <- a$x
y.coordinate <- a$y
energy.table <- as.data.frame(a$z) 

names(energy.table) <- y.coordinate
energy.table[is.na(energy.table)] <- 0
energy.table$x <- x.coordinate
longenergy <- melt(as.data.table(energy.table),id="x")

ggheat <- ggplot(longenergy,aes(x=variable,y=x, fill=value)) +
                geom_tile() + 
                theme(axis.text.x=element_blank(),axis.text.y=element_blank()) + 
                xlab("y") + ylab("x") 
ggheat

The code above produces the image below. You can then use ggplot to fix the colours, the labels, titles, ...

theImage

fra
  • 832
  • 6
  • 14
  • 1
    It's not recommended to use `aes(x=longenergy$variable)` but `aes(x = variable)`, you have already specified the data. – Axeman Dec 18 '19 at 20:44
  • @Axeman thanks for pointing that out, I will fix that. I took this code from an old script I used to plot the Potential Energy Surface coming from Molecular dynamics simulations. I was using the code wrapped in a function and the explicit declaration was a way of making the value recognised by ggplot. this was before I found `environment = environment()` – fra Dec 19 '19 at 00:17