[英]Plotting a choropleth map (with geopandas) using a user_defined classification scheme
我对 python 有点陌生,所以我希望我的问题的答案相对简单。
我正在尝试使用 geopandas 制作区域分布图。 但是,由于我正在制作需要相互比较的多个地图,因此使用自定义数据分类方案(而不是分位数或 jenks)是必不可少的。 因此,我一直在尝试使用 User_Defined 方案,我能够创建垃圾箱,但我不知道如何将它们应用到地图本身。
这是我为创建分类方案所做的工作:
import pysal.esda.mapclassify as ps
from pysal.esda.mapclassify import User_Defined
bins = [5, 20, 100, 600, 1000, 3000, 5000, 10000, 20000, 400000]
ud = User_Defined(projected_world_exports['Value'], bins)
(其中“值”是我在地图中绘制的列)
然后当我尝试绘制等值线图时,我不知道该计划的含义是什么
projected_world_exports.plot(column='Value', cmap='Greens', scheme = ?????)
如果有人可以提供帮助,我将不胜感激!
谢谢 x
我看了一下 geopandas 绘图函数的代码( https://github.com/geopandas/geopandas/blob/master/geopandas/plotting.py )但我猜plot
方法只接受三个名称之一(“分位数", "equal_interval", "fisher_jenks") 但不是直接的 bin 列表或pysal.esda.mapclassify
分类器,例如User_Defined
。
(我想这可能与最后一条评论是关于为“用户定义”分箱定义 API 的那个问题相关联)。
但是现在我想你可以通过稍微修改和重用我链接的文件中的函数来实现这一点。 例如,您可以像这样重写您自己的plot_dataframe
版本:
import numpy as np
def plot_dataframe(s, column, binning, cmap,
linewidth=1.0, figsize=None, **color_kwds):
import matplotlib.pyplot as plt
values = s[column]
values = np.array(binning.yb)
fig, ax = plt.subplots(figsize=figsize)
ax.set_aspect('equal')
mn = values.min()
mx = values.max()
poly_idx = np.array(
(s.geometry.type == 'Polygon') | (s.geometry.type == 'MultiPolygon'))
polys = s.geometry[poly_idx]
if not polys.empty:
plot_polygon_collection(ax, polys, values[poly_idx], True,
vmin=mn, vmax=mx, cmap=cmap,
linewidth=linewidth, **color_kwds)
plt.draw()
return ax
然后你需要通过复制它们来定义函数_flatten_multi_geoms和plot_polygon_collection ,你就可以像这样使用它了:
bins = [5, 20, 100, 600, 1000, 3000, 5000, 10000, 20000, 400000]
ud = User_Defined(projected_world_exports['Value'], bins)
plot_dataframe(projected_world_exports, 'Value', ud, 'Greens')
这是一种不需要修改 geopandas 代码的替代方法。 它涉及首先标记垃圾箱,以便您可以创建将每个垃圾箱标签映射到特定颜色的自定义颜色图。 然后必须在您的地理数据框中创建一列,指定将哪个 bin 标签应用于地理数据框中的每一行,然后该列用于使用自定义颜色图绘制等值线图。
from matplotlib.colors import LinearSegmentedColormap
bins = [5, 20, 100, 600, 1000, 3000, 5000, 10000, 20000, 400000]
# Maps values to a bin.
# The mapped values must start at 0 and end at 1.
def bin_mapping(x):
for idx, bound in enumerate(bins):
if x < bound:
return idx / (len(bins) - 1.0)
# Create the list of bin labels and the list of colors
# corresponding to each bin
bin_labels = [idx / (len(bins) - 1.0) for idx in range(len(bins))]
color_list = ['#edf8fb', '#b2e2e2', '#66c2a4', '#2ca25f', '#006d2c', \
'#fef0d9', '#fdcc8a', '#fc8d59', '#e34a33', '#b30000']
# Create the custom color map
cmap = LinearSegmentedColormap.from_list('mycmap',
[(lbl, color) for lbl, color in zip(bin_labels, color_list)])
projected_world_exports['Bin_Lbl'] = projected_world_exports['Value'].apply(bin_mapping)
projected_world_exports.plot(column='Bin_Lbl', cmap=cmap, alpha=1, vmin=0, vmax=1)
这可以使用UserDefined scheme轻松完成。 在定义这样的方案时,将在幕后使用mapclassify.MapClassifier对象。 实际上,所有支持的方案都是由mapclassify提供的。
为了传递您的垃圾箱,您需要将它们传递到classification_kwds参数中。
所以,你的代码将是:
projected_world_exports.plot(
column='Value',
cmap='Greens',
scheme='UserDefined',
classification_kwds={'bins': bins}
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.