ほぼコピペですが、みます。
https://www.kaggle.com/code/alexisbcook/interactive-maps
導入
このチュートリアルでは、foliumパッケージを使用してインタラクティブな地図を作成する方法を学びます。その過程で、新しいスキルを活用してボストンの犯罪データを可視化します。
import pandas as pd
import geopandas as gpd
import math
import folium
from folium import Choropleth, Circle, Marker
from folium.plugins import HeatMap, MarkerCluster
最初のインタラクティブ地図
folium.Map()を使用して、比較的シンプルな地図を作成します。
# Create a map
m_1 = folium.Map(location=[42.32,-71.0589], tiles='openstreetmap', zoom_start=10)
Display the map
m_1
いくつかの引数を使用して、地図の外観をカスタマイズできます:
- `location`:地図の初期中心を設定します。ここではボストン市の緯度(42.32°北)と経度(-71.0589°東)を使用しています。
- `tiles`:地図のスタイリングを変更します。この場合、OpenStreetMapスタイルを選択しています。興味がある場合、他のオプションはこちらでリストされています。
- `zoom_start`:地図の初期のズームレベルを設定します。高い値は地図をより詳細にズームインします。
今すぐ、ズームイン、ズームアウト、または地図を異なる方向にドラッグして探索してみてください。
データ
次に、地図にいくつかの犯罪データを追加します!
データの読み込みステップに焦点を当てません。代わりに、既にデータをpandas DataFrameで持っていると想像してください。データの最初の5行は以下に示されています。
# Load the data
crimes = pd.read_csv("../input/geospatial-learn-course-data/crimes-in-boston/crimes-in-boston/crime.csv", encoding='latin-1')
Drop rows with missing locations
crimes.dropna(subset=['Lat', 'Long', 'DISTRICT'], inplace=True)
Focus on major crimes in 2018
crimes = crimes[crimes.OFFENSE_CODE_GROUP.isin([
'Larceny', 'Auto Theft', 'Robbery', 'Larceny From Motor Vehicle', 'Residential Burglary',
'Simple Assault', 'Harassment', 'Ballistics', 'Aggravated Assault', 'Other Burglary',
'Arson', 'Commercial Burglary', 'HOME INVASION', 'Homicide', 'Criminal Harassment',
'Manslaughter'])]
crimes = crimes[crimes.YEAR>=2018]
Print the first five rows of the table
crimes.head()
点のプロット
地図に表示する必要があるデータの量を減らすために、(一時的に)昼間の強盗に焦点を当てます。
daytime_robberies = crimes[((crimes.OFFENSE_CODE_GROUP == 'Robbery') & \
(crimes.HOUR.isin(range(9,18))))]
folium.Marker
folium.Marker()を使用して地図にマーカーを追加します。以下の各マーカーは異なる強盗に対応しています。
# Create a map
m_2 = folium.Map(location=[42.32,-71.0589], tiles='cartodbpositron', zoom_start=13)
Add points to the map
for idx, row in daytime_robberies.iterrows():
Marker([row['Lat'], row['Long']]).add_to(m_2)
Display the map
m_2
folium.plugins.MarkerCluster
多くのマーカーを追加する場合、folium.plugins.MarkerCluster()を使用すると、地図を整理するのに役立ちます。各マーカーはMarkerClusterオブジェクトに追加されます。
# Create the map
m_3 = folium.Map(location=[42.32,-71.0589], tiles='cartodbpositron', zoom_start=13)
Add points to the map
mc = MarkerCluster()
for idx, row in daytime_robberies.iterrows():
if not math.isnan(row['Long']) and not math.isnan(row['Lat']):
mc.add_child(Marker([row['Lat'], row['Long']]))
m_3.add_child(mc)
Display the map
m_3
バブルマップ
バブルマップは、マーカーの代わりに円を使用します。各円のサイズと色を変えることで、位置と他の2つの変数との関係も示すことができます。
folium.Circle()を使用して、バブルを繰り返し追加することでバブルマップを作成します。以下のコードセルでは、9時から12時に発生した強盗が緑でプロットされ、13時から17時に発生した強盗が赤でプロットされています。
# Create a base map
m_4 = folium.Map(location=[42.32,-71.0589], tiles='cartodbpositron', zoom_start=13)
def color_producer(val):
if val <= 12:
return 'forestgreen'
else:
return 'darkred'
Add a bubble map to the base map
for i in range(0,len(daytime_robberies)):
Circle(
location=[daytime_robberies.iloc[i]['Lat'], daytime_robberies.iloc[i]['Long']],
radius=20,
color=color_producer(daytime_robberies.iloc[i]['HOUR'])).add_to(m_4)
Display the map
m_4
folium.Circle()はいくつかの引数を受け取ります:
- `location`:緯度と経度で円の中心を含むリストです。
- `radius`:円の半径を設定します。
- 伝統的なバブルマップでは、各円の半径が異なることが許容されています。これを実装するには、各円の色を変えるために使用されるcolor_producer()関数に類似した関数を定義することができます。
- `color`:各円の色を設定します。
- hourの影響を強調するためにcolor_producer()関数が使用されています。
ヒートマップを作成するには、folium.plugins.HeatMap()を使用します。これにより、都市の異なる地域での犯罪の密度が表示され、赤い地域ほど犯罪事件が比較的多いことを示します。
大都市には期待されるように、犯罪の大部分は中心部近くで発生しています。
# Create a base map
m_5 = folium.Map(location=[42.32,-71.0589], tiles='cartodbpositron', zoom_start=12)
Add a heatmap to the base map
HeatMap(data=crimes[['Lat', 'Long']], radius=10).add_to(m_5)
Display the map
m_5
上記のコードセルでわかるように、folium.plugins.HeatMap()はいくつかの引数を受け取ります:
- `data`:プロットしたい場所を含むDataFrameです。
- `radius`:ヒートマップの滑らかさを制御します。値を高くすると、ヒートマップがより滑らかに見えます(つまり、ギャップが少なくなります)。
コロプレスマップ
犯罪が警察管区ごとにどのように異なるかを理解するために、コロプレスマップを作成します。
最初のステップとして、各管区に異なる行が割り当てられ、"geometry"列に地理的境界が含まれるGeoDataFrameを作成します。
# GeoDataFrame with geographical boundaries of Boston police districts
districts_full = gpd.read_file('../input/geospatial-learn-course-data/Police_Districts/Police_Districts/Police_Districts.shp')
districts = districts_full[["DISTRICT", "geometry"]].set_index("DISTRICT")
districts.head()
また、各管区の犯罪件数を示すPandas Seriesである`plot_dict`も作成します。
# Number of crimes in each police district
plot_dict = crimes.DISTRICT.value_counts()
plot_dict.head()
Out[11]:
D4 2885
B2 2231
A1 2130
C11 1899
B3 1421
Name: DISTRICT, dtype: int64
`plot_dict`が`districts`と同じインデックスを持っていることが非常に重要です。これにより、コードは地理的境界を適切な色と一致させる方法を把握します。
folium.Choropleth()クラスを使用することで、コロプレスマップを作成できます。もし下の地図が表示されない場合は、異なるウェブブラウザでページを表示してみてください。
# Create a base map
m_6 = folium.Map(location=[42.32,-71.0589], tiles='cartodbpositron', zoom_start=12)
Add a choropleth map to the base map
Choropleth(geo_data=districts.__geo_interface__,
data=plot_dict,
key_on="feature.id",
fill_color='YlGnBu',
legend_name='Major criminal incidents (Jan-Aug 2018)'
).add_to(m_6)
Display the map
m_6
folium.Choropleth()はいくつかの引数を受け取ります:
- `geo_data`:各地理的領域の境界を含むGeoJSON FeatureCollectionです。
上記のコードでは、districts GeoDataFrameを__geo_interface__属性を使用してGeoJSON FeatureCollectionに変換しています。
- `data`:各地理的領域を色分けするために使用される値を含むPandas Seriesです。
- `key_on`:常に`feature.id`に設定されます。
これは、geo_dataに使用されるGeoDataFrameと、dataで提供されるPandas Seriesが同じインデックスを持っていることを指します。詳細を理解するには、GeoJSON Feature Collectionの構造を詳しく調べる必要があります("features"キーに対応する値がリストであり、各エントリは"id"キーを含む辞書です)。
- `fill_color`:色のスケールを設定します。
- `legend_name`:地図の右上隅にある凡例にラベルを付けます。