【问题标题】:Convex hull / concave hull for multiple clusters in data数据中多个集群的凸包/凹包
【发布时间】:2014-04-04 21:36:10
【问题描述】:

我已经阅读了大量关于在集群周围绘制多边形的文章,并意识到 convhull 可能是最好的前进方式。基本上,我正在寻找一个类似弹性的多边形来环绕我的聚类点。

我的数据是由 x(第 1 列)和 y(第 2 列)点组成的矩阵,这些点按簇(第 3 列)分组。我有 700 个这样的集群,因此单独绘制每个集群是不可行的。

有没有办法分别为每个集群执行 convhull,然后将它们中的每一个绘制在一个图表上。

编辑

到目前为止,我编写的代码无法在每个单独的集群上运行凸包...

    [ndata, text, alldata] =  xlsread(fullfile(source_dir));

       [~, y] = sort(ndata(:,end));
       As = ndata(y,:);

       lon = As(:,1); 
       lat = As(:,2);
       cluster = As(:,3);

       %% To find number of points in a cluster (repetitions)
   rep = zeros(size(cluster));

   for j = 1:length(cluster)
       rep(j) = sum(cluster==cluster(j));
   end

   %% Less than 3 points in a cluster are filtered out

   x = lon (rep>3);
   y = lat (rep>3);
   z = cluster (rep>3);

   %% convex hull for each cluster plotted ....hold....then display all.

   figure
   hold on

   clusters = unique(z);

       for i = 1:length(z)

          k=convhull(x(z==clusters(i)), y(z==clusters(i)));

          plot(x, y, 'b.'); %# plot cluster points
          plot(x(k),y(k),'r-'); %# plots only k indices, giving the convex hull


      end

下面是正在显示的图像;

如果这个问题已经被问过,我很抱歉重复,但请引导我找到你认为合适的答案。

请任何人都可以帮助解决这个问题,但我真的很挣扎!

【问题讨论】:

  • 如果将数据分成 700 组数据点(每个集群一组),似乎应该很简单。为每个集群运行凸包算法,然后绘制结果包。
  • @Nuclearman 绝对是,但我对 matlab 不是很好,无法实现它。我已经编写了一些代码,但它为整个数据集而不是组实现了凸包。不知道如何分别为每个集群实现它。编辑我的问题以添加我现在拥有的代码。
  • 我想我应该预料到问题是缺乏熟悉。那是一个问题,因为我也不熟悉matlab(因此是评论而不是回答)。但是,您应该能够通过按集群对数据进行排序以按集群对数据进行分组。然后使用 for 循环遍历每个数据点并将其添加到该集群中的点列表中,直到集群发生变化。发生这种情况时,构建并绘制前一个集群列表的凸包,并创建一个新列表,其中当前点作为下一个集群列表的开始。只要确保你绘制了最后一个集群。
  • 恭喜。 您即将编写您的第一个重要程序!它可以使用 for 循环 来实现!所以开始吧!
  • 嘿@Anony-Mousse 我知道这不是一个复杂的问题,只是我无法实现它。如果您可以查看代码并提出解决方案,我将不胜感激。谢谢

标签: matlab polygon cluster-analysis convex-hull


【解决方案1】:

我将遍历所有集群并执行您已经编写的操作,并使用hold on 选项将所有图累积在同一个图中。像这样的:

% Generate three clouds of points in 2D:
c1 = bsxfun(@plus, 0.5 * randn(50,2), [1 3]);
c2 = bsxfun(@plus, 0.6 * randn(20,2), [0 0]);
c3 = bsxfun(@plus, 0.4 * randn(20,2), [1 1]);

data = [c1, ones(50,1); ...
        c2, 2*ones(20,1); ...
        c3, 3*ones(20,1)];

% Plot the data points with different colors

clf
plot(c1(:,1), c1(:,2),'r+', 'LineWidth', 2);
hold on
plot(c2(:,1), c2(:,2),'k+', 'LineWidth', 2);
plot(c3(:,1), c3(:,2),'b+', 'LineWidth', 2);

x = data(:,1);
y = data(:,2);
cluster = data(:,3);

clusters = unique(cluster);

for i = 1:length(clusters)
    px = x(cluster == clusters(i));
    py = y(cluster == clusters(i));
    if length(px) > 2
        k = convhull(px, py);
        plot(px(k), py(k), '-');
    end
end

它给出以下结果:

【讨论】:

  • 非常感谢您,我理解该脚本背后的逻辑,但是当我使用我的数据运行它时,我得到一个错误???使用 ==> convhull 时出错 计算凸包时出错。指定的唯一点数不足。 ==> cluster_polygon 在 21 k=convhull(x(cluster==clusters(i)), y(cluster==clusters(i))) 处出错;
  • 是的,它接缝你至少需要 3 个不同的点,但这可以通过放置一个 if 并检查 length(cluster==clusters(i)) > 2 来解决,如果不是,那么做其他事情(比如不绘制凸包或只绘制由两点定义的线..)
  • 感谢您的编辑,正如您建议的那样,我已经删除了那些少于 3 分的集群。但是代码仍然没有达到我的预期。我在当前显示的问题中添加了一张图片。你能帮忙吗?非常感谢。
  • 非常感谢!!!它奏效了,你真的非常非常非常有帮助!真的非常感谢你。祝你有美好的一天!! :)
猜你喜欢
  • 2019-07-28
  • 2015-03-21
  • 2017-05-01
  • 2012-09-10
  • 1970-01-01
  • 2013-10-09
  • 2018-05-08
  • 2013-07-11
  • 1970-01-01
相关资源
最近更新 更多