D3:散点图中人口最多的区域

时间:2014-10-04 15:13:52

标签: d3.js scatter-plot

我用D3做了散点图。如何识别绘图中人口最多的区域并用椭圆环绕它们。例如,图表右上角有2个人口稠密点。有功能吗?如果不是,我欣赏2件事的建议:识别,包围或以任何方式标记它们。

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

2 个答案:

答案 0 :(得分: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面板的底部,抱歉。

答案 1 :(得分:3)

如果您只想要一个可视化表示,并且您不需要计算位置或中心或类似的东西,那么解决方案可能非常简单。除了表示数据点的现有圆圈外,还要使每个数据点绘制一个半透明的较大圆圈。如果这些较大的圆圈重叠,则交叉点将变得更暗,并且越重叠越暗(它假设您将背景保持为白色)。您可以选择圆圈的大小,颜色和不透明度/透明度。