We are going to demonstrate polygon plotting in this example with the help of folium
import geopandas as gpd
import folium
import matplotlib.pyplot as plt
We make use of nybb dataset
path = gpd.datasets.get_path('nybb')
df = gpd.read_file(path)
df.head()
BoroCode | BoroName | Shape_Leng | Shape_Area | geometry | |
---|---|---|---|---|---|
0 | 5 | Staten Island | 330470.010332 | 1.623820e+09 | (POLYGON ((970217.0223999023 145643.3322143555... |
1 | 4 | Queens | 896344.047763 | 3.045213e+09 | (POLYGON ((1029606.076599121 156073.8142089844... |
2 | 3 | Brooklyn | 741080.523166 | 1.937479e+09 | (POLYGON ((1021176.479003906 151374.7969970703... |
3 | 1 | Manhattan | 359299.096471 | 6.364715e+08 | (POLYGON ((981219.0557861328 188655.3157958984... |
4 | 2 | Bronx | 464392.991824 | 1.186925e+09 | (POLYGON ((1012821.805786133 229228.2645874023... |
Plot from the original dataset
df.plot(figsize=(6, 6))
plt.show()
One thing to notice is that the values of the geometry do not directly represent the values of latitude of longitude in geographic coordinate system
print(df.crs)
{'init': 'epsg:2263'}
As folium(i.e. leaflet.js) by default takes input of values of latitude and longitude, we need to project the geometry first
df = df.to_crs(epsg=4326)
print(df.crs)
df.head()
{'init': 'epsg:4326', 'no_defs': True}
BoroCode | BoroName | Shape_Leng | Shape_Area | geometry | |
---|---|---|---|---|---|
0 | 5 | Staten Island | 330470.010332 | 1.623820e+09 | (POLYGON ((-74.05050806403247 40.5664220341607... |
1 | 4 | Queens | 896344.047763 | 3.045213e+09 | (POLYGON ((-73.83668274106707 40.5949466970158... |
2 | 3 | Brooklyn | 741080.523166 | 1.937479e+09 | (POLYGON ((-73.86706149472118 40.5820879767934... |
3 | 1 | Manhattan | 359299.096471 | 6.364715e+08 | (POLYGON ((-74.01092841268031 40.6844914725429... |
4 | 2 | Bronx | 464392.991824 | 1.186925e+09 | (POLYGON ((-73.89680883223774 40.7958084451597... |
df.plot(figsize=(6, 6))
plt.show()
Initialize folium map object
m = folium.Map(location=[40.70, -73.94], zoom_start=10, tiles='CartoDB positron')
m
Overlay the boundaries of boroughs on map with borough name as popup
for _, r in df.iterrows():
#without simplifying the representation of each borough, the map might not be displayed
#sim_geo = gpd.GeoSeries(r['geometry'])
sim_geo = gpd.GeoSeries(r['geometry']).simplify(tolerance=0.001)
geo_j = sim_geo.to_json()
geo_j = folium.GeoJson(data=geo_j,
style_function=lambda x: {'fillColor': 'orange'})
folium.Popup(r['BoroName']).add_to(geo_j)
geo_j.add_to(m)
m
Add marker showing the area and length of each borough
df['lat'] = df.centroid.y
df['lon'] = df.centroid.x
df.head()
BoroCode | BoroName | Shape_Leng | Shape_Area | geometry | lat | lon | |
---|---|---|---|---|---|---|---|
0 | 5 | Staten Island | 330470.010332 | 1.623820e+09 | (POLYGON ((-74.05050806403247 40.5664220341607... | 40.580858 | -74.153369 |
1 | 4 | Queens | 896344.047763 | 3.045213e+09 | (POLYGON ((-73.83668274106707 40.5949466970158... | 40.707604 | -73.818485 |
2 | 3 | Brooklyn | 741080.523166 | 1.937479e+09 | (POLYGON ((-73.86706149472118 40.5820879767934... | 40.644734 | -73.947677 |
3 | 1 | Manhattan | 359299.096471 | 6.364715e+08 | (POLYGON ((-74.01092841268031 40.6844914725429... | 40.777276 | -73.967159 |
4 | 2 | Bronx | 464392.991824 | 1.186925e+09 | (POLYGON ((-73.89680883223774 40.7958084451597... | 40.852627 | -73.866524 |
for _, r in df.iterrows():
folium.Marker(location=[r['lat'], r['lon']], popup='length: {} <br> area: {}'.format(r['Shape_Leng'], r['Shape_Area'])).add_to(m)
m