D3.js v4/v5 密度推定 contourDensity – 使い方
D3での密度推定の使い方を紹介します。データの個数密度を計算してコンター図を作成することができます。サンプルは黒いプロットが元データで、コンター図は個数密度を推定した結果です。
サンプルデモ
サンプルプログラム
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>D3 Dencity Countour</title> <script src="https://d3js.org/d3.v5.min.js"></script> <!-- <script src="https://d3js.org/d3.v4.min.js"></script> --> <!-- <script src="https://d3js.org/d3-contour.v1.min.js"></script> --> </head> <body> <script> // 1. データの準備 var width = 600; // グラフの幅 var height = 400; // グラフの高さ var n = 500; //データ数 var values = new Array(n); for(var i = 0; i < n; ++i) { values[i] = { "x": d3.randomNormal(width / 2, width / 7)(), "y": d3.randomNormal(height / 2, height / 7)() }; } // 2. SVG領域の設定 var svg = d3.select("body").append("svg").attr("width", width).attr("height", height); // 3. スケールの設定 var x = d3.scaleLinear() .domain([0, width]) .rangeRound([0, width]); var y = d3.scaleLinear() .domain([height, 0]) .rangeRound([height, 0]); // 4. 密度推定の計算 var contourDensity = d3.contourDensity() .x(function(d) { return x(d.x); }) .y(function(d) { return y(d.y); }) .size([width, height]) .bandwidth(50) var contourDensityValues = contourDensity(values); // 5. カラースケールの設定 var color = d3.scaleSequential(function(t) { return d3.hsl(t * 230, 1, 0.5) + "" }) .domain([d3.max(contourDensityValues, function(d) { return d.value }), 0.00]); // 6. コンターの設定 svg.insert("g") .attr("stroke", "white") .attr("stroke-width", "0.5") .selectAll("path") .data(contourDensityValues) .enter() .append("path") .attr("fill", function(d) { return color(d.value); }) .attr("d", d3.geoPath()); // 7. プロットの設定 svg.append("g") .selectAll("circle") .data(values) .enter().append("circle") .attr("cx", function(d) { return x(d.x); }) .attr("cy", function(d) { return y(d.y); }) .attr("r", 2); </script> </body> </html> |
解説
d3.contourDensityはv5で追加されたメソッドです。v4ではHTMLのヘッダーに下記を記載して呼び出すことで使うことができます。
1 |
<script src="https://d3js.org/d3-contour.v1.min.js"></script> |
1. データの準備
密度推定用のデータを準備します。
1 2 3 4 5 6 7 8 |
var n = 500; //データ数 var values = new Array(n); for(var i = 0; i < n; ++i) { values[i] = { "x": d3.randomNormal(width / 2, width / 7)(), "y": d3.randomNormal(height / 2, height / 7)() }; } |
d3.randomNormal(a,b)()は、a:平均値、b:標準偏差としてガウス分布に従う乱数を算出するメソッドです。
4. 密度推定の計算
準備したデータから密度推定します。
1 2 3 4 5 6 7 |
var contourDensity = d3.contourDensity() .x(function(d) { return x(d.x); }) .y(function(d) { return y(d.y); }) .size([width, height]) .bandwidth(50) var contourDensityValues = contourDensity(values); |
d3.contourDensity()は密度推定用の関数を設定するもので、次の設定が可能です。
contourDensity .x | データのx座標を指定します。デフォルトは function x(d) { return d[0]; } です。 |
contourDensity .y | データのy座標を指定します。デフォルトは function y(d) { return d[1]; } です。 |
contourDensity .size | データの領域サイズを設定します。[width, height]の配列で設定します。デフォルトは[960, 500]です。 |
contourDensity .cellSize | 密度を計算するセルのサイズを設定します。デフォルトは4です。設定値が2の累乗となるように調整されます。 |
contourDensity .thresholds | コンター図のしきい値を設定します。[x0, x1, …]のような一次元配列で設定します。デフォルトでは等間隔に20分割されたしきい値が設定されます。 |
contourDensity .bandwidth | 密度推定に用いるGaussianカーネルのバンド幅を設定します。デフォルトは20.4939です。値が大きいほど滑らかな分布になります。 |
5. カラースケールの設定
コンター図の色分け用のカラースケールをD3のメソッドを使って設定します。
1 2 |
var color = d3.scaleSequential(function(t) { return d3.hsl(t * 230, 1, 0.5) + "" }) .domain([d3.max(contourDensityValues, function(d) { return d.value }), 0.00]); |
d3.scaleSequential(function(t){}).domain([,])は、domainで設定した範囲を0.0~1.0に線形変換して内部の関数に渡し、内部の関数の返り値を出力する関数をcolorに設定します。d3.hslは、HSL色空間のRGB値を算出してくれるものです。d3.hslの一つ目の変数が角度に相当するものですが、0~230度に設定するとサンプルのような色使いになります。カラースケールの作り方についてはこちらを参照ください。
6. コンターの設定
コンター図用のSVG要素を設定します。
1 2 3 4 5 6 7 8 9 |
svg.insert("g") .attr("stroke", "white") .attr("stroke-width", "0.5") .selectAll("path") .data(contourDensityValues) .enter() .append("path") .attr("fill", function(d) { return color(d.value); }) .attr("d", d3.geoPath()); |
dataメソッドの引数に算出した密度推定の値を入れます。また、"d"属性にはd3.geoPathメソッドを使ってコンター用のパスを作成します。
7. プロットの設定
データの確認用に散布図のプロットを作成します。
1 2 3 4 5 6 7 |
svg.append("g") .selectAll("circle") .data(values) .enter().append("circle") .attr("cx", function(d) { return x(d.x); }) .attr("cy", function(d) { return y(d.y); }) .attr("r", 2); |
まとめ
大量データの散布図を作成するときに重宝します。プロット点が多すぎて分布が不明なときにお試しください。