Skip to main content

plotting - Improve Plot3D resolution near max/mins


I have the following function


$$V(r) = \sum_{i=1}^N 4 \epsilon_i \left(\frac{\sigma_i^{12}}{\|r-r_{0i}\|^{12}}-\frac{\sigma_i^6}{\|r-r_{0i}\|^6}\right)$$


which -for those interested- corresponds to a sum of Lennard-Jones potentials, with the following real life set of parameters


sig = {0.329633, 0.0400014, 0.405359, 0.235197, 0.387541, 0.235197,
0.235197, 0.387541, 0.235197, 0.235197, 0.387541, 0.235197,
0.235197, 0.387541, 0.235197, 0.235197, 0.329633, 0.0400014,
0.0400014, 0.0400014, 0.356359, 0.302906, 0.329633, 0.0400014,
0.387541, 0.235197, 0.235197, 0.356359, 0.302906, 0.329633,

0.0400014, 0.405359, 0.235197, 0.387541, 0.235197, 0.235197,
0.405359, 0.235197, 0.36705, 0.235197, 0.235197, 0.235197, 0.36705,
0.235197, 0.235197, 0.235197, 0.356359, 0.302906, 0.329633,
0.0400014, 0.405359, 0.235197, 0.387541, 0.235197, 0.235197,
0.387541, 0.235197, 0.235197, 0.356359, 0.302906, 0.329633,
0.0400014, 0.0400014, 0.356359, 0.302906, 0.329633, 0.0400014,
0.405359, 0.235197, 0.405359, 0.235197, 0.36705, 0.235197, 0.235197,
0.235197, 0.387541, 0.235197, 0.235197, 0.36705, 0.235197, 0.235197,
0.235197, 0.356359, 0.302906}


eps = {0.8368, 0.192464, 0.08368, 0.092048, 0.23012, 0.092048, 0.092048,
0.23012, 0.092048, 0.092048, 0.23012, 0.092048, 0.092048, 0.23012,
0.092048, 0.092048, 0.8368, 0.192464, 0.192464, 0.192464, 0.46024,
0.50208, 0.8368, 0.192464, 0.23012, 0.092048, 0.092048, 0.46024,
0.50208, 0.8368, 0.192464, 0.08368, 0.092048, 0.23012, 0.092048,
0.092048, 0.08368, 0.092048, 0.33472, 0.092048, 0.092048, 0.092048,
0.33472, 0.092048, 0.092048, 0.092048, 0.46024, 0.50208, 0.8368,
0.192464, 0.08368, 0.092048, 0.23012, 0.092048, 0.092048, 0.23012,
0.092048, 0.092048, 0.29288, 0.50208, 0.8368, 0.192464, 0.192464,
0.46024, 0.50208, 0.8368, 0.192464, 0.08368, 0.092048, 0.08368,

0.092048, 0.33472, 0.092048, 0.092048, 0.092048, 0.23012, 0.092048,
0.092048, 0.33472, 0.092048, 0.092048, 0.092048, 0.46024, 0.50208}

r0 = {{0.681, -2.673}, {0.605, -2.736}, {0.715, -2.578}, {0.812, -2.583},
{0.628, -2.607}, {0.654, -2.698}, {0.533, -2.609}, {0.63, -2.515},
{0.559, -2.545}, {0.609, -2.423}, {0.763, -2.509}, {0.825, -2.446},
{0.804, -2.6}, {0.742, -2.461}, {0.709, -2.367}, {0.829, -2.465},
{0.642, -2.547}, {0.629, -2.515}, {0.675, -2.642}, {0.555, -2.543},
{0.693, -2.445}, {0.778, -2.359}, {0.585, -2.422}, {0.526, -2.499},
{0.55, -2.291}, {0.543, -2.236}, {0.459, -2.299}, {0.638, -2.219},

{0.661, -2.105}, {0.715, -2.293}, {0.688, -2.387}, {0.829, -2.244},
{0.791, -2.156}, {0.867, -2.346}, {0.893, -2.431}, {0.946, -2.309},
{0.754, -2.38}, {0.674, -2.422}, {0.697, -2.255}, {0.627, -2.281},
{0.77, -2.205}, {0.657, -2.197}, {0.802, -2.482}, {0.729, -2.503},
{0.825, -2.566}, {0.883, -2.448}, {0.956, -2.216}, {1.034, -2.126},
{0.986, -2.287}, {0.921, -2.356}, {1.104, -2.268}, {1.178, -2.271},
{1.13, -2.381}, {1.056, -2.379}, {1.217, -2.362}, {1.135, -2.523},
{1.218, -2.53}, {1.055, -2.534}, {1.137, -2.64}, {1.171, -2.628},
{1.083, -2.751}, {1.043, -2.753}, {1.08, -2.832}, {1.099, -2.133},
{1.196, -2.059}, {0.987, -2.095}, {0.911, -2.161}, {0.964, -1.963},

{1.042, -1.957}, {0.833, -1.955}, {0.818, -1.859}, {0.844, -2.053},
{0.759, -2.051}, {0.92, -2.024}, {0.861, -2.146}, {0.714, -1.996},
{0.729, -2.089}, {0.708, -1.934}, {0.581, -1.991}, {0.505, -2.018},
{0.565, -1.898}, {0.586, -2.053}, {0.98, -1.845}, {1.047, -1.739}}

