This page was generated from notebooks/value_by_alpha.ipynb.
Interactive online version:
Value-by-Alpha Choropleth¶
Value-by-Alpha Choropleth plotting with mapclassify
This notebook is adapted from one originally written by @slumnitz in the
splot
project (original here).
Set up¶
Imports¶
[1]:
import geopandas
import libpysal
import matplotlib.pyplot as plt
Data Preparation¶
Load example data into a geopandas.GeoDataFrame
and inspect column names. In this example we will use the columbus.shp
file containing neighborhood crime data of 1980.
[2]:
link_to_data = libpysal.examples.get_path("columbus.shp")
gdf = geopandas.read_file(link_to_data)
gdf.columns
[2]:
Index(['AREA', 'PERIMETER', 'COLUMBUS_', 'COLUMBUS_I', 'POLYID', 'NEIG',
'HOVAL', 'INC', 'CRIME', 'OPEN', 'PLUMB', 'DISCBD', 'X', 'Y', 'NSA',
'NSB', 'EW', 'CP', 'THOUS', 'NEIGNO', 'geometry'],
dtype='object')
Our two variables of interest in gdf
:
x
:HOVAL
– housing value (in $1,000); the rgb variabley
:CRIME
– residential burglaries and vehicle thefts per 1000 households; the alpha variable
[3]:
x = "HOVAL"
y = "CRIME"
Create Value-by-Alpha Choropleths¶
What is a Value by Alpha choropleth?¶
In a nutshell, a Value-by-Alpha Choropleth is a bivariate choropleth that uses the values of the second input variable y
as a transparency mask, determining how much of the choropleth displaying the values of a first variable x
is shown. In comparison to a cartogram, Value-By-Alpha choropleths will not distort shapes and sizes but modify the alpha channel (transparency) of polygons according to the second input variable y
.
Let’s look at a couple of examples.
[4]:
from mapclassify.value_by_alpha import vba_choropleth
We can create a value by alpha map using vba_choropleth
.
We will plot a Value-by-Alpha Choropleth with x
(HOVAL
) defining the rgb values and y
(CRIME
) defining the alpha value. For comparison we plot a choropleth of x
with gdf.plot()
:
[5]:
# Create new figure
fig, axs = plt.subplots(2, 2, figsize=(15, 10))
# use gdf.plot() to create regular choropleth
axs[0, 0].set_title("normal Choropleth")
axs[0, 0].set_axis_off()
gdf.plot(column=x, scheme="quantiles", cmap="RdBu", ax=axs[0, 0])
# use vba_choropleth to create Value-by-Alpha Choropleth
axs[0, 1].set_title("Value-by-Alpha Choropleth")
axs[0, 1].set_axis_off()
vba_choropleth(
x,
y,
gdf,
x_classification_kwds={"classifier": "quantiles"},
y_classification_kwds={"classifier": "quantiles"},
cmap="RdBu",
ax=axs[0, 1],
)
# create a VBA Choropleth - divergent=False, revert_alpha=False
axs[1, 0].set_title("divergent=False, revert_alpha=False")
axs[1, 0].set_axis_off()
vba_choropleth(
x,
y,
gdf,
x_classification_kwds={"classifier": "quantiles"},
y_classification_kwds={"classifier": "quantiles"},
cmap="RdBu",
ax=axs[1, 0],
divergent=True,
revert_alpha=False,
)
# create a VBA Choropleth - divergent=False, revert_alpha=True
axs[1, 1].set_title("divergent=False, revert_alpha=True")
axs[1, 1].set_axis_off()
vba_choropleth(
x,
y,
gdf,
x_classification_kwds={"classifier": "quantiles"},
y_classification_kwds={"classifier": "quantiles"},
cmap="RdBu",
ax=axs[1, 1],
divergent=False,
revert_alpha=True,
)
plt.show()

You can see the original choropleth is fading into transparency wherever there is a high y
value.
Classification & binning options¶
You can use the option to bin or classify your x
and y
values, and display the alternative color and alpha ranges:
[6]:
# Create new figure
fig, axs = plt.subplots(2, 2, figsize=(15, 10))
# classify with Quantiles
axs[0, 0].set_axis_off()
vba_choropleth(
x,
y,
gdf,
cmap="viridis",
ax=axs[0, 0],
x_classification_kwds={"classifier": "quantiles", "k": 3},
y_classification_kwds={"classifier": "quantiles", "k": 3},
)
# classifier with Natural Breaks
axs[0, 1].set_axis_off()
vba_choropleth(
x,
y,
gdf,
cmap="viridis",
ax=axs[0, 1],
x_classification_kwds={"classifier": "natural_breaks"},
y_classification_kwds={"classifier": "natural_breaks"},
)
# classify with Standard Deviation Mean
axs[1, 0].set_axis_off()
vba_choropleth(
x,
y,
gdf,
cmap="viridis",
ax=axs[1, 0],
x_classification_kwds={"classifier": "std_mean"},
y_classification_kwds={"classifier": "std_mean"},
)
# classify with Fisher Jenks
axs[1, 1].set_axis_off()
vba_choropleth(
x,
y,
gdf,
cmap="viridis",
ax=axs[1, 1],
x_classification_kwds={"classifier": "fisher_jenks", "k": 3},
y_classification_kwds={"classifier": "fisher_jenks", "k": 3},
)
plt.show()

