# Clustering of peaks in 2D spectra

I'm having some problems clustering data in a 2D spectra and will really appreciate some help. I've been playing around with the FindClusters function but wasn't able to tune it appropriately. Maybe someone can give me a hand on how to customize the DistanceFunction option or so.

A sample of my data looks like this:

Ideally I would want the peaks to be clustered as this:

I tried the FindClusters functions with different parameters but only got partial clusters like these:

I believe it may be easy if I can define my own DistanceFunction but I don't understand how to use a custom function there with a threshold or so.

I've seen other posts like this one, this other one and this one too but I wasn't able to successfully apply those methods.

It doesn't matter if I don't get that red circle clustering like the ideal image. If I can just get to identify the whole clusters, I can reduce that set to just one point that would be the center of gravity.

It would be awesome if you can point me the way on how to solve this. You can download that sample from here.

Just one thing, I don't know before hand how many clusters I'll get. I believe there are 30 in this dataset but this is just a sample. Thank you!!

• I will give you two links to read First and Second Sep 1, 2013 at 2:02
• Those were the first things I read but couldn't understand how a custom DistanceFunction works Sep 1, 2013 at 2:27
• Well, you need to make up your mind how do you want to partition the set of data/measurements. You need to define a metric and based on that proceed with implementing the DistanceFunction[]. Long story - short - on what similar characteristic do you plan to partition the set of data ? Sep 1, 2013 at 2:41
• OK, let's say I use the default EuclideanDistance function, how do I know what is the threshold it's using to discriminate? Like "points with distance < 0.5 between them are considered a cluster"? My guess is that, if the DistanceFunction f satisfies f(ei,ej)>0, I would have to make a function that, for distances greater than 0.5 => f(ei,ej)<0. In that sense, f will no longer fulfill the condition and those points will be left outside the cluster. Makes sense? Thanx! Sep 1, 2013 at 2:55
• To answer the question what threshold is used in the algorithms you should read this general method Link Sep 1, 2013 at 3:25

Inspired by Murta answer I have this one:

Get["https://dl.dropboxusercontent.com/u/81954930/datapairs.m"];
Manipulate[
With[{list =
Join @@ (Split[
SortBy[#, Last], (Abs[(#1[[2]] - #2[[2]])] < limY) &] & /@
Gather[datapairs, Abs[(#1[[1]] - #2[[1]])] < limX &])},
Column[{ListPlot[list, ImageSize -> 400],
Row[{"Number of clusters:", Length[list]}]}]]
, {{limY, 5}, 0, 50}, {{limX, 5}, 0, 50}]


I split first by column and then by the other axis.

This can be a first step.

Get["https://dl.dropboxusercontent.com/u/81954930/datapairs.m"]
Manipulate[
dataC = Mean /@ Gather[datapairs, EuclideanDistance[#1, #2] < lim &];
p1 = ListPlot[datapairs];
p2 = ListPlot[dataC, PlotStyle -> Directive[Opacity[0.5], PointSize[0.02], Red]];
Show[p2, p1]
, {lim, 5, 50, 10}
]