1. 读取并可视化Shapefile文件

读取并可视化Shapefile文件 学习卡片

任务说明

本案例将使用GeoPandas读取一个真实可用的Shapefile文件(世界主要城市点数据),并通过Matplotlib绘制地图,展示城市点的空间分布。完成本案例后,你将掌握GeoPandas读取矢量数据、查看属性表以及基础可视化的完整流程。

环境准备

需要安装以下Python库(建议使用conda或venv环境):

pip install geopandas matplotlib pandas

数据准备

本案例使用Natural Earth提供的世界城市点数据集(110m分辨率,包含约240个主要城市)。执行以下代码自动下载并解压数据:

import os
import urllib.request
import zipfile

# 下载数据(约200KB)
url = "https://naturalearth.s3.amazonaws.com/110m_cultural/ne_110m_populated_places_simple.zip"
zip_path = "ne_110m_populated_places_simple.zip"
extract_dir = "ne_110m_data"

if not os.path.exists(os.path.join(extract_dir, "ne_110m_populated_places_simple.shp")):
    urllib.request.urlretrieve(url, zip_path)
    with zipfile.ZipFile(zip_path, 'r') as zip_ref:
        zip_ref.extractall(extract_dir)
    os.remove(zip_path)
    print("数据下载并解压完成")
else:
    print("数据已存在,跳过下载")

核心实现

以下代码完成Shapefile读取、属性查看与地图绘制:

import geopandas as gpd
import matplotlib.pyplot as plt

# 1. 读取Shapefile
shapefile_path = "ne_110m_data/ne_110m_populated_places_simple.shp"
gdf = gpd.read_file(shapefile_path)

# 2. 查看数据基本信息
print("数据行数:", len(gdf))
print("\n属性列名:", gdf.columns.tolist())
print("\n前5行属性数据:")
print(gdf[['name', 'pop_max', 'geometry']].head())

# 3. 检查坐标系
print("\n坐标系:", gdf.crs)

# 4. 绘制地图
fig, ax = plt.subplots(figsize=(12, 8))

# 绘制所有城市点,点大小根据人口数量分级
gdf.plot(ax=ax, 
         markersize=gdf['pop_max'] / 200000,  # 人口越多点越大
         color='#d7191c', 
         alpha=0.7, 
         edgecolor='black', 
         linewidth=0.3)

# 添加标题和网格
ax.set_title("World Major Cities Distribution (Natural Earth)", fontsize=14)
ax.grid(True, linestyle='--', alpha=0.3)

# 保存图片
plt.savefig("world_cities_map.png", dpi=150, bbox_inches='tight')
print("\n地图已保存为: world_cities_map.png")
plt.show()

代码说明

数据读取:gpd.read_file()自动识别Shapefile格式,返回GeoDataFrame对象。该对象是pandas DataFrame的扩展,额外包含geometry列存储地理要素。

属性查看:通过columns、head()和crs属性快速了解数据内容与坐标系(本数据为WGS84经纬度)。

可视化逻辑:使用plot()方法绘制点要素,markersize参数根据人口字段pop_max动态映射点大小,使大城市更突出。颜色、透明度、边框等参数用于提升可读性。

验证方法

运行完整代码后,按以下标准验证结果:

  1. 数据读取成功:控制台输出数据行数(应为约242行),属性列包含name、pop_max、geometry等字段;
  2. 坐标系正确:显示EPSG:4326(WGS84经纬度坐标系);
  3. 地图生成:当前目录出现world_cities_map.png,图中可见六大洲主要城市点,点大小与人口规模呈正相关,美洲、欧洲、亚洲东部点较密集,海洋区域无点分布。
Shapefile读取与可视化流程 Shapefile文件 ne_110m_populated_ places_simple.shp + .shx .dbf .prj gpd.read_file() 解析几何与属性 自动识别坐标系 返回GeoDataFrame GeoDataFrame对象 • geometry列: 点坐标 • name / pop_max 等属性 crs: EPSG:4326 属性数据查看 gdf.columns → 字段列表 gdf.head() → 前5行预览 地图绘制 gdf.plot(markersize=pop_max/200000) 保存为 world_cities_map.png 控制台属性信息 world_cities_map.png

预期输出示例

控制台输出(部分):

数据行数: 242

属性列名: ['scalerank', 'natscale', 'labelrank', 'featurecla', 'name', 'namepar', 'namealt', 'adm0cap', 'capalt', 'capin', 'worldcity', 'megacity', 'sov0name', 'adm0name', 'adm0_a3', 'adm1name', 'iso_a2', 'note', 'latitude', 'longitude', 'pop_max', 'pop_min', 'pop_other', 'rank_max', 'rank_min', 'mech', 'pop_year', 'nameabb', 'name_local', 'geometry']

前5行属性数据:
        name  pop_max                   geometry
0   Vatican City    1000  POINT (12.45339 41.90328)
1     San Marino    7500  POINT (12.44177 43.93610)
2      Vaduz      5000  POINT (9.51667 47.13333)
3  Lobamba      1000  POINT (31.71667 -26.46667)
4  Kingston      1000  POINT (168.31667 -29.05000)

坐标系: epsg:4326

生成的world_cities_map.png将显示全球城市点分布,点大小反映人口规模。