CrossletというLeafletの地図表示上と、Crossfilterを連動させたJavascriptライブラリを用いて、各都道府県の国籍別に人口データを表示してみました。
ライブラリはLeafletがCloudMadeのAPIを使う仕様のままになっており、
今のLeafletのようにOpen Street Mapを使うようにライブラリの修正が必要ですが、
今回はそのまま利用しました。
github.com
ちなみにこのCrossletのことをRライブラリのrMapsではじめて知りました。
rMapsは、rChartsやSlidifyと同じ方で、Rのビジュアライゼーションの可能性を広げられてます。
データ
D3.jsが流行ってからShapefileからTopojsonを作る解説が巷にいくつもでているので、割愛。
Topojson形式のデータを使用していますが、Geojsonもサポートされているそうです。
Crosslet also supports TopoJSON, a GeoJSON extension that allows to present geometry in a highly compact way.
人口統計データは、e-Statという政府統計データのポータルサイトからダウンロード致しました。項目は「外国人」にある41項目目です。そのままCSVをダウンロードするのではなく、[DB]から都道府県だけにデータをそぎ落としてからCSV形式でダウンロードしました。
その他にもデータにした修正
* 文字コードの修正 (Shift-JISからUTF-8)
* ヘッダーの修正
* 文字列の数字を数値データ
"1234"
みないなデータであれば、pandas.DataFrame.as_type
で変換できますが、"1,234"
とカンマが入っていたために詰まった..。
データ少なかったから手で修正してしまったけど、課題として残しておく。
Crosslet
CSS
LeafletとCrossletのCSSを読み込みます。
<link rel="stylesheet" href="styles/crosslet-min.css" />
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" />
<style>
html{
height: 100%;
}
body{
margin: 0px;
padding: 0px;
height: 100%;
}
#map{
height: 100%;
}
</style>
Javascript
Backboneを採用しているとのこと。ほー。
<script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.2/underscore-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/2.10.0/d3.v2.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.2/backbone-min.js"></script>
<script src="scripts/lib/crosslet.js"></script>
Crossletの描画設定
Crossletは、設定をJson形式で記載してCrossletのインスタンスを生成する際に引数で与えます。
このJsonの中身は以下のようになっています。
var config = {
map : {
(LeafletとオーバーレイさせるGeojsonまたはTopojsonの設定)
},
data : {
(読み込むデータのうち、先に読み込んだGeojsonまたはTopojsonの各地域と結ぶための列名を指定)
},
dimensions : {
(地図と関連させる棒チャートの設定。データの読み込む列やフォーマット、カラースケールを設定)
},
defaults: {
(棒チャートのパネルの表示を設定)
}
};
new crosslet.MapView($("#map"),config);
あとはhtmlのmap
要素に表示されます。
<div id="map"></div>
map
CloudMadeのAPIはもう利用できないので、leaflet
の設定はほっておきます。TopoJsonはgeo
配下で設定しています。
name_field
は表示名として使用されるもので、TopoJsonの中のフィールド名を指定します。id_field
は後ほど読み込むデータと行を一致させるための一意になっているフィールド名Topojsonから選びます。 topo_object
はTopojsonの時に必須の項目で、Topojsonの中から"objects"のすぐ直下のフィールド名を拾います。
map: {
leaflet: {
key: (CloudMade発行のAPI Key,
styleId: 64657,
attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="http://cloudmade.com">CloudMade</a>'
},
view: {
center: [39, 135],
zoom: 6
},
geo: {
url: "data/crosslet/japan.topo.json",
name_field: "name_local",
id_field: "name",
topo_object: "japan"
}
},
data
version
は特につかっていないようなので、データの列名で先ほど設定したid_field
と一致させる列名を指定します。
data: {
version: "1.0",
id_field: "id"
},
dimension
ほぼ同じ設定なので、一例のみ。japanese
とあるフィールド名はこの後のdefaultで指定するので一意に設定します。
title
は各パネルに表示されるタイトル、dataSet
は読み込むデータファイル, field
はそのうちこのパネルで読み込むデータ列の列名, さらに読み込むデータファイルの形式はデフォルトTSVですが、method
でd3.csv
とするとCSV形式を読むことができます。colorscale
には、d3.scale.linear()
を渡してカラースケールを設定することができます。最後のformat
は、別に定義したvar inp = function() { return d3.format(",.0f") };
を渡して、千の位にカンマを入れるフォーマットにしています。またshort
も表示される表示データのフォーマットを指定するものです。
dimensions: {
japanese: {
title: "Japanese population",
data: {
dataSet: "data/crosslet/foreign_census.csv",
field: "日本人",
method: d3.csv,
colorscale: d3.scale.linear().domain([0,5,20]).range(["green","yellow","red"]).interpolate(d3.cie.interpolateLab)
},
format:{
short: inp,
},
},
},
defalt
最後のdefault
は、パネルの並びとアクティブなパネルの設定を設定します。
opacity
はパネルの透過度かとも思ったんですが、変えても変化がない...。
これはソースコード読まないとわからないですね。
defaults: {
opacity: 0.7,
order: ["korean", "chinese", "philipino", "thai", "indonesian", "vietnamese", "english", "american", "brazilian", "peruvian", "others", "japanese"],
active: "korean"
},
表示してみたら、兵庫が消えた\(^o^)/
というか静岡もnull !
原因
Topojsonを見てみたら、Hyōgo
となっているoに長音記号がついてる...。
静岡もname_local
がnullになっていたので修正して、無事表示されました。