5

我对python有点陌生,所以我希望我的问题的答案相对简单。

我正在尝试使用 geopandas 制作等值线图。但是,由于我正在制作多个需要相互比较的地图,因此使用自定义数据分类方案(而不是分位数或詹克斯)是必不可少的。因此,我一直在尝试使用 User_Defined 方案,并且我能够创建 bin,但我不知道如何将它们应用于地图本身。

这是我为创建分类方案所做的:

    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

4

3 回答 3

5

这是一种不需要修改 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)
于 2017-08-09T17:53:44.577 回答
5

I took a look at the code of geopandas plotting function (https://github.com/geopandas/geopandas/blob/master/geopandas/plotting.py) but I guess the plot method only accepts one of the three name ("quantiles", "equal_interval", "fisher_jenks") but not directly a list of bins or a pysal.esda.mapclassify classifier such as User_Defined.
(I guess it could be linked to that issue where the last comment is about defining an API for "user defined" binning).

However for now I guess you can achieve this by slightly modifying and reusing the functions from the file I linked. For example you could rewrite you're own version of plot_dataframe like this :

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

Then you would need to define the functions _flatten_multi_geoms and plot_polygon_collection by copying them and you are ready to use it like this :

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')
于 2017-01-21T22:09:44.400 回答
2

这可以使用UserDefined 方案轻松完成。在定义此类方案时,将在后台使用mapclassify.MapClassifier对象。事实上,所有支持的方案都是由mapclassify提供的。

要传递您的垃圾箱,您需要将它们传递到classification_kwds参数中。

因此,您的代码将是:

projected_world_exports.plot(
    column='Value', 
    cmap='Greens', 
    scheme='UserDefined', 
    classification_kwds={'bins': bins}
)
于 2021-02-17T02:48:27.913 回答