which -again, for those interested- correspond to a 2D projection of the first five residues of a S4S5 alpha helix for the Kv1.2 Ion Channel.


Defining $V(r)$ as


v[r_, r0_, s_, ep_] := 4 ep (s^12/EuclideanDistance[r, r0]^12 -
s^6/EuclideanDistance[r, r0]^6);


I can plot the potential with


Plot3D[Sum[v[{x, y}, r0[[i]], sig[[i]], eps[[i]]], {i, 1, 84}], 
{x, -0.5, 2}, {y, -3.5, -1},
PlotStyle -> Directive[Opacity[0.35], Blue],
AxesLabel -> {x, y}, PlotRange -> {-5, 1}
]

obtaining the following output


plot of sum of potentials


or, using PlotPoints -> 50



refined plot of sum of potentials


where the minima/maxima can be seen really well.


The thing is, I have a lot of these objects, with a lot more elements, and a lot of minima/maxima, in a way that is very expensive for my (old) computer to simply increase PlotPoints for smoother graphics, and I was wondering, due the fact that $V(r)$ rapidly decreases, if there is a way to ask MMA to increase resolution near the minima/maxima, and reduce it far from the data set r0.


Hope my question is clear and interesting.


--FINAL EDIT--


First of all, I want to thank you all for your comments and answers. If I could, I'd accept all of them, since each one gave me the insight needed to solve my problem. For obvious reasons, Silvia's answer deserves maximum recognition, but readers should also check PlatoManiac and Sjoerd C. de Vries responses, as they will provide a full picture.


Now, to honour the work of all the people involved, I'll show you the beautiful application of the code they've worked out.


Here is a caricaturization of the S4S5 linker helix, believed to play a major role in the opening and closing of voltage gated potassium channels.


S4S5 linker helix


This helix generates all sort of van der Waals interactions, that can be modelled by the Lennard-Jones potential.



For specific reasons, I need to see how this potential looks on a given plane, namely the XY plane, and it is very important to capture all the maxima and minima of it, as it will provide a full picture of the dynamics in that plane.


Thanks to Silvia's code, one can see:


a view from below of the potential generated by the helix, View from below


a sideways view, where the peaks are actually minima, Sideways veiw, the peaks are actually minima


and a view form above,


View from above


What you are seeing is the van der Waals interactions generated by the helix over that plane, and if you're wondering what does that sharp barrier around the helix is, it's the macroscopic consequence of Pauli's Exclusion Principle!


Thank you all for your help, you've put a big smile on my face!



Answer



In order to emphasize the wanted features, my idea is to manually generate a grid which is fine near the ridge line and sketchy far away:



Mathematica graphics



First we define our functions following Simon's suggestion:


