Is there a way to dynamically define a polygon on a plot (I'm working with ListPlot
and SmoothDensityHistogram
) to select a cluster of interest, and give the positions of those points in the original list of data?
I'd appreciate any help!
Here's just an example set of points:
x = {
{RandomReal[{0, 5}, 20],
RandomReal[{4, 4.5}, 10]},
{RandomReal[1, 20],
RandomReal[{1.5, 2}, 10]}
};
points = Transpose[Join @@@ x] ~RandomSample~ 30;
SmoothDensityHistogram[points, ColorFunction -> "TemperatureMap"]
ListPlot[points, PlotRange -> {{0, 5.5}, {0, 2.5}}]
Answer
This is basically the same as what b.gatessucks is doing. The main addition is that I've put all the locators in one list. To add vertices to the polygon you just click somewhere on the graph. I've also added a reset button and a button that prints the indices of the points inside the polygon which makes it easier to copy.
points = RandomSample[
Transpose[{Flatten[{RandomReal[{0, 5}, 20], RandomReal[{4, 4.5}, 10]}],
Flatten[{RandomReal[1, 20], RandomReal[{1.5, 2}, 10]}]}], 30];
winding[poly_, pt_] := Round[(Total @ Mod[(# - RotateRight[#]) &@
(ArcTan @@ (pt - #) & /@ poly), 2 Pi, -Pi]/2/Pi)]
DynamicModule[{pl, pos},
pl = SmoothDensityHistogram[points, ColorFunction -> "TemperatureMap"];
Manipulate[
pos = Pick[Range[Length[points]], Unitize[winding[poly, #] & /@ points], 1];
Show[pl,
Epilog -> {{Darker[Green], PointSize[Medium], Point[points[[pos]]]},
{Black, Point[Complement[points, points[[pos]]]]},
{EdgeForm[{Red, Dashed}], FaceForm[], Polygon[poly]}}],
{{poly, {}}, Locator, LocatorAutoCreate -> All},
Row[{Button["Copy Points", Print[pos]], Button["Reset", poly = {}; pos = {}]}]]]
Comments
Post a Comment