【Leaflet】マップ上にバブルチャートを描画する

はじめに

 バブルチャートとは、円の大きさによってデータの大きさを表すグラフのことです。マップとの親和性も高くて、どこに、何が、どれくらいあるのかを視覚化することができます。

 今回はそんなバブルチャートを、Leaflet を使って作成してみました。

DrawTrail

図1. 東京23区の人口分布

DrawTrail で生成する方法

 当サイトでは、Leaflet のバブルチャートを簡単に生成できるようなフォームをつくっています。

 まず、Excel で A 列に緯度、B 列に経度、C列に円の半径(ピクセル)、D列に円の色(カラーコード)を入力して、バブルチャートのもととなる表を作成します。このとき C 列と D 列が空欄になっていると、円の半径は 5 ピクセル、円の色は赤色(#FF0000)になります。
 表が出来たら、ファイル形式に「CSV (コンマ区切り)」を選択して保存します。
 

図2. 読み込むためのCSVデータを作成する。

 次にトップページを開き、①「CSV読み込み」→ ②「バブルチャートをつくる」と順に選択します。すると別ウインドウが開くので、そこから作成したCSVデータを選択すると、マップ上にバブルチャートが描画されます。

 あとは「エクスポート」→「埋め込みコードを生成」→ 「クリップボードにコピー」と順に選択すれば、サイトやブログへの埋め込みコードが生成されます。
 

図3. 「CSV読み込み」→「バブルチャートをつくる」を選ぶ


 実際にCSVデータ読み込みを使って、日本百名山と日本百名湯の位置を描画してみました。ここで、円の直径は全て5ピクセルとしています。図より、火山帯と温泉地はざっくり一致していることなどが分かって、データを視覚化することの重要性が分かります。

DrawTrail

図4. 日本百名山(赤)と百名湯(黄)

JS / HTML で表示させる方法

 次に、自分で Leaflet を使って表示させる方法について説明します。

 Leaflet でバブルチャートを表示させるには、L.circleMarker がよさそうです。例えば、半径20ピクセル、線幅3ピクセルの円を描く場合は次のように指示します。

L.circleMarker([35.646481	139.653208] /*円の緯度と経度*/, { 
            radius: 20,  /*円の半径*/
            fill: true, /*円の内側に色を塗るかどうか*/
            color: 'red',  /*円の色*/
            weight: 3    /*円の線幅*/
    }).addTo(map);
項目内容
radius円の半径(ピクセル)
weight円の線幅(ピクセル)
color円の色(カラーコード)
opacity線の不透明度(0 で透明, 1 で不透明)
dashArray点線にする。例えば dashArray: [20, 10] とすると、線分の長さが20ピクセル、線分の間隔が10ピクセルの点線になる。)
fill円の中身を塗りつぶすかどうか。fill: true で塗りつぶし、fill:false で塗りつぶさない。
fillColor塗りつぶしたエリアの色(String)
fillOpacity塗りつぶしたエリアの不透明度
表1.circleMarkerのオプション


 全体のソースコードは以下の通りです。

<!DOCTYPE html>
<html>
<head>
<title>htmlMap</title>
<meta http-equiv='content-type' charset='utf-8'>
<meta name='viewport' content='width=device-width'>
</head>
<body>
<div id='mapcontainer' style='width:100%; height:300px; z-index:0;'></div>
<link rel='stylesheet' href='https://unpkg.com/leaflet@1.3.0/dist/leaflet.css' />
<script src='https://unpkg.com/leaflet@1.3.0/dist/leaflet.js'></script>
<script>
function init_map() {

    var map = L.map('mapcontainer',{
            worldCopyJump: true, //一周してもマーカー保持
            maxBounds: [[90, -Infinity], [-90, Infinity]], //北極と南極で範囲制限
        });
    map.setView([35.646481, 139.653208], 6); 
    L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', 
        {attribution: "<a href='http://osm.org/copyright'> ©OpenStreetMap </a>"}).addTo(map);

    //東京を中心に半径20ピクセルのcircleMarkerを追加
    L.circleMarker([35.646481, 139.653208] /*円の緯度と経度*/, { 
            radius: 50,   /*円の半径*/
            fill: true,   /*円の内側に色を塗るかどうか*/
            color: 'red', /*円の色*/
            weight: 3     /*円の線幅*/
        }).addTo(map);
}
    window.addEventListener('DOMContentLoaded', init_map());
</script>
</body>
</html>

実装例



 for ループを使えば circleMarker を沢山描画できるようになるので、マップをバブルチャートにすることができます。
 以下の図は、円の面積がアジア各国の人口に比例するよう、for ループを使って circleMarker を描画した例です。ここで、各円の中心は首都の位置としました。

/*ソースコードの一部*/

var marker_database = [
    /* 緯度, 経度, 円の半径 */
    [35.681, 139.77, 20.07],     /*日本*/
    [39.897, 116.40, 66.51],     /*中国*/
    [37.554, 126.97, 12.81], ... /*韓国*/

/*中略*/

for(var i = 0; i < marker_database.length; i++){
     var marker_information = marker_database[i];
     L.circleMarker([marker_information[0], marker_information[1]], {
     radius: marker_information[2], color: "#FF0000", opacity: 0.7,
     fill: true, fillOpacity: 0.4, weight:1}).addTo(map);
}

DrawTrail

図5. アジア各国の人口分布

 

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です