5

Suppose we have a hard to calculate function f. We plot it like e.g.

Plot3D[f[x,y],{x,-5,5},{y,-5,5},MaxRecursion->5,PlotPoints->30,PlotRange->All]

After some long calculation this gives us a nice image, it can be rotated and all, but suddenly we want to look at a density plot of f. We can of course repeat the whole long calculation with DensityPlot, but it's wasteful. We could instead have pre-calculated a table of values of f using Table, but this would imply homogeneous (or some manually-parametrized) grid, which can be an inefficient (or hard to implement) choice for many functions.

So what is needed is a way to sample the function as e.g. Plot3D would do it with given MaxRecursion and PlotPoints, but instead of putting the result into a graphics box, put it into a variable as a list of coordinates or whatever form suitable for List*Plot* family of functions. How can this be done?

Ruslan
  • 7,152
  • 1
  • 23
  • 52
  • Make an appromixation, e.g. f2 = FunctionInterpolation[f[x, y], {x, xmin, xmax}, {y, ymin, ymax}] and use that in the plots. – Coolwater Sep 03 '16 at 21:05
  • @Coolwater but FunctionInterpolation doesn't seem to have controls over how it samples the function. – Ruslan Sep 03 '16 at 21:07
  • Take a look here: http://mathematica.stackexchange.com/q/216/12 and here: http://mathematica.stackexchange.com/a/1011/12 I recommend the second. The first has issues. I have a much more complex solution to the first one which unfortunately was too messy and too involved to post here ... – Szabolcs Sep 03 '16 at 22:13
  • The title would seem to be duplicate of these: http://mathematica.stackexchange.com/questions/82912/how-to-obtain-adaptive-sampling-as-in-plot-function, http://mathematica.stackexchange.com/questions/88299/how-to-implement-the-sample-point-process-like-the-built-ins-of-mathematica -- maybe indicate it's higher dimensional sampling or 2D sampling that you're interested in, whichever is more accurate? – Michael E2 Sep 03 '16 at 22:39

1 Answers1

5

Say for example :

 gr00 = Plot3D[
            Sin[x y],
            {x, -5, 5}, {y, -5, 5},
            MaxRecursion -> 5, PlotPoints -> 30, PlotRange -> All]  

enter image description here

The data, including the mesh, are the first element of GraphicsComplex[...] in gr00 :

gr00 // InputForm // Short  

enter image description here

Then :

ListDensityPlot[gr00[[1, 1]]]  

enter image description here

ListDensityPlot[gr00[[1, 1]], Mesh -> All]  

enter image description here

You can even do a copy-paste of your graphic inside the ListDensityPlot, the data are not lost :

enter image description here

--> same result as above

andre314
  • 18,474
  • 1
  • 36
  • 69
  • 2
    I like this, but it does depend on the internal, undocumented structure of an object – mikado Sep 04 '16 at 05:27
  • 1
    @mikado The doc of Plot3D says : "Plot3D returns GraphicsComplex[data]]" without saying what is exactly data. You can use a more robust extraction of data with something like Cases[...,GraphicsComplex[___],{1,Infinity}]. The philosophy not do mix data and presentation (tick...) is stable on mathematica since the beginning. I think that the main risk is to have the Graphics[...] form instead of GraphicsComplex (see Normal[ComplexExpand[..]]), because GraphicsComplex[] was only introduced in 2007. So effectively, I only use this is interactive sessions. – andre314 Sep 04 '16 at 09:48