コンピューターシステム株式会社

技術BLOG

Pythonで日本地図に色を塗ってみた

2021/07/30 東京担当

こんにちは。東京本社のK.Mです。

Pythonには日本地図を描画できる「japanmap」という便利なモジュールがあることを知りました。そこで今回は「japanmap」を使って日本地図に色を塗ってみようと思います。

■前準備

まずは、pipでrequests・japanmap・pandas・matplotlibをインストールします。

PS C:\> pip install requests

PS C:\> pip install japanmap

PS C:\> pip install pandas

PS C:\> pip install matplotlib

では、まずは日本地図の画像を生成させましょう。

■日本の地図の画像ファイルを生成する

日本の地図のグラフィックの生成にはjapanmapモジュールのpicture関数を使用します。

また、japanmapを描くために、グラフ生成モジュールのmatplotlibを使用します。

日本地図はmatplotlib.plt.imshow関数で生成できます。引数にはjapanmapモジュールのpicture関数を指定し、

これを地図のグラフィックとして描画します。

生成した地図は、matplotlib.plt.savefig関数で名前を付けて保存できます。引数には生成する地図のファイル名を指定します。

地図のサイズ変更には matplotlib のプロパティを含む辞書オブジェクトrcParamsのfigure.figsizeを設定します。

import matplotlib.pyplot as plt

from japanmap import picture

from pylab import rcParams


rcParams['figure.figsize'] = (8, 8)

plt.imshow(picture())

plt.savefig('japanmap.png')

■日本地図に色を塗る

都道府県に色を塗るには、都道府県名をキーとした辞書データを作成し、

色、またはRGBを指定します。

色を指定した辞書データをpicture関数の引数とすることで地図に色を塗ることが可能となります。

import matplotlib.pyplot as plt

from japanmap import picture

from pylab import rcParams


rcParams['figure.figsize'] = (20, 20)

data = {

  '北海道':(255, 0, 0),

  '東京':(0, 255, 0),

  '愛知':(0, 0, 255),

  '大阪':'Yellow',

  '愛媛':'Purple',

  '香川':(255,255, 0)

}


plt.imshow(picture(data))

plt.savefig('japan_colormap.png')

■新型コロナ感染者数のJSONデータを取得する

今回は、公開されている新型コロナウイルスの感染者情報を利用します。

参考https://www.stopcovid19.jp/data/covid19japan.json

指定のアドレスにアクセスしてデータを取り出すにはPythonのrequestモジュールのget関数を使用します。

引数にURLを文字列として指定することでJSONデータの取得が可能です。

取得したデータをPythonオブジェクトとして取得するにはjson関数を使用します。

これはJSONデータを辞書オブジェクトに変換して返してくれます。

取得したデータはpandasモジュールのDataFrameクラスを使用して処理します。

pandasはデータ解析を効率的に扱うために開発されたPythonのライブラリの1つで、DataFrameクラスは2次元リストを扱うことができるクラスです。

取得した辞書オブジェクトの'area'キーには各都道府県の各種感染情報が保管されています。これをDataFrameの引数とすることで各種感染情報を一覧として表示できます。

print関数でDataFrameのデータ一覧を出力させることができます。

import requests

from pandas import DataFrame


url = 'https://www.stopcovid19.jp/data/covid19japan.json'


coviddata = requests.get(url).json()

df = DataFrame(coviddata['area'])

print(df)

         name name_jp  npatients  ncurrentpatients  nexits  ndeaths  nheavycurrentpatients  nunknowns  ninspections ISO3155-2
