参考资料:
https://github.com/mikhailsirenko/bivariate-choropleth/blob/main/bivariate-choropleth.ipynb
Bivariate choropleth map using Plotly
代码:
import pandas as pd
import geopandas as gpd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
from adjustText import adjust_text
import contextily as ctx
from sklearn.preprocessing import MinMaxScaler
from scipy.stats.mstats import winsorize
data = gpd.read_file('data.json')
data.head()
border = gpd.read_file('border.json')
# Define the bins
bins = [0, 0.33, 0.66, 1]
# Bin the first variable - x
data['Var1_Class'] = pd.cut(data['x'], bins=bins, include_lowest=True)
data['Var1_Class'] = data['Var1_Class'].astype('str')
# Bin the second variable - y
data['Var2_Class'] = pd.cut(data['y'], bins=bins, include_lowest=True)
data['Var2_Class'] = data['Var2_Class'].astype('str')
# Code created x bins to 1, 2, 3
x_class_codes = np.arange(1, len(bins))
d = dict(zip(data['Var1_Class'].value_counts().sort_index().index, x_class_codes))
data['Var1_Class'] = data['Var1_Class'].replace(d)
# Code created y bins to A, B, C
y_class_codes = ['A', 'B', 'C']
d = dict(zip(data['Var2_Class'].value_counts().sort_index().index, y_class_codes))
data['Var2_Class'] = data['Var2_Class'].replace(d)
# Combine x and y codes to create Bi_Class
data['Bi_Class'] = data['Var1_Class'].astype('str') + data['Var2_Class']
all_colors = ['#e8e8e8', '#b0d5df', '#64acbe', '#e4acac', '#ad9ea5', '#627f8c', '#c85a5a', '#985356', '#574249']
colors = ['#e8e8e8', # 1A
'#b0d5df', # 1B
# '#64acbe', # 1C
'#e4acac', # 2A
'#ad9ea5', # 2B
# '#627f8c', # 2C
'#c85a5a', # 3A
'#985356'] # 3B
# '#574249'] # 3C
cmap = matplotlib.colors.ListedColormap(colors)
fig, ax = plt.subplots(figsize=(8,8))
# Step 1: Draw the map
border.to_crs('EPSG:3857').plot(ax=ax, facecolor='none', edgecolor='black', alpha=.5) # city border
data.to_crs('EPSG:3857').plot(ax=ax,
column='Bi_Class', # variable that is going to be used to color the map
cmap=cmap, # newly defined bivariate cmap
categorical=True, # bivariate choropleth has to be colored as categorical map
legend=False) # we're going to draw the legend ourselves
ctx.add_basemap(ax=ax, source=ctx.providers.CartoDB.Positron) # add the basemap
plt.tight_layout() # "tighten" two figures map and basemap
plt.axis('off') # we don't need axis with coordinates
ax.set_title('Bivariate Choropleth Amsterdam')
# Step 2: draw the legend
# We're drawing a 3x3 "box" as 3 columns
# The xmin and xmax arguments axvspan are defined to create equally sized small boxes
img2 = fig # refer to the main figure
ax2 = fig.add_axes([0.15, 0.25, 0.1, 0.1]) # add new axes to place the legend there
# and specify its location
alpha = 1 # alpha argument to make it more/less transperent
# Column 1
ax2.axvspan(xmin=0, xmax=0.33, ymin=0, ymax=0.33, alpha=alpha, color=all_colors[0])
ax2.axvspan(xmin=0, xmax=0.33, ymin=0.33, ymax=0.66, alpha=alpha, color=all_colors[1])
ax2.axvspan(xmin=0, xmax=0.33, ymin=0.66, ymax=1, alpha=alpha, color=all_colors[2])
# Column 2
ax2.axvspan(xmin=0.33, xmax=0.66, ymin=0, ymax=0.33, alpha=alpha, color=all_colors[3])
ax2.axvspan(xmin=0.33, xmax=0.66, ymin=0.33, ymax=0.66, alpha=alpha, color=all_colors[4])
ax2.axvspan(xmin=0.33, xmax=0.66, ymin=0.66, ymax=1, alpha=alpha, color=all_colors[5])
# Column 3
ax2.axvspan(xmin=0.66, xmax=1, ymin=0, ymax=0.33, alpha=alpha, color=all_colors[6])
ax2.axvspan(xmin=0.66, xmax=1, ymin=0.33, ymax=0.66, alpha=alpha, color=all_colors[7])
ax2.axvspan(xmin=0.66, xmax=1, ymin=0.66, ymax=1, alpha=alpha, color=all_colors[8])
# Step 3: annoate the legend
ax2.tick_params(axis='both', which='both', length=0) # remove ticks from the big box
ax2.axis('off'); # turn off its axis
ax2.annotate("", xy=(0, 1), xytext=(0, 0), arrowprops=dict(arrowstyle="->", lw=1)) # draw arrow for x
ax2.annotate("", xy=(1, 0), xytext=(0, 0), arrowprops=dict(arrowstyle="->", lw=1)) # draw arrow for y
ax2.text(s='Var1\_Class', x=0.1, y=-0.25) # annotate x axis
ax2.text(s='Var2\_Class', x=-0.25, y=0.1, rotation=90); # annotate y axis
plt.savefig('bivariate_choropleth.png', dpi=300)
代码来源:https://github.com/mikhailsirenko/bivariate-choropleth/blob/main/bivariate-choropleth.ipynb