Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Is it possible to increase the perforamce the DensityPlot?

For example, let's try to plot this "flower"

f[x_, y_] := (x^2 + y^2) Exp[-x^2 - y^2] Sin[10 Sqrt[x^2 + y^2] + 10 ArcTan[x, y]]^4;

DensityPlot[f[x, y], {x, -3, 3}, {y, -3, 3}, PlotPoints -> 200, 
 MaxRecursion -> 3, ColorFunction -> Hue, PlotRange -> All, 
 ColorFunctionScaling -> False, ImageSize -> 600]

enter image description here

This toy example takes about 12 seconds on my laptop, eats about 1GB of RAM while plotting and the 34MB result slow down the notebook.

The question is

  1. How to increase the speed?

  2. How to decrease the MaxMemoryUsed?

  3. How to decrease the size of the output?

share|improve this question

1 Answer 1

up vote 15 down vote accepted

I have found that my approach with textures has different applications:

Now I want to use it for the enhancement of the DensityPlot:

Options[fastDensityPlot] = Append[Options[DensityPlot], Subpoints -> 30];
SyntaxInformation[fastDensityPlot] = SyntaxInformation[DensityPlot];

fastDensityPlot[f_, {x_, xmin_, xmax_}, {y_, ymin_, ymax_}, opts : OptionsPattern[]] :=
 DensityPlot[f, {x, xmin, xmax}, {y, ymin, ymax},
       Evaluate@FilterRules[{opts}, Except@Subpoints]] // Normal // toTriangles // 
   texturize[Function[{#1, #2}, #3] & @@ {x, y, f},
        OptionValue[Subpoints], OptionValue[ColorFunction]]

Here Normal convert GraphicsComplex to separate polygons, toTriangles split polygons to triangles, and texturize put textures on every triangle (defined below), f is assumed to be Listable.

f[x_, y_] := (x^2 + y^2) Exp[-x^2 - y^2] Sin[10 Sqrt[x^2 + y^2] + 10 ArcTan[x, y]]^4;

fastDensityPlot[f[x, y], {x, -3, 3}, {y, -3, 3}, PlotPoints -> 10, 
 MaxRecursion -> 2, ColorFunction -> Hue, Subpoints -> 20, 
 PlotRange -> All, ImageSize -> 600]

enter image description here

This image looks a bit better. At the same time fastDensityPlot is ~10 times faster then the regular DensityPlot, MaxMemoryUsed is only 64MB and ByteCount is 10MB.

One can see that fastDensityPlot uses the advantage of the non-equidistant mesh:

fastDensityPlot[f[x, y], {x, -3, 3}, {y, -3, 3}, PlotPoints -> 10, 
 MaxRecursion -> 2, ColorFunction -> Hue, Subpoints -> 20, 
 PlotRange -> All, ImageSize -> 600, Mesh -> All]

enter image description here

The definitions of the above functions are

toTriangles = # /. Polygon[v_ /; Length[v] > 3, ___] :> (Polygon@Append[#, Mean[v]] & /@ 
       Partition[v, 2, 1, 1]) &;

texturize[f_, n_, colf_] := # /. Polygon[{v1_, v2_, v3_}, ___] :> {Texture@
       ImageData@Colorize[
         Image@f[v3[[1]] + (v1[[1]] - v3[[1]]) #1 + (v2[[1]] - v3[[1]]) #2, 
                v3[[2]] + (v1[[2]] - v3[[2]]) #1 + (v2[[2]] - v3[[2]]) #2] 
          &[#, Transpose[#]] &@ConstantArray[Range[-1./n, 1 + 1./n, 1./n], n + 3], 
         ColorFunction -> colf, ColorFunctionScaling -> False], 
      Polygon[{v1, v2, v3}, 
       VertexTextureCoordinates -> {{1 - 1.5/(n + 3), 
          1 - 1.5/(n + 3)}, {1.5/(n + 3), 1.5/(n + 3)}, {1.5/(n + 3), 
          1 - 1.5/(n + 3)}}]} &;

As in the linked answer I add textures to every triangle with an appropriate rectangular grid. This method is fast because it uses packed arrays.

share|improve this answer
    
As I understand, you subdivide each triangle into Subpoints^2 regions and calculate values of f in the nodes. Is it correct? –  Alexey Popkov Jan 5 at 14:24
    
Yes! More precisely, I calculate the texture for a parallelogram and use only a half of it. One can optimize it further, but it is no so simple. –  ybeltukov Jan 5 at 14:30
    
So PlotPoints->n, Subpoints->m, MaxRecursion->0 should be equivalent to PlotPoints->n*m, Subpoints->0, MaxRecursion->0? –  Alexey Popkov Jan 5 at 14:45
    
@AlexeyPopkov Yes, but with Subpoints->1 in the second case. –  ybeltukov Jan 5 at 15:03
1  
@AlexeyPopkov They are visually similar, but not equivalent. The second one contains a lot of small triangles with a lot of small textures. This is very slow and inefficient. fastDensityPlot is fast when you use a small number of big triangles with big textures (two big triangles in the limit). The opposite limit is DensityPlot which produce a lot of small colorized (not texturized) triangles. –  ybeltukov Jan 5 at 15:52

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.