简体   繁体   中英

How to plot a contour/ heat map plot with 3 vectors?

Here is a toy version of my problem

x = runif(10);
y = runif(10);
z = (x+y)*(x-y);

I would like to then generate a heatmap of z vs. (x+y) and (xy). The problem is that z is a vector and is not defined over all combinations of y and x. Please note I am not looking for an answer that generates z for these missing values , that is not a possibility in the real version of the problem. This is just a minimal version to work with. All solutions I've been able to find, such as filled.contour need a matrix for z specified over a grid of the independent variables rather than just a set of (x,y,z) data points with no structure per se .

Package akima has what you need. It does bivariate interpolation with interp . It does generate z values for the missing combinations, but couldnt you just exclude those if you wanted to? If you aren't generating z-values just plot a 3d scatter of z ~ x*y.

x = runif(10);
y = runif(10);
z = (x+y)*(x-y);

library(akima)
dens <- interp(x+y, x-y, z, 
               xo=seq(min(x+y), max(x+y), length=100),
               yo=seq(min(x-y), max(x-y), length=100),
               duplicate="median")

filled.contour(dens, xlab="x+y", ylab="x-y", main="z",
               color.palette = heat.colors)

在此输入图像描述

If you are truly set on not interpolating, to add to the ggplot options provided by @Frank, there are a number of aesthetics you can use to contrast points by a third dimension.

library(ggplot2)
dat <- data.frame(x1=x+y, x2=x-y, z=z)

## Scaling points by z dimension using size, color, and shading
ggplot(dat, aes(x1, x2, size=z, alpha=z, color=z)) +
  geom_point() +
  scale_color_gradient(low="red", high="yellow") +
  theme_bw()

在此输入图像描述

Here is a possibility with ggplot2 where I do not generate values for z when they are "missing", unlike the answer using interpolation..

set.seed(54321)
x = runif(10)
y = runif(10)
z = (x+y)*(x-y)

ggplot(df, aes(x+y, x-y, fill=z)) +
  scale_fill_gradient(low = "blue", high = "red") + geom_tile()

在此输入图像描述

You can force/manipulate the tile size and overall appearance by using round or cut :

ggplot(df, aes(round(x+y,1),round(x-y,1), fill=z)
  scale_fill_gradient(low = "blue", high = "red") + 
  geom_tile()
# OR
ggplot(df, aes(cut(x+y, 15), cut(x-y, 15), fill=z))
  scale_fill_gradient(low = "blue", high = "red") + 
  geom_tile() + 
  theme(axis.text.x=element_blank(), axis.text.y=element_blank())

在此输入图像描述在此输入图像描述

Maybe the most simple way to achieve a result that resembles what I believe is the requested output could consist in using the lattice package:

set.seed(12358)
x <- runif(10)
y <- runif(10)
z <-(x+y)*(x-y)
x1<-x+y
y1<-x-y
library(lattice)
df<-data.frame(x=x1,y=y1,z=z)
levelplot(z~x1*y1,df,cuts=9,col.regions=grey.colors(10)[10:1])

在此输入图像描述

But admittedly, this does not look very pretty. Probably a better way to represent the data is an interactive 3D-scatterplot, which can be generated with the rgl package, as shown below. For this chart I used a function from the "R Graphics Cookbook" by Winston Chang to draw the vertical blue lines:

library(rgl)
plot3d(x1,y1,z, size=1,type="s")
interleave <- function(v1,v2) as.vector(rbind(v1,v2))
segments3d(interleave(x1,x1), interleave(y1,y1), interleave(z,0),alpha=0.4,col="blue")
planes3d(a=0,b=0,c=1,d=0,alpha=0.1)

在此输入图像描述

Since the OP stated very clearly that no interpolation was desired, I refrain from posting simple possibilities to display such continuous heatmaps, even though I think that for such a type of data set it usually makes sense to interpolate the data.

In fact, I have some difficulties in understanding the use of a heatmap (which in my opinion is inherently a 2D object) applied to a structureless set of disconnected points.

Here is a variation with base plot:

x = runif(10);
y = runif(10);
z = (x+y)*(x-y);

n = 5
zz = cut(z, n)
cols <- heat.colors(n)
plot(x, y, col=cols[zz], cex=4, pch=20)
legend('topright', legend=levels(zz), pch=20, col=cols, pt.cex=3)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM