Visualize Parks and Racial Distribution in NYC with Dash

Using multiple callback inputs to produce dynamic Dash apps

Justin Morgan Williams


Photo by Eric Prouzet on Unsplash


I had envisioned a Dash app where one could hover over a choropleth map and trigger changes in the the dashboard, however, I also wanted a dropdown selector, that would trigger the same response. Essentially, I wanted to create an output, that had multiple inputs, and I needed to specify which input fired, to elicit the correct output response. I wasn’t able to get this to work with basic callback features. This took endless trial and era to complete (the documentation for advanced callback features isn’t that explicit), so I figured I would dedicate a blog to this app, with multiple input advanced callbacks being the focal point.


I wanted to show proportion of parks within each NYC Community District Tabulation Area (CDTA), juxtaposed against racial distribution. The intention was to be exploratory in nature, allowing one to view the different demographics in each CDTA, and parks.


The Parks Properties dataset identifies property managed partially or solely by NYC Parks. We download the shapefile directly to our notebook as a GeoDataFrame with GeoPandas. Then, convert the coordinate reference system (CRS) to New York State Plan 2263 (this is the preferred CRS used by NYC governmental entities).

import geopandas as gpd

# define url
parks_url = ''
gdf_parks = gpd.read_file(parks_url) # import shapefile as gdf

# change crs
gdf_parks.to_crs(2263, inplace=True)

# preview gdf

Preview the GeoDataFrame:

Preview of Parks Properties (not all colums are shown)

Let’s create a simple plot using the contextily package for a base map.



Justin Morgan Williams

Data scientist passionate about the intersectionality of sustainability and data.