v[r_, r0_, s_, ep_] := 4*ep*(s^12/(#.#&)[r-r0]^(12/2)-s^6/(#.#&)[r-r0]^(6/2))

expr = Sum[v[{x, y}, r0[[i]], sig[[i]], eps[[i]]], {i, 1, 84}];

func = Compile[{x, y}, Evaluate[expr // Expand]];

funcWrap[x_?NumericQ, y_?NumericQ] := func[x, y]



The shape of the plot makes me feel that it's more convenient to work in a polar coordinate system in the $x$-$y$ plane, with rC (center of r0) as the origin. In order to generate a grid fit for expr, two key lines need to be known first: one is the boundary innerBoundLine where expr==2 (because we want to cut the PlotRange below $1<2$), and the other is the ridge line minPointsPolar, highlighted blue in the plot above:


rC = Mean[r0];

innerBoundLine = ContourPlot[funcWrap[x, y] == 2,
{x, -0.5, 2}, {y, -3.5, -1}, PlotPoints -> 50];

innerBoundPoints = Cases[
Normal[innerBoundLine[[1]] /.Tooltip[expr_, _] :> expr],

Line[pts_] :> pts, ∞][[1]] // Most;

innerBoundPointsPolar =
{Arg[{1, I}.#], Norm@#} &[# - rC] & /@ innerBoundPoints // SortBy[#, First] &;

innerBoundFunc = Interpolation[
ReplacePart[#,{{1, 2}, {-1, 2}} -> Mean[#[[{1, -1}, 2]]]] &[innerBoundPointsPolar],
PeriodicInterpolation -> True, InterpolationOrder -> 1];

minPointsPolar = Module[

{ρmin, linefunc, ρinit},
Table[ρinit = innerBoundFunc[φ];
ρmin = ρ /. FindMinimum[ funcWrap @@ (ρ {Cos[φ], Sin[φ]} + rC),
{ρ, ρinit}, Method -> "PrincipalAxis"][[2]];
{φ, ρmin},
{φ, 0, 2 π, 1. Degree}]];

minFunc = Interpolation[
ReplacePart[#, {{1, 2}, {-1, 2}} -> Mean[#[[{1, -1}, 2]]]] &[minPointsPolar],
PeriodicInterpolation -> True, InterpolationOrder -> 1];



Now we can proceed to the grid generation step. Here, four grids with different fineness are generated. minLineGrid is near the ridge line and is the finest. From fineGrid to transitionalGrid to outlineGrid, the grids are farther and farther from the ridge, and sketchier and sketchier.


minLineGrid = Module[{ρmin, linefunc},
Table[
ρmin = minFunc[φ];
linefunc = Append[#,
funcWrap @@ #] &[
ρ {Cos[φ], Sin[φ]} + rC];
Table[linefunc, {ρ,

Range[.98, 1.02, .01] ρmin
}],
{φ, 0, 2 π, 1. Degree}] // Flatten[#, 1] &
];

fineGrid = Module[{ρmin, linefunc, ρinit},
Table[
ρinit = innerBoundFunc[φ];
ρmin = minFunc[φ];
linefunc = Append[#,

funcWrap @@ #] &[
ρ {Cos[φ], Sin[φ]} + rC];
Table[linefunc, {ρ, Join[
Rescale[Range[0, 1, .5], {0, 1}, {ρinit, ρmin}],
Rescale[Range[0, 1, .3], {0, 1}, {ρmin, 1.1 ρmin}]
]}],
{φ, 0, 2 π, 2. Degree}] // Flatten[#, 1] &
];

transitionalGrid = Module[{ρmin, linefunc},

Table[
ρmin = minFunc[φ];
linefunc = Append[#,
funcWrap @@ #] &[
ρ {Cos[φ], Sin[φ]} + rC];
Table[linefunc, {ρ,
Rescale[Range[0, 1, .2], {0, 1}, {1.1 ρmin, 1.5 ρmin}]
}],
{φ, 0, 2 π, 5. Degree}] // Flatten[#, 1] &
];


outlineGrid = Module[{ρmin, linefunc},
Table[
ρmin = minFunc[φ];
linefunc = Append[#,
funcWrap @@ #] &[
ρ {Cos[φ], Sin[φ]} + rC];
Table[linefunc, {ρ,
Rescale[Range[0, 1, .5], {0, 1}, {1.5 ρmin, 2}]
}],

{φ, 0, 2 π, 20. Degree}] // Flatten[#, 1] &
];

dataGrid = Join[outlineGrid, transitionalGrid, fineGrid, minLineGrid];

The grid points would look like this in the $x$-$y$ plane:


Graphics[{PointSize[.001], Black, Point[minLineGrid[[All, 1 ;; 2]]],
PointSize[.002], Red, Point[fineGrid[[All, 1 ;; 2]]],
PointSize[.005], Darker@Green, Point[transitionalGrid[[All, 1 ;; 2]]],
PointSize[.008], Blue, Point[outlineGrid[[All, 1 ;; 2]]]},

Frame -> True, FrameLabel -> (Style[#, Bold, 20] & /@ {x, y})]

Mathematica graphics



Plot the dataGrid by ListPlot3D:


ListPlot3D[dataGrid,
PlotRange -> {{-.5, 2}, {-3.5, -1}, {-5, 1}},
ClippingStyle -> Gray, BoundaryStyle -> Blue,
AxesLabel -> (Style[#, Bold, 20] & /@ {x, y})]


Mathematica graphics


($x$,$y$) grid of the plot:


ListPlot3D[dataGrid,
PlotRange -> {{-.5, 2}, {-3.5, -1}, {-5, 1}},
Mesh -> All, PlotStyle -> None,
AxesLabel -> (Style[#, Bold, 20] & /@ {x, y}),
ViewPoint -> {0, 0, ∞}]

Mathematica graphics


Remarks: I believe it can be made more adaptive by finding an appropriate coordinate transformation which converts the ridge-line and the outside borders (-0.5 <= x <= 2 && -3.5 <= y <= -1) to centered concentric circles, and then generate polar grids in this new coordinate system.



Edit: The typical time spent for generating above grids on my computer:


Timing[
rC = Mean[r0];

...

outlineGrid = ...;
]



{1.482, Null}



Comments

Popular posts from this blog

plotting - Plot 4D data with color as 4th dimension

I have a list of 4D data (x position, y position, amplitude, wavelength). I want to plot x, y, and amplitude on a 3D plot and have the color of the points correspond to the wavelength. I have seen many examples using functions to define color but my wavelength cannot be expressed by an analytic function. Is there a simple way to do this? Answer Here a another possible way to visualize 4D data: data = Flatten[Table[{x, y, x^2 + y^2, Sin[x - y]}, {x, -Pi, Pi,Pi/10}, {y,-Pi,Pi, Pi/10}], 1]; You can use the function Point along with VertexColors . Now the points are places using the first three elements and the color is determined by the fourth. In this case I used Hue, but you can use whatever you prefer. Graphics3D[ Point[data[[All, 1 ;; 3]], VertexColors -> Hue /@ data[[All, 4]]], Axes -> True, BoxRatios -> {1, 1, 1/GoldenRatio}]

plotting - Filling between two spheres in SphericalPlot3D

Manipulate[ SphericalPlot3D[{1, 2 - n}, {θ, 0, Pi}, {ϕ, 0, 1.5 Pi}, Mesh -> None, PlotPoints -> 15, PlotRange -> {-2.2, 2.2}], {n, 0, 1}] I cant' seem to be able to make a filling between two spheres. I've already tried the obvious Filling -> {1 -> {2}} but Mathematica doesn't seem to like that option. Is there any easy way around this or ... Answer There is no built-in filling in SphericalPlot3D . One option is to use ParametricPlot3D to draw the surfaces between the two shells: Manipulate[ Show[SphericalPlot3D[{1, 2 - n}, {θ, 0, Pi}, {ϕ, 0, 1.5 Pi}, PlotPoints -> 15, PlotRange -> {-2.2, 2.2}], ParametricPlot3D[{ r {Sin[t] Cos[1.5 Pi], Sin[t] Sin[1.5 Pi], Cos[t]}, r {Sin[t] Cos[0 Pi], Sin[t] Sin[0 Pi], Cos[t]}}, {r, 1, 2 - n}, {t, 0, Pi}, PlotStyle -> Yellow, Mesh -> {2, 15}]], {n, 0, 1}]

plotting - Mathematica: 3D plot based on combined 2D graphs

I have several sigmoidal fits to 3 different datasets, with mean fit predictions plus the 95% confidence limits (not symmetrical around the mean) and the actual data. I would now like to show these different 2D plots projected in 3D as in but then using proper perspective. In the link here they give some solutions to combine the plots using isometric perspective, but I would like to use proper 3 point perspective. Any thoughts? Also any way to show the mean points per time point for each series plus or minus the standard error on the mean would be cool too, either using points+vertical bars, or using spheres plus tubes. Below are some test data and the fit function I am using. Note that I am working on a logit(proportion) scale and that the final vertical scale is Log10(percentage). (* some test data *) data = Table[Null, {i, 4}]; data[[1]] = {{1, -5.8}, {2, -5.4}, {3, -0.8}, {4, -0.2}, {5, 4.6}, {1, -6.4}, {2, -5.6}, {3, -0.7}, {4, 0.04}, {5, 1.0}, {1, -6.8}, {2, -4.7}, {3, -1....