charter(JJ1PID)

献血ルーム巡り・旅行・アマチュア無線

cartopyで地図上に駅をプロット

今回は駅を地図上にプロットする

大まかな流れは
1. 駅・路線データをダウンロード
2.cartopyのインストール
3.行政区域のダウンロード
4. 前処理・プロット

basemapでは行政区域の境が表示されないそうなのでcartopyを用いる
.shpファイルの内容をcartopyに渡すことで、行政区域の境を表示させた地図にプロットできる

県境のみの方法は模索中


手順1
駅データをダウンロードする。
駅データ.jpに会員登録すると、全国の駅や路線、事業者データを無料でダウンロードできる。有料版もあるけどこれで大して不足はない
筆者はpytonを動かすディレクトリに置いた
www.ekidata.jp

手順2
cartopyのインストール

$conda install -c scitools cartopy

デフォルトのpythonを消してanacondaのpython一本でやっているのでconda installでOK
そうでない場合はページ下にある参考ブログに方法が書いてある

手順3
国土数値情報ダウンロードサービスから行政区域のデータをインストールする
筆者は../行政区域/全国/ に移動させておいた

手順4
IPythonで対話的に打ちこんだのを抜粋してまとめたのでちょっと見栄え悪い

ソースコード(大部分は
駅の位置情報から路線の経路を推測する | mwSoft
からお借りした)

import pandas as pd
stations = pd.read_csv('station20180330free.csv')
lines = pd.read_csv('line20180424free.csv')

stations = stations[['station_cd','station_name','line_cd','lon','lat']].merge(lines[['line_cd','line_name']])

import cartopy.crs as ccrs
import cartopy.io.shapereader as shpreader
import matplotlib.pyplot as plt

#プロットサイズの指定
from pylab import rcParams
rcParams['figure.figsize'] = 10,10
#日本語フォントの設定
from matplotlib.font_manager import FontProperties
fp = FontProperties(fname='/Library/Fonts/ipaexg.ttf', size=8)

ax = plt.axes(projection=ccrs.PlateCarree())
ax.add_geometries(shapes, ccrs.PlateCarree(), edgecolor='black', facecolor='gray', alpha=0.3)
ax.set_extent([138.9, 140, 35.6, 36.2], ccrs.PlateCarree())

for idx, station in stations[stations.line_name.isin(['東武東上線','東武伊勢崎線'])].iterrows():
    if station.lat<36.2:
        ax.plot(station.lon,station.lat, 'o',color='blue')
        ax.text(station.lon, station.lat, station.station_name,fontproperties=fp)

for idx, station in stations[stations.line_name == '西武新宿線'].iterrows():
    ax.plot(station.lon,station.lat, 'o',color='yellow')
    ax.text(station.lon, station.lat, station.station_name,fontproperties=fp)

for idx, station in stations[stations.line_name.isin(['西武池袋線', '西武秩父線'])].iterrows():
    ax.plot(station.lon,station.lat, 'x',color='yellow')
    ax.text(station.lon, station.lat, station.station_name,fontproperties=fp)

for idx, station in stations[stations.line_name == '秩父鉄道秩父本線'].iterrows():
    ax.plot(station.lon,station.lat, 'o',color='#e41a1c')
    ax.text(station.lon, station.lat, station.station_name,fontproperties=fp)

for idx, station in stations[stations.line_name.isin(['JR高崎線','JR川越線','JR埼京線', 'JR八高線(八王子~高麗川)', 'JR八高線(高麗川~高崎)','JR中央本線(東京~塩尻)'])].iterrows():
    if station.lat <= 36.2 and station.lon >= 138.9:
        ax.plot(station.lon,station.lat, 'o',color='green')
        ax.text(station.lon, station.lat, station.station_name,fontproperties=fp)

結果

f:id:monhime:20180717190655p:plain
都心から秩父鉄道まで在来線・私鉄で行くルートで考えられる路線をプロットした

駅名も表示してるから見にくいかな
今回はそこまでこだわりはないのでこれぐらいにしておく

余談
これでpythonの記事は2つめになるけど、参考書模写より自分で何か作りながら勉強したほうがずっと効率が良いと感じる
今後も一日で作れるくらいのものを作ってブログに載せていこうと思う

参考
basemapやcartopyで地図上でplot | mwSoft