Python AI 画像

cartorpyで東京都・23区を描く。犯罪件数を地図上に描画する。

Cartopyは、イギリス気象局(MetOffice)によりオープンソースライブラリScitoolsの一部として開発されている地図描画用のPythonライブラリです。
conda install cartopyでインストールできます。
国土地理院数値情報(シェープファイル)を事前にダウンロードしてください http://nlftp.mlit.go.jp/ksj/

In [1]:
# ライブラリインポート

import numpy as np
import pandas as pd

import matplotlib.pyplot as plt
import matplotlib.ticker as tick

import cartopy.crs as ccrs
import cartopy.io.shapereader as shpreader
import cartopy.feature as cfeature
from cartopy.mpl.ticker import LatitudeFormatter, LongitudeFormatter
In [2]:
# 東京都全域を表示
fname = 'N03-190101_13_GML/N03-19_13_190101.shp' # 国土地理院数値情報 http://nlftp.mlit.go.jp/ksj/ tokyo 事前にダウンロードしてください
shapes = list(shpreader.Reader(fname).geometries())

plt.figure(figsize = (12, 8))
ax = plt.axes(projection = ccrs.PlateCarree())
ax.add_geometries(shapes, ccrs.PlateCarree(), edgecolor='black', facecolor='gray', alpha=0.3)
ax.set_extent([138.8, 140, 35.4, 36.0], ccrs.PlateCarree())
plt.title('Tokyo', fontsize=15)
plt.show()
In [3]:
# 東京23区表示 (gadm市町村データを用いて)

fname2 = 'gadm36_JPN_shp/gadm36_JPN_2.shp' #市町村境 https://gadm.org/download_country_v3.html  事前にダウンロードしてください
adm2_shapes = list(shpreader.Reader(fname2).geometries())

plt.figure(figsize = (12, 8))
ax = plt.axes(projection = ccrs.PlateCarree())
ax.add_geometries(adm2_shapes, ccrs.PlateCarree(), edgecolor='black', facecolor='gray', alpha=0.3)
ax.set_extent([139.54, 139.93, 35.52, 35.84], ccrs.PlateCarree())
plt.title('prefectural_bound2', fontsize=15)
plt.show()
In [4]:
# tokyo 23 wards
#codes:names
wards = {13101:'千代田区', 13102:'中央区', 13103:'港区', 13104:'新宿区', 13105:'文京区', 
         13106:'台東区', 13107:'墨田区', 13108:'江東区', 13109:'品川区', 13110:'目黒区', 
         13111:'大田区', 13112:'世田谷区', 13113:'渋谷区', 13114:'中野区', 13115:'杉並区',
         13116:'豊島区', 13117:'北区', 13118:'荒川区', 13119:'板橋区', 13120:'練馬区', 
         13121:'足立区', 13122:'葛飾区', 13123:'江戸川区'}

#longitudes
lons = [139.74, 139.77, 139.73, 139.70, 139.74, 
        139.77, 139.80, 139.81, 139.72, 139.69, 
        139.70, 139.62, 139.68, 139.65, 139.62, 
        139.71, 139.72, 139.78, 139.68, 139.61, 
        139.79, 139.83, 139.87]
        
#latitudes
lats = [35.68, 35.67, 35.65, 35.70, 35.71, 
        35.71, 35.70, 35.67, 35.61, 35.63, 
        35.57, 35.63, 35.67, 35.71, 35.69, 
        35.73, 35.76, 35.73, 35.75, 35.75, 
        35.78, 35.74, 35.70]
In [5]:
# 東京23区表示
# 国土地理院数値情報 http://nlftp.mlit.go.jp/ksj/ 都市地域データ tokyo wards# は事前にダウンロードしてください
plt.figure(figsize = (12, 8))

ax = plt.axes(projection = ccrs.PlateCarree())

i = 0
for v, k in wards.items(): # v:13101 to 13123, k 千代田区 to 江戸川区
    fname = 'A09-18_13_GML/shp_file/' + str(v) + '_' + k + '.shp'# 国土地理院数値情報 http://nlftp.mlit.go.jp/ksj/ 都市地域データ tokyo wards
    shape = list(shpreader.Reader(fname).geometries()) 
    ax.add_geometries(shape, ccrs.PlateCarree(), edgecolor='black', facecolor='gray', alpha=0.3)

    ax.text(lons[i], lats[i], k, horizontalalignment='left', transform=ccrs.Geodetic(), fontname="MS Gothic") # 日本語フォント
    i+=1 

