如何使用 GEOPANDAS 和 matplotlib 按条件添加阴影线

How to add hatching by condition with GEOPANDAS and matplotlib

我尝试绘制一张地图,其中一个值应定义每个多边形的阴影线类型。 我设法得到了整个情节的孵化器,但不是基于条件。 有没有办法用 geopandas 做到这一点? 我的代码:

import matplotlib as mpl
import matplotlib.pyplot as plt
import geopandas as gpd
from matplotlib.colors import Normalize

project_data = 'XXX'
border = gpd.read_file(f'{project_data}GIS/border.json')
data = gpd.read_file(f'{project_data}GIS/shape.json')

def marker(row, field):
    m = ''
    if (row[field] <= 0):
        m = ''
    elif (row[field] <= 0.5):
        m = '--'
    elif (row[field] <= 1):
        m = '/////'
    elif (row[field] <= 1.6):
        m = 'x'
    return m

data['UI_P45_M'] = data.apply(marker, field='UI_P45', axis=1)

field1 = 'AL_CUR_I'
hatch1 = 'UI_P45_M'
cmap = mpl.cm.get_cmap('pink_r')

fig, ax = plt.subplots(1)
ax.axis('off')
border.plot(facecolor="none", edgecolor="black",
       ax=ax, zorder=2, linewidth=0.5)
data.plot(
column=field1, linewidth=0, norm=Normalize(0, 1.2),
cmap=cmap, ax=ax, hatch=hatch1, zorder=1
)

fig = plt.gcf()

plt.savefig(f'{project_data}results/hatched.pdf')
plt.close(fig)

我也试过在我做阴影的地方放一层:

border.plot(facecolor="none", edgecolor="black",
           ax=ax,  zorder=3, linewidth=0.5)

data.plot(
    column=field1, linewidth=0,norm=Normalize(0,1.2),
    cmap=cmap, ax=ax, zorder=1
)
data.plot(
    column=field1, linewidth=0, hatch=hatch1,
    facecolor='none',
    ax=ax, zorder=2
)

...但它仍然没有出现。 我得到的图片是这样的:

我做错了什么?

import geopandas as gpd
import folium
from folium.plugins import StripePattern

gdf = gpd.read_file(gpd.datasets.get_path("naturalearth_lowres")).loc[
    lambda d: (d["continent"] == "Europe") & (~d["iso_a3"].isin(["-99", "RUS"]))
]
# classify countries into 4 with a label
gdf["fill_cat"] = pd.qcut(gdf["pop_est"], 4, labels=list("abcd"))

m = folium.Map(
    location=(gdf.total_bounds[[1, 3]].mean(), gdf.total_bounds[[0, 2]].mean()),
    height=300,
    width=500,
)
m.fit_bounds([gdf.total_bounds[[1, 0]].tolist(), gdf.total_bounds[[3, 2]].tolist()])

# category config
hatch_style = {
    "a": {"angle": 0, "color": "grey"},
    "b": {"angle": 45, "color": "red"},
    "c": {"angle": 90, "color": "green"},
    "d": {"angle": 135, "color": "blue"},
}
folium.GeoJson(
    gdf.__geo_interface__,
    tooltip=gpd.explore._tooltip_popup("tooltip", True, gdf),
    style_function=lambda p: {
        "color": hatch_style[p["properties"]["fill_cat"]]["color"],
        "weight": 1,
        "fillPattern": StripePattern(**hatch_style[p["properties"]["fill_cat"]]),
    },
).add_to(m)

m

绘制具有多边形几何的地理数据框利用了 matplotlib 的 Polygon artists,因此 hatch 关键字参数被传递到那里。

从多边形文档中,您可以看到 hatch 关键字本身由 matplotlib.patches.Patch.set_hatch 解释。来自这些文档:

set_hatch(hatch)

Set the hatching pattern.

hatch can be one of:

/   - diagonal hatching
\   - back diagonal
|   - vertical
-   - horizontal
+   - crossed
x   - crossed diagonal
o   - small circle
O   - large circle
.   - dots
*   - stars

Letters can be combined, in which case all the specified hatchings are done. If same letter repeats, it increases the density of hatching of that pattern.

所以问题实际上是您不能将列名指定为影线指示符。取而代之的是,对每种舱口类型的数据进行子集化,然后选择一个有效的舱口,例如:

data.loc[some_criteria_1].plot(..., hatch='/')
data.loc[some_criteria_2].plot(..., hatch='|')
# etc