User-defined colors¶
Instead of using a colormap you can also pass a list of colors:
[7]:
color_list = ["#a1dab4", "#41b6c4", "#225ea8"]
[8]:
_, ax = vba_choropleth(
x,
y,
gdf,
cmap=color_list,
x_classification_kwds={"classifier": "quantiles", "k": 3},
y_classification_kwds={"classifier": "quantiles"},
)
ax.set_axis_off()
plt.show()

Transposing transparency¶
Sometimes it is important in geospatial analysis to actually see the high values and let the small values fade out. With the revert_alpha = True
argument, you can revert the transparency of the y
values so that high y
values will more transparent and low values will more opaque.
[9]:
# Create new figure
fig, axs = plt.subplots(1, 2, figsize=(20, 10))
# create a vba_choropleth
axs[0].set_title("revert_alpha = False")
axs[0].set_axis_off()
vba_choropleth(
x,
y,
gdf,
x_classification_kwds={"classifier": "quantiles"},
y_classification_kwds={"classifier": "quantiles"},
cmap="RdBu",
ax=axs[0],
revert_alpha=False,
)
# set revert_alpha argument to True
axs[1].set_title("revert_alpha = True")
axs[1].set_axis_off()
vba_choropleth(
x,
y,
gdf,
x_classification_kwds={"classifier": "quantiles"},
y_classification_kwds={"classifier": "quantiles"},
cmap="RdBu",
ax=axs[1],
revert_alpha=True,
)
plt.show()

Displaying divergency¶
You can use the divergent
argument to display divergent alpha values. This means values at the extremes of your data range will be displayed with an alpha value of 1. Values towards the middle of your data range will be mapped increasingly transparent approaching an alpha value of 0.
[10]:
# create new figure
fig, axs = plt.subplots(1, 2, figsize=(20, 10))
# create a vba_choropleth
axs[0].set_title("divergent = False")
axs[0].set_axis_off()
vba_choropleth(x, y, gdf, cmap="RdBu", divergent=False, ax=axs[0])
# set divergent to True
axs[1].set_title("divergent = True")
axs[1].set_axis_off()
vba_choropleth(x, y, gdf, cmap="RdBu", divergent=True, ax=axs[1])
plt.show()

Create your own cmap for plotting¶
Colormap shifting¶
Sometimes you need to display divergent values with a natural midpoint not overlapping with the median of your data. For example, if you measure the temperature over a country ranging from -2 to 10 degrees Celsius. Or if you need to assess whether a certain threshold is reached.
For cases like this, we can use shift_colormap
.
[11]:
from mapclassify.value_by_alpha import shift_colormap
[12]:
# shift the midpoint to the 80th percentile of your datarange
mid08 = shift_colormap("RdBu", midpoint=0.8, name="RdBu_08")
mid08
[12]:
[13]:
# shift the midpoint to the 20th percentile of your datarange
mid02 = shift_colormap("RdBu", midpoint=0.2, name="RdBu_02")
mid02
[13]:
[14]:
# create new figure
fig, axs = plt.subplots(1, 2, figsize=(20, 10))
# vba_choropleth with cmap mid08
vba_choropleth(x, y, gdf, cmap=mid08, ax=axs[0], divergent=True)
axs[0].set_axis_off()
# vba_choropleth with cmap mid02
vba_choropleth(x, y, gdf, cmap=mid02, ax=axs[1], divergent=True)
axs[1].set_axis_off()
plt.show()

Colormap truncation¶
You may also want to truncate minimum and maximum values for demonstrative or merely aesthetic purposes.
For cases like this, we can use truncate_colormap
.
[15]:
from mapclassify.value_by_alpha import truncate_colormap
[16]:
# truncate to the 20th-60th percentile of your datarange
trunc0206 = truncate_colormap("RdBu", minval=0.2, maxval=0.6, n=2)
trunc0206
[16]:
[17]:
# truncate to the 40th-90th percentile of your datarange
trunc0409 = truncate_colormap("RdBu", minval=0.4, maxval=0.9, n=2)
trunc0409
[17]:
[18]:
# create new figure
fig, axs = plt.subplots(1, 2, figsize=(20, 10))
# vba_choropleth with cmap trunc0206
vba_choropleth(x, y, gdf, cmap=trunc0206, ax=axs[0], divergent=True)
axs[0].set_axis_off()
# vba_choropleth with cmap trunc0409
vba_choropleth(x, y, gdf, cmap=trunc0409, ax=axs[1], divergent=True)
axs[1].set_axis_off()
plt.show()

Add a legend¶
If your values are classified, you have the option to add a legend to your map.
[19]:
fig = plt.figure(figsize=(15, 10))
ax = fig.add_subplot(111)
gdf.plot(ax=ax, fc="none", ec="k", lw=0.1)
vba_choropleth(
x,
y,
gdf,
ax=ax,
x_classification_kwds={"classifier": "quantiles", "k": 5},
y_classification_kwds={"classifier": "quantiles", "k": 5},
legend=True,
legend_kwargs={"x_label": x, "y_label": y},
)
ax.set_axis_off()
plt.show()
