0
$\begingroup$

A have 2D function defined on some square (e.g. {x, 1, 10}, {y, 1, 10} with step 1). It's represented via array, e.g.: RandomReal[1, {10, 10}]. And I need to detect centers of "minimum areas" in the ListContourPlot[] of this data (probably using some threshold). For example, one of my samples has next representation and I want to find coordinates of red points:

enter image description here

I know I can go for converting the plot to the image and using some image-based segmentation to locate these areas and to define their centres, but it's too time-consuming approach (a have a lot of such samples).

So the question is: how do I find such points by analyzing "raw" data from my array (the faster - the better).

NB: there may be multiple target areas in different locations - I need them all...

$\endgroup$
4
  • $\begingroup$ FindMinimum[{f[x,y], 6 <= x <= 10, 8 <= y <= 10}, {x, y}] and FindMinimum[{f[x,y], 6 <= x <= 10, 6 <= y <= 8}, {x, y}] $\endgroup$
    – Feyre
    Commented Nov 22, 2016 at 16:52
  • $\begingroup$ @Feyre, I've updated the question: I don't have f[x,y] - I have an array. And also I don't know the borders of the target area, so I can't use constraints like 6 <= x <= 10 or 8 <= y <= 10. $\endgroup$ Commented Nov 22, 2016 at 16:56
  • $\begingroup$ If you run {Position[f = RandomReal[1, {10, 10}], min = Min@f], min} you generate an array in f, and print its minimum value and all the positions where this value is achieved. $\endgroup$
    – Feyre
    Commented Nov 22, 2016 at 17:00
  • $\begingroup$ Are you asking for the centroid of the area enclosed by the minimum contour? That is going to be a function of the contour algorithm ( interpolation, selection of contour intervals, etc ), so you can not get it from the raw data. $\endgroup$
    – george2079
    Commented Nov 22, 2016 at 17:15

1 Answer 1

2
$\begingroup$
data = RandomReal[1, {10, 10}];

plot = ListContourPlot[data, PlotLegends -> Automatic, Contours -> 5];
p1 = RegionCentroid[
   Cases[Normal@plot, Line[x_] :> Polygon[x], Infinity][[-1]]];
Show[plot, Graphics[{Red, PointSize[.02], Point[p1]}]]

enter image description here

when you have multiple regions at the lowest level you'll need to manually take the 'last n' results from Cases:

plot = ListContourPlot[data, PlotLegends -> Automatic, Contours -> 5];
pts = RegionCentroid /@ 
   Cases[Normal@plot, Line[x_] :> Polygon[x], Infinity][[-9 ;;]];
Show[plot, Graphics[{Red, PointSize[.02], Point[pts]}]]

enter image description here

The green marker is the minimum for the interpolation function found by

Last@Quiet@
  FindMinimum[
   Interpolation[Flatten[MapIndexed[{#2, #} &, data, {2}], 1], 
     InterpolationOrder -> 3][x, y], {x, y}]

as you see its a little different.

$\endgroup$
2
  • $\begingroup$ Awesome answer, thanks! But still... Is there any way to obtain the SAME result without plotting? I mean... Mathematica does the 'levels' computation somehow (detects regions with different colors on the plot). Is it possible to perform such computations manually on the input data (directly) and then detect target points? If no, I'll accept this answer as a correct one anyway. I see the example with Interpolation and FindMinimum, but it finds only one point and the interpolation itself is quite time-consumable. Is there any "multi-point discrete algorithm"? $\endgroup$ Commented Nov 22, 2016 at 18:21
  • $\begingroup$ you would basically need to reverse engineer the contour algorithm. If you want the "Real" minima for each contour region you can try feeding each centroid point as an initial point for FindMinimum. You might also specify more contours on the plot. $\endgroup$
    – george2079
    Commented Nov 22, 2016 at 18:57

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.