This comes up quite often here - Mathematica simply does a much better job of making 2D plots when the data is an $n\times n$ array of z-values than it does when the data is an $n^2 \times 3$ list of {x, y, z}
tuples. I think it uses different interpolation algorithms.
If the data is on a regular grid, then there is absolutely no reason to use the tuples form, since you can specify the x and y ranges using DataRange
. Here is an example, with a larger list of data than in the OP,
testdata1 =
Flatten[Table[{x, y,
Sin[x - 2 y] Cos[
2 x + y]}, {x, -π, π, .01}, {y, -π, π, .01}],
1];
Dimensions@testdata1
(* {395641, 3} *)
If I use ListDensityPlot
on the data in this format, it takes 81 seconds on my machine (ListContourPlot
takes a bit longer),
ListDensityPlot[testdata1, ImageSize -> 400] // AbsoluteTiming
If, however, I restructure the data using Partition
(and Transpose
to keep the x and y axes in the same spot), then it only takes about 4 seconds,
testdata2 = Transpose[Partition[testdata1[[All, 3]], 629]];
ListDensityPlot[testdata2, ImageSize -> 400,
DataRange -> {{-π, π}, {-π, π}}] // AbsoluteTiming
Exact same output, in much less time.
You can get a similar plot with ArrayPlot
, although it doesn't make the tick marks look very nice. You have to reverse the data to account for the reversal that automatically happens with ArrayPlot
,
ArrayPlot[Reverse@testdata2,
ColorFunction -> "M10DefaultDensityGradient",
DataRange -> {{-π, π}, {-π, π}}, AspectRatio -> 1,
FrameTicks -> All, ImageSize -> 500(*,DataReversed\[Rule]{True,
False}*)] // AbsoluteTiming
This is the fastest non-interpolating option. You can get away from the ugly tick labels if you use the CustomTicks
package, part of the SciDraw
package. If you do the above plot using FrameTicks -> {{LinTicks, StripTickLabels@LinTicks}, {LinTicks, StripTickLabels@LinTicks}}
then it comes out looking decent.
Another workaround is to use Interpolation
, and it is faster, but it's usually better to work with the data itself. And to get the same quality, you often have to use a high value for PlotPoints
,
func = Interpolation[testdata1];
DensityPlot[func[x, y], {x, -π, π}, {y, -π, π},
ImageSize -> 400, PlotPoints -> 100] // AbsoluteTiming
{{x1, y1, z1}, {x2, y2, z2},.......{xn, yn, zn}}
? $\endgroup$ListDensityPlot[{{x1, y1, z1}, {x2, y2, z2},.......{x262144, y262144, z262144}}]
. $\endgroup$intfunc=Interpolation[data]; DensityPlot[ intfunc[x, y], {x, xmin, xmax}, {y, ymin, ymax}, options]
wheredata
is your data andoptions
are all the options you use withListDensityPlot
$\endgroup$