# Replicating $\LaTeX$'s pgfplot Style in Mathematica

I'm trying to replicate the plot theme of $$\LaTeX$$'s pgtplots for 3D surfaces in Mathematica's Plot3D Function. The goal is to create something similar to this: So I played around with the opacity and different color gradients for a bit until i got this:

 Plot3D[Sin[Sqrt[x^2 + y^2]]/Sqrt[x^2 + y^2], {x, -2 Pi, 2 Pi}, {y, -2 Pi, 2 Pi},
PlotRange -> {-1, 1},
BoxRatios -> {1, 1, 1},
Boxed -> False,
Axes -> False,
ColorFunction -> (Opacity[#3 + .1, ColorData[{"DeepSeaColors", "Reverse"}][#3]] &),
Mesh -> None,
PlotPoints -> 100
]


However, I want the ColorFunction directives to be applied to the mesh rather than the surface. My approach was to simply do something like this:

 Plot3D[Sin[Sqrt[x^2 + y^2]]/Sqrt[x^2 + y^2], {x, -2 Pi, 2 Pi}, {y, -2 Pi, 2 Pi},
PlotRange -> {-1, 1},
BoxRatios -> {1, 1, 1},
Boxed -> False,
Axes -> False,
PlotStyle -> Opacity,
MeshStyle -> ColorFunction -> (Opacity[#3 + .1, ColorData[{"DeepSeaColors", "Reverse"}][#3]] &),
PlotPoints -> 100
]


But apparently, this idea is completely wrong. It seems to me that MeshStyle will not accept values that depend on the plotted function. Is there any way to make this work within the Plot3D function? Any help would be greatly appreciated.

• Yes, there is. Read this question. With[{plot=Plot3D[Sin[Sqrt[x^2 + y^2]]/Sqrt[x^2 + y^2], {x, -2 Pi, 2 Pi}, {y, -2 Pi, 2 Pi}, BoxRatios -> {1, 1, 1}, PlotRange -> {-1, 1}, Boxed -> False, Axes -> False, PlotStyle -> None, PlotPoints -> 100]}, With[{cf = ColorData["RedBlueTones"][#3] &}, plot /. GraphicsComplex[pts_, g_, opts___] :> GraphicsComplex[pts, g /. Line[p_] :> Line[p, VertexColors -> MapThread[cf, Part[Rescale /@ Transpose[pts], All, p]]], opts]]] Dec 20, 2021 at 16:10
• @Domen - your version that keeps the GraphicsComplex intact is much more responsive. I will borrow from it if you don't mind. Dec 20, 2021 at 17:33
• @JasonB., not mine, of course, just changed the function in Michael E2's answer :-) Dec 20, 2021 at 17:38

I noticed that for plots like this you get a significantly better performance when rotating the Graphics3D if you keep the answer inside a GraphicsComplex and avoid calling Normal. Borrowing from this comment and this answer, and wrapping it in a function you get

ClearAll @ MeshPlot3D;
Options[MeshPlot3D] = Options @ Plot3D;
SetOptions[MeshPlot3D,
{
ColorFunction -> (ColorData[{"DeepSeaColors", "Reverse"}][#3]&),
Mesh -> Full, PlotPoints -> 50,PlotStyle->None
}
];
MeshPlot3D[args__, opts:OptionsPattern[]] := Module[{plot},
plot = With[
{options = FilterRules[{opts}, Except[ColorFunction | ColorFunctionScaling]]},
Plot3D[args,
options, Mesh -> OptionValue[Mesh],PlotStyle -> OptionValue[PlotStyle],
PlotPoints -> OptionValue[PlotPoints]
]
];
ReplaceAll[plot,
gc, OptionValue[ColorFunction], OptionValue @ ColorFunctionScaling
]
]
];
Attributes[MeshPlot3D] = {HoldAll}

addColorFunction[GraphicsComplex[pts_, g_, opts___], cf_, scaling_] := With[
{rescale = If[TrueQ[scaling], Rescale, Identity]},
GraphicsComplex[pts,
ReplaceAll[g,
Line[p_] :> Line[p,
VertexColors -> MapThread[cf, Part[Map[rescale, Transpose[pts]], All, p]]
]
],
opts
]
]


Called via

MeshPlot3D[Sin[Sqrt[(x ^ 2) + y ^ 2]] / Sqrt[(x ^ 2) + y ^ 2],
{x, -2 * Pi, 2 * Pi},
{y, -2 * Pi, 2 * Pi},
PlotRange -> {-1, 1},
BoxRatios -> {1, 1, 1}, PlotPoints -> 100,
Boxed -> False, Axes -> False
] or

MeshPlot3D[x / Exp[(x ^ 2) + y ^ 2],
{x, -2, 2},
{y, -2, 2},
ColorFunction -> Function[{x, y, z}, Hue[0.65 * (1 + -z)]],
PlotStyle -> Directive[Opacity[0.5], Blue]
] • (+1) The OP's figure seems to be using the so-called "cool" colormap from MATLAB, so to emulate that, one can use ColorFunction -> (RGBColor[#3, 1 - #3, 1] &). Dec 20, 2021 at 18:45
• Great job. Thanks. How to export it as a high-quality .eps figure? Export["highquality.eps", %] doesn't give high-quality figure? (Mathematica 13 on Windows 11) Dec 22, 2021 at 18:49

We can use the simple trick from this answer: Define

f = ReplaceAll[Rule[VertexColors, None] -> Rule[VertexColors, Automatic]];


and simply add the option DisplayFunction -> f to Plot3D:

Plot3D[Sin[Sqrt[(x^2) + y^2]]/Sqrt[(x^2) + y^2], {x, -2*Pi,
2*Pi}, {y, -2*Pi, 2*Pi}, PlotRange -> {-1, 1},
Mesh -> 50,
DisplayFunction -> f,
PlotStyle -> FaceForm[],
ColorFunction -> (RGBColor[#3, 1 - #3, 1] &),
BoxRatios -> {1, 1, 1},
PlotPoints -> 100,
Boxed -> False,
Axes -> False,
ImageSize -> Large] where I used the color function suggested by J.M. in comments. If we use the color function in OP

 ColorFunction -> (Opacity[#3 + .1, ColorData[{"DeepSeaColors", "Reverse"}][#3]] &)


we get A function that applies ColorFunction to mesh lines and PlotStyle to polygon faces:

ClearAll[meshPlot3D]

SetAttributes[meshPlot3D, HoldAll];

meshPlot3D[args__, opts : OptionsPattern[Plot3D]] := Module[
{df = ReplaceAll[Rule[VertexColors, None] -> Rule[VertexColors, Automatic]]},
Show[Plot3D[args, Mesh -> None, BoundaryStyle -> None, ColorFunction -> None, opts],
Plot3D[args, DisplayFunction -> df, PlotStyle -> FaceForm[], opts]]]


Examples:

meshPlot3D[Sin[Sqrt[x^2 + y^2]]/Sqrt[x^2 + y^2], {x, -2 Pi, 2 Pi}, {y, -2 Pi, 2 Pi},
Mesh -> 50,
PlotStyle -> FaceForm[],
ColorFunction -> (Opacity[#3 + .1, RGBColor[#3, 1 - #3, 1]] &),
PlotPoints -> 100,
PlotRange -> {-1, 1},
BoxRatios -> {1, 1, 1},
Boxed -> False, Axes -> False, ImageSize -> Large]

same picture as above


Using the second example from Jason B.'s answer:

meshPlot3D[x/Exp[(x^2) + y^2], {x, -2, 2}, {y, -2, 2},
Mesh -> 50,
PlotPoints -> 100,
PlotStyle -> FaceForm[{Opacity[.5], Blue}],
ColorFunction -> Function[{x, y, z}, Hue[0.65*(1 + -z)]],
ImageSize -> Large, Boxed -> False, Axes -> False] • Great job. Thanks. How to export it as a high-quality .eps figure? Export["highquality.eps", %] doesn't give high-quality figure? (Mathematica 13 on Windows 11) Dec 22, 2021 at 18:48