Public parks in San Francisco¶
This notebook attempts to locate all the public parks in San Francisco. One of my goals in 2025 is to visit every park in the city.
I figure it'd be too difficult to rigorously do this from google maps on my phone, so I reached for openstreetmaps and the associated ecosystem. It did not disappoint!
This notebook was used to gather the data for https://parks.dxuuu.xyz/.
import osmnx
import folium
tags = {
'leisure': 'park',
# Could also include: 'garden', 'nature_reserve' depending on your needs
}
sf_boundary = osmnx.geocode_to_gdf("San Francisco, California")
parks = osmnx.features_from_polygon(
sf_boundary.geometry.iloc[0],
tags=tags
)
parks
geometry | ele | gnis:feature_id | leisure | name | wikidata | wikipedia | historic | opening_hours | smoking | ... | leaf_type | acres | communication:amateur_radio:pota | name:pt | tourism | fee | location | type | disused:landuse | source:operator | ||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
element | id | |||||||||||||||||||||
node | 358767175 | POINT (-122.49088 37.72237) | 16 | 224922 | park | Harding Park | Q49497924 | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
358803650 | POINT (-122.40303 37.79687) | 7 | 1655668 | park | Jackson Square Historic District | Q49506269 | NaN | district | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
358803668 | POINT (-122.49942 37.72549) | 8 | 1655678 | park | Lake Merced Sports Center | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
358803681 | POINT (-122.41367 37.72248) | 55 | 1655685 | park | Louis Sutter Playground | Q49519583 | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
358803706 | POINT (-122.37692 37.72965) | 56 | 1655701 | park | Milton Myer Recreation Center | Q49526782 | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
way | 1286999777 | POLYGON ((-122.39559 37.79113, -122.3952 37.79... | NaN | NaN | park | Urban Park | NaN | NaN | NaN | Mo-Fr 08:00-20:00 | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
1293746220 | POLYGON ((-122.47178 37.75073, -122.47106 37.7... | NaN | NaN | park | Mandalay Lane Park | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
1293746848 | POLYGON ((-122.48591 37.75188, -122.4818 37.75... | NaN | NaN | park | Sunset Reservoir Park | NaN | NaN | NaN | 24/7 | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
1300623937 | POLYGON ((-122.44574 37.75953, -122.44508 37.7... | NaN | NaN | park | Al's Park | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
1329130170 | POLYGON ((-122.38623 37.7696, -122.38616 37.76... | NaN | NaN | park | Bayfront Park | NaN | NaN | NaN | sunrise-sunset | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
340 rows × 98 columns
park_names = parks['name'].tolist()
park_names
['Harding Park', 'Jackson Square Historic District', 'Lake Merced Sports Center', 'Louis Sutter Playground', 'Milton Myer Recreation Center', 'Rolph-Nicol Playground', 'Farallon Islands State Game Refuge', 'Bush Street-Cottage Row Historic District', 'Russian Hill-Vallejo Street Crest Historic District', 'Ulrich Field', 'Benedetti Diamond', 'Fairy Circle', 'Secret Garden', 'Annie St Plaza', 'Maritime Plaza', 'Lands End', 'China Beach', "Saint Mary's Park", 'Presidio of San Francisco', 'Lincoln Park', 'Salesforce Park', 'Brotherhood-Head Mini Park', 'Sue Bierman Park', 'Mount Davidson Park', 'Buena Vista Park', 'McCoppin Square', 'Panhandle', 'Alta Plaza Park', 'Lafayette Park', 'Bernal Heights Park', 'Holly Park', 'Marina Green', 'Washington Square Park', 'South Beach Park', 'Jackson Park', 'Mission Dolores Park', 'Rolph Playground', 'Precita Park', 'Sydney G. Walton Square', 'South Park', 'Garfield Square', 'Potrero Del Sol Park', 'Franklin Square', 'McKinley Square', 'Balboa Park', 'Duboce Park', 'Moscone Recreation Center', 'Kid Power Park', 'Union Square', "Levi's Plaza", 'Tank Hill', 'Grattan Playground', 'Embarcadero Plaza', 'Warm Water Cove Park', 'Esprit Park', 'Mission Creek Park', 'Minnesota Grove', 'China Basin Park', 'Juri Commons', "Patricia's Green", 'India Basin Shoreline Park', "Heron's Head Park", 'Tulare Park', 'John McLaren Park', "Saint Mary's Square", 'Yerba Buena Gardens', 'The Crossing at East Cut', 'Silver Terrace Playground', nan, 'Music Concourse', 'Aquatic Park Historic District', 'Marini Plaza', 'Rincon Park', nan, 'Huntington Park', 'Boeddeker Park', nan, 'Kite Hill Open Space', 'Willie "Woo Woo" Wong Park', 'Sergeant John Macaulay Park', 'Joe DiMaggio Playground', 'Glen Canyon Park', 'Cottage Row Mini Park', 'Baker & Broderick Mini Park', 'Turk-Hyde Mini Park', 'Sunset Tunnel Park', 'Excelsior Playground', 'Palega Recreation Center', 'Candlestick Point State Recreation Area', nan, 'Victoria Manalo Draves Park', 'Marietta Green Space', 'Aptos Playground', 'Terrace Green Park', nan, 'Mission Bay Commons', 'Rochambeau Playground', 'Mission Creek Park', 'Allyne Park', 'Cayuga Park', '10th Avenue & Clement Mini Park', 'Parque Niños Unidos', '24th & York Mini Park', 'Adam Rodgers Park', 'Alice Chalmers Playground', 'Little Marina Green', 'Alioto Mini Park', 'Angelo Rossi Park', 'Helen Wills Park', nan, 'Broadway Tunnel West Mini Park', 'Fort Mason', 'Bayview Playground', 'Crocker Amazon Playground', 'Bayview Hill Park', nan, 'Koret Quad', 'Edgehill Mountain Open Space', 'Douglass Playground', 'Dorothy W. Erskine Park', 'Noe Valley Courts', 'Duncan-Castro Open Space', 'Fulton Playground', 'Richmond Playground', 'Richmond Recreation Center', 'George Christopher Playground', '29th & Diamond Open Space', 'Walter Haas Playground', 'Billy Goat Hill', nan, 'Topaz Open Space', nan, 'Fairmount Open Space', 'Argonne Playground', 'Sunset Playground', 'West Portal Playground', 'West Sunset Playground', 'Fallen Bridge Park', 'Youngblood-Coleman Playground', 'Presidio Tunnel Tops', nan, 'George Sterling Park', 'Presidio Heights Playground', 'Laurel Hill Playground', 'Sigmund Stern Recreation Grove', 'Pine Lake Park', 'Parkside Square', 'Robert Pender Park', 'Kelloch-Velasco Park', 'Rolph Nicol Jr Playground', 'Michelangelo Playground', 'Ina Coolbrith Park', 'Noe & Beaver Mini Park Community Garden', 'Potrero Hill Recreation Center', 'Golden Gate Heights Park', 'Islais Landing', 'Page & Laguna Mini Park', 'Seward Mini Park', 'Mission Playground', 'Rooftop Park', 'Koshland Park', 'Community Park', nan, 'Golden Gate Park', 'Sutro Heights Park', 'Fay Park', nan, 'Woh Hei Yuen Recreation Center', 'Muriel Leff Mini Park', 'Cabrillo Playground', 'Merced Heights Playground', 'Ocean View Park', 'Langton Community Garden', 'Jane Warner Plaza', 'San Jose/Guerrero Park', 'Naples Green', 'Naples Green', 'Brooks Park', 'Cayuga & Lamartine mini park', 'Brannan Street Wharf', 'Pier 94 Wetlands', 'Little Hollywood Park', 'Sunnyside Conservatory', nan, 'Pink Triangle Memorial', 'Baden-Joost Mini Park', 'Coso Square', 'Pioneer Park', 'Corona Heights Park', 'Harvey Milk Plaza', 'Sunnyside Playground', 'India Basin Open Space', 'The Parks at 5M', 'Noe Valley Town Square', 'Agua Vista Park', 'Coleridge Mini Park', 'Coleridge Park', 'Argonne Community Garden', 'Empire Park', 'Midtown Terrace Park and Sutro Recreation Center', 'Transamerica Redwood Park', 'Woods Yard Park', 'Hippie Hill', 'Green Hairstreak Corridor - Quintara Steps', 'Green Hairstreak Corridor - 14th Avenue & Pacheco', 'Green Hairstreak Corridor - 12th and Pacheco', 'Green Hairstreak Corridor - Aerial Steps (access point)', 'Green Hairstreak Corridor - Aloha & Lomita', 'Green Hairstreak Corridor - Mount Steps (access point)', 'Civic Center Plaza', 'Rocky Outcrop', 'Starr King Open Space', 'McCoppin Hub', 'Palou Community Garden', 'Palou Phelps Mini Park', 'Mariposa Park', 'J.P. Murphy Playground', 'Benches Park', 'Mission Bay Kids Park', 'Bernal Recreation Center', 'Progress Park', nan, "Greenie's Conservation Corner", 'Randolph & Bright Mini Park', 'Lessing & Sears Mini Park', 'Yik Oi Huang Peace and Friendship Park', 'Visitacion Valley Greenway', 'Hayes Valley Playground', 'Lakeview and Ashton Mini Park', nan, 'La Playa Park', nan, 'Mountain Lake Park', 'Miraloma Playground', 'Grand View Park', 'Larsen Park', nan, 'Lake Merced Park', nan, 'Emerald Park', 'Hilltop Park', 'Mansell Parkway', 'Shoreview Park', nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, 'In Chan Kaajal Park', 'Tara Street Park', 'Athens Avalon Greens Terace', '50 Beale Street Plaza', 'Bayview Gateway', 'Parklab', 'Jack Early Park', nan, 'Mission Valencia Plaza', 'Mullen & Peralta Mini Park', 'Bosworth Street Open Space', "Adah's Stairway Garden", nan, 'Tunnel Top Park', 'Daggett Park', nan, 'Fillmore & Turk Mini Park', 'Raymond Kimbell Playground', nan, 'Japan Town Peace Plaza', 'Golden Gate & Steiner Mini Park', 'Mary Ellen Pleasant Memorial Park', nan, 'Coleman Bluff', 'Redwood Grove', nan, 'Mission Creek Park', "Tenderloin Children's Playground", 'Rossi Playground Edward St Annex', 'UCSF Mission Bay Park', 'Waterfront Plaza', 'La Playa Park', 'Margaret S. Hayward Playground', 'Jefferson Square', 'Eureka Valley Recreation Center', 'Gilman Playground', nan, 'Alcatraz Island', 'Prentiss Mini-Park', nan, 'Alamo Square', 'Dogpatch Arts Plaza', 'Francisco Park', nan, nan, 'Frank Cresci Plaza', 'Molinari Mana Park', '15th Avenue Steps', 'Crane Cove Park', 'Hunters Point Community Youth Park', nan, nan, nan, 'PG&E Plaza', nan, nan, nan, nan, 'War Memorial Court', nan, nan, 'Deepistan National Parklet', nan, nan, 'Treat Plaza', 'Yosemite Slough', 'The Parks at 5M', 'Grandview Open Space', nan, 'Pier 29 Public Shore', 'The Commons', nan, 'moscone dog play area', 'Buckeye Grove', 'Panorama Park', 'Clipper Cove Beach', 'Rincon Place', 'Ecker Square', 'Urban Alchemy Oasis', 'Urban Park', 'Mandalay Lane Park', 'Sunset Reservoir Park', "Al's Park", 'Bayfront Park']
Define thumbnail helper¶
This helper generates a park map thumbnail given a row in parks dataset.
We'll use it to
def generate_park_map(row, zoom=15):
# Map to longitude and latitude
longitude = row.geometry.centroid.x
latitude = row.geometry.centroid.y
# Create figure with an appropriate aspect ratio
m = folium.Map(
location=[latitude, longitude],
zoom_start=zoom,
tiles='OpenStreetMap',
)
folium.Marker(
[latitude, longitude],
popup=folium.Popup(row['name'], max_width=300, auto_open=True)
).add_to(m)
return m
generate_park_map(parks.iloc[0])
Investigate NaN name parks¶
Now that we know the data is reasonable, let's look at anomalies. There's a few parks with NaN for name, so let's see if they're valid parks.
no_name_parks = parks.query('name.isna()')
no_name_parks
geometry | ele | gnis:feature_id | leisure | name | wikidata | wikipedia | historic | opening_hours | smoking | ... | leaf_type | acres | communication:amateur_radio:pota | name:pt | tourism | fee | location | type | disused:landuse | source:operator | ||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
element | id | |||||||||||||||||||||
way | 30029902 | POLYGON ((-122.41934 37.80672, -122.41897 37.8... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
32862942 | POLYGON ((-122.39404 37.79096, -122.394 37.790... | NaN | NaN | park | NaN | NaN | NaN | NaN | Mo-Fr 08:00-20:00 | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
33883156 | POLYGON ((-122.41934 37.79765, -122.41932 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | 05:00-24:00 | no | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
41373180 | POLYGON ((-122.46506 37.73889, -122.46472 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
48537425 | POLYGON ((-122.47418 37.72429, -122.47418 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
69422745 | POLYGON ((-122.44674 37.80187, -122.44723 37.8... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
84812337 | POLYGON ((-122.38706 37.77128, -122.3867 37.77... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
85891398 | POLYGON ((-122.43321 37.74195, -122.43334 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
85930055 | POLYGON ((-122.46371 37.75846, -122.46318 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
91913157 | POLYGON ((-122.40898 37.80847, -122.40896 37.8... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
157018893 | POLYGON ((-122.44365 37.7608, -122.44354 37.76... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
161843752 | POLYGON ((-122.4358 37.8066, -122.43559 37.806... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
219036273 | POLYGON ((-122.44008 37.76212, -122.44007 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
382113061 | POLYGON ((-122.44536 37.76337, -122.4454 37.76... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
399402796 | POLYGON ((-122.47126 37.77316, -122.47141 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
401354282 | POLYGON ((-122.47284 37.78631, -122.47314 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
404847042 | POLYGON ((-122.49831 37.7315, -122.49831 37.73... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
407324072 | POLYGON ((-122.41913 37.77138, -122.41912 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
414135696 | POLYGON ((-122.49368 37.73306, -122.49356 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
414135697 | POLYGON ((-122.49437 37.73479, -122.49433 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
414135698 | POLYGON ((-122.49321 37.73205, -122.49356 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
414135699 | POLYGON ((-122.49398 37.73304, -122.49396 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
414135700 | POLYGON ((-122.49348 37.73413, -122.49352 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
414135702 | POLYGON ((-122.4934 37.72975, -122.49337 37.72... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
414135703 | POLYGON ((-122.49428 37.732, -122.49423 37.731... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
414135705 | POLYGON ((-122.49393 37.74235, -122.49549 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
414135706 | POLYGON ((-122.49425 37.74037, -122.49413 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
414135707 | POLYGON ((-122.49453 37.74213, -122.49499 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
414135708 | POLYGON ((-122.49427 37.73181, -122.49416 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
414135709 | POLYGON ((-122.49389 37.73511, -122.49399 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
414135710 | POLYGON ((-122.49441 37.74036, -122.49428 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
458217887 | POLYGON ((-122.42382 37.77434, -122.42374 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
488800989 | POLYGON ((-122.41066 37.72666, -122.41039 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
545347966 | POLYGON ((-122.4327 37.78347, -122.43263 37.78... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
545436378 | POLYGON ((-122.42865 37.77927, -122.42866 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
565996156 | POLYGON ((-122.36844 37.72777, -122.36833 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
574610487 | POLYGON ((-122.40211 37.77003, -122.40201 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
693102678 | POLYGON ((-122.47051 37.71211, -122.47089 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
730336617 | POLYGON ((-122.40881 37.80823, -122.40883 37.8... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
775796578 | POLYGON ((-122.37648 37.82303, -122.37602 37.8... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
817076988 | POLYGON ((-122.38945 37.77214, -122.38945 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
894478070 | POLYGON ((-122.44733 37.75461, -122.44821 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
894478071 | POLYGON ((-122.44733 37.75461, -122.44741 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
894529444 | POLYGON ((-122.38257 37.73112, -122.38243 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
908050668 | POLYGON ((-122.43004 37.77972, -122.42996 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
918133828 | POLYGON ((-122.39705 37.76157, -122.39694 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
918165494 | POLYGON ((-122.3695 37.72682, -122.36947 37.72... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
918165497 | POLYGON ((-122.37194 37.72697, -122.37189 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
956484465 | POLYGON ((-122.37104 37.72715, -122.37093 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
956484476 | POLYGON ((-122.37044 37.72678, -122.37029 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
1047715315 | POLYGON ((-122.38854 37.77019, -122.38852 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | no | roof | NaN | NaN | NaN | |
1047715319 | POLYGON ((-122.38838 37.7702, -122.38836 37.76... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
1191526718 | POLYGON ((-122.38662 37.75431, -122.38662 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
1195049111 | POLYGON ((-122.41337 37.73753, -122.41335 37.7... | NaN | NaN | park | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
54 rows × 98 columns
generate_park_map(no_name_parks.iloc[1])
Disregard no-name parks and otherwise clean data¶
Looks like they are kinda valid parks. But small enough where they're unnamed. Let's just disregard them - they're probably not interesting to visit.
Also change /
in park names to -
. /
Causes issues with filenames.
named_parks = parks.query('not name.isna()')
named_parks = named_parks.copy()
named_parks['name'] = named_parks['name'].str.replace('/', '-')
named_parks
geometry | ele | gnis:feature_id | leisure | name | wikidata | wikipedia | historic | opening_hours | smoking | ... | leaf_type | acres | communication:amateur_radio:pota | name:pt | tourism | fee | location | type | disused:landuse | source:operator | ||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
element | id | |||||||||||||||||||||
node | 358767175 | POINT (-122.49088 37.72237) | 16 | 224922 | park | Harding Park | Q49497924 | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
358803650 | POINT (-122.40303 37.79687) | 7 | 1655668 | park | Jackson Square Historic District | Q49506269 | NaN | district | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
358803668 | POINT (-122.49942 37.72549) | 8 | 1655678 | park | Lake Merced Sports Center | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
358803681 | POINT (-122.41367 37.72248) | 55 | 1655685 | park | Louis Sutter Playground | Q49519583 | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
358803706 | POINT (-122.37692 37.72965) | 56 | 1655701 | park | Milton Myer Recreation Center | Q49526782 | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
way | 1286999777 | POLYGON ((-122.39559 37.79113, -122.3952 37.79... | NaN | NaN | park | Urban Park | NaN | NaN | NaN | Mo-Fr 08:00-20:00 | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
1293746220 | POLYGON ((-122.47178 37.75073, -122.47106 37.7... | NaN | NaN | park | Mandalay Lane Park | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
1293746848 | POLYGON ((-122.48591 37.75188, -122.4818 37.75... | NaN | NaN | park | Sunset Reservoir Park | NaN | NaN | NaN | 24/7 | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
1300623937 | POLYGON ((-122.44574 37.75953, -122.44508 37.7... | NaN | NaN | park | Al's Park | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
1329130170 | POLYGON ((-122.38623 37.7696, -122.38616 37.76... | NaN | NaN | park | Bayfront Park | NaN | NaN | NaN | sunrise-sunset | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
286 rows × 98 columns
Sort by size¶
# Project to web mercator
sized_parks = named_parks.copy().to_crs(3857)
# Calculate area in square meters
sized_parks['area'] = sized_parks.geometry.area
# Convert to acres
sized_parks['area_acres'] = (sized_parks.geometry.area / 4046.86).round(2)
# Maintain descending order
sized_parks.sort_values('area_acres', ascending=False, inplace=True)
sized_parks[['name', 'area_acres']]
name | area_acres | ||
---|---|---|---|
element | id | ||
relation | 8346137 | Presidio of San Francisco | 2411.04 |
way | 158602261 | Golden Gate Park | 1611.13 |
404847043 | Lake Merced Park | 973.44 | |
28716696 | John McLaren Park | 571.30 | |
40060675 | Candlestick Point State Recreation Area | 250.48 | |
... | ... | ... | ... |
node | 12440345641 | Maritime Plaza | 0.00 |
358803668 | Lake Merced Sports Center | 0.00 | |
358803681 | Louis Sutter Playground | 0.00 | |
358803650 | Jackson Square Historic District | 0.00 | |
358767175 | Harding Park | 0.00 |
286 rows × 2 columns
Park size distribution¶
Just to get a sense of how many big parks there are. We also want to know how many parks are represented as a point (that is, without geometry).
import matplotlib.pyplot as plt
import numpy as np
def plot_park_size_distribution(sized_parks):
"""
Create a histogram of park sizes with log scaling.
Input: GeoDataFrame with 'area_acres' column
"""
plt.figure(figsize=(12, 6))
# Create histogram with log scale on x-axis due to likely long tail distribution
plt.hist(sized_parks['area_acres'],
bins=np.logspace(np.log10(0.1), np.log10(sized_parks['area_acres'].max()), 20),
alpha=0.7)
#plt.xscale('log') # Log scale for x-axis since park sizes likely vary by orders of magnitude
plt.xlabel('Park Size (acres)')
plt.ylabel('Number of Parks')
plt.title('Distribution of San Francisco Park Sizes')
plt.grid(True, alpha=0.3)
# Add some summary statistics
plt.figtext(0.15, 0.85,
f"Total Parks: {len(sized_parks)}\n"
f"Median Size: {sized_parks['area_acres'].median():.1f} acres\n"
f"Mean Size: {sized_parks['area_acres'].mean():.1f} acres",
bbox=dict(facecolor='white', alpha=0.8))
return plt
plot_park_size_distribution(sized_parks)
<module 'matplotlib.pyplot' from '/nix/store/1zyma6bfryj88cfdxs59phs5xzgmy5w9-python3-3.12.8-env/lib/python3.12/site-packages/matplotlib/pyplot.py'>
Export data as HTML and JSON¶
We want to build a standalone webapp to track park visitation progress. So export this data into something a webapp can work with.
import os
import json
from pathlib import Path
def generate_park_maps_and_data(sized_parks, named_parks):
# Create maps directory if it doesn't exist
Path("maps").mkdir(exist_ok=True)
# Create dictionary for park sizes
park_sizes = {}
for idx, park in sized_parks.iterrows():
name = str(park['name'])
print(f"Generating map for: {name}")
m = generate_park_map(named_parks[named_parks['name'] == name].iloc[0])
m.save(f"maps/{name}.html")
# Add to sizes dictionary
park_sizes[name] = round(park.area_acres, 2)
# Write JSON file
with open('park_sizes.json', 'w') as f:
json.dump(park_sizes, f, indent=2, sort_keys=True)
print(f"\nGenerated {len(park_sizes)} maps")
print("Park sizes saved to park_sizes.json")
generate_park_maps_and_data(sized_parks, named_parks)
Generating map for: Presidio of San Francisco Generating map for: Golden Gate Park Generating map for: Lake Merced Park Generating map for: John McLaren Park Generating map for: Candlestick Point State Recreation Area Generating map for: Lands End Generating map for: Lincoln Park Generating map for: Glen Canyon Park Generating map for: Fort Mason Generating map for: Bayview Hill Park Generating map for: Crocker Amazon Playground Generating map for: Mount Davidson Park Generating map for: Buena Vista Park Generating map for: Sunset Reservoir Park Generating map for: Sigmund Stern Recreation Grove Generating map for: Bernal Heights Park Generating map for: Pine Lake Park Generating map for: Sutro Heights Park Generating map for: Balboa Park Generating map for: Panhandle Generating map for: Heron's Head Park Generating map for: Alcatraz Island Generating map for: West Sunset Playground Generating map for: Mission Dolores Park Generating map for: Corona Heights Park Generating map for: Presidio Tunnel Tops Generating map for: Yosemite Slough Generating map for: Mountain Lake Park Generating map for: Alamo Square Generating map for: Moscone Recreation Center Generating map for: Alta Plaza Park Generating map for: Lafayette Park Generating map for: Ocean View Park Generating map for: Potrero Hill Recreation Center Generating map for: Pier 94 Wetlands Generating map for: Saint Mary's Park Generating map for: Mission Creek Park Generating map for: Aquatic Park Historic District Generating map for: Music Concourse Generating map for: Parkside Square Generating map for: Holly Park Generating map for: India Basin Shoreline Park Generating map for: Marina Green Generating map for: Larsen Park Generating map for: McCoppin Square Generating map for: Mission Creek Park Generating map for: Golden Gate Heights Park Generating map for: George Christopher Playground Generating map for: Crane Cove Park Generating map for: Angelo Rossi Park Generating map for: Youngblood-Coleman Playground Generating map for: Raymond Kimbell Playground Generating map for: Pioneer Park Generating map for: Jefferson Square Generating map for: China Beach Generating map for: Bayfront Park Generating map for: Civic Center Plaza Generating map for: India Basin Open Space Generating map for: Silver Terrace Playground Generating map for: Palega Recreation Center Generating map for: Margaret S. Hayward Playground Generating map for: China Basin Park Generating map for: Aptos Playground Generating map for: Franklin Square Generating map for: Gilman Playground Generating map for: Walter Haas Playground Generating map for: Francisco Park Generating map for: Jackson Park Generating map for: Salesforce Park Generating map for: Sue Bierman Park Generating map for: Potrero Del Sol Park Generating map for: Grand View Park Generating map for: Brooks Park Generating map for: Duboce Park Generating map for: Yerba Buena Gardens Generating map for: Embarcadero Plaza Generating map for: Parklab Generating map for: Hilltop Park Generating map for: Bayview Playground Generating map for: Sunset Playground Generating map for: Mansell Parkway Generating map for: The Crossing at East Cut Generating map for: Billy Goat Hill Generating map for: Cayuga Park Generating map for: Palou Phelps Mini Park Generating map for: Rincon Park Generating map for: Koret Quad Generating map for: Robert Pender Park Generating map for: Garfield Square Generating map for: Rolph Playground Generating map for: Douglass Playground Generating map for: Coleman Bluff Generating map for: Tank Hill Generating map for: Adam Rodgers Park Generating map for: George Sterling Park Generating map for: Starr King Open Space Generating map for: Edgehill Mountain Open Space Generating map for: Kite Hill Open Space Generating map for: Joe DiMaggio Playground Generating map for: Clipper Cove Beach Generating map for: Buckeye Grove Generating map for: Victoria Manalo Draves Park Generating map for: McKinley Square Generating map for: Mission Bay Commons Generating map for: Rolph Nicol Jr Playground Generating map for: Panorama Park Generating map for: Union Square Generating map for: Little Marina Green Generating map for: Miraloma Playground Generating map for: Washington Square Park Generating map for: Mariposa Park Generating map for: Bosworth Street Open Space Generating map for: Hunters Point Community Youth Park Generating map for: Dorothy W. Erskine Park Generating map for: Precita Park Generating map for: Sunnyside Playground Generating map for: Esprit Park Generating map for: Mission Playground Generating map for: Yik Oi Huang Peace and Friendship Park Generating map for: Levi's Plaza Generating map for: Sydney G. Walton Square Generating map for: Eureka Valley Recreation Center Generating map for: Warm Water Cove Park Generating map for: Terrace Green Park Generating map for: Rocky Outcrop Generating map for: Alice Chalmers Playground Generating map for: Brannan Street Wharf Generating map for: Brotherhood-Head Mini Park Generating map for: Excelsior Playground Generating map for: Mission Creek Park Generating map for: Kelloch-Velasco Park Generating map for: Grattan Playground Generating map for: Midtown Terrace Park and Sutro Recreation Center Generating map for: Laurel Hill Playground Generating map for: Tulare Park Generating map for: Little Hollywood Park Generating map for: Saint Mary's Square Generating map for: Mission Bay Kids Park Generating map for: J.P. Murphy Playground Generating map for: Bayview Gateway Generating map for: West Portal Playground Generating map for: Hippie Hill Generating map for: Huntington Park Generating map for: Merced Heights Playground Generating map for: South Beach Park Generating map for: 29th & Diamond Open Space Generating map for: Topaz Open Space Generating map for: Cabrillo Playground Generating map for: Noe Valley Courts Generating map for: Shoreview Park Generating map for: South Park Generating map for: Koshland Park Generating map for: Fulton Playground Generating map for: Boeddeker Park Generating map for: 10th Avenue & Clement Mini Park Generating map for: Richmond Recreation Center Generating map for: Ina Coolbrith Park Generating map for: Argonne Playground Generating map for: Richmond Playground Generating map for: Rochambeau Playground Generating map for: Helen Wills Park Generating map for: Allyne Park Generating map for: Transamerica Redwood Park Generating map for: Sunset Tunnel Park Generating map for: Grandview Open Space Generating map for: In Chan Kaajal Park Generating map for: Bernal Recreation Center Generating map for: Fairmount Open Space Generating map for: Duncan-Castro Open Space Generating map for: Japan Town Peace Plaza Generating map for: Daggett Park Generating map for: Hayes Valley Playground Generating map for: Tunnel Top Park Generating map for: Agua Vista Park Generating map for: UCSF Mission Bay Park Generating map for: Parque Niños Unidos Generating map for: Visitacion Valley Greenway Generating map for: Islais Landing Generating map for: Progress Park Generating map for: Seward Mini Park Generating map for: Lakeview and Ashton Mini Park Generating map for: 50 Beale Street Plaza Generating map for: Willie "Woo Woo" Wong Park Generating map for: Patricia's Green Generating map for: Mullen & Peralta Mini Park Generating map for: Waterfront Plaza Generating map for: War Memorial Court Generating map for: Pier 29 Public Shore Generating map for: Emerald Park Generating map for: Presidio Heights Playground Generating map for: Michelangelo Playground Generating map for: Tenderloin Children's Playground Generating map for: Rooftop Park Generating map for: The Parks at 5M Generating map for: Argonne Community Garden Generating map for: Sunnyside Conservatory Generating map for: Palou Community Garden Generating map for: Fillmore & Turk Mini Park Generating map for: Rossi Playground Edward St Annex Generating map for: Rincon Place Generating map for: Woh Hei Yuen Recreation Center Generating map for: Harvey Milk Plaza Generating map for: Minnesota Grove Generating map for: Redwood Grove Generating map for: The Parks at 5M Generating map for: Kid Power Park Generating map for: Fay Park Generating map for: Woods Yard Park Generating map for: moscone dog play area Generating map for: Fallen Bridge Park Generating map for: Noe Valley Town Square Generating map for: The Commons Generating map for: Jane Warner Plaza Generating map for: Juri Commons Generating map for: Langton Community Garden Generating map for: Muriel Leff Mini Park Generating map for: 15th Avenue Steps Generating map for: Sergeant John Macaulay Park Generating map for: Lessing & Sears Mini Park Generating map for: Alioto Mini Park Generating map for: Dogpatch Arts Plaza Generating map for: Adah's Stairway Garden Generating map for: Coleridge Park Generating map for: Benches Park Generating map for: Coso Square Generating map for: Page & Laguna Mini Park Generating map for: Al's Park Generating map for: Broadway Tunnel West Mini Park Generating map for: San Jose-Guerrero Park Generating map for: Cottage Row Mini Park Generating map for: Athens Avalon Greens Terace Generating map for: La Playa Park Generating map for: Cayuga & Lamartine mini park Generating map for: Naples Green Generating map for: McCoppin Hub Generating map for: 24th & York Mini Park Generating map for: Marietta Green Space Generating map for: Turk-Hyde Mini Park Generating map for: Urban Park Generating map for: Greenie's Conservation Corner Generating map for: Urban Alchemy Oasis Generating map for: Community Park Generating map for: Mission Valencia Plaza Generating map for: Baden-Joost Mini Park Generating map for: Jack Early Park Generating map for: La Playa Park Generating map for: Baker & Broderick Mini Park Generating map for: Frank Cresci Plaza Generating map for: Randolph & Bright Mini Park Generating map for: Golden Gate & Steiner Mini Park Generating map for: Marini Plaza Generating map for: Pink Triangle Memorial Generating map for: Ecker Square Generating map for: Mandalay Lane Park Generating map for: Green Hairstreak Corridor - 12th and Pacheco Generating map for: Noe & Beaver Mini Park Community Garden Generating map for: Green Hairstreak Corridor - 14th Avenue & Pacheco Generating map for: Treat Plaza Generating map for: Mary Ellen Pleasant Memorial Park Generating map for: Green Hairstreak Corridor - Mount Steps (access point) Generating map for: Coleridge Mini Park Generating map for: Tara Street Park Generating map for: Prentiss Mini-Park Generating map for: Empire Park Generating map for: Green Hairstreak Corridor - Quintara Steps Generating map for: Molinari Mana Park Generating map for: Naples Green Generating map for: Green Hairstreak Corridor - Aloha & Lomita Generating map for: PG&E Plaza Generating map for: Green Hairstreak Corridor - Aerial Steps (access point) Generating map for: Deepistan National Parklet Generating map for: Fairy Circle Generating map for: Annie St Plaza Generating map for: Secret Garden Generating map for: Bush Street-Cottage Row Historic District Generating map for: Russian Hill-Vallejo Street Crest Historic District Generating map for: Ulrich Field Generating map for: Benedetti Diamond Generating map for: Farallon Islands State Game Refuge Generating map for: Rolph-Nicol Playground Generating map for: Milton Myer Recreation Center Generating map for: Maritime Plaza Generating map for: Lake Merced Sports Center Generating map for: Louis Sutter Playground Generating map for: Jackson Square Historic District Generating map for: Harding Park Generated 281 maps Park sizes saved to park_sizes.json
Tarball the maps up for easier download¶
import tarfile
def archive_maps_tar():
with tarfile.open("maps.tar.gz", "w:gz") as tar:
tar.add("maps")
print("Created maps.tar.gz")
archive_maps_tar()
Created maps.tar.gz