0    Hokkaido     北海道      41935               620   39901     1413                     11          1        806134     JP-01
1      Aomori     青森県       2548                27    2490       31                      0          0         52952     JP-02
2       Iwate     岩手県       1812               109    1656       47                      1          0         89480     JP-03
3      Miyagi     宮城県       9362               173    9079       91                      3         19        163484     JP-04
4       Akita     秋田県        944                39     885       20                      1          0         16377     JP-05
5    Yamagata     山形県       2070                45    1978       47                      1          0         68214     JP-06
6   Fukushima     福島県       5108               171    4776      161                      4          0        292436     JP-07
7     Ibaraki     茨城県      10893               268   10459      166                      5          0         34027     JP-08
8     Tochigi     栃木県       7280               170    7028       82                     10          0        313280     JP-09
9       Gunma     群馬県       8100                55    7891      154                      3          0        201211     JP-10
10    Saitama     埼玉県      48217              1588   45790      839                     26          0       1008436     JP-11
11      Chiba     千葉県      42338              1412   40208      718                     16          0        725365     JP-12
12      Tokyo     東京都     182970              6366  174346     2258                     58          0       2631654     JP-13
13   Kanagawa   神奈川県      70904              2494   67446      964                     38          0       1085652     JP-14
14    Niigata     新潟県       3497                76    3367       54                      0          0        179294     JP-15
15     Toyama     富山県       2066                26    2002       38                      1          0         76995     JP-16
16   Ishikawa     石川県       4061               116    3826      115                      1          4        126868     JP-17
17      Fukui     福井県       1399                93    1271       35                      1          0         73448     JP-18
18  Yamanashi     山梨県       2171                56    2094       21                      0          0         62325     JP-19
19     Nagano     長野県       5065                33    5015       94                      0         77        214429     JP-20
20       Gifu     岐阜県       9512                65    9260      187                      4          0        279896     JP-21
21   Shizuoka     静岡県       9660               318    9189      153                      5          0        424082     JP-22
22      Aichi     愛知県      51665               657   50024      984                     16          0        864872     JP-23
23        Mie     三重県       5359                92    5293      113                      3        139        148938     JP-24
24      Shiga     滋賀県       5640                78    5472       90                      2          0        158985     JP-25
25      Kyoto     京都府      16850               189   16396      247                      4         18        292903     JP-26
26      Osaka     大阪府     105179              1633  100044     2696                    115        806       2268681     JP-27
27      Hyogo     兵庫県      41306               326   39670     1310                     15          0        525436     JP-28
28       Nara     奈良県       8497               138    8227      132                      4          0        176518     JP-29
29   Wakayama   和歌山県       2715                19    2589       49                      0         58         42600     JP-30
30    Tottori     鳥取県        496                21     465        2                      0          8         86537     JP-31
31    Shimane     島根県        562                 8     552        2                      0          0         32023     JP-32
32    Okayama     岡山県       7628                22    7455      127                      1         24        168599     JP-33
33  Hiroshima     広島県      11592                69   11336      176                      5         11        565969     JP-34
34  Yamaguchi     山口県       3177                32    3065       80                      1          0        124469     JP-35
35  Tokushima     徳島県       1668                11    1593       63                      0          1         67021     JP-36
36     Kagawa     香川県       2120                25    2069       31                      1          5         88883     JP-37
37      Ehime     愛媛県       2761                 8    2678       75                      2          0         98783     JP-38
38      Kochi     高知県       1904                63    1814       27                      3          0         58679     JP-39
39    Fukuoka     福岡県      36024               432   35017      526                      9         49        862359     JP-40
40       Saga     佐賀県       2572                12    2573       24                      0         37         59257     JP-41
41   Nagasaki     長崎県       3232                31    3132       69                      0          0        129130     JP-42
42   Kumamoto     熊本県       6501                24    6358      119                      1          0         82540     JP-43
43       Oita     大分県       3506                19    3423       64                      0          0        175343     JP-44
44   Miyazaki     宮崎県       3114                16    3060       27                      0         11         44801     JP-45
45  Kagoshima   鹿児島県       3742                48    3692       39                      1         37        114003     JP-46
46    Okinawa     沖縄県      21442               580   20662      206                     40          6        260989     JP-47 

※データは2021年7月16日のものです

■新型コロナウイルス感染者数に応じて日本地図に色を塗る

前述した内容を踏まえて、japanmapで各都道府県に感染者数に応じた色を塗っていきます。

色を塗るために都道府県名をキーとしてRGBを値とする辞書データを作成します。

取得した各都道府県のデータの中に、都道府県名は'name_jp'キー、感染者数は'npatients'キーのデータがあるのでfor文を使用してこれを順に取得します。

RGB値は、「感染者数/最大感染者数」として、最大感染者数を持つ都道府県と比べどのくらい感染者数がいるのかを計算します。

最大感染者数はmax関数で取得できます。

「感染者数/最大感染者数」の計算結果にRGBの最大値となっている255をかけることでRGBの値(0~255の値)として取得できます。

算出した値を255から引いたものを計算し、(255, n, n)の形として指定することで、RGBの緑と青の値を設定します。以下に設定例を示します。

----------------------------------------------------------------------------------------------------------

【例】

