GeoPandas绘图太丑?GIS可视化教程(含:配色表)
如果你正在搜索“GeoPandas绘图太丑?GIS可视化教程(含:配色表)”,大概率已经遇到过一个很典型的问题:同样一份矢量数据,在 QGIS 或 ArcGIS Pro 里看起来还不错,但用 GeoPandas 的 .plot() 一画,颜色生硬、边界粗糙、图例难看、中文标题还可能乱码。
这篇教程面向 GIS 学生、空间数据分析师和 Python GIS 初学者,重点解决一个具体问题:如何用 GeoPandas 做出更适合汇报、论文插图和数据分析报告的 GIS 可视化图件。文章会讲清楚 GeoPandas 绘图为什么“默认不好看”,并给出可直接复用的配色表、参数模板和检查清单。
引言:GeoPandas绘图不好看,通常不是数据的问题
很多人第一次使用 GeoPandas 绘图时,会写出类似下面的代码:
import geopandas as gpd
import matplotlib.pyplot as plt
gdf = gpd.read_file("districts.shp")
gdf.plot()
plt.show()
这段代码能画出地图,但通常只能算“快速预览”,不适合正式制图。常见问题包括:
- 默认颜色随机感强,不适合表达空间差异。
- 边界线过粗或过黑,导致面状要素显得脏乱。
- 图例位置、字号、标题不符合报告排版。
- 分类数量过多,颜色难以区分。
- 没有处理坐标系,面积、距离或比例判断容易出错。
- 中文字体没有配置,标题和图例可能显示为方框。
GeoPandas 本身不是专业制图软件,它更像是 Python 空间数据分析流程中的“绘图出口”。想让 GeoPandas 可视化变好看,需要同时控制数据字段、分类方法、配色方案、边界样式、图例和版式。

