[Tex/LaTex] Create 3D heatmap density plot using TikZ

3dpgfplotstikz-pgf

My question is very similar to "Create heatmap with PSTricks or TikZ", but this time in 3D. So I have tabular data as follows:

x   | y   | z   | value
1.2 | 1.3 | 1.4 | 1.20
0.2 | 0.3 | 0.4 | 3.20

With this data I want to create 3D density plot or isosurface plot like:

desired result

Maybe with the opacity as function of value. Sure I know the solution will be more than time consuming, but I have already seen similar results and they look pretty good.

Best Answer

As Jake said in the comments, this is probably beyond the realm of writing directly into TikZ, but you could probably still get it done, if you wanted some other benefits of TikZ. (e.g., fonts that are consistent with the rest of the documents)

If you already have some software to generate 3D plots separately from LaTeX (such as MATLAB or Mathematica), then you might want to look to see if there’s a library that translates drawing code from that software into TikZ that you can embed in LaTeX. Here are some examples of what I mean:

Doing it externally and importing TikZ is almost certainly the way to go. It will be a lot easier than trying to get it to get something that’s workable, and the end result will be a lot better.

Below I’ve given a brief example of how I do it, using R. It’s unlikely that you’ll be able to use my solution directly, but it might give you an idea of what I mean, and perhaps give you a pointer in the right direction.


A personal example:

I often use R to do my plots (R is a free, statistical programming language), and R has a useful module for exporting to TikZ. This TikZ code can then be loaded into a LaTeX document and compiled as normal.

The R package for 3d contour plots is contour3d, and here’s an example from that documentation page:

require(tikzDevice)
require("misc3d")

tikz("isosurface.tex", width=5, height=5)

##################################################################
#                                                                #
# Example from the R documentation                               #
# http://rss.acs.unt.edu/Rdoc/library/misc3d/html/contour3d.html #
#                                                                #
##################################################################

nmix3 <- function(x, y, z, m, s) {
      0.4 * dnorm(x, m, s) * dnorm(y, m, s) * dnorm(z, m, s) +
      0.3 * dnorm(x, -m, s) * dnorm(y, -m, s) * dnorm(z, -m, s) +
      0.3 * dnorm(x, m, s) * dnorm(y, -1.5 * m, s) * dnorm(z, m, s)
  }
  f <- function(x,y,z) nmix3(x,y,z,.5,.5)
  g <- function(n = 40, k = 5, alo = 0.1, ahi = 0.5, cmap = heat.colors) {
      th <- seq(0.05, 0.2, len = k)
      col <- rev(cmap(length(th)))
      al <- seq(alo, ahi, len = length(th))
      x <- seq(-2, 2, len=n)
      contour3d(f,th,x,x,x,color=col,alpha=al)
      rgl.bg(col="white")
  }
  g(40,5)
  gs <- function(n = 40, k = 5, cmap = heat.colors, ...) {
      th <- seq(0.05, 0.2, len = k)
      col <- rev(cmap(length(th)))
      x <- seq(-2, 2, len=n)
      m <- function(x,y,z) x > .25 | y < -.3
      contour3d(f,th,x,x,x,color=col, mask = m, engine = "standard",
                scale = FALSE, ...)
      rgl.bg(col="white")
  }
  gs(40, 5, screen=list(z = 130, x = -80), color2 = "lightgray", cmap=rainbow)

### End of example

dev.off()

Most of that is just drawing the 3D plot, but the lines at the top and bottom turn the plotted output into TikZ, which gets saved to isosurface.tex.

Once I've run that script, I can \input that document into another LaTeX file. For example:

\documentclass{article}

\usepackage{tikz}

\begin{document}

\input{isosurface.tex}

\end{document}

This is what it looks like:

enter image description here

and the rendering in the LaTeX-ed PDF is remarkably faithful to the original:

enter image description here

Some caveats:

  • For a 3D plot, the associated TikZ file is ~big. Approximately 2.2 MB, which is an order of magnitude bigger than most TikZ documents.
  • It will slow you down. That smallish example added ~30 seconds to the compile time. If you have more complicated ones, or lots of them, expect to get significantly slowed down. You might want to look at using something like TikZ’s externalize library to avoid the worst performance hit.

If you want to use R, then questions about how to draw your plots are off-topic at this Stack Exchange, but you might want to head over to Cross Validated if you need a hand. Topics about R and data visualisation are more on-topic there.