Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Inconsistent behavior of RegionFunction in ContourPlot and ListContourPlot

118 views
Skip to first unread message

Alexey Popkov

unread,
Aug 18, 2012, 3:44:02 AM8/18/12
to
Hello folks,

When trying to plot a non-covex set of datapoints ListContourPlot produces a
convex graph effectively extrapolating values outside of the actual range of
the original dataset:

pts = {{1, 1, 1}, {2, 1.2, .8}, {3, 1.3, .7}, {3, 2, 1}, {1.5, 2,
1}, {1.5, 1.5, 1}};
epilog = {FaceForm[None], EdgeForm[Red], Polygon[Most /@ pts]};
ListContourPlot[pts, Epilog -> epilog]

(the red polygon shows the actual range of the data).

I need to remove the extrapolated parts of the graph and define
RegionFunction:

leftBorder =
Interpolation[pts[[{5, 6, 1}, {2, 1}]], InterpolationOrder -> 1];
bottomBorder =
Interpolation[pts[[{1, 2, 3}, {1, 2}]], InterpolationOrder -> 1];
ListContourPlot[pts, Epilog -> epilog,
RegionFunction ->
Function[{x, y, z},
x >= leftBorder[y] && y >= bottomBorder[x]]]

But as you see, nothing happens! The drawn region of the plot still contains
areas outside of the area allowed by the RegionFunction.

There is no such problem with ContourPlot:

ContourPlot[Sin[x y], {x, 1, 3}, {y, 1, 2}, Epilog -> epilog,
RegionFunction ->
Function[{x, y, z}, x >= leftBorder[y] && y >= bottomBorder[x]]]

Is it a bug in ListContourPlot? How to achieve consistent behavior of
RegionFunction in both ContourPlot and ListContourPlot?

Thanks in advance!



djmpark

unread,
Aug 18, 2012, 8:37:29 PM8/18/12
to
It's a disappointment! I thought I would demonstrate John Browne's Grassmann
algebra by using its routines to generate a RegionFunction.

The idea is:
1) There is a simple Grassmann algebra expression that determines whether a
test point is on the same side of a line as a reference point.
2) You can then test if a point is inside a triangle by applying the test to
each side with the opposite vertex as the reference point.
3) You can then triangulate any polygon, convex or not, and test if a point
is in any of the triangles.

For your polygon I generated, by this method, the following RegionFunction:

inPolygon =
Function[{x, y},
(NonNegative[3. - 0.75 x - 1.25 y] &&
NonNegative[1.25 x - 1.25 y] &&
NonNegative[-2. - 0.5 x + 2.5 y]) || (NonNegative[-3. + 2. x] &&
NonNegative[-4.8 + 1.2 x + 2. y] &&
NonNegative[8.8 - 3.2 x - 2. y]) || (NonNegative[2.5 - 1.25 y] &&
NonNegative[-1.83333 + 0.666667 x + 0.416667 y] &&
NonNegative[0.333333 - 0.666667 x + 0.833333 y]) || (NonNegative[
3. - 1. x] && NonNegative[-0.571429 + 1.14286 x - 1.42857 y] &&
NonNegative[-1.42857 - 0.142857 x + 1.42857 y])]

This all works very well and I can even make a dynamic diagram with a spoken
voice that says "Inside" or "Outside" whenever a point locator crosses the
boundary.

But the sad fact is that ListContourPlot has a bug and does not implement
RegionFunction properly - neither your function nor my function. It does
appear to work properly in other plot types: ContourPlot or RegionPlot.

A possible work around is to use RegionPlot with ! inPolygon to mask the
undesired region.

Show[
{ListContourPlot[pts],
RegionPlot[! inPolygon[x, y], {x, 0.4, 3.6}, {y, 0.4, 2.6},
MaxRecursion -> 4,
PlotStyle -> White]},
AspectRatio -> Automatic,
PlotRange -> {{0.5, 3.5}, {0.5, 2.5}},
Frame -> True,
BaseStyle -> {FontSize -> 12},
ImageSize -> 400]


David Park
djm...@comcast.net
http://home.comcast.net/~djmpark/index.html
0 new messages