2d data set as contour

There is a set of data in the form of a table that I import into Mathematica:

https://dropmefiles.com/7BXAE

a = Import["To.mat"];

a = Partition[Flatten[a], 3];


Then I plot $$x,y$$ on the plane:

data = Transpose@{a[[All, 1]], a[[All, 2]]};


And I get the following picture:

ListPlot[data]


Desired result that I need:

That is, I need the place where the points are concentrated (where they are built) to be represented as a contour or surface. How to do it with Mathematica commands?

• I cannot import the file you provided. Is it MATLAB specific? Oct 17, 2022 at 16:53
• When importing the data file Mathematica 13.1 (Windows 10) gives the error message "Data cannot be imported because it contains infinite or indeterminate values. Use the option "IndeterminateValues" to provide replacements." My attempts to provide "IndeterminateValues" were unsuccessful.
– JimB
Oct 17, 2022 at 17:52
• While you can probably get a desired result from using SmoothKernelDistribution, the apparent criterion for success is that it will look like what you did by hand as opposed to something more objective. How the data was collected and what are the consequences of not having an appropriate contour would be helpful to know.
– JimB
Oct 17, 2022 at 17:56
• For a workaround for the data: a = Import["To.mat", "IndeterminateValues" -> 999999] /. {999999. -> Nothing} /. {} -> Nothing; Oct 17, 2022 at 18:26
• @JimB 1. The data were collected as follows: an inequality is given, and the space of its solutions is filled with uniformly distributed parameter values for which the inequality is satisfied. 2. The outline is necessary because the boundaries of this contour will be used in tasks of orientation of the robot in a complex environment.
– dtn
Oct 17, 2022 at 19:52

The following will essentially duplicate what you did by hand (although the dataset you provided isn't quite the same dataset shown in your question).

If you need to have the contours more "shrink-wrapped" to the outside border or something completely automatic, then you'll need something else as I tried a few different values for the kernel bandwidth and the contour value.

a = Import["c:\\users\\drjba\\Downloads\\To.mat",
"IndeterminateValues" -> 999999] /. {999999. -> Nothing} /. {} -> Nothing;
skd = SmoothKernelDistribution[a[[1]], {0.25, 0.25}];
Show[ContourPlot[PDF[skd, {x, y}], {x, -6, 4}, {y, -5, 5},
Contours -> {0.0023}, ContourShading -> None], ListPlot[a[[1]]]]


A completely automatic way is to allow the default bandwidth to be selected and then choose the contour that encompasses all points.

skd = SmoothKernelDistribution[a[[1]], "SheatherJones"];
pdf = PDF[skd, {#[[1]], #[[2]]}] & /@ a[[1]];
Show[ContourPlot[PDF[skd, {x, y}], {x, -6, 4}, {y, -5, 5},
Contours -> {Min[pdf]}, ContourShading -> None,
PlotPoints -> 100], ListPlot[a[[1]]]]


• thank you for this answer: very nice :) Oct 20, 2022 at 7:05
• Using the data a as @BobHanlon show in the comment.
• Using RegionDilation to inflate every point.
a = Import["To.mat",
"IndeterminateValues" -> 999999] /. {999999. -> Nothing} /. {} ->
Nothing;
reg = MeshRegion[a[[1]], Point /@ Range@Length@a[[1]]];
dilation = RegionDilation[reg, .3];
Show[Region[RegionBoundary[dilation], BaseStyle -> Red],
Region[reg, BaseStyle -> Blue]]


Using the free cloud account (since I don't have ConcaveHullMesh on v12.2.0-Win7-x64)

pts = RandomPoint[Annulus[{0, 0}, {50, 100}], 100];
{m1=ConcaveHullMesh[pts],m2= DelaunayMesh[pts]};
reg=BoundaryDiscretizeRegion[m1];
Show[reg,Graphics[{Red,MeshPrimitives[reg,1]}],Graphics[{Black,Point@pts}]]


• +1 Very nice! I wonder if the robots need a little buffering around each point? Maybe: n = 20; radius = 1/4; bufferedPts = Flatten[Table[{#[[1]], #[[2]]} + Sqrt[RandomReal[]]* radius*{Cos[\[Theta]], Sin[\[Theta]]}, {\[Theta], 0, 2 \[Pi] (1 - 1/n), 2 \[Pi]/n}] & /@ pts, 1];.
– JimB
Oct 18, 2022 at 1:34

Using fake data since we can't access your actual data:

data = Flatten[Table[{x, y}, {x, -1, 1, .1}, {y, -1, 1, .1}], 1];
data // Short
(* {{-1., -1.}, {-1., -0.9}, <<437>>, {1., 0.9}, {1., 1.}} *)


Now, let's add some z data so we can generate contours:

Raise[{x_, y_}] := If[RegionDistance[Circle[], {x, y}] < .2, {x, y, 1}, {x, y, 0}];
newData = Map[Raise, data, {-2}];
newData // Short
(* {{-1., -1., 0}, {-1., -0.9, 0}, <<437>>, {1., 0.9, 0}, {1., 1., 0}} *)


Now ListContourPlot can do the job:

ListContourPlot[newData, Contours -> 1]


All of this assumes that you can augment your data as needed. It looks like your data is on a grid/lattice, so I assume that this is feasible.

• ibb.co/rv2s23q I tried your code for my data (by the way, if you downloaded it to your computer, try using the file path in the import command via Insert - File Path) and I play with the outline settings. Unfortunately, the results are unsatisfactory (see link to the picture). Although for your "fake" matrix, the result is not bad.
– dtn
Oct 17, 2022 at 19:49

I just learned about ReconstructionMesh. So, taking a similar approach as Syed:

pts = RandomPoint[Annulus[{0, 0}, {50, 100}], 100];
reg = BoundaryDiscretizeRegion[ReconstructionMesh[pts]];
Show[reg, Graphics[{Red, MeshPrimitives[reg, 1]}], Graphics[{Black, Point@pts}]]


• Thank you for your answer! I think it's time to think about switching to a new version of Mathematica for me. Because most of the commands proposed here do not work in the old 12 PC-version. They only work in the cloud version But every way is good!
– dtn
Oct 20, 2022 at 15:45