matplotlib - Geopandas 一致的用户定义子图配色方案
问题描述
我是 geopandas 的新手,我在创建具有一致 bin 的 choropleth 子图时遇到了麻烦。我需要在所有子图中创建一致的用户定义配色方案。
我遵循了以下示例: matplotlib geopandas plot chloropleth with set bins for colourscheme https://github.com/geopandas/geopandas/issues/1019
虽然我能够重现这两个示例,但我对自己的数据有非常奇怪的行为。下面是一个复制我的问题的玩具示例。
import geopandas as gpd
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from mapclassify import Quantiles, UserDefined
import os
# Note you can read directly from the URL
gdf = gpd.read_file('https://opendata.arcgis.com/datasets/8d3a9e6e7bd445e2bdcc26cdf007eac7_4.geojson')
#gdf.plot()
gdf.shape
gdf.columns
gdf['rgn15nm'].head(9)
d = {
'rgn15nm': ['North East', 'North West', 'Yorkshire and The Humber', 'East Midlands', 'West Midlands', 'East of England', 'London', 'South East', 'South West'],
'1980' : pd.Series([0, 1, 0, 0, 0, 0, 0, 0, 0]),
'2000' : pd.Series([1, 1, 1, 0, 0, 0, 0, 0, 0]),
'2020' : pd.Series([1, 1, 10, 3, 1, 0, 0, 0, 1])
}
df = pd.DataFrame(d)
数据如下所示:
gdf = gdf.merge(df, on='rgn15nm')
# Define bins
gdf['2020'].describe()
bins= UserDefined(gdf['2020'], bins=[0,1,2,3,4,5,6,7,8,9,10]).bins
bins
# create a new column with the discretized values and plot that col
# repeat for each view
fig,(ax1,ax2,ax3) = plt.subplots(1,3,figsize=(15,6))
gdf.assign(cl=UserDefined(gdf['1980'].dropna(), bins).yb).plot(column='cl', ax=ax1, cmap='OrRd', legend = True )
gdf.assign(cl=UserDefined(gdf['2000'].dropna(), bins).yb).plot(column='cl', ax=ax2, cmap='OrRd', legend = True)
gdf.assign(cl=UserDefined(gdf['2020'].dropna(), list(bins)).yb).plot(column='cl', ax=ax3, cmap='OrRd', legend = True)
for ax in (ax1,ax2,ax3,):
ax.axis('off')
显然,不同 subplots的配色方案是不一样的。我的意思是,“西北”(1980 年子图中唯一突出显示的区域)在 1980、2000和 2020年的所有年份中都具有相同的值1。然而,该区域在 3 个子图中以不同的颜色显示,尽管值是恒定的。我希望“西北”在所有 3 个子图中以相同的颜色(2020 年子图的颜色)显示。
我也试过这个:
fig,(ax1,ax2,ax3) = plt.subplots(1,3,figsize=(15,6))
ax1.set_title('1980')
ax2.set_title('2000')
ax3.set_title('2020')
gdf.plot(column='1980', ax=ax1, cmap='OrRd', scheme='userdefined', classification_kwds={'bins':[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]})
gdf.plot(column='2000', ax=ax2, cmap='OrRd', scheme='userdefined', classification_kwds={'bins':[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]})
gdf.plot(column='2020', ax=ax3, cmap='OrRd', scheme='userdefined', classification_kwds={'bins':[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]})
for ax in (ax1,ax2,ax3):
ax.axis('off')
但得到了与上面完全相同的数字(见下文)
有没有人有任何见解?我想要在所有 3 个子图中使用一致的配色方案。
解决方案
所以最终解决方案是使用“规范”选项。按照这个例子:Geopandas 用户定义的配色方案会掉色。见下文:
from matplotlib.colors import Normalize
bins= UserDefined(gdf['2020'], bins=[0,1,2,3,4,5,6,7,8,9,10]).bins
bins
fig,(ax1,ax2,ax3) = plt.subplots(1,3,figsize=(15,6))
ax1.set_title('1980')
ax2.set_title('2000')
ax3.set_title('2020')
gdf.plot(column='1980', ax=ax1, cmap='OrRd', scheme='userdefined', classification_kwds={'bins':bins}, norm=Normalize(0, len(bins)))
gdf.plot(column='2000', ax=ax2, cmap='OrRd', scheme='userdefined', classification_kwds={'bins':bins}, norm=Normalize(0, len(bins)))
gdf.plot(column='2020', ax=ax3, cmap='OrRd', scheme='userdefined', classification_kwds={'bins':bins}, norm=Normalize(0, len(bins)))
for ax in (ax1,ax2,ax3):
ax.axis('off')
结果就是我想要的:
或按照 Paul H 的建议:
fig,(ax1,ax2,ax3) = plt.subplots(1,3,figsize=(15,6))
ax1.set_title('1980')
ax2.set_title('2000')
ax3.set_title('2020')
gdf.plot(column='1980', ax=ax1, cmap='OrRd', scheme='userdefined', classification_kwds={'bins':bins}, vmin = 0, vmax = 10)
gdf.plot(column='2000', ax=ax2, cmap='OrRd', scheme='userdefined', classification_kwds={'bins':bins}, vmin = 0, vmax = 10)
gdf.plot(column='2020', ax=ax3, cmap='OrRd', scheme='userdefined', classification_kwds={'bins':bins}, vmin = 0, vmax = 10)
for ax in (ax1,ax2,ax3):
ax.axis('off')
推荐阅读
- powershell - (get-date).today 检索日期信息失败
- java - Go DSA 和 Java DSA 的区别
- c# - 当光标移动到 FlowDocumentPageViewer 上时如何捕获光标后面的单词
- postgresql - PostgreSQL 列来跟踪某种类型的出现次数
- c - GCC编译错误,不确定要改什么
- javascript - 在对象数组或对象对象中查找特定键的所有值
- android - 堆叠条上的圆角 - MPAndroidChart
- javascript - 如何从多个函数调用中获取组合参数
- javascript - 当用户单击javascript中的其他元素时如何停止播放视频
- ethereum - 是否可以直接从 etherscan 重新映射