GeoPandas采用UserDefined方案绘图时中间类别缺失问题
解决GeoPandas UserDefined分级图部分场景分箱缺失问题
问题根源
你遇到的分箱缺失、颜色错位问题,本质是当待绘制的var1数据未覆盖所有预设区间时,GeoPandas会自动剔除无数据的分箱,导致你定义的ListedColormap颜色列表与实际显示的分箱不匹配——空分箱对应的颜色会被跳过,后面的颜色往前补,就出现了中间颜色丢失的情况。另外你的bins定义也有问题:6个分界点只能生成5个区间,但你有7个标签,这也是分箱逻辑混乱的原因之一。
解决方案
通过手动分箱+自定义图例的方式,强制保留所有预设的7个分箱,不管对应区间有没有数据。
步骤1:修正分箱规则,手动强制分箱
先把bins调整为能生成7个区间的分界点,再用pd.cut把var1按固定规则分箱,强制保留所有7个类别标签。
步骤2:自定义图例,确保所有类别显示
默认图例只会渲染有数据的分箱,手动创建图例可以保证7个类别全部显示,且颜色与预设列表严格对应。
修改后的完整代码
import pandas as pd import matplotlib.pyplot as plt from matplotlib.colors import ListedColormap from matplotlib.patches import Patch # 预设颜色与对应标签 list_colours = [ "#004c6d", "#628199", "#abbac7", "#f6f6f6", "#f3bcbc", "#e88184", "#d43d51", ] list_leg_labels = [ "Large decline", "Moderate decline", "Small decline", "No change", "Small increase", "Moderate increase", "Large increase", ] # 修正bins:7个分界点对应7个区间,覆盖所有可能的var1取值 bins = [-float('inf'), -20, -10, -1, 1, 10, 20, float('inf')] cmap = ListedColormap(list_colours) bbox_to_anchor = (0.225, 0.26) figsize = (20, 20) # 手动分箱:强制生成7个类别,空区间也保留标签 df_to_plot['var1_binned'] = pd.cut( df_to_plot[var1], bins=bins, labels=list_leg_labels, include_lowest=True, right=True # 保持与GeoPandas默认的右闭区间逻辑一致 ) # 绘制分级图:按分类数据绘制,关闭默认图例 fig, ax = plt.subplots(figsize=figsize) df_to_plot.plot( column='var1_binned', ax=ax, linewidth=0.2, cmap=cmap, categorical=True, # 明确为分类数据,避免自动剔除空类别 legend=False, zorder=1, ) # 手动创建包含所有7个类别的图例 legend_elements = [Patch(facecolor=color, label=label) for color, label in zip(list_colours, list_leg_labels)] ax.legend( handles=legend_elements, bbox_to_anchor=bbox_to_anchor, borderaxespad=0, fontsize=9, ncol=1, frameon=False, ) plt.show()
关键修改说明
- 修正
bins定义:7个分界点生成7个区间,完美匹配你预设的7个标签。 - 手动分箱:
pd.cut强制保留所有7个类别,即使某个区间没有数据,对应的标签也不会被剔除。 - 分类绘制:
categorical=True告诉GeoPandas按分类数据处理,不会自动过滤空类别。 - 自定义图例:用
Patch手动生成图例元素,确保所有7个类别都显示,颜色与预设列表一一对应。
内容的提问来源于stack exchange,提问作者gkr
相关产品推荐
相关产品推荐

