Picking data from a list

For the purpose of my question, I cannot use random data. So the data are provided.

data = ReadList["bas_frac.out", Number, RecordLists -> True];
getColor[m_List, i_Integer] := Module[{s = m[[i, 4]]},
Which[s == 0, Cyan, s == 1, Red, s == 2, Blue, s == 3, Orange, s == 4, Darker[Green], True, Black]];
data3 = Table[{PointSize[0.005], getColor[data, i],
Point[{data[[i, 1]], data[[i, 2]]}]}, {i, 1, Length[data]}];
S0 = Graphics[data3]


f0 = GradientFilter[Image[S0], 1]


My question is: how can I extract (in a new list, let's say dataN) the four-column data, corresponding to the non-black points of the above figure? Any suggestions?

• Please share the data through a more reputable service (pastebin maybe). Even just attempting to look at the structure of your data opened a page alleging that I needed to “Download.an update for my flash player”. Also, GradientFilter works on arrays directly: do you need to go back and forth between lists and images? Finally, when you say “white points”, do you mean just pure white, or also any gray level, non-black ones? May 28 '20 at 4:30
• @MarcoB I never had problems with Mediafire. I actually want to extract all the data corresponding to the non-black points. Anu suggestions? May 28 '20 at 8:42

This approach avoids conversion to images. First, let's import the data:

data = ReadList["bas_frac.out", Number, RecordLists -> True];


Then we generate a bivariate interpolation from the data, ignoring the values in the third column of data which do not seem relevant to the problem at hand, and using the fourth column as the response variable. With this interpolation in hand, we can calculate the gradient of this function and take its magnitude, which should be conceptually equivalent to applying the GradientFilter you had used:

if = Interpolation[data[[All, {1, 2, 4}]]];

Norm@D[if[x, y], {{x, y}}];
DensityPlot[
Unitize@%, {x, 10, 15}, {y, 2.3652, 3.927},
PlotPoints -> 75, PlotRangePadding -> 0,
AspectRatio -> Automatic, ColorFunction -> GrayLevel
]


As you can see, the magnitude of the gradient of the interpolating function closely resembles the result you had obtained from GradientFilter.

We can then use the magnitude of the gradient calculated at each point in your original data set data as a selector to pick out those points where the gradient is non-zero:

ClearAll[gradeval]
gradeval[{x0_, y0_}] = Norm[ D[if[x, y], {{x, y}}] /. {x -> x0, y -> y0} ];

results = Select[data, gradeval[ #[[;; 2]] ] > 0 &];

Dimensions[data]         (* Out: {100489, 4} *)
Dimensions[results]      (* Out: { 36427, 4} *)


Here is a small portion of those results for illustration:

results[[1 ;; 100 ;; 10]]

(* Out:
{{10.,     2.3652, 191.05, 1}, {10.1582, 2.3652, 157.14, 4},
{10.3323, 2.3652, 227.99, 3}, {10.4905, 2.3652, 753.49, 1},
{10.6487, 2.3652, 167.62, 4}, {10.807,  2.3652, 216.08, 2},
{10.9652, 2.3652, 315.17, 4}, {11.1234, 2.3652, 189.63, 4},
{11.2975, 2.3652, 365.39, 3}, {11.4557, 2.3652, 319.18, 2}}
*)

• The output is not satisfying. I want to pick all the points which occupy the so-called fractal regions of the plane. Those points are the non-black points of the GradientFilter while the above approach does not produce the same result as it misses all the fine details. May 28 '20 at 16:38
• @Vaggelis_Z How did you figure that it does not work? Which points does my approach miss? Note that the appearance of the result of the DensityPlot depends on the PlotPoints setting, but that setting has no influence on the selection, which simply relies on the value of the gradient. May 28 '20 at 16:41
• Your output contains large white regions while the output of the GradientFilter contains many more points inside these white regions. May 28 '20 at 16:44
• For example, where you provide a small output of results you include the points (10.1582, 2.3652, 157.14, 4) and (10.6487, 2.3652, 167.62, 4). However these points belong to the escape basins and they do not belong to the fractal regions. So they were wrongly classified with your approach. May 28 '20 at 16:47
• @Vaggelis_Z Have you tried adjusting the value within the selector function? Instead of simply a positive gradient magnitude, you may need to increase it to a higher value to reproduce the Gaussian smoothing effect from GradientFilter. May 29 '20 at 15:47