背景:GeoPandas适合做什么类型的GIS可视化
GeoPandas 绘图基于 Matplotlib,适合做静态 GIS 可视化,尤其适合以下场景:
- 行政区专题图,例如人口密度、GDP、耕地占比。
- 点数据空间分布图,例如 POI、采样点、事件点。
- 线数据展示,例如道路、河流、轨迹线。
- 空间分析结果图,例如缓冲区、叠加分析结果、热点区域。
- 数据清洗前后的对比图。
但 GeoPandas 不适合直接替代 QGIS 或 ArcGIS Pro 的完整制图流程。如果你需要复杂标注、地图整饰、比例尺、指北针、制图模板、地图册批量输出,专业 GIS 软件仍然更合适。
比较合理的工作方式是:用 GeoPandas 完成空间数据处理和快速专题图输出;如果要做正式地图版面,再进入 QGIS 或 ArcGIS Pro 做最终整饰。
原理:为什么GeoPandas默认绘图看起来太丑
GeoPandas 绘图不好看,核心原因有四个。
1. 默认绘图只是数据预览,不是制图模板
gdf.plot() 的目标是快速查看几何对象是否正确,而不是生成出版级地图。它默认不会主动帮你选择合适的分类方法、图例格式、边界线宽、中文字体和输出分辨率。
2. 专题图的关键在于分类方法
同一列数值字段,使用不同分类方法会得到完全不同的视觉结果。例如自然断点、等距分级、分位数分级对地图表达的影响很大。如果只是直接按连续色带绘制,极端值可能会压缩大部分区域的颜色差异。
3. 配色需要符合数据类型
GIS 可视化中,颜色不能随便选。一般来说:
- 连续数值字段适合使用顺序色带,例如浅色到深色。
- 正负变化字段适合使用发散色带,例如蓝到白到红。
- 类别字段适合使用定性色带,例如不同类别使用明显不同的颜色。
4. Matplotlib版式需要手动调整
GeoPandas 的底层是 Matplotlib,所以图例、标题、边距、坐标轴、字体、输出 DPI 都要通过 Matplotlib 控制。只写一行 plot(),很难得到专业效果。
步骤:用GeoPandas画一张更好看的GIS专题图
步骤1:读取数据并检查坐标系
先读取矢量数据,并检查坐标系。这里假设数据是行政区面数据,字段 pop_density 表示人口密度。
import geopandas as gpd
import matplotlib.pyplot as plt
gdf = gpd.read_file("districts.shp")
print(gdf.crs)
print(gdf.columns)
print(gdf.head())
如果你要做面积、距离或密度相关分析,建议先确认数据是否在合适的投影坐标系中。经纬度坐标系适合显示位置,但不适合直接计算面积和距离。
# 示例:转换到适合本地分析的投影坐标系
# EPSG 需要根据你的研究区选择,不能机械照抄
gdf = gdf.to_crs(epsg=3857)
注意:EPSG:3857 常用于 Web 地图显示,并不一定适合严肃面积统计。正式面积计算应选择研究区对应的等面积投影或当地常用投影。
步骤2:设置中文字体和基础画布
如果图中包含中文标题、图例或标注,建议先配置中文字体。不同系统的字体名称可能不同,需要按本机环境调整。
import matplotlib.pyplot as plt
plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
fig, ax = plt.subplots(figsize=(8, 6), dpi=150)
如果你在 macOS 或 Linux 环境中运行,SimHei 不一定存在,可以改用系统中已安装的中文字体。
步骤3:选择合适的字段和配色表
对于人口密度、地价、降水量、污染浓度这类连续数值,推荐使用顺序色带。下面是一个常用配置:
fig, ax = plt.subplots(figsize=(8, 6), dpi=150)
gdf.plot(
column="pop_density",
cmap="YlOrRd",
linewidth=0.4,
edgecolor="#666666",
legend=True,
ax=ax
)
ax.set_title("人口密度空间分布", fontsize=14, pad=12)
ax.set_axis_off()
plt.tight_layout()
plt.show()
这段代码比默认绘图更清晰,主要原因是它控制了专题字段、色带、边界线、图例和标题。
步骤4:使用分级设色,让空间差异更清楚
如果字段值差异很大,直接连续渐变可能不容易读图。可以使用 scheme 参数进行分级,但这通常需要安装 mapclassify。
pip install mapclassify
然后使用分位数分级或自然断点分级:
fig, ax = plt.subplots(figsize=(8, 6), dpi=150)
gdf.plot(
column="pop_density",
cmap="YlOrRd",
scheme="Quantiles",
k=5,
linewidth=0.4,
edgecolor="#666666",
legend=True,
legend_kwds={
"title": "人口密度",
"loc": "lower left"
},
ax=ax
)
ax.set_title("人口密度分级设色图", fontsize=14, pad=12)
ax.set_axis_off()
plt.tight_layout()
plt.show()
scheme="Quantiles" 表示每一类包含大致相同数量的要素,适合突出相对排名。若希望突出数据本身的自然分组,可以尝试 scheme="NaturalBreaks"。
步骤5:给不同数据类型选择不同配色表
下面是一份适合 GeoPandas GIS 可视化的常用配色表,可直接作为日常工作参考。
| 数据类型 | 适用场景 | 推荐配色 | 说明 |
|---|---|---|---|
| 连续数值 | 人口密度、GDP、降水量、地价 | YlOrRd、OrRd、Blues、Greens |
从浅到深表达数值从低到高 |
| 正负变化 | 增长率、温度距平、变化量 | RdBu_r、coolwarm、PiYG |
适合表达负值、中性值、正值 |
| 类别字段 | 土地利用类型、行政等级、设施类型 | Set2、tab10、Pastel1 |
不同类别使用差异明显的颜色 |
| 二值结果 | 是否覆盖、是否达标、是否在范围内 | Greys、Set1 |
重点突出有无、是非、通过与不通过 |
| 风险等级 | 低中高风险、适宜性等级 | YlGn、YlOrBr、YlOrRd |
等级越高颜色越深,读图更直观 |
步骤6:优化边界线和背景
很多 GeoPandas 图看起来“脏”,不是颜色错了,而是边界线太重。面状数据通常不建议使用纯黑粗边界。
gdf.plot(
column="pop_density",
cmap="YlOrRd",
scheme="Quantiles",
k=5,
linewidth=0.3,
edgecolor="#777777",
legend=True,
ax=ax
)
如果研究区内部单元很多,可以进一步减弱边界线:
linewidth=0.15
edgecolor="#999999"
如果边界不是重点,也可以不显示边界:
edgecolor="none"
步骤7:叠加点、线、面图层
GeoPandas 可视化经常需要叠加多个图层。例如先画行政区,再叠加河流和采样点。
districts = gpd.read_file("districts.shp")
rivers = gpd.read_file("rivers.shp")
points = gpd.read_file("sample_points.shp")
rivers = rivers.to_crs(districts.crs)
points = points.to_crs(districts.crs)
fig, ax = plt.subplots(figsize=(8, 6), dpi=150)
districts.plot(
column="pop_density",
cmap="YlOrRd",
scheme="Quantiles",
k=5,
linewidth=0.3,
edgecolor="#888888",
legend=True,
ax=ax
)
rivers.plot(
ax=ax,
color="#3182bd",
linewidth=0.8
)
points.plot(
ax=ax,
color="#252525",
markersize=12,
alpha=0.8
)
ax.set_title("人口密度与采样点分布", fontsize=14, pad=12)
ax.set_axis_off()
plt.tight_layout()
plt.show()
叠加图层时,最重要的是保证所有图层使用同一个坐标参考系统,也就是同一个 CRS。
步骤8:导出适合报告使用的图片
如果地图要放入 Word、PPT、论文或网页,建议使用 savefig() 导出,而不是截图。
plt.savefig(
"geopandas_map.png",
dpi=300,
bbox_inches="tight",
facecolor="white"
)
常用导出建议:
- 网页文章:PNG,宽度适中,DPI 可设置为 150 到 200。
- 论文插图:PNG 或 PDF,DPI 建议 300。
- 后期编辑:优先导出 SVG 或 PDF 矢量格式。
常见坑:GeoPandas GIS可视化最容易踩的错误
坑1:字段是字符串,导致无法正确分级
有些 Shapefile 或 CSV 合并后的字段看起来是数字,其实是字符串。绘图前建议检查字段类型。
print(gdf["pop_density"].dtype)
gdf["pop_density"] = gdf["pop_density"].astype(float)
如果字段中有空值、逗号或特殊字符,直接转换可能报错,需要先清洗。
坑2:空值导致颜色缺失
专题字段中存在空值时,部分区域可能没有颜色。可以用 missing_kwds 设置缺失值样式。
gdf.plot(
column="pop_density",
cmap="YlOrRd",
legend=True,
missing_kwds={
"color": "lightgrey",
"edgecolor": "white",
"hatch": "///",
"label": "缺失值"
},
ax=ax
)
坑3:分类数量太多,地图反而难读
专题图并不是分类越多越专业。对于多数行政区专题图,5 到 7 类通常比较容易阅读。类别太多会导致图例复杂,颜色差异也不明显。
坑4:使用彩虹色带表达连续变量
彩虹色带看起来鲜艳,但不利于判断数值大小,也容易造成视觉误读。对于连续变量,优先使用单色系或近似单色系的顺序色带。
坑5:坐标系不一致导致图层叠不上
如果点、线、面图层叠加后位置不对,第一时间检查 CRS。
print(districts.crs)
print(points.crs)
print(rivers.crs)
然后统一坐标系:
points = points.to_crs(districts.crs)
rivers = rivers.to_crs(districts.crs)
坑6:中文乱码
中文乱码通常不是 GeoPandas 的问题,而是 Matplotlib 没有找到中文字体。可以先查看系统可用字体,再设置字体名称。
import matplotlib.font_manager as fm
for font in fm.fontManager.ttflist:
if "SimHei" in font.name or "Microsoft" in font.name:
print(font.name)
方法比较:GeoPandas、QGIS、ArcGIS Pro和WebGIS怎么选
| 工具 | 适合任务 | 优点 | 限制 |
|---|---|---|---|
| GeoPandas | 空间分析结果快速出图、批量制图、数据报告 | 可编程、可复现、方便与 Pandas 分析流程结合 | 复杂制图整饰能力弱,需要手动调 Matplotlib |
| QGIS | 正式地图制图、样式设计、标注、布局导出 | 可视化操作强,制图功能完整,免费开源 | 批量自动化需要额外配置 PyQGIS 或处理模型 |
| ArcGIS Pro | 专业制图、企业 GIS、空间分析和地图册输出 | 工具链成熟,布局和符号系统强 | 软件授权成本较高,Python 环境相对封闭 |
| Leaflet / OpenLayers | 交互式 WebGIS 地图 | 适合网页交互、缩放、点击查询和图层控制 | 不适合直接做静态论文图,前端优化要求高 |
如果你的目标是“用 Python 处理数据并快速生成专题图”,GeoPandas 很合适。如果你的目标是“做一张可以直接交付的正式地图”,建议把 GeoPandas 的结果导入 QGIS 或 ArcGIS Pro 继续整饰。
检查清单:让GeoPandas绘图更专业的10个检查点
- 检查坐标系:所有图层 CRS 是否一致?是否适合当前分析?
- 检查字段类型:专题字段是否为数值类型?是否含空值?
- 检查分类方法:连续值是否需要分级?适合分位数、等距还是自然断点?
- 检查配色表:连续变量、类别变量、正负变量是否使用了不同色带?
- 检查边界线:边界是否过黑、过粗、过密?
- 检查图例:图例标题是否清楚?分类数量是否过多?
- 检查标题:标题是否说明了变量、区域和时间?
- 检查中文字体:中文是否乱码?负号是否正常显示?
- 检查输出质量:是否使用
savefig()导出?DPI 是否足够? - 检查地图目的:这是分析预览图、报告图,还是正式地图?不同目的需要不同标准。
FAQ:GeoPandas绘图常见问题
GeoPandas绘图可以做正式地图吗?
可以做较规范的专题图,但不建议把 GeoPandas 当作完整制图软件。GeoPandas 适合批量、可复现、分析型 GIS 可视化;正式地图的比例尺、指北针、标注避让和版式设计,QGIS 或 ArcGIS Pro 更方便。
GeoPandas怎么选择配色表?
先判断字段类型。连续数值用 YlOrRd、Blues、Greens;正负变化用 RdBu_r 或 coolwarm;类别字段用 Set2、tab10。不要对连续变量随意使用彩虹色带。
GeoPandas图例太丑怎么办?
可以通过 legend_kwds 设置图例标题、位置和格式,也可以在 Matplotlib 中进一步自定义图例。如果要求很高,建议将图导出后在 QGIS、Illustrator 或 Inkscape 中做最终排版。
GeoPandas绘图中文乱码怎么解决?
需要配置 Matplotlib 中文字体,例如设置 plt.rcParams["font.sans-serif"] = ["SimHei"]。如果本机没有该字体,需要换成本机已安装的中文字体。
GeoPandas分类设色为什么报错?
如果使用 scheme 参数,需要安装 mapclassify。另外,专题字段必须是可用于分类的数值字段,不能是混有文本、空字符串或异常字符的字段。
GeoPandas绘图和Contextily底图能一起用吗?
可以。通常需要把数据转换为 Web Mercator 坐标系,也就是 EPSG:3857,然后用 Contextily 添加在线底图。但要注意,EPSG:3857 适合网页显示,不一定适合面积和距离计算。
为什么同样的数据在QGIS里更好看?
QGIS 内置了完整的符号系统、图例、标注和布局工具,而 GeoPandas 的默认绘图更偏向数据预览。想让 GeoPandas 图件接近 QGIS 效果,需要手动设置分类、色带、线宽、字体、图例和输出参数。
结论:GeoPandas可视化的关键是“分类、配色、边界、图例”
GeoPandas绘图太丑,通常不是因为 GeoPandas 不能制图,而是因为默认参数只适合快速预览。只要你把专题字段、分类方法、配色表、边界线、图例和导出参数控制好,GeoPandas 完全可以输出清晰、稳定、适合报告使用的 GIS 可视化图件。
实际工作中,建议把 GeoPandas 当作 Python GIS 分析流程中的制图工具:先保证数据和坐标系正确,再根据数据类型选择配色表,最后用 Matplotlib 调整版式。如果要做正式地图交付,可以继续进入 QGIS 或 ArcGIS Pro 完成最终制图整饰。