杰瑞科技汇

Python Basemap教程怎么学?入门到精通指南

Python Basemap 教程:从入门到实战

Basemap 是 Matplotlib 的一个扩展库,它提供了在地图上绘制 2D 数据的强大功能,虽然从 2025 年起 Basemap 已进入维护模式(不再有新功能开发),并且其官方推荐替代品是 Cartopy,但 Basemap 仍然非常成熟、稳定,并且拥有海量的教程和现有代码,对于许多用户来说,它仍然是进行科学数据可视化的首选工具。

Python Basemap教程怎么学?入门到精通指南-图1
(图片来源网络,侵删)

本教程将带你一步步掌握 Basemap 的核心用法。

目录

  1. 环境准备:安装 Basemap
  2. 第一个地图:drawcoastlines()
  3. 核心概念:投影
  4. 地图定制:添加更多元素
    • 国家、州/省边界
    • 经纬度网格和标签
    • 地图填充(陆地、海洋)
  5. 在地图上绘制数据点
  6. 实战案例:绘制全球地震分布图
  7. Basemap vs. Cartopy:我应该选择哪个?
  8. **总结与资源---

环境准备:安装 Basemap

Basemap 的安装有时可能会遇到一些依赖问题,特别是如果你使用的是 Anaconda。

推荐使用 Conda 安装:

# 创建一个新的虚拟环境(推荐)
conda create -n basemap_env python=3.8
conda activate basemap_env
# 安装 basemap 和其依赖项
conda install -c conda-forge basemap

使用 Pip 安装(可能不成功):

Python Basemap教程怎么学?入门到精通指南-图2
(图片来源网络,侵删)
pip install basemap

Pip 安装失败,通常是因为缺少 geos 库,在 Linux 上,你可能需要先安装 libgeos-dev,在 Windows 上,这个问题会更复杂,因此强烈推荐使用 Conda。

验证安装:

在你的 Python 环境中运行以下代码,如果没有报错,说明安装成功。

from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
print("Basemap 安装成功!")

第一个地图:drawcoastlines()

让我们从一个最简单的例子开始:绘制海岸线。

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
# 1. 创建一个图形和坐标轴
fig = plt.figure(figsize=(8, 8))
ax = fig.add_subplot(111)
# 2. 创建一个 Basemap 实例
# 这里我们使用 'ortho' 投影,即正射投影,看起来像一个球体。
# lat_0=0, lon_0=0 表示将 (0, 0) 这个点(非洲几内亚湾)放在中心。
m = Basemap(projection='ortho', lat_0=0, lon_0=0)
# 3. 绘制海岸线
m.drawcoastlines()
# 4. 显示图形
plt.show()

代码解释:

  1. fig = plt.figure(...): 创建一个 Matplotlib 图形窗口。
  2. m = Basemap(...): 这是核心步骤,我们创建了一个 Basemap 对象 m
    • projection='ortho': 指定了地图的投影方式。'ortho' 是正射投影,模拟从太空看地球的效果。
    • lat_0=0, lon_0=0: 设置了地图的中心点。
  3. m.drawcoastlines(): 调用 Basemap 对象的方法来绘制海岸线,Basemap 内置了 GSHHS 数据集,可以绘制出非常精细的海岸线。

运行这段代码,你应该能看到一个蓝色的球体,上面有白色的陆地轮廓。

核心概念:投影

地球是一个三维球体,而地图是二维平面。投影就是将三维表面映射到二维平面上的数学方法,不同的投影适用于不同的场景。

Basemap 支持数十种投影,我们来看几个常见的例子:

圆柱投影

# Cylindrical Equidistant (Plate Carrée)
# 这是最简单的投影,经纬线都是直线。
m = Basemap(projection='cyl', llcrnrlat=-90, urcrnrlat=90, llcrnrlon=-180, urcrnrlon=180)

墨卡托投影

# Mercator projection
# 常用于网络地图(如 Google Maps),但会导致高纬度地区面积失真。
m = Basemap(projection='merc', llcrnrlat=-80, urcrnrlat=80, llcrnrlon=-180, urcrnrlon=180)

兰伯特等角圆锥投影

# Lambert Conformal Conic
# 适合绘制中纬度地区的地图,如美国或欧洲。
m = Basemap(projection='lcc', lat_1=45, lat_2=55, lat_0=50, lon_0=-100)

关键参数:

  • llcrnrlat (lower left corner latitude): 左下角的纬度。
  • urcrnrlat (upper right corner latitude): 右上角的纬度。
  • llcrnrlon (lower left corner longitude): 左下角的经度。
  • urcrnrlon (upper right corner longitude): 右上角的经度。

这些参数定义了你想要显示的地图的矩形边界。

地图定制:添加更多元素

一张好的地图不仅仅是海岸线,Basemap 提供了丰富的定制方法。

# 创建一个墨卡托投影的地图,聚焦于中国及周边地区
fig = plt.figure(figsize=(10, 10))
m = Basemap(projection='merc', 
            llcrnrlat=0, urcrnrlat=60, 
            llcrnrlon=70, urcrnrlon=140)