ax.set_extent([139.54, 139.93, 35.52, 35.84], ccrs.PlateCarree())
plt.title('東京23区', fontsize=15, fontname="MS Gothic")
plt.show()
In [6]:
# 犯罪件数で色分けする

# Read csv file 読み込むCSVファイルを指定してください(犯罪件数を事前に作成してください 本データは2018年度データ)
# https://www.keishicho.metro.tokyo.jp/about_mpd/jokyo_tokei/jokyo/ninchikensu.html

COLUMNS = ('区名', '総合計') # 使うものだけを読み込む

df = pd.read_csv("23wards_crime.csv", sep = ",", encoding = 'Shift-jis', usecols = COLUMNS) # Exelで作成したファイルは、Shift-jis

# ward = [] # 区名
# total = [] # 犯罪総合計
# violent = [] # 凶悪犯罪
# burglar = [] # 空き巣
# bycycle = [] # 自転車盗難
# veihcle = [] # 車上荒らし

# カラム名変更
df = df.rename(columns = 
                     {'区名': 'ward',
                     '総合計': 'total',
                     })
df.tail()
Out[6]:
ward total
18 板橋区 4211
19 練馬区 4535
20 足立区 5230
21 葛飾区 3654
22 江戸川区 5431
In [7]:
# df.dtypes # データ型確認 int64
df['total'] = pd.Series(df['total'], dtype=np.float64) # int to float
# df.dtypes # データ型確認 float64
max = df['total'].max()
min = df['total'].min()
print('max:', max, 'min:', min)
max: 6416.0 min: 1261.0
In [8]:
df['total'] = (df['total'] - min) / (max - min) * 256. # カラーマップ256色で正規化
df['total'] = pd.Series(df['total'], dtype=np.int64) # float to int
df
Out[8]:
ward total
0 千代田区 96
1 中央区 50
2 港区 127
3 新宿区 256
4 文京区 0
5 台東区 93
6 墨田区 67
7 江東区 126
8 品川区 66
9 目黒区 30
10 大田区 202
11 世田谷区 237
12 渋谷区 207
13 中野区 64
14 杉並区 113
15 豊島区 159
16 北区 76
17 荒川区 12
18 板橋区 146
19 練馬区 162
20 足立区 197
21 葛飾区 118
22 江戸川区 207
In [27]:
# 東京23区犯罪件数カラーマップ表示

# 国土地理院数値情報 http://nlftp.mlit.go.jp/ksj/ 都市地域データ tokyo wards# は事前にダウンロードしてください

plt.figure(figsize = (12, 8))

#cmap = plt.cm.jet
cmap = plt.cm.inferno_r
#cmap = plt.cm.Greys
#cmap = plt.cm.Reds

ax = plt.axes(projection = ccrs.PlateCarree())

i = 0
for v, k in wards.items(): # v:13101 to 13123, k 千代田区 to 江戸川区
    fname = 'A09-18_13_GML/shp_file/' + str(v) + '_' + k + '.shp'# 国土地理院数値情報 http://nlftp.mlit.go.jp/ksj/ 都市地域データ tokyo wards
    shape = list(shpreader.Reader(fname).geometries()) 

    c = df.loc[i:i, ['total']].values[0][0] # 最初の[0]で配列にし、次の[0]で値に変換(カラーマップに変換)
    
    im = ax.add_geometries(shape, ccrs.PlateCarree(), edgecolor='black', facecolor=cmap(c), alpha=1.0)
    # 区名表示、日本語フォントは matplotlib 3.1.0 以降だと表示できる
    ax.text(lons[i], lats[i], k, horizontalalignment='left', transform=ccrs.Geodetic(), fontname="MS Gothic", color="aqua") 
    i+=1 

ax.set_extent([139.54, 139.93, 35.52, 35.84], ccrs.PlateCarree())
plt.title('東京23区 犯罪総合計', fontsize=15, fontname="MS Gothic")

# カラーバー表示
gradient = np.linspace(0, 1, 256)
gradient = np.vstack((gradient, gradient))
img = ax.imshow(gradient, aspect='auto', cmap=cmap, vmax= max, vmin=min, alpha=1.0)
#plt.colorbar(img, ticks=np.linspace(min, max, 5))
plt.colorbar(img, fraction=0.04)
plt.show()
In [ ]: