The code below renders a map of Census Tracts in San Francisco County. Note that it hard-codes the center of the map:
import plotly.express as px
import censusdis.data as ced
from censusdis.datasets import ACS5
variable = 'B01001_001E'
df = ced.download(
dataset=ACS5,
vintage=2022,
download_variables=['NAME', variable],
state='06',
county='075',
tract='*',
with_geometry=True)
df = df.set_index('NAME')
df = df.dropna()
fig = px.choropleth_mapbox(df,
geojson=df.geometry,
locations=df.index,
center={'lat': 37.74180915, 'lon': -122.38474831884692},
color=variable,
color_continuous_scale="Viridis",
mapbox_style="carto-positron",
opacity=0.5,
zoom=10)
fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
fig.show()
I would like to programmatically create maps like this for every county in the country. To do this, however, I need to be able to derive the center of df
(which is an object of type geopandas.geodataframe.GeoDataFrame
). I am unsure how to do this.
I am aware that the class has a member variable .centroid
. But when I call it:
geopandas.geoseries.GeoSeries
which seems to be the center of each Tract. But I need a single center point for all tracts.Geometry is in a geographic CRS. Results from 'centroid' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.
So even if I solve the first point, it appears that I would still need to do an additional step.How can I get the center of all tracts in the county?
If I understand correctly, you are looking for geopandas.total_bounds. This property returns the minimum bounding box for the entire GeoDataFrame.
To get the center of it, you can use e.g. shapely.centroid. E.g. something like this:
import geopandas as gpd
import shapely
p1 = shapely.Polygon([[0, 0], [0, 1], [1, 1], [0, 0]])
p2 = shapely.Polygon([[99, 99], [99, 100], [100, 100], [99, 99]])
df = gpd.GeoDataFrame(data={"desc": ["p1", "p2"]}, geometry=[p1, p2])
center = shapely.box(*df.total_bounds).centroid
print(center)
# POINT (50 50)