# 1. 绘制填充的陆地和海洋
m.drawmapboundary(fill_color='aqua')  # 绘制地图边界并填充海洋颜色
m.fillcontinents(color='coral', lake_color='aqua') # 填充陆地颜色,湖泊用海洋色
# 2. 绘制海岸线、国界、州界
m.drawcoastlines()
m.drawcountries()   # 绘制国界
m.drawstates()      # 绘制美国州界(在中国地区可能没有效果)
# 3. 绘制经纬度网格
m.drawparallels(np.arange(0, 61, 10), labels=[1, 0, 0, 0]) # 绘制纬度线,只在左边显示标签
m.drawmeridians(np.arange(70, 141, 10), labels=[0, 0, 0, 1]) # 绘制经度线,只在底部显示标签
# 4. 添加标题"Map of China and Surrounding Areas", fontsize=16)
plt.show()

新方法解释:

  • drawmapboundary(fill_color=...): 绘制地图的边界(通常是矩形)并填充颜色,默认是海洋。
  • fillcontinents(color=..., lake_color=...): 用指定颜色填充大陆,lake_color 指定湖泊的颜色(通常与海洋一致)。
  • drawcountries(): 绘制国家边界。
  • drawparallels() / drawmeridians(): 绘制纬线和经线。
    • np.arange(0, 61, 10) 表示从 0 到 60,每隔 10 度画一条线。
    • labels=[1, 0, 0, 0] 是一个四元组,分别控制 [左, 右, 上, 下] 是否显示经纬度标签。1 表示显示,0 表示不显示。

在地图上绘制数据点

这是 Basemap 最强大的功能之一,假设我们有一些城市的经纬度数据,我们想将它们标记在地图上。

关键步骤:

  1. 准备好你的数据(经度、纬度)。
  2. 使用 Basemap 的 transform_point() 或更方便的 x, y = m(lon, lat) 将经纬度坐标投影为地图的二维坐标。
  3. 使用标准的 Matplotlib 绘图函数(如 plot, scatter, text)在 (x, y) 坐标上绘图。

示例:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
# 1. 准备数据:几个主要城市的经纬度
cities = {
    'Beijing': (116.4, 39.9),
    'Shanghai': (121.47, 31.23),
    'Tokyo': (139.69, 35.69),
    'Bangkok': (100.50, 13.75),
    'Mumbai': (72.82, 18.96)
}
lons, lats = zip(*[(lon, lat) for name, (lon, lat) in cities.items()])
# 2. 创建地图 (使用墨卡托投影)
fig = plt.figure(figsize=(10, 8))
m = Basemap(projection='merc', llcrnrlat=0, urcrnrlat=50, llcrnrlon=70, urcrnrlon=150)
# 3. 绘制地图背景
m.drawcoastlines()
m.drawcountries()
m.drawmapboundary(fill_color='lightblue')
m.fillcontinents(color='lightgray', lake_color='lightblue')
# 4. 将经纬度数据转换为地图坐标
# 这是最关键的一步!
x, y = m(lons, lats)
# 5. 在地图上绘制点
m.scatter(x, y, color='red', s=100, zorder=5, label='Cities')
# 6. 添加城市名称标签
for name, lon, lat in cities.items():
    x, y = m(lon, lat)
    plt.text(x, y + 0.5, name, fontsize=9, ha='center')
"Major Cities in East Asia")
plt.legend()
plt.show()

代码解释:

  • x, y = m(lons, lats): 这行代码非常神奇,它接收了经度和纬度的 NumPy 数组,并返回了对应地图投影下的二维坐标 xy,之后,你就可以直接用这些 xy 坐标来绘图了。
  • m.scatter(...): 使用 Matplotlib 的 scatter 函数在地图上绘制散点。
    • zorder=5: 设置绘图顺序,确保点绘制在海岸线之上(海岸线的 zorder 较低)。

实战案例:绘制全球地震分布图

让我们结合前面所学的知识,绘制一个更有意义的地图:全球 5.0 级以上地震分布图。

我们将使用 USGS 提供的地震数据(CSV 格式)。

准备数据

假设你有一个名为 earthquakes.csv 的文件,内容如下(你可以从 USGS 网站下载):

time,latitude,longitude,depth,mag,magType,place
"2025-10-27T02:10:18.580Z",37.7952,-122.4078,10.4,4.1,ml,"8 km W of The Geysers, CA"
"2025-10-27T01:18:30.580Z",-23.165,179.85,557.8,5.6,m,"342 km ENE of Tadine, New Caledonia"
...

编写 Python 脚本

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
# --- 1. 数据加载 ---
# 读取 CSV 文件
# 注意:如果你的文件很大,可能需要使用 chunksize 参数分块读取
try:
    df = pd.read_csv('earthquakes.csv')
