GIG

赴くままに技術を。

LeafletとCrossletを組み合わせたCrossLetで日本の人口統計データを表示する

CrossletというLeafletの地図表示上と、Crossfilterを連動させたJavascriptライブラリを用いて、各都道府県の国籍別に人口データを表示してみました。

ライブラリはLeafletがCloudMadeのAPIを使う仕様のままになっており、 今のLeafletのようにOpen Street Mapを使うようにライブラリの修正が必要ですが、 今回はそのまま利用しました。

github.com

ちなみにこのCrossletのことをRライブラリのrMapsではじめて知りました。 rMapsは、rChartsやSlidifyと同じ方で、Rのビジュアライゼーションの可能性を広げられてます。

データ

  • 日本topojsonデータ

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 &copy; <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ですが、methodd3.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 !

f:id:hermesian:20150329200753p:plain

原因

Topojsonを見てみたら、Hyōgoとなっているoに長音記号がついてる...。 静岡もname_localがnullになっていたので修正して、無事表示されました。

f:id:hermesian:20150329200807p:plain