🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

3046閲覧

Foliumでオリジナルカラーマップのコロプレス図を描きたい

mhtl

総合スコア1

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2021/01/25 07:50

前提・実現したいこと

PythonのFoliumライブラリを使用して、GeoJSONファイルと紐づけたいデータ(pandas DataFrame形式)をもとに、オリジナルのカラーマップでコロプレス図を描きたいと思っています。

下記のサイトを参考にスクリプトを作成しましたが、エラーが発生しました。
https://medium.com/analytics-vidhya/create-and-visualize-choropleth-map-with-folium-269d3fd12fa0

pandas DataFrameで、indexはgeoJSONファイルのfeatures.properties.idに対応したコード番号、列データとしてカラーマップで表現したい値を格納しました。

使用したGeoJSONファイル(japan.geojson(https://github.com/dataofjapan/land))の冒頭部分を以下に示します。

{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "nam": "Kyoto Fu", "nam_ja": "京都府", "id": 26 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 135.036697387695, 35.537334442138686 ],

発生している問題・エラーメッセージ

以下のよなエラーが発生し、コロプレス図が作成されません。

Traceback (most recent call last): File "C:\Users(ユーザー名)\AppData\Local\Programs\Python\Python39\lib\site-packages\pandas\core\indexes\base.py", line 2898, in get_loc return self._engine.get_loc(casted_key) File "pandas\_libs\index.pyx", line 70, in pandas._libs.index.IndexEngine.get_loc File "pandas\_libs\index.pyx", line 101, in pandas._libs.index.IndexEngine.get_loc File "pandas\_libs\hashtable_class_helper.pxi", line 1675, in pandas._libs.hashtable.PyObjectHashTable.get_item File "pandas\_libs\hashtable_class_helper.pxi", line 1683, in pandas._libs.hashtable.PyObjectHashTable.get_item KeyError: 26 The above exception was the direct cause of the following exception: Traceback (most recent call last): File "C:\Users(ユーザー名)\python_proj\quake_map_japan\folium_choropleth\for_teratail.py", line 39, in <module> folium.GeoJson( File "C:\Users(ユーザー名)\AppData\Local\Programs\Python\Python39\lib\site-packages\folium\features.py", line 458, in __init__ self._validate_function(style_function, 'style_function') File "C:\Users(ユーザー名)\AppData\Local\Programs\Python\Python39\lib\site-packages\folium\features.py", line 523, in _validate_function if not callable(func) or not isinstance(func(test_feature), dict): File "C:\Users(ユーザー名)\python_proj\map\folium_choropleth\test.py", line 42, in <lambda> 'fillColor': step(df[feature['properties']['id']]), File "C:\Users(ユーザー名)\AppData\Local\Programs\Python\Python39\lib\site-packages\pandas\core\frame.py", line 2906, in __getitem__ indexer = self.columns.get_loc(key) File "C:\Users(ユーザー名)\AppData\Local\Programs\Python\Python39\lib\site-packages\pandas\core\indexes\base.py", line 2900, in get_loc raise KeyError(key) from err KeyError: 26

該当のソースコード

python

1import folium 2import json 3import pandas as pd 4import branca.colormap as cmp 5 6# DataFrame作成 7data = { 8 'value' : [1, 2, 3, 4, 5, 6, 7, 8] 9} 10idx = [22, 14, 19, 11, 12, 13, 20, 23] 11df = pd.DataFrame(data, index=idx) 12 13# 地図の設定 14japan_location = [37, 137] 15m = folium.Map( 16 location=japan_location, 17 tiles='https://cyberjapandata.gsi.go.jp/xyz/pale/{z}/{x}/{y}.png', 18 attr='Geospatial Information Authority of Japan', 19 zoom_start=5, 20 width=670, 21 height=690, 22 zoom_control=False 23) 24 25# geojsonファイルを開く 26geojson_file = 'japan.geojson' 27with open(geojson_file, encoding="utf-8_sig") as f: 28 japan_geojson = json.load(f) 29 30# カラーマップ作成 31step = cmp.StepColormap( 32 ['yellow', 'green', 'purple'], 33 vmin=1, vmax=10, 34 index=[3, 6, 8, 10], 35 caption='Color Scale for Map' 36) 37 38# コロプレス図を作画 39folium.GeoJson( 40 japan_geojson, 41 style_function=lambda feature: { 42 'fillColor': step(df[feature['properties']['id']]), 43 'color': 'black', 44 'weight': 1, 45 'dashArray': '5, 3' 46 } 47).add_to(m) 48step.add_to(m) 49 50# ファイル保存 51m.save('test.html')

試したこと

indexに26がないのが問題かと思い、geoJSONファイルの冒頭のfeatureのproperties.idを22に書き換えましたが、同様のエラーが発生しました。

geoJSONファイルのidがstr型になっているのかもしれないと思い、

'fillColor': step(df[feature['properties']['id']]),

の部分を下記のように書き換えましたが、同様のエラーが発生しました。

'fillColor': step(df[int(feature['properties']['id'])]),

補足情報

Pythonのバージョン
3.9.0

ライブラリのバージョン
Folium: 0.11.0
pandas: 1.1.5

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

エラーの直接の原因は DataFrame の値を参照する文法が間違っていることです。

python

1'fillColor': step(df[feature['properties']['id']]),

この箇所で feature['properties']['id'] には1から47のいずれかの値が入りますので、たとえばidが26であるfeatureのときは

python

1df[26]

で DataFrame の値を参照しようとしますが、この文法は26という列名の列を取り出す操作ですので、ここではエラーになります。正しくは

python

1df.loc[26, "value"]

もしくは

python

1df.at[26, "value"]

でなければなりません。つまり元のソースコードを修正すると

python

1'fillColor': step(df.at[feature['properties']['id'], 'value']),

となります。

ただしこの修正を行っても、GeoJSONファイルのidの値は1から47であるにも関わらず、それと紐づけたいデータであるはずの DataFrame には 22, 14, 19, 11, 12, 13, 20, 23 のid番号とそれに対応した値しか格納されていませんので、同じ箇所で同様のKeyErrorが発生しエラーになるのは変わりません。

DataFrame の作成部分をたとえば、

python

1data = { 2 'value' : [random.randint(1, 10) for i in range(47)] 3} 4idx = [i for i in range(1, 48)] 5df = pd.DataFrame(data, index=idx)

と変更してみれば、エラーなく動くのが確認できるでしょう。この例の場合は冒頭に

python

1import random

を追記するのも忘れないでください。

投稿2021/01/25 14:39

編集2021/01/25 23:27
etherbeg

総合スコア1195

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mhtl

2021/01/26 10:40

ご助言のとおり修正したところ、エラーは発生せずファイルが作成されました。本当に助かりました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問