except FileNotFoundError:
    print("错误:请确保 'earthquakes.csv' 文件在当前目录下。")
    # 创建一些示例数据以防文件不存在
    np.random.seed(42)
    num_quakes = 200
    df = pd.DataFrame({
        'latitude': np.random.uniform(-60, 70, num_quakes),
        'longitude': np.random.uniform(-180, 180, num_quakes),
        'mag': np.random.uniform(4.0, 7.0, num_quakes)
    })
    print("已生成示例数据。")
# 筛选震级大于 5.0 的地震
strong_quakes = df[df['mag'] >= 5.0]
# --- 2. 创建地图 ---
fig = plt.figure(figsize=(16, 10))
# 使用 Robinson 投影,这是一种世界地图常用的、视觉上比较平衡的投影
m = Basemap(projection='robin', lon_0=0)
# 绘制地图元素
m.drawcoastlines(linewidth=0.5)
m.drawcountries(linewidth=0.5)
m.drawmapboundary(fill_color='white')
m.fillcontinents(color='lightgray', lake_color='white')
# 绘制经纬度网格
m.drawparallels(np.arange(-90, 91, 30), labels=[1, 0, 0, 0], color='gray')
m.drawmeridians(np.arange(-180, 181, 60), labels=[0, 0, 0, 1], color='gray')
# --- 3. 在地图上绘制地震数据 ---
# 将经纬度转换为地图坐标
lons = strong_quakes['longitude'].values
lats = strong_quakes['latitude'].values
x, y = m(lons, lats)
# 震级越大,点越大,颜色越深
# 使用 mag 列来设置点的大小
sizes = strong_quakes['mag'] * 5
# 使用 scatter 绘制,并添加颜色映射
# cmap='YlOrRd' 表示从黄色到红色的渐变
# c=strong_quakes['mag'] 表示用震级来确定颜色
scatter = m.scatter(x, y, s=sizes, c=strong_quakes['mag'], 
                    cmap='YlOrRd', alpha=0.7, edgecolors='k', linewidths=0.5, zorder=5)
# --- 4. 添加标题和图例 ---"Global Earthquakes (Magnitude >= 5.0)", fontsize=18)
# 添加颜色条
cbar = plt.colorbar(scatter, orientation='horizontal', pad=0.05, shrink=0.7)
cbar.set_label('Magnitude', fontsize=12)
plt.show()

运行结果: 你将得到一张世界地图,上面用不同大小和颜色的点标记了 5.0 级以上的地震,点越大、颜色越红,代表震级越大。

Basemap vs. Cartopy:我应该选择哪个?

这是一个非常重要的问题。

特性 Basemap Cartopy
状态 维护模式 (不再有新功能) 积极开发中
许可证 MIT License LGPLv3 (更宽松)
API 设计 基于 Basemap 对象,调用其方法绘图 基于 Matplotlib 的 Axes (ax),直接在 Axes 上绘图
语法 m = Basemap(...)
m.plot(x, y)
ax = plt.gca()
ax.add_geometries(...)ax.stock_img()
数据源 内置 GSHHS, DCW 等数据 内置 Natural Earth 数据,并支持通过 cartopy.feature 动态加载
投影 支持多种投影 支持更多、更现代的投影,特别是极地投影
社区与文档 海量教程和现有代码,但不再更新 官方文档优秀,是未来的趋势,但社区资源相对较少
性能 性能良好 性能同样优秀,甚至在某些方面更优

结论与建议:

  • 如果你是初学者,或者需要维护/复现旧的 Basemap 代码继续使用 Basemap,它的教程非常多,概念清晰,足以完成绝大多数地理数据可视化任务。
  • 如果你在启动一个新项目,特别是长期项目,或者需要使用最新的地图投影强烈推荐学习 Cartopy,它是未来的标准,API 设计更符合 Matplotlib 的现代风格,功能也更强大,学习 Cartopy 的初期可能会遇到一些文档和教程较少的问题,但长期来看是值得的投资。

总结与资源

本教程带你走过了 Basemap 的核心使用流程:

  1. 安装:使用 Conda 是最稳妥的方式。
  2. 基础绘图:创建 Basemap 实例并调用 drawcoastlines()
  3. 投影选择:理解投影是地图绘图的灵魂,学会使用不同投影。
  4. 地图美化:添加国界、网格、填充颜色等,让地图更专业。
  5. 数据可视化:掌握 x, y = m(lon, lat) 这一核心转换,将你的数据点绘制到正确的地理位置。
  6. 实战演练:通过一个完整的案例,将所有知识点串联起来。

进一步学习的资源:

  1. Basemap 官方文档https://matplotlib.org/basemap/stable/ (虽然不再更新,但仍然是权威参考)
  2. 示例画廊https://matplotlib.org/basemap/stable/users/examples.html (这里有很多可以直接运行的例子,是学习的最佳材料)
  3. Cartopy 官方文档:如果你决定转向 Cartopy,这里是最好的起点:https://scitools.org.uk/cartopy/docs/latest/

希望这份教程能帮助你顺利入门 Python 地理数据可视化!

分享:
扫描分享到社交APP
上一篇
下一篇