2014-10-04 15 views
3

我用D3做了散點圖。我如何識別劇情中人口最多的地區,並用橢圓包圍它們。例如,在波紋管圖的右上角有2個人口稠密的點。有沒有一個功能可以做到這一點?如果不是,我對兩件事的建議感激:識別,包圍或以任何方式標記它們。D3:散點圖中人口最多的區域

Scater plot http://tetet.net/clusterLab/scatter.png

var width = 300, 
    height = 200; 

var x = d3.scale.linear().range([0, width]), 
    y = d3.scale.linear().range([height, 0]); 

var svg = d3.select("body") 
    .append("svg") 
    .attr("width", width) 
    .attr("height", height); 

d3.tsv("data.tsv", function(error, data) { 
    if (error) console.warn(error); 
    x.domain(d3.extent(data, function(q) {return q.xCoord;})); 
    y.domain(d3.extent(data, function(q) {return q.yCoord;})); 

    svg.selectAll("circle") 
     .data(data) 
     .enter().append("circle") 
      .attr("r", 5) 
      .attr("cx", function(d) { return x(d.xCoord); }) 
      .attr("cy", function(d) { return y(d.yCoord); }) 
}); 

數據

xCoord yCoord 
0 0 
5 3 
2 1 
4 7 
7 4 
5 2 
9 9 
3 4 
1 6 
5 4 
8.1 6.2 
8.4 6.6 
8 6 
8 7 
7 8 
6.8 8.3 
6.4 8.4 
6.2 8.3 
+0

一個簡單的思考橢圓的方法,如果每個簇中沒有多個點:遍歷一個簇中的所有點對以找到彼此距離最遠的一對點。在這兩點之間的直線上構造一個具有焦點的橢圓的公式,例如,使用[這些答案](http://math.stackexchange.com/questions/426150/what-is-the-general-equation-of-the-ellipse-that-is-not-in-the-origin-and-旋轉)。調整參數,使橢圓包括集羣中的所有點,但不能變窄(從包含兩個點的圓大到足夠大)。 – Mars 2014-10-04 17:02:07

回答

3

a number of clustering algorithms在那裏。我將以OPTICS algorithm(我真的是隨機挑選它)爲例來舉例說明,並用一種​​方法來標記每個羣集具有唯一顏色的點。

請注意,我正在使用npm上的density-clustering軟件包。

一旦加載和分析數據(但在此之前,我們在屏幕上繪製的任何東西),讓我們設置的算法:

var optics = new OPTICS(), 

    // The algorithm requires a dataset of arrays of points, 
    // so we need to create a modified copy of our original data: 
    opticsData = data.map(function (d) { 
     return [d.xCoord, d.yCoord]; 
    }), 

    // Algorithm configuration: 
    epsilon = 2, // min distance between points to be considered a cluster 
    minPts = 2, // min number of points in a cluster 

    // Now compute the clusters: 
    clusters = optics.run(opticsData, epsilon, minPts); 

現在我們可以與集羣所屬的信息標誌着我們的原始數據點至。一個很粗的解決方案...你可能想到的東西更優雅:

clusters.forEach(function (cluster, clusterIndex) { 
    cluster.forEach(function (index) { 
     // data is our original dataset: 
     data[index].cluster = clusterIndex; 
    }); 
}); 

現在讓我們創建一個非常簡單的色標,並把它應用到我們的觀點:

var colorScale = d3.scale.category20(); 

// Some code omitted for brevity: 
...enter().append("circle") 
    ... 
    .style('fill', function (d) { 
     return colorScale(d.cluster); 
    }); 

你可以看看demo。我必須按原樣包含庫,因此您需要滾動到JavaScript面板的底部,對不起。

3

如果您只需要一個可視化表示,並且不需要計算位置或中心或類似的東西,那麼解決方案可能非常簡單。除了代表數據點的現有圓圈之外,還要讓每個數據點繪製一個半透明的大圓。如果這些較大的圓圈重疊,交叉點將會變暗,並且越重疊越深,它將會得到(假設您保持背景爲白色)。你可以非常大小的圓圈,它們的顏色和不透明度/透明度。