I have a list of data which I can plot as a surface with ListPlot3D
. Moreover I have a set of other surfaces and I have plotted the projection of their intersection curves onto a plane via ContourPlot
.
Is there a way of plotting on the surface originating from ListPlot3D
above the curve originating from the ContourPlot
?
2 Answers
Few more alternatives:
data = Table[Cos[x] + Cos[y], {x, 0, 4 Pi, .2}, {y, 0, 4 Pi, .2}];
Using a combination of Mesh
, MeshFunctions
, MeshShading
:
ListPlot3D[data, DataRange -> {{0, 4 Pi}, {0, 4 Pi}},
MeshFunctions -> {#3 &, #1 &, #2 &},
Mesh -> {5, 10, 10}, MeshStyle -> {None, Automatic, Automatic},
MeshShading -> {{Directive[{EdgeForm[], #}] & /@ {Red, Green, Blue,Orange, Magenta, Cyan}}}]
Using Texture
:
cp = ContourPlot[Cos[x] + Cos[y], {x, 0, 4 Pi}, {y, 0, 4 Pi},
Contours -> 5, ContourStyle -> None,
ContourShading -> {Red, Green, Blue, Orange, Magenta, Cyan},
ImagePadding -> 0, PlotRangePadding -> 0, Frame -> False, Axes -> False];
ListPlot3D[data, PlotStyle -> Texture[cp], DataRange -> {{0, 4 Pi}, {0, 4 Pi}}]
One solution is to transform your 2d contour plot into 3d coordinates. For this, you have to look at the underlying representation of the Graphics
that ContourPlot
creates. This is usually a Graphics[GraphicsComplex[coords,...],...]
object, where coords
are the coordinates of the points used.
Let us create simple example data and plot them
data = Table[Cos[x] + Cos[y], {x, 0, 4 Pi, .2}, {y, 0, 4 Pi, .2}];
lp = ListPlot3D[data, PlotStyle -> None, DataRange -> {{0, 4 Pi}, {0, 4 Pi}}]
And here is a possible contour plot that you want to lift onto the surface of the 3d plot
cp = ContourPlot[Cos[x] + Cos[y], {x, 0, 4 Pi}, {y, 0, 4 Pi}]
Now, your task would be to replace the 2d coordinates with their 3d counterpart and replace Graphics
with Graphics3D
. Then, you can easily put your ListPlot3D
and the ContourPlot
together. For this, I suggest to interpolate the data so that you can extract the height of the surface of each point.
ip = ListInterpolation[data, {{0, 4 Pi}, {0, 4 Pi}}];
in3D = cp /.
Graphics[GraphicsComplex[coords_, rest__], ___] :>
Graphics3D[GraphicsComplex[Append[#, ip @@ #] & /@ coords, rest]]
To say in words what happens above: I replace every 2d coordinate of the contour plot with a 3d coordinate, where the z value is extracted from the interpolation of your data.
Now you are done and you can combine the two 3d graphics
Show[in3D, lp]
-
$\begingroup$ @Pugliam Oh well, I have misunderstood the line plotting on the surface originating from ListPlot3D above the curve.. For your questions does exist an answer too. I would interpolate your data-set and use the hight-values at x,y for the height of your curve.. let's see whether I can code this up in a sec $\endgroup$– halirutan ♦Dec 2, 2014 at 16:00
-
$\begingroup$ Thank you! But maybe I haven't been clear enough in asking what I need ;) I do not want to plot, in the same graph, a surface and its contours lines on the plane. I'd like to plot the contour lines on the surface itself. Moreover I need to plot curves which are not contour lines of the same surface but they are given by the intersection of other surfaces I do not care at the moment. $\endgroup$– pugliamDec 2, 2014 at 16:04
-
-
$\begingroup$ Thanks! Unfortunately the set of data I have is pretty weird and I think ListInterpolation gets stuck (I tried plotting the Interpolating Function and it didn't resemble at all the original set of data, but maybe I'm simply making some mistakes I don't know). Anyhow may you kindly post again the previous solution: surface plot on the same graph as contiurlines? Thanks $\endgroup$– pugliamDec 2, 2014 at 17:26
-
1$\begingroup$ @Pugliam You don't need me for this. Under my answer you should see a link "edited yesterday". When you click on this, you see the whole history of the post. $\endgroup$– halirutan ♦Dec 4, 2014 at 1:13
MeshFunctions
$\endgroup$