# Color a single contour from a ListContourPlot3D using values from a list

I want to map an electrostatic potential onto a density map.

How can I color a single contour from a ListContourPlot3D using the values from another list?

1. Make a 3D contour plot from a list of electron density values, of which I only need one contour.

2. Color the single contour based on the electrostatic potential density at that point. (Need help on this.)

I have this so far:

Den = Import["Density.dat", "Table"]; (* Contains, {x, y, z, Density} pointS *)

EP = Import["ElectrostaticPotential.dat", "Table"]; (* Contains, {x, y, z, EP} point *)

ListContourPlot3D[Den,
Contours -> {0.05}, Mesh -> None,
ColorFunction -> ColorData[Function[{x, y, z}, Hue[EP]]]]


I can't seem the find the right way to write the ColorFunction. Please help.

• Can you include samples of your density and electrostatic potential data? Or perhaps put them into a pastebin for people to download? – MarcoB Feb 4 '16 at 1:01
• Can one assume that the $(x, y, z)$ grid at which the values are calculated will be the same for the density and electrostatic potential data sets? – MarcoB Feb 4 '16 at 1:18
• If you have Mathematica 10.2 or higher, you could also try ListSliceDensityPlot3D. – Rahul Feb 4 '16 at 6:26
• I just don't see how "This question cannot be answered without additional information" is true in this case. The question is clear, "How can I color a single contour from a ListContourPlot3D using the values from another list", given that both lists are in the form {x,y,z, f[x,y,z]}. The actual data being plotted is irrelevant. – Jason B. Feb 4 '16 at 13:54
• If I understand it correctly, it's a duplicate of Smooth 4D (3D + color) plot from discrete points – Jens Feb 4 '16 at 15:20

In the absence of your data, I'll just use some data that I make up. One of these is an example from the help on ListContourPlot3D and one is a 3D-Gaussian,

list1 = Table[{x, y, z, x^2 + y^2 - z^2}, {x, -1, 1, .05}, {y, -1,
1, .05}, {z, -1, 1, .05}]~Flatten~2;
list2 = Table[{x, y, z,
2 Exp[-3^2 ((x - .3)^2 + (y - .3)^2 + (z - .3)^2)]}, {x, -1,
1, .01}, {y, -1, 1, .01}, {z, -1, 1, .01}]~Flatten~2;


These are structured like your data, in the form of {x,y,z,f[x,y,z]} tuples. Here are their contour plots,

ListContourPlot3D[#, Contours -> {0.3},
PlotRange -> {{-1, 1}, {-1, 1}, {-1, 1}}] & /@ {list1, list2}


So to do this using ColorFunction, which is my preferred way to do it, you need to have a function to use, not a list. We can make an interpolation function from the data, and we can use this opportunity to rescale it so that the values lie between 0 and 1.

 func = Module[{rescaledlist = list2},
rescaledlist[[All, 4]] =
rescaledlist[[All, 4]]/Max[rescaledlist[[All, 4]]];
rescaledlist = {{#1, #2, #3}, #4} & @@@ rescaledlist;
Interpolation[rescaledlist]
]


And now we use this function inside the ColorFunction

ListContourPlot3D[list1, Contours -> {0.3},
ColorFunction -> Function[{x, y, z},
Hue[
func[x, y, z]
]],
ColorFunctionScaling -> False, Mesh -> None, MaxPlotPoints -> 40]


We can get basically the same thing from ListSliceDensityPlot3D but it is a bit trickier. Look at the usage information,

?ListSliceDensityPlot3D


So we need to define a surface object from a ListContourPlot3D. Thanks to Szabolcs for figuring out how to do this. This command gives an error, but produces the right output,

surf = DiscretizeGraphics@
Normal@ListContourPlot3D[list1, Contours -> {0.3},
MaxPlotPoints -> 40];


Then we take some care to get the color function scaled properly, and

ListSliceDensityPlot3D[list2, surf,
ColorFunction -> (Hue[#/Max[list2[[All, 4]]]] &),
ColorFunctionScaling -> False]


I prefer the output by using the scaled colorfunction on ListContourPlot3D, and I think the workflow is simpler, but this option works as well.

On a side note, I always recommend avoiding the rainbow color palette (be it the Jet or Hue variants). I'm partial to the Parula color map in Matlab, which you can define in Mathematica via <<"http://pastebin.com/raw.php?i=sqYFdrkY";. If you replace Hue[func[x, y, z]] above with ParulaCM[1.5 func[x, y, z]] then you get the nice plot below

• You could also just use one of Mathematica's many nice built-in color schemes, like ColorData["StarryNightColors"][func[x, y, z]]. – Rahul Feb 4 '16 at 18:06
• That looks like a good color scheme I haven't used before. I often like to build up my own functions and don't notice the built in stuff as much – Jason B. Feb 4 '16 at 19:29