東京:感染者数:60

大阪:感染者数:30人

愛知:感染者数:5人

->最大感染者数:東京:60

東京:

60人/最大数(60人)*255 = 255

RGBの緑と青の値:255 - 255 = 0

->RGB(255, 0, 0) -> 濃い赤色

大阪:

30人/最大数(60人)*255 = 127

RGBの緑と青の値:255 - 127 = 128

->RGB(255, 128, 128) -> 少し濃い赤色

愛知:

5人/最大数(60人)*255 = 21

RGBの緑と青の値:255 - 21 = 234

->RGB(255, 234, 234) -> 薄い赤色

----------------------------------------------------------------------------------------------------------

つまり、RGBの緑と青の値の値が低いほど(「感染者数/最大感染者数」の値が1に近いほど)濃い色が塗られます。

そして、作成した辞書データをpicture関数の引数として指定することで色を塗ることができます。

ただし、東京は人口が多いため感染者数も多く、東京以外の都道府県が全く塗られないといったことになりかねません。

実際に以下のプログラムを実行してみます。

import requests

import matplotlib.pyplot as plt

from japanmap import picture

from pandas import DataFrame

from pylab import rcParams


url = 'https://www.stopcovid19.jp/data/covid19japan.json'


coviddata = requests.get(url).json()

df = DataFrame(coviddata['area'])


max = df['npatients'].max()

covidpatients = {}

for item in coviddata['area']:

  n = 255 -item['npatients'] / max * 255

  covidpatients[item['name_jp']] = (255, n, n)


rcParams['figure.figsize'] = (8,8)

plt.imshow(picture(covidpatients))

plt.savefig('covid19_japanmap.png')

そこで、値の調整を行い、見栄えを調整します。RGBの最大値255の2倍の値510を使用して計算します。

その値を255から引くと東京の半分の値がゼロとなるようにします。

以下に例を示します。

【例】

東京:感染者数:60

愛知:感染者数:5人

->最大感染者数:東京:60

------------------------------------------------------------------------------------------------------------------------------------------------------

①【調整前】RGB値の緑と青の値は255から「感染者数/最大感染者数 *255」を引いて設定。

東京:

60/最大数(60)*255 = 255

RGBの緑と青:255 - 255 = 0

->東京都に設定するRGB:(255, 0, 0) ->濃い赤色

愛知:

5/最大数(60)*255 = 21.25

RGBの緑と青:255 - 21.25 = 233.75

->愛知県に設定するRGB:(255, 233.75, 233.75) ->薄い赤色

------------------------------------------------------------------------------------------------------------------------------------------------------

②【調整後】より濃く塗られてみえるようにするため、

 RGB値の緑と青の値は255からRGB値を2倍した「感染者数/最大感染者数 *510」を引いて設定

東京:

60/最大数(60)*510 = 510

RGBの緑と青:255 - 510 = -255

->東京都に設定するRGB:(255, -255, -255)

 ->RGB値は0より下の値を指定した場合は0が設定されます。したがって、(255, 0, 0)->濃い赤色

愛知:

5/最大数(60)*510 = 42.5

RGBの緑と青:255 - 42.5 = 212.5

->愛知県に設定するRGB:(255, 212.5, 212.5) ->調整前より少しだけ濃い赤色

------------------------------------------------------------------------------------------------------------------------------------------------------

この調整を行うことで、東京以外の都道府県が全く塗られないといった状態を避けることができます。

上記内容を取り込んだプログラム、及び実行結果は以下の通りです。

import requests

import matplotlib.pyplot as plt

from japanmap import picture

from pandas import DataFrame

from pylab import rcParams

url = 'https://www.stopcovid19.jp/data/covid19japan.json'

coviddata = requests.get(url).json()

df = DataFrame(coviddata['area'])


max = df['npatients'].max()

covidpatients = {}

for item in coviddata['area']:

  n = 255 -item['npatients'] / max * 510

  covidpatients[item['name_jp']] = (255, n, n)


rcParams['figure.figsize'] = (8,8)

plt.imshow(picture(covidpatients))

plt.savefig('covid19_japanmap.png')

■使ってみた感想

日本地図の表示を数ステップで実行できるので便利だと感じました。色を塗るのも辞書オブジェクトを作るだけなのでお手軽です。

これから日本地図を利用するプログラムを作成することがあれば、japanmapモジュールを利用していこうと思います。