8
$\begingroup$

I have this data

b = .1 {{1, 1}, {0, 1}};
pts = Tuples[Range[-20, 20], 2] . b;
data = {#[[1]], #[[2]], Sin[#[[1]] #[[2]]]} & /@ pts;  

I would like to use ListDensityPlot with InterpolationOrder -> 0

ListDensityPlot[data, InterpolationOrder -> 0]    

enter image description here

There are some data points outside the data range! the date range should be like this

ListDensityPlot[data, InterpolationOrder -> 1]    

enter image description here

$\endgroup$
1
  • 2
    $\begingroup$ Noteworthy (I think): ListDensityPlot[data] is identical to ListDensityPlot[data,InterpolationOrder -> 1] $\endgroup$
    – bmf
    Commented Feb 23, 2023 at 9:44

2 Answers 2

10
$\begingroup$

Background

Look into RegionFunction.

RegionFunction is an option for plotting functions that specifies the region to include in the plot drawn.

If you know how to define the region analytically, that could be faster (Solution 2). Here I first take the more general route of using ConvexHullRegion

ConvexHullRegion is also known as convex envelope or convex closure. The convex hull mesh is the smallest convex set that includes the points $p_i$.

enter image description here

Region check happens using RegionMember

Solution 1

With[
    {reg = ConvexHullRegion[pts]},
    ListDensityPlot[
        data, 
        InterpolationOrder -> 0, 
        RegionFunction -> Function[{x, y, z},RegionMember[reg, {x,y}]]
    ] 
]

enter image description here

Solution 2

Defining the RegionFunction by hand

ListDensityPlot[
        data, 
        InterpolationOrder -> 0, 
        RegionFunction -> Function[{x, y, z}, x-2 < y  < x + 2]
    ] 
]

Solution 3

See solution by @valarmorghulis, they figured out that pre-defining the RegionFunction makes all the difference and has the best performance. Replicating my version of his solution here for completeness.

With[
    {regfunc = RegionMember[ ConvexHullRegion[pts]]},
    ListDensityPlot[
        data, 
        InterpolationOrder -> 0, 
        RegionFunction ->(regfunc[{#1,#2}]&)
    ] 
]

Performance

Using RegionMember[ ConvexHullRegion[pts], {x,y}] much slower than Function[{x, y, z}, x-2 < y < x + 2].

Using AbsoluteTiming I compare the two solutions.

Sol 1

enter image description here

Sol 2

enter image description here

Sol 3

enter image description here

$\endgroup$
4
  • 2
    $\begingroup$ (+1) and very nicely done. Perhaps you could demonstrate the result from reg = ConicHullRegion[pts] $\endgroup$
    – bmf
    Commented Feb 23, 2023 at 9:55
  • $\begingroup$ @bmf ConicHullRegion doesn't help here. Does it? $\endgroup$
    – rhermans
    Commented Feb 23, 2023 at 11:54
  • 1
    $\begingroup$ it is exactly the result from InterpolationOrder->0. So yes, you are right. It is not a solution, but I think it's a nice and illustrative connection. This is what I meant. $\endgroup$
    – bmf
    Commented Feb 23, 2023 at 11:59
  • $\begingroup$ I don't understand why RegionFunction -> Composition[regfunc, Most, List] doesn't work. $\endgroup$
    – rhermans
    Commented Mar 3, 2023 at 14:16
6
$\begingroup$

in light of the Answer by @rhermans, the performance can be boosted like the one below, but it would be nice to boost it without using two superimposed graphics and directly obtain using ListDensityPlot

reg = ConvexHullRegion[pts]; 

then

Show[ListDensityPlot[data, InterpolationOrder -> 0], 
  Graphics[{White, 
    Polygon[{{-4, -4}, {-4, 4}, {4, 4}, {4, -4}} -> 
      reg[[1]]]}]] // AbsoluteTiming       

enter image description here

Update

For arbitrarily shaped data, we can predefine the RegionMember and results much faster though don't know why

Block[{RegFun = RegionMember[ConvexHullRegion[pts]]}, 
  ListDensityPlot[data, InterpolationOrder -> 0, 
   RegionFunction -> (RegFun[{#1, #2}] &)]] // AbsoluteTiming    

enter image description here

Adding it in the RegionFunction makes it 20 times slow

Block[{reg = ConvexHullRegion[pts]}, 
  ListDensityPlot[data, InterpolationOrder -> 0, 
   RegionFunction -> 
    Function[{x, y, z}, RegionMember[reg, {x, y}]]]] // AbsoluteTiming     

enter image description here

$\endgroup$
6
  • $\begingroup$ I have updated my answer with similar performance as yours, but you need to define the function by hand. $\endgroup$
    – rhermans
    Commented Feb 23, 2023 at 11:56
  • $\begingroup$ That is great, but what if the data are hexagon shaped or other nonunform shape? $\endgroup$
    – MMA13
    Commented Feb 23, 2023 at 12:05
  • 1
    $\begingroup$ Another interesting question to ask, how to make RegionMember[ConvexHullRegion[pnts], {x,y}] fast, or something equivalent. $\endgroup$
    – rhermans
    Commented Feb 24, 2023 at 7:31
  • $\begingroup$ @rhermans check my update! $\endgroup$
    – MMA13
    Commented Feb 25, 2023 at 12:30
  • 1
    $\begingroup$ Using RegionFunction -> Function[{x, y, z}, Evaluate@RegionMember[reg, {x, y}]]] achieves the same speedup as predefining the region. $\endgroup$
    – Chris K
    Commented Mar 3, 2023 at 21:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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