from matplotlib import pyplot as plt
import numpy as np
import pandas as pd
import geopandas as gpd
import altair as alt
pd.options.display.max_columns = 999
Oct 31, 2022
Great source of data: street networks and a wealth of amenity information
https://www.openstreetmap.org
Related: interactive web maps in Python
Several key features:
import osmnx as ox
philly = ox.geocode_to_gdf('Philadelphia, PA')
philly.head()
geometry | bbox_north | bbox_south | bbox_east | bbox_west | place_id | osm_type | osm_id | lat | lon | display_name | class | type | importance | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | POLYGON ((-75.28030 39.97500, -75.28022 39.974... | 40.137959 | 39.867005 | -74.955831 | -75.280298 | 282365563 | relation | 188022 | 39.952724 | -75.163526 | Philadelphia, Philadelphia County, Pennsylvani... | boundary | administrative | 0.823797 |
philly.crs
<Geographic 2D CRS: EPSG:4326> Name: WGS 84 Axis Info [ellipsoidal]: - Lat[north]: Geodetic latitude (degree) - Lon[east]: Geodetic longitude (degree) Area of Use: - name: World. - bounds: (-180.0, -90.0, 180.0, 90.0) Datum: World Geodetic System 1984 ensemble - Ellipsoid: WGS 84 - Prime Meridian: Greenwich
We can plot it just like any other GeoDataFrame
# Project it to Web Mercator first and plot
ax = philly.to_crs(epsg=3857).plot(facecolor='none', edgecolor='black')
ax.set_axis_off()
Key function: project_gdf()
(docs)
Automatically projects to the Universal Transverse Mercator (UTM) CRS for the UTM zone that the centroid of the polygon lies in
A good, general projection that works for most latitudes except very northern locations.
ax = ox.project_gdf(philly).plot(fc="lightblue", ec="gray")
ax.set_axis_off()
Some more examples:
# Some examples
place1 = ox.geocode_to_gdf('Manhattan, New York City, New York, USA')
place2 = ox.geocode_to_gdf('Miami-Dade County, Florida')
place3 = ox.geocode_to_gdf('Florida, USA')
place4 = ox.geocode_to_gdf('Spain')
# Manhattan
ax = ox.project_gdf(place1).plot(fc="lightblue", ec="gray");
ax.set_axis_off()
# Miami-Dade County
ax = ox.project_gdf(place2).plot(fc="lightblue", ec="gray")
ax.set_axis_off()
# Florida
ax = ox.project_gdf(place3).plot(fc="lightblue", ec="gray")
ax.set_axis_off()
# Spain
ax = ox.project_gdf(place4).plot(fc="lightblue", ec="gray")
ax.set_axis_off()
Key functions: geometries_from_*
geometries_from_place()
(docs)geometries_from_address()
(docs)geometries_from_bbox()
(docs)geometries_from_point()
(docs)geometries_from_polygon()
(docs)Important reference: https://wiki.openstreetmap.org/wiki/Map_Features
In the language of OSM, the "key" is the main feature category (e.g., amenity) and the "value" is the sub-category type (e.g., "bar")
Use a dict to specify the features you want:
# Get all amenities in Philadelphia
amenities = ox.geometries_from_place("Philadelphia, PA", tags={"amenity": True})
len(amenities)
9913
amenities.head()
highway | geometry | amenity | direction | created_by | cuisine | name | brand | brand:wikidata | brand:wikipedia | operator | operator:wikidata | operator:wikipedia | shop | short_name | addr:city | addr:housenumber | addr:postcode | addr:state | addr:street | official_name | opening_hours | phone | takeaway | source | wheelchair | healthcare | internet_access | url | contact:phone | description | website | wikidata | internet_access:ssid | brewery | alt_name | ele | gnis:county_id | gnis:created | gnis:feature_id | gnis:state_id | religion | historic:amenity | old_name | denomination | building | comment | operator:type | school | wikipedia | gnis:edited | craft | microbrewery | restaurant | name:en | social_facility | operator:short | emergency | healthcare:speciality | bicycle_parking | capacity | covered | atm | attraction | gnis:county_name | gnis:import_uuid | gnis:reviewed | internet_access:fee | addr:county | addr:country | outdoor_seating | air_conditioning | diet:vegetarian | toilets:wheelchair | addr:housename | bottle | parking | designation | not:brand:wikidata | dispensing | drive_through | barrier | screen | delivery | diet:vegan | payment:cash | payment:coins | collection_times | ref | male | female | check_date | fee | fax | smoking | bar | bus | public_transport | tourism | source:pkey | access | changing_table | toilets | name:zh | addr:full | entrance | level | indoor_seating | fuel:biodiesel | fuel:biogas | fuel:cng | fuel:diesel | fuel:e10 | fuel:e85 | fuel:electricity | wifi | drive_in | check_date:collection_times | food | payment:bitcoin | diet:halal | disused:amenity | self_service | note | leisure | sport | branch | drink:club-mate | car_wash | opening_hours:covid19 | toilets:disposal | unisex | diet:pescetarian | lgbtq | payment:credit_cards | payment:debit_cards | reservation | park_ride | supervised | landuse | fixme | check_date:opening_hours | flickr | contact:facebook | contact:email | service_times | youtube | source:cuisine | social_facility:for | disused:shop | diet:kosher | maxheight | wheelchair:description | wheelchair:description:en | contact:website | layer | service:bicycle:chain_tool | service:bicycle:pump | currency:USD | drink:coca-cola | drink:coke | drink:cola_zero | drink:soda | drink:water | vending | network | network:wikidata | network:wikipedia | amenity_1 | recycling:computers | recycling:tv_monitor | recycling_type | ferry | kitchen_hours | animal | was:amenity | was:cuisine | was:delivery | was:drive_through | was:name | was:outdoor_seating | was:takeaway | backrest | service:bicycle:repair | payment:cards | name:es | theatre:genre | addr:unit | service:bicycle:tools | beds | payment:visa | cash_in | currency:BCH | currency:LTC | currency:XBT | opening_hours:kitchen | office | date | display | faces | studio | name:ca | bench | lit | shelter_type | addr:city:ar | name:ar | start_date | colour | material | music_venue | addr:block_number | seats | brand:type | indoor | historic | type | payment:american_express | payment:discover_card | payment:mastercard | parcel_mail_in | recycling:beverage_cartons | recycling:cans | recycling:glass_bottles | recycling:paper | recycling:plastic | recycling:plastic_bottles | recycling:plastic_packaging | portable | toilets:handwashing | toilets:position | internet_access:description | name:vi | payment:cheque | min_age | tram | contact:instagram | waste | bicycle_rental | payment:cash_app | payment:venmo | seating | street_vendor | theatre:type | smoothness | surface | disused | location | drinking_water | fountain | height | fridge | image | diet:healthy | country | nodes | building:levels | capacity:disabled | contact:twitter | ref:nrhp | vehicle | natural | water | building:use | ship:type | roof:shape | automated | brand:website | building:material | name:he | source:name | roof:levels | roof:material | access:conditional | rite | heritage | heritage:operator | architect:wikidata | building:levels:underground | heritage:website | name:etymology:wikidata | nrhp:criteria | nrhp:inscription_date | wikimedia_commons | urgent_care | building:colour | area | gnis:fcode | nonsquare | name:ja | name:zn | roof:orientation | building:part | elevation | historic:name | grades | maxstay | monastery:type | library | theme | owner | loc_name | drink | bin | police | school:type | old_name1 | old_name2 | fuel:octane_95 | fuel:gasoline | fuel:octane_87 | healthcare:counselling | parking:orientation | ways | healthcare:for | ||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
element_type | osmid | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
node | 109811385 | NaN | POINT (-75.19487 40.05846) | bench | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
109993125 | traffic_signals | POINT (-75.19107 40.06019) | pub | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
274215467 | NaN | POINT (-75.19492 39.95935) | fast_food | NaN | Potlatch 0.9c | pizza | Powelton Pizza | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
274216093 | NaN | POINT (-75.19126 39.95765) | atm | NaN | NaN | NaN | Citibank | Citibank | Q857063 | en:Citibank | Citibank | Q857063 | en:Citibank | convenience | Citi | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
274216804 | NaN | POINT (-75.19844 39.95571) | pub | NaN | Potlatch 0.9c | NaN | Brownie's 38th St. | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
# Get all bars in philadelphia
bars = ox.geometries_from_place("Philadelphia, PA", tags={"amenity": "bar"})
len(bars)
156
bars.head()
addr:city | addr:housenumber | addr:postcode | addr:state | addr:street | amenity | brewery | craft | gnis:county_id | microbrewery | name | operator | restaurant | website | wikidata | wikipedia | geometry | opening_hours | phone | smoking | toilets:wheelchair | wheelchair | addr:housename | indoor_seating | outdoor_seating | designation | source | wifi | leisure | sport | cuisine | diet:vegan | diet:vegetarian | food | internet_access | wheelchair:description | contact:facebook | fixme | description | name:en | name:es | addr:unit | check_date:opening_hours | music_venue | payment:cash | min_age | alt_name | nodes | atm | building | building:levels | nonsquare | heritage | ||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
element_type | osmid | |||||||||||||||||||||||||||||||||||||||||||||||||||||
node | 357303425 | Philadelphia | 500 | 19123 | PA | Spring Garden Street | bar | yes | brewery | 101 | yes | Yards Brewing Company | Yards Brewing Company | yes | https://yardsbrewing.com/ | Q16903914 | en:Yards Brewing Company | POINT (-75.14712 39.96067) | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
655425272 | NaN | NaN | NaN | NaN | NaN | bar | NaN | NaN | NaN | NaN | Drinkers West | NaN | NaN | NaN | NaN | NaN | POINT (-75.20020 39.95521) | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
1167079387 | NaN | NaN | NaN | NaN | NaN | bar | NaN | NaN | NaN | NaN | Milkboy | NaN | NaN | NaN | NaN | NaN | POINT (-75.14925 39.94170) | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
1204761128 | NaN | NaN | NaN | NaN | NaN | bar | NaN | NaN | NaN | NaN | Vikings High School Club | NaN | NaN | NaN | NaN | NaN | POINT (-75.16363 39.92685) | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
1424271155 | NaN | 344 | 19147 | NaN | South Street | bar | NaN | NaN | NaN | NaN | Copabanana | NaN | NaN | http://copabanana.com/ | NaN | NaN | POINT (-75.14909 39.94152) | Mo-Su 11:30-02:00 | +1 215 9236180 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
# Get bar, pub, and restaurant features in Philadelphia
food_and_drink = ox.geometries_from_place("Philadelphia, PA", tags={"amenity": ["pub", "bar", "restaurant"]})
len(food_and_drink)
1031
food_and_drink.head()
amenity | highway | geometry | created_by | name | source | wheelchair | addr:city | addr:housenumber | addr:postcode | addr:state | addr:street | brewery | opening_hours | craft | gnis:county_id | microbrewery | operator | restaurant | website | wikidata | wikipedia | cuisine | outdoor_seating | brand | brand:wikidata | phone | diet:vegetarian | description | addr:housename | designation | not:brand:wikidata | diet:vegan | fax | smoking | bar | takeaway | toilets:wheelchair | addr:country | alt_name | short_name | name:zh | level | indoor_seating | wifi | drive_in | internet_access | food | payment:cash | delivery | payment:bitcoin | diet:halal | disused:amenity | air_conditioning | brand:wikipedia | official_name | capacity | note | leisure | sport | branch | opening_hours:covid19 | contact:phone | diet:pescetarian | lgbtq | payment:credit_cards | payment:debit_cards | reservation | source:cuisine | diet:kosher | wheelchair:description | amenity_1 | contact:facebook | kitchen_hours | fixme | name:en | name:es | addr:unit | check_date:opening_hours | opening_hours:kitchen | name:ca | internet_access:fee | toilets | start_date | music_venue | payment:american_express | payment:discover_card | payment:mastercard | payment:visa | internet_access:description | internet_access:ssid | min_age | disused | diet:healthy | drive_through | nodes | building | historic | payment:cards | ship:type | tourism | atm | building:levels | area | image | building:material | roof:levels | name:ja | name:zn | nonsquare | theme | heritage | |||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
element_type | osmid | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
node | 109993125 | pub | traffic_signals | POINT (-75.19107 40.06019) | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
274216804 | pub | NaN | POINT (-75.19844 39.95571) | Potlatch 0.9c | Brownie's 38th St. | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
333786044 | restaurant | NaN | POINT (-75.15893 39.94086) | Potlatch 0.10f | Sam's Morning Glory | knowledge | limited | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
343293806 | pub | NaN | POINT (-75.15946 39.96073) | NaN | Prohibition Taproom | survey | NaN | Philadelphia | 501 | 19123 | PA | North 13th Street | yes | Mo-Su 11:00-02:00 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
357303425 | bar | NaN | POINT (-75.14712 39.96067) | NaN | Yards Brewing Company | NaN | NaN | Philadelphia | 500 | 19123 | PA | Spring Garden Street | yes | NaN | brewery | 101 | yes | Yards Brewing Company | yes | https://yardsbrewing.com/ | Q16903914 | en:Yards Brewing Company | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
# Get higway bus stop features
bus_stops = ox.geometries_from_place("Philadelphia, PA", tags={"highway": "bus_stop"})
len(bus_stops)
286
bus_stops.head()
bus | highway | public_transport | geometry | bench | covered | name | network | network:wikidata | operator | shelter | network:wikipedia | ref | tactile_paving | wheelchair | route_ref | local_ref | designation | source | bin | lit | departures_board | internet_access | addr:street | route_ref_1 | note | operator:wikidata | brand | brand:wikidata | railway | tram | trolleybus | network:short | description | not:network:wikidata | ||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
element_type | osmid | |||||||||||||||||||||||||||||||||||
node | 109812837 | yes | bus_stop | platform | POINT (-75.19363 40.05964) | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
361011456 | yes | bus_stop | platform | POINT (-75.16166 39.95223) | yes | yes | 13th St & Market St | SEPTA | Q2037863 | SEPTA | yes | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
750281693 | yes | bus_stop | platform | POINT (-75.07732 40.01797) | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
768271130 | yes | bus_stop | platform | POINT (-75.20726 40.01487) | NaN | NaN | Wissahickon Transportation Center | SEPTA | Q2037863 | SEPTA | yes | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
1015342921 | yes | bus_stop | platform | POINT (-75.18187 39.96640) | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
# Get commercial and retail landuse features
landuse = ox.geometries_from_place("Philadelphia, PA", tags={"landuse": ["commercial", "retail"]})
len(landuse)
333
fig, ax = plt.subplots(figsize=(10, 6))
ax = landuse.plot(ax=ax)
ax.set_axis_off()
Key functions: graph_from_*
graph_from_place()
(docs)graph_from_address()
(docs)graph_from_bbox()
(docs)graph_from_point()
(docs)graph_from_polygon()
(docs)Get streets within 500 meters of the center of Northern Liberties
G = ox.graph_from_address("Northern Liberties, Philadelphia, PA", dist=500)
Project and plot it:
G_projected = ox.project_graph(G)
ox.plot_graph(G_projected);
Remove the nodes:
ox.plot_graph(G_projected, node_size=0);
Let's zoom out to 2,000 meters. This will take a little longer.
G = ox.graph_from_address("Northern Liberties, Philadelphia, PA", dist=2000)
G_projected = ox.project_graph(G)
ox.plot_graph(G_projected, node_size=0);
drive
- get drivable public streets (but not service roads)drive_service
- get drivable streets, including service roadswalk
- get all streets and paths that pedestrians can use (this network type ignores one-way directionality)bike
- get all streets and paths that cyclists can useall
- download all non-private OSM streets and pathsall_private
- download all OSM streets and paths, including private-access ones (default)# the "drive" network
G = ox.graph_from_address("Northern Liberties, Philadelphia, PA",
network_type='drive')
ox.plot_graph(G);
# the "walk" network
G = ox.graph_from_address("Northern Liberties, Philadelphia, PA",
network_type='walk')
ox.plot_graph(ox.project_graph(G));
Use graph_from_place()
to get the streets within a specific OSM place.
Note: the place query has to be resolved by OSM.
berkeley = ox.graph_from_place("Berkeley, California, USA",)
ox.plot_graph(ox.project_graph(berkeley), node_size=0);
Example: all streets within Northern Liberties and Fishtown
url = "https://github.com/azavea/geo-data/raw/master/Neighborhoods_Philadelphia/Neighborhoods_Philadelphia.geojson"
hoods = gpd.read_file(url).rename(columns={"mapname": "neighborhood"})
hoods.head()
name | listname | neighborhood | shape_leng | shape_area | cartodb_id | created_at | updated_at | geometry | |
---|---|---|---|---|---|---|---|---|---|
0 | PENNYPACK_PARK | Pennypack Park | Pennypack Park | 87084.285589 | 6.014076e+07 | 9 | 2013-03-19T17:41:50.507999+00:00 | 2013-03-19T17:41:50.743000+00:00 | MULTIPOLYGON (((-75.05645 40.08743, -75.05667 ... |
1 | OVERBROOK | Overbrook | Overbrook | 57004.924607 | 7.692499e+07 | 138 | 2013-03-19T17:41:50.507999+00:00 | 2013-03-19T17:41:50.743000+00:00 | MULTIPOLYGON (((-75.22719 39.97740, -75.22984 ... |
2 | GERMANTOWN_SOUTHWEST | Germantown, Southwest | Southwest Germantown | 14880.743608 | 1.441867e+07 | 59 | 2013-03-19T17:41:50.507999+00:00 | 2013-03-19T17:41:50.743000+00:00 | MULTIPOLYGON (((-75.16208 40.02829, -75.16145 ... |
3 | EAST_PARKSIDE | East Parkside | East Parkside | 10885.781535 | 4.231000e+06 | 129 | 2013-03-19T17:41:50.507999+00:00 | 2013-03-19T17:41:50.743000+00:00 | MULTIPOLYGON (((-75.19931 39.97462, -75.19869 ... |
4 | GERMANY_HILL | Germany Hill | Germany Hill | 13041.939087 | 6.949968e+06 | 49 | 2013-03-19T17:41:50.507999+00:00 | 2013-03-19T17:41:50.743000+00:00 | MULTIPOLYGON (((-75.22722 40.03523, -75.22865 ... |
Trim to Fishtown and Northern Liberties
sel = hoods['neighborhood'].isin(['Fishtown - Lower Kensington', 'Northern Liberties'])
nolibs_fishtown = hoods.loc[sel]
nolibs_fishtown.head()
name | listname | neighborhood | shape_leng | shape_area | cartodb_id | created_at | updated_at | geometry | |
---|---|---|---|---|---|---|---|---|---|
105 | FISHTOWN | Fishtown - Lower Kensington | Fishtown - Lower Kensington | 25973.395800 | 3.360583e+07 | 87 | 2013-03-19T17:41:50.507999+00:00 | 2013-03-19T17:41:50.743000+00:00 | MULTIPOLYGON (((-75.12718 39.96086, -75.13048 ... |
106 | NORTHERN_LIBERTIES | Northern Liberties | Northern Liberties | 20685.015399 | 2.031376e+07 | 89 | 2013-03-19T17:41:50.507999+00:00 | 2013-03-19T17:41:50.743000+00:00 | MULTIPOLYGON (((-75.12718 39.96086, -75.12959 ... |
ax = ox.project_gdf(nolibs_fishtown).plot(fc="lightblue", ec="gray")
ax.set_axis_off()
unary_union
ox.graph_from_polygon()
nolibs_fishtown_outline = nolibs_fishtown.geometry.unary_union
nolibs_fishtown_outline
type(nolibs_fishtown_outline)
shapely.geometry.polygon.Polygon
# get the graph
G_nolibs_fishtown = ox.graph_from_polygon(nolibs_fishtown_outline, network_type='drive')
# viola!
ox.plot_graph(ox.project_graph(G_nolibs_fishtown), node_size=0);
We could also use unary_union.convex_hull
. This will be an encompassing polygon around any set of geometries.
nolibs_fishtown.geometry.unary_union
nolibs_fishtown.geometry.unary_union.convex_hull
type(G_nolibs_fishtown)
networkx.classes.multidigraph.MultiDiGraph
# only get the edges
nolibs_edges = ox.graph_to_gdfs(G_nolibs_fishtown,
edges=True,
nodes=False)
# we have lots of data associated with each edge!
nolibs_edges.head()
osmid | oneway | name | highway | reversed | length | geometry | lanes | maxspeed | bridge | ref | |||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
u | v | key | |||||||||||
109729430 | 109729453 | 0 | 12109175 | True | North 5th Street | residential | False | 117.685 | LINESTRING (-75.14637 39.96458, -75.14655 39.9... | NaN | NaN | NaN | NaN |
1 | 789845372 | True | North 5th Street | tertiary | False | 97.779 | LINESTRING (-75.14637 39.96458, -75.14627 39.9... | NaN | NaN | NaN | NaN | ||
109729453 | 109729801 | 0 | 789845372 | True | North 5th Street | tertiary | False | 32.185 | LINESTRING (-75.14617 39.96544, -75.14609 39.9... | NaN | NaN | NaN | NaN |
109729699 | 109811674 | 0 | [424804073, 121643778] | True | Callowhill Street | trunk | False | 135.768 | LINESTRING (-75.14724 39.95779, -75.14739 39.9... | 5 | 35 mph | NaN | NaN |
109729709 | 0 | [633770802, 41959235] | True | North 5th Street | secondary | False | 90.451 | LINESTRING (-75.14724 39.95779, -75.14722 39.9... | NaN | NaN | NaN | NaN |
# plot it like any old GeoDataFrame
ax = nolibs_edges.to_crs(epsg=3857).plot(color='gray')
# add the neighborhood boundaries
boundary = gpd.GeoSeries([nolibs_fishtown_outline], crs='EPSG:4326')
boundary.to_crs(epsg=3857).plot(ax=ax, facecolor='none', edgecolor='red', linewidth=3, zorder=2)
ax.set_axis_off()
And much more: see the OSMnx repository of Jupyter notebook examples
We can use the ox.basic_stats()
to get some basic network statistics
ox.basic_stats(G_nolibs_fishtown)
{'n': 629, 'm': 1229, 'k_avg': 3.9077901430842608, 'edge_length_total': 103561.27499999995, 'edge_length_avg': 84.26466639544341, 'streets_per_node_avg': 3.379968203497615, 'streets_per_node_counts': {0: 0, 1: 18, 2: 2, 3: 342, 4: 259, 5: 6, 6: 2}, 'streets_per_node_proportions': {0: 0.0, 1: 0.028616852146263912, 2: 0.003179650238473768, 3: 0.5437201907790143, 4: 0.4117647058823529, 5: 0.009538950715421303, 6: 0.003179650238473768}, 'intersection_count': 611, 'street_length_total': 86326.12299999999, 'street_segment_count': 1009, 'street_length_avg': 85.55611793855302, 'circuity_avg': 1.0165046392413242, 'self_loop_proportion': 0.0}
import networkx as nx
Let's calculate the shortest route between Frankford Hall (a bar in Fishtown) and the Spring Garden subway station:
# Get all food and drink places within our Fishtown/No Libs polygon
fishtown_food_drink = ox.geometries_from_polygon(nolibs_fishtown_outline,
tags={"amenity": ["restaurant", "bar", "pub"]})
len(fishtown_food_drink)
68
fishtown_food_drink.head()
addr:city | addr:housenumber | addr:postcode | addr:state | addr:street | amenity | brewery | craft | gnis:county_id | microbrewery | name | operator | restaurant | website | wikidata | wikipedia | geometry | opening_hours | phone | addr:housename | designation | cuisine | brand | brand:wikidata | brand:wikipedia | official_name | drive_in | outdoor_seating | smoking | takeaway | wheelchair | payment:bitcoin | leisure | sport | addr:country | source | capacity | addr:unit | description | diet:vegan | min_age | nodes | building | kitchen_hours | ||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
element_type | osmid | ||||||||||||||||||||||||||||||||||||||||||||
node | 357303425 | Philadelphia | 500 | 19123 | PA | Spring Garden Street | bar | yes | brewery | 101 | yes | Yards Brewing Company | Yards Brewing Company | yes | https://yardsbrewing.com/ | Q16903914 | en:Yards Brewing Company | POINT (-75.14712 39.96067) | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
1475230378 | Philadelphia | 1001 | 19123 | NaN | North 2nd Street | bar | NaN | NaN | NaN | NaN | Gunner's Run | NaN | NaN | http://gunnersrun.com/ | NaN | NaN | POINT (-75.14002 39.96627) | Mo-Su 11:00-02:00 | 215-923-4600 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
1712028161 | Philadelphia | 901 | 19123 | NaN | North 2nd Street | restaurant | NaN | NaN | NaN | NaN | Standard Tap | NaN | NaN | standardtap.com | NaN | NaN | POINT (-75.14057 39.96416) | NaN | 215 -238-0630 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
1712044411 | NaN | NaN | NaN | NaN | thompson and susquahana | pub | NaN | NaN | NaN | NaN | Les n Doreen's Happy Tap | NaN | NaN | NaN | NaN | NaN | POINT (-75.12558 39.97373) | NaN | NaN | the happy tap | local dive | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | |
1712050828 | NaN | 931 | 19123 | NaN | North 2nd Street | restaurant | NaN | NaN | NaN | NaN | Cantina Dos Segundos | NaN | NaN | https://www.cantinadossegundos.com/ | NaN | NaN | POINT (-75.14042 39.96483) | NaN | 215-629-0500 | NaN | NaN | mexican | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
# Select Frankford Hall based on the name column
frankford_hall = fishtown_food_drink.query("name == 'Frankford Hall'").squeeze()
# Get the x/y coordinates
frankford_hall_x = frankford_hall.geometry.x
frankford_hall_y = frankford_hall.geometry.y
frankford_hall_y
39.9694855
# Get all subway stations within our Fishtown/No Libs polygon
fishtown_subway_stops = ox.geometries_from_polygon(nolibs_fishtown_outline,
tags={"railway": "station"})
# Select Spring Garden based on the name column
spring_garden_station = fishtown_subway_stops.query("name == 'Spring Garden'").squeeze()
# Get the x/y coordinates
spring_garden_x = spring_garden_station.geometry.x
spring_garden_y = spring_garden_station.geometry.y
Find the nearest nodes on our OSMnx graph:
# Get the origin node
orig_node = ox.distance.nearest_nodes(G_nolibs_fishtown, spring_garden_x, spring_garden_y)
# Get the destination node
dest_node = ox.distance.nearest_nodes(G_nolibs_fishtown, frankford_hall_x, frankford_hall_y)
Use networkx
to find the shortest path between these graph nodes
orig_node
110156961
# get the shortest path --> just a list of node IDs
route = nx.shortest_path(G_nolibs_fishtown,
orig_node,
dest_node,
weight='length')
route
[110156961, 110156976, 110240102, 110240110, 110156990, 110408354, 110150984, 110151026, 109812663, 3405862196, 110274404, 786190278, 786189685, 786189751, 786190146, 786189922, 110227372, 110549183, 110207010, 7738710013, 7738710015, 1479201402, 1479201356, 1479201380, 1479201400, 1479201370, 7741504690, 1479201401, 110447508, 109990294, 109834418, 109921057, 109801805, 109801799, 109998370]
Use ox.plot_graph_route()
to plot a graph and highlight a specific route
ox.plot_graph_route(G_nolibs_fishtown, route, node_size=0);
"Pandas Network Analysis - dataframes of network queries, quickly"
A complementary set of OSM-related features:
import pandana as pnda
from pandana.loaders import osm
Key function: osm.node_query()
ox.geometries_from_bbox()
function in OSMnx, but we slightly different syntax.osm.node_query?
Signature: osm.node_query(lat_min, lng_min, lat_max, lng_max, tags=None) Docstring: Search for OSM nodes within a bounding box that match given tags. Parameters ---------- lat_min, lng_min, lat_max, lng_max : float tags : str or list of str, optional Node tags that will be used to filter the search. See http://wiki.openstreetmap.org/wiki/Overpass_API/Language_Guide for information about OSM Overpass queries and http://wiki.openstreetmap.org/wiki/Map_Features for a list of tags. Returns ------- nodes : pandas.DataFrame Will have 'lat' and 'lon' columns, plus other columns for the tags associated with the node (these will vary based on the query). Index will be the OSM node IDs. File: ~/mambaforge/envs/musa-550-fall-2022/lib/python3.9/site-packages/pandana/loaders/osm.py Type: function
Get the bounding box for Northern Liberties / Fishtown:
boundary = nolibs_fishtown_outline.bounds
boundary
(-75.14891, 39.955458, -75.113226, 39.984757)
[lng_min, lat_min, lng_max, lat_max] = boundary
# query OSM
poi_df = osm.node_query(lat_min, lng_min, lat_max, lng_max)
# remove missing data
poi_df = poi_df.dropna(subset=['amenity'])
poi_df.head()
lat | lon | highway | traffic_signals | railway | old_ref | ref | noref | name | stop | crossing | traffic_signals:direction | direction | disused:railway | ele | gnis:Class | gnis:County | gnis:County_num | gnis:ST_alpha | gnis:ST_num | gnis:id | import_uuid | is_in | place | wikidata | wikipedia | addr:city | addr:housenumber | addr:postcode | addr:street | opening_hours | phone | shop | website | alt_name | amenity | gnis:county_id | gnis:created | gnis:feature_id | gnis:state_id | historic:amenity | note | comment | old_name | addr:state | brewery | craft | microbrewery | operator | restaurant | man_made | gnis:county_name | gnis:import_uuid | gnis:reviewed | network | public_transport | subway | brand | brand:wikidata | brand:wikipedia | platforms | station | wheelchair | cuisine | disused:amenity | denomination | religion | tactile_paving | capacity | source:pkey | addr:housename | building | designation | payment:bitcoin | addr:full | description | diet:vegetarian | internet_access | short_name | tram | bus | drive_in | outdoor_seating | smoking | takeaway | drink:club-mate | internet_access:fee | contact:phone | social_facility | leisure | healthcare | sport | is_in:state_code | population | collection_times | operator:short | operator:type | operator:wikidata | operator:wikipedia | compost | farm_boxes | addr:place | addr:country | atm | air_conditioning | crossing:island | barrier | foot | motor_vehicle | emergency | access | fee | toilets:disposal | unisex | fax | fixme | branch | official_name | animal | delivery | tourism | addr:unit | crossing_ref | payment:cash | payment:cheque | payment:credit_cards | diet:vegan | beds | advertising | lit | artwork_type | entrance | office | diet:dairy | organic | payment:credit_card | communication:mobile_phone | tower:type | playground | drive_through | locked | level | historic | disused:leisure | construction:amenity | natural | kerb | books | demolished:leisure | opening_hours:covid19 | min_age | artist_name | bicycle_parking | covered | generator:method | generator:output:electricity | generator:source | generator:type | power | flag:type | traffic_calming | support | bridge:support | ||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
id | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
357274893 | 39.972335 | -75.130176 | NaN | NaN | NaN | NaN | NaN | NaN | Adaire Alexander School | NaN | NaN | NaN | NaN | NaN | 7 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | Adaire School | school | 101 | 08/02/1979 | 1168055 | 42 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
357283515 | 39.976497 | -75.116743 | NaN | NaN | NaN | NaN | NaN | NaN | Maritime Academy Charter High School | NaN | NaN | NaN | NaN | NaN | 4 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | school | 101 | 08/02/1979 | 1173424 | 42 | NaN | NaN | Stephen A. Douglas High School closed in 2013 | Stephen A. Douglas High School | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
357288962 | 39.981243 | -75.126783 | NaN | NaN | NaN | NaN | NaN | NaN | Horatio B. Hackett School | NaN | NaN | NaN | NaN | NaN | 8 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | Hackett School | school | 101 | 08/02/1979 | 1176347 | 42 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
357297150 | 39.983189 | -75.141190 | NaN | NaN | NaN | NaN | NaN | NaN | McKinley William School | NaN | NaN | NaN | NaN | NaN | 16 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | McKinley School | school | 101 | 08/02/1979 | 1180755 | 42 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
357303425 | 39.960668 | -75.147121 | NaN | NaN | NaN | NaN | NaN | NaN | Yards Brewing Company | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | Q16903914 | en:Yards Brewing Company | Philadelphia | 500 | 19123 | Spring Garden Street | NaN | NaN | NaN | https://yardsbrewing.com/ | NaN | bar | 101 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | PA | yes | brewery | yes | Yards Brewing Company | yes | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
len(poi_df)
227
poi_df[['lat', 'lon', 'amenity']].head(10)
lat | lon | amenity | |
---|---|---|---|
id | |||
357274893 | 39.972335 | -75.130176 | school |
357283515 | 39.976497 | -75.116743 | school |
357288962 | 39.981243 | -75.126783 | school |
357297150 | 39.983189 | -75.141190 | school |
357303425 | 39.960668 | -75.147121 | bar |
357373853 | 39.972874 | -75.127243 | school |
367962776 | 39.978845 | -75.118371 | fire_station |
1475159482 | 39.969869 | -75.144829 | place_of_worship |
1475229905 | 39.967481 | -75.139696 | disused |
1475230378 | 39.966270 | -75.140024 | bar |
For the full list of amenities, see the OSM Wikipedia
chart = (
alt.Chart(poi_df)
.mark_bar()
.encode(y=alt.Y("amenity", sort="-x"), x="count()", tooltip=["amenity", "count()"])
)
chart
pdna_network_from_bbox()
net = osm.pdna_network_from_bbox(
lat_min, lng_min, lat_max, lng_max, network_type="walk"
)
/Users/nhand/mambaforge/envs/musa-550-fall-2022/lib/python3.9/site-packages/osmnet/load.py:445: FutureWarning: Assigning CRS to a GeoDataFrame without a geometry column is now deprecated and will not be supported in the future. gdf.crs = crs /Users/nhand/mambaforge/envs/musa-550-fall-2022/lib/python3.9/site-packages/pyproj/crs/crs.py:141: FutureWarning: '+init=<authority>:<code>' syntax is deprecated. '<authority>:<code>' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6 in_crs_string = _prepare_from_proj_string(in_crs_string) /Users/nhand/mambaforge/envs/musa-550-fall-2022/lib/python3.9/site-packages/osmnet/load.py:445: FutureWarning: Assigning CRS to a GeoDataFrame without a geometry column is now deprecated and will not be supported in the future. gdf.crs = crs /Users/nhand/mambaforge/envs/musa-550-fall-2022/lib/python3.9/site-packages/osmnet/load.py:147: ShapelyDeprecationWarning: __len__ for multi-part geometries is deprecated and will be removed in Shapely 2.0. Check the length of the `geoms` property instead to get the number of parts of a multi-part geometry. 'in {:,} request(s)'.format(len(geometry))) /Users/nhand/mambaforge/envs/musa-550-fall-2022/lib/python3.9/site-packages/osmnet/load.py:151: ShapelyDeprecationWarning: Iteration over multi-part geometries is deprecated and will be removed in Shapely 2.0. Use the `geoms` property to access the constituent parts of a multi-part geometry. for poly in geometry:
Requesting network data within bounding box from Overpass API in 1 request(s) Posting to http://www.overpass-api.de/api/interpreter with timeout=180, "{'data': '[out:json][timeout:180];(way["highway"]["highway"!~"motor|proposed|construction|abandoned|platform|raceway"]["foot"!~"no"]["pedestrians"!~"no"](39.95545800,-75.14891000,39.98475700,-75.11322600);>;);out;'}"
/Users/nhand/mambaforge/envs/musa-550-fall-2022/lib/python3.9/site-packages/osmnet/load.py:237: DeprecationWarning: Flags not at the start of the expression '//(?s)(.*?)/' but at position 2 domain = re.findall(r'//(?s)(.*?)/', url)[0] /Users/nhand/mambaforge/envs/musa-550-fall-2022/lib/python3.9/site-packages/osmnet/load.py:171: ShapelyDeprecationWarning: __len__ for multi-part geometries is deprecated and will be removed in Shapely 2.0. Check the length of the `geoms` property instead to get the number of parts of a multi-part geometry. ' {:,.2f} seconds'.format(len(geometry), time.time()-start_time))
Downloaded 1,889.5KB from www.overpass-api.de in 1.13 seconds Downloaded OSM network data within bounding box from Overpass API in 1 request(s) and 1.18 seconds Returning OSM data with 10,476 nodes and 3,323 ways... Edge node pairs completed. Took 1.10 seconds Returning processed graph with 5,058 nodes and 7,666 edges... Completed OSM data download and Pandana node and edge table creation in 2.37 seconds Generating contraction hierarchies with 10 threads. Setting CH node vector of size 5058 Setting CH edge vector of size 7732 Range graph removed 298 edges of 15464 . 10% . 20% . 30% . 40% . 50% . 60% . 70% . 80% . 90% . 100%
Key function: network.set_pois()
# sensible defaults
max_distance = 2000 # in meters
num_pois = 10 # only need the 10 nearest POI to each point in the network
AMENITIES = ["restaurant", "bar", "school", "car_sharing"]
for amenity in AMENITIES:
# get the subset of amenities for this type
pois_subset = poi_df[poi_df["amenity"] == amenity]
# set the POI, using the longitude and latitude of POI
net.set_pois(
amenity, max_distance, num_pois, pois_subset["lon"], pois_subset["lat"]
)
/Users/nhand/mambaforge/envs/musa-550-fall-2022/lib/python3.9/site-packages/pandana/network.py:660: FutureWarning: The default dtype for empty Series will be 'object' instead of 'float64' in a future version. Specify a dtype explicitly to silence this warning. elif isinstance(maxitems, type(pd.Series())): /Users/nhand/mambaforge/envs/musa-550-fall-2022/lib/python3.9/site-packages/pandana/network.py:668: FutureWarning: The default dtype for empty Series will be 'object' instead of 'float64' in a future version. Specify a dtype explicitly to silence this warning. elif isinstance(maxdist, type(pd.Series())): /Users/nhand/mambaforge/envs/musa-550-fall-2022/lib/python3.9/site-packages/pandana/network.py:660: FutureWarning: The default dtype for empty Series will be 'object' instead of 'float64' in a future version. Specify a dtype explicitly to silence this warning. elif isinstance(maxitems, type(pd.Series())): /Users/nhand/mambaforge/envs/musa-550-fall-2022/lib/python3.9/site-packages/pandana/network.py:668: FutureWarning: The default dtype for empty Series will be 'object' instead of 'float64' in a future version. Specify a dtype explicitly to silence this warning. elif isinstance(maxdist, type(pd.Series())): /Users/nhand/mambaforge/envs/musa-550-fall-2022/lib/python3.9/site-packages/pandana/network.py:660: FutureWarning: The default dtype for empty Series will be 'object' instead of 'float64' in a future version. Specify a dtype explicitly to silence this warning. elif isinstance(maxitems, type(pd.Series())): /Users/nhand/mambaforge/envs/musa-550-fall-2022/lib/python3.9/site-packages/pandana/network.py:668: FutureWarning: The default dtype for empty Series will be 'object' instead of 'float64' in a future version. Specify a dtype explicitly to silence this warning. elif isinstance(maxdist, type(pd.Series())): /Users/nhand/mambaforge/envs/musa-550-fall-2022/lib/python3.9/site-packages/pandana/network.py:660: FutureWarning: The default dtype for empty Series will be 'object' instead of 'float64' in a future version. Specify a dtype explicitly to silence this warning. elif isinstance(maxitems, type(pd.Series())): /Users/nhand/mambaforge/envs/musa-550-fall-2022/lib/python3.9/site-packages/pandana/network.py:668: FutureWarning: The default dtype for empty Series will be 'object' instead of 'float64' in a future version. Specify a dtype explicitly to silence this warning. elif isinstance(maxdist, type(pd.Series())):
# keyword arguments to pass for the matplotlib figure
bbox_aspect_ratio = (lat_max - lat_min) / (lng_max - lng_min)
fig_kwargs = {"facecolor": "w", "figsize": (10, 10 * bbox_aspect_ratio)}
# keyword arguments to pass for scatter plots
plot_kwargs = {"s": 20, "alpha": 0.9, "cmap": "viridis_r", "edgecolor": "none"}
For every point on the network, find the nth nearest POI, calculate the distance, and color that point according to the distance.
network.nearest_poi()
to get distances from nodes to nearest POIsnetwork.nearest_poi()
to get distances from nodes to nearest POIs¶amenity = 'bar'
access = net.nearest_pois(distance=2000,
category=amenity,
num_pois=num_pois)
access.head(n=20)
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | |
---|---|---|---|---|---|---|---|---|---|---|
id | ||||||||||
103353219 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 |
103357134 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 |
103357139 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 |
103407531 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 |
103407534 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 |
103417453 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 |
103426172 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 |
103426218 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 |
103439886 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 |
103449512 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 |
103455424 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 |
103455428 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 | 2000.000000 |
109729330 | 549.151001 | 874.491028 | 1169.784058 | 1180.850952 | 1351.123047 | 1466.088989 | 1626.576050 | 1628.883057 | 1694.576050 | 1719.431030 |
109729372 | 420.627014 | 745.966980 | 1041.260010 | 1052.327026 | 1222.598999 | 1337.564941 | 1500.359009 | 1507.890991 | 1566.052002 | 1590.906982 |
109729430 | 456.679993 | 615.130005 | 617.140991 | 621.968994 | 640.507019 | 706.966003 | 713.599976 | 745.981995 | 900.133972 | 989.281982 |
109729453 | 554.469971 | 615.809998 | 648.192017 | 650.901001 | 712.919983 | 714.931030 | 719.758972 | 738.296997 | 833.804016 | 922.952026 |
109729661 | 480.838989 | 806.179016 | 1101.472046 | 1112.538940 | 1282.811035 | 1397.776978 | 1560.571045 | 1582.126953 | 1626.264038 | 1651.119019 |
109729673 | 412.653015 | 737.992981 | 1033.286011 | 1044.353027 | 1214.625000 | 1329.590942 | 1492.385010 | 1524.015991 | 1558.078003 | 1582.932983 |
109729699 | 306.233002 | 631.572998 | 926.866028 | 937.932983 | 1108.204956 | 1223.171021 | 1385.964966 | 1421.582031 | 1451.657959 | 1476.512939 |
109729709 | 215.768005 | 541.107971 | 836.401001 | 847.468018 | 1017.739990 | 1132.706055 | 1295.500000 | 1339.989990 | 1361.192993 | 1386.047974 |
net.nodes_df.head()
x | y | |
---|---|---|
id | ||
103353219 | -75.115434 | 39.957472 |
103357134 | -75.114734 | 39.954193 |
103357139 | -75.113843 | 39.957221 |
103407531 | -75.120641 | 39.955889 |
103407534 | -75.119286 | 39.955627 |
access.head()
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | |
---|---|---|---|---|---|---|---|---|---|---|
id | ||||||||||
103353219 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 |
103357134 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 |
103357139 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 |
103407531 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 |
103407534 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 |
# Merge the nodes and the distance to POIs
nodes = pd.merge(net.nodes_df, access, left_index=True, right_index=True)
# Make into a geodataframe
nodes = gpd.GeoDataFrame(
nodes, geometry=gpd.points_from_xy(nodes["x"], nodes["y"]), crs="EPSG:4326"
)
nodes.head()
x | y | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | geometry | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
id | |||||||||||||
103353219 | -75.115434 | 39.957472 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | POINT (-75.11543 39.95747) |
103357134 | -75.114734 | 39.954193 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | POINT (-75.11473 39.95419) |
103357139 | -75.113843 | 39.957221 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | POINT (-75.11384 39.95722) |
103407531 | -75.120641 | 39.955889 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | POINT (-75.12064 39.95589) |
103407534 | -75.119286 | 39.955627 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | 2000.0 | POINT (-75.11929 39.95563) |
Let's define a function to do this for us, since we'll repeat this plot multiple times
def plot_walking_distance(net, amenity, distance=1000, n=1):
"""
Plot the walking distance to the specified amenity
"""
from mpl_toolkits.axes_grid1 import make_axes_locatable
# subset of POI
poi_subset = poi_df[poi_df["amenity"] == amenity]
# get the distances to nearest num_pois POI
access = net.nearest_pois(distance=1000, category=amenity, num_pois=num_pois)
# merge node positions and distances to nearest PO
nodes = pd.merge(net.nodes_df, access, left_index=True, right_index=True)
nodes = gpd.GeoDataFrame(
nodes, geometry=gpd.points_from_xy(nodes["x"], nodes["y"]), crs="EPSG:4326"
)
# Create the figure
fig, ax = plt.subplots(figsize=(10, 10))
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.1)
# plot the distance to the nth nearest amenity
ax = nodes.plot(ax=ax, cax=cax, column=nodes[n], legend=True, **plot_kwargs)
# add the amenities as stars
for i, row in poi_subset.iterrows():
ax.scatter(row["lon"], row["lat"], color="red", s=100, marker="*")
# format
ax.set_facecolor("black")
ax.figure.set_size_inches(fig_kwargs["figsize"])
# set extent
[xmin, ymin, xmax, ymax] = nodes.geometry.total_bounds
ax.set_xlim(xmin, xmax)
ax.set_ylim(ymin, ymax)
return ax
The difference between maps to the nearest amenity and for example, the 5th nearest amenity tells us about the options consumers have
ax = plot_walking_distance(net, "bar", n=1)
ax.set_title("Walking distance to the nearest bar", fontsize=18);
ax = plot_walking_distance(net, "bar", n=3)
ax.set_title("Walking distance to the 3rd nearest bar", fontsize=18);
ax = plot_walking_distance(net, "school", n=1)
ax.set_title("Walking distance to the nearest school", fontsize=18);
ax = plot_walking_distance(net, "school", n=3)
ax.set_title("Walking distance to the 3rd nearest school", fontsize=18);
ax = plot_walking_distance(net, "restaurant", n=1)
ax.set_title("Walking distance to the nearest restaurant", fontsize=18);
ax = plot_walking_distance(net, "restaurant", n=5)
ax.set_title("Walking distance to the 5th nearest restaurant", fontsize=18);
ax = plot_walking_distance(net, "car_sharing", n=1)
ax.set_title("Walking distance to the nearest car sharing", fontsize=18);
ax = plot_walking_distance(net, "car_sharing", n=5)
ax.set_title("Walking distance to the 5th nearest car sharing", fontsize=18);
Many, many more amenities are logged throughout the city. Pick your favorite neighborhood and explore.
See this page for the full list of amenities.
Final project idea: With this kind of analysis, you can look at amenity-based influence in housing, neighborhood selection, etc. or something similar to the Walk Score.