Quick Start: Create Your First Flow Cartogram¶
Get started with carto-flow by creating a population cartogram in just a few lines of code.
What You'll Learn¶
- How to download population and geographic data from the US Census Bureau
- How to create a basic flow cartogram from geographic data using the
morph_gdffunction - How to visualize the flow cartogram
Prerequisites¶
Install carto-flow first. For the examples, we use data from the US Census Bureau. The censusdis package offers a convenient interface for downloading this data.
# Install prerequisites (run this once in your terminal)
# pip install carto-flow
# pip install censusdis
Step 1: Import Libraries¶
import matplotlib.pyplot as plt
import carto_flow.data as examples
import carto_flow.flow_cartogram as flow
Step 2: Load Geographic Data¶
Load population and geometry data for the lower 48 US States from the US Census Bureau data repository.
us_states = examples.load_us_census(population=True)
The us_states variable is a GeoPandas DataFrame, with for each US State the requested variables, the computed population density, and its geometry.
Let's plot a color map of the population in each state and the population density (i.e., the number of people per area). GeoPandas DataFrames have a convenient plot method that we use here to create a choropleth map in which colors represent the population or density. Note that some states are large in size, but have a small population. Overall, population density varies significantly across states.
fig, axes = plt.subplots(2, 1, figsize=(8, 12))
for ax, col, vmax in zip(axes, ("Population (Millions)", "Population Density"), (40, 500), strict=False):
us_states.plot(
col,
ax=ax,
vmin=0,
vmax=vmax,
legend=True,
legend_kwds={"shrink": 0.6, "label": col},
cmap="RdYlGn_r",
linewidth=0.5,
)
ax.set(title=col)
ax.axis("off")
plt.tight_layout();
Step 3: Creating a Flow Cartogram for Population Visualization¶
Flow cartograms are used to visualize data where region areas are proportional to a variable of interest, making it easier to compare magnitudes across geographic regions. The goal in creating a flow cartogram is to deform the geometries such that each region's area matches its population size while ensuring contiguousness and preserving spatial relationships between neighboring states. In this example, we create a flow cartogram of US states where each state's area is proportional to its population. This helps overcome the misleading visual bias caused by large but sparsely populated states (those with low population density, meaning fewer people per unit of land area).
result = flow.morph_gdf(us_states, "Population")
Morph geometries: 22%|████▍ | 112/500 [00:05<00:19, 19.56it/s, max=1.2%, mean=0.2% - converged]
Let's plot the result. Note that US States with a high population density (such as New Jersey, California, and New York) have increased in size, whereas those with a low population density (such as North Dakota and Montana) have decreased in size. After morphing, the population densities have been equalized and are close to the average population density across all States.
fig, axes = plt.subplots(2, 1, figsize=(8, 12))
# Note that we could use the `plot` method directly on the result object
# But we need to recompute the population density in people / square km
# And thus we convert the result to a dataframe
result_df = result.to_geodataframe()
# and recompute population density
result_df["Population Density"] = result_df["Population"] / (result_df.area / 1e6)
for ax, col, vmax in zip(axes, ("Population (Millions)", "Population Density"), (40, 500), strict=False):
result_df.plot(
col,
ax=ax,
vmin=0,
vmax=vmax,
legend=True,
legend_kwds={"shrink": 0.6, "label": col},
cmap="RdYlGn_r",
linewidth=0.5,
)
ax.set(title=col)
ax.axis("off")
plt.tight_layout();
Additional Resources¶
This notebook is part of the carto-flow documentation. Report issues at https://github.com/bright-fakl/carto-flow/issues