0

Following code plots a math function as a heatmap (from: How to plot a maths function as a heatmap):

xvec <- yvec <- seq(0,10,length.out=41)
z <- outer(xvec,yvec,function(x,y) x*y^2)
image(xvec,yvec,z)

How can I create this using ggplot2 geom_tile() ?

Following commands do not work:

ggplot()+geom_tile(aes(x=xvec, y=yvec, z=z))

and

zdf = data.frame(z)
ggplot(zdf)+geom_tile(aes(z=zdf))

I am surprised not to find similar question on searching. Thanks for your help.

2 Answers 2

2

You need to arrange the X/Y coordinates and the data (z in your case) into a data.frame instead of a matrix.

For example:

xvec <- yvec <- seq(0,10,length.out=41)
df <- expand.grid(xvec, yvec)
df$z <- apply(df, 1, function(p) p[1] * p[2]^2)

head(df)

#   Var1 Var2 z
# 1 0.00    0 0
# 2 0.25    0 0
# 3 0.50    0 0
# 4 0.75    0 0
# 5 1.00    0 0
# 6 1.25    0 0

library(ggplot2)
ggplot(df) + geom_tile(aes(x=Var1, y=Var2, fill=z))

And you get:

enter image description here

Sign up to request clarification or add additional context in comments.

1 Comment

expand.grid function is the key. Thanks.
2

You could also reshape your outer results with

xvec <- yvec <- seq(0,10,length.out=41)
z <- outer(xvec,yvec,function(x,y) x*y^2)

ggplot(data.frame(xvec=xvec[row(z)], yvec=yvec[col(z)], z=as.numeric(z))) + 
    geom_tile(aes(x=xvec, y=yvec, fill=z))

What we are doing here is building a new data.frame with triplets of values to plot: (x,y,color). The problem is we have length(xvec) rows and length(yvec) columns but length(xvec) * length(yvec) actual observations. So this trick will repeat the row and column values to make them the same length as the z values. Since z is a matrix, row(z) will give the row number for each value in z. We use this to repeat the xvec values multiple times and keep them insync with the z values. Same goes for the yvec values but we match those up to the columns of z. This is another way to create a data.frame in the form

  xvec yvec z
1 0.00    0 0
2 0.25    0 0
3 0.50    0 0
4 0.75    0 0
5 1.00    0 0
6 1.25    0 0

2 Comments

It works but change in data is difficult to understand.
I tried to add some further explanation. But if your data isn't already in a matrix, then the expand.grid option probably would be best for you.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.