Python绘制时间序列与地理地图数据可视化实例

巷口听风
巷口听风
发布时间:2026-10-26| 4人浏览过
原创
在数据分析中,时间与空间是最基础的两大观测维度。时间序列揭示指标随周期的演变趋势与异常波动,而地理地图展现指标在空间拓扑上的集聚与分异。本文将以Python为工具,聚焦Matplotlib、Pandas与GeoPandas生态,通过可运行的代码实例、端到端的操作步骤与排错策略,完整拆解时序图表、空间地图以及二者联动可视化的实现全过程。

一、环境准备与核心依赖栈

进行时空数据可视化前,需要配置合适的基础库环境。处理时间序列主要依赖 pandas(用于时序索引与聚合)与 matplotlib(基础渲染底座);处理地理空间数据则需要 geopandas(基于Shapely和GDAL的矢量处理库)以及 contextily(可选,用于加载Web地图底图)。

建议在干净的虚拟环境中执行以下安装命令:

pip install pandas matplotlib geopandas shapely

如果在Windows或特定Linux环境中安装 geopandas 遇到编译底层C依赖(GDAL/GEOS)的问题,建议使用 conda install -c conda-forge geopandas 进行安装,由Conda自动解决二进制动态链接库依赖。

二、时间序列数据可视化实例

绘制时间序列的核心并非仅仅是把日期作为X轴画一条折线,而在于对时间维度的结构化处理,包括日期格式标准化、设定DatetimeIndex、周期性重采样以及滚动统计特征的叠加呈现。

Python绘制时间序列与地理地图数据可视化实例
图 1:时间序列数据可视化清洗、聚合与视觉分层四步执行流程

2.1 时间序列绘制完整示例代码

下面是一个包含真实观测模拟、滚动平均(Rolling Average)、波动带填充(Confidence Interval)及日期自适应刻度的完整脚本:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

# 1. 模拟生成连续90天的逐小时时序数据
np.random.seed(42)
dates = pd.date_range(start="2024-01-01", periods=90 * 24, freq="h")
# 生成基准正弦波周期信号 + 趋势 + 随机扰动
trend = np.linspace(20, 35, len(dates))
seasonal = 8 * np.sin(2 * np.pi * dates.hour / 24)
noise = np.random.normal(0, 3, size=len(dates))
values = trend + seasonal + noise

df = pd.DataFrame({"timestamp": dates, "load": values})
df.set_index("timestamp", inplace=True)

# 2. 时序聚合:按日重采样并计算均值、滚动指标与标准差
daily_df = df.resample("D").mean()
daily_df["rolling_7d"] = daily_df["load"].rolling(window=7, min_periods=1).mean()
daily_df["std_7d"] = daily_df["load"].rolling(window=7, min_periods=1).std().fillna(0)

# 3. 创建图表画布
fig, ax = plt.subplots(figsize=(12, 5), dpi=120)

# 绘制日均散点、周滚动趋势线与波动区间
ax.plot(daily_df.index, daily_df["load"], color="#5a646e", linestyle="--", alpha=0.6, label="每日均值")
ax.plot(daily_df.index, daily_df["rolling_7d"], color="#b96555", linewidth=2.5, label="7日滑动平均趋势")
ax.fill_between(
    daily_df.index,
    daily_df["rolling_7d"] - daily_df["std_7d"],
    daily_df["rolling_7d"] + daily_df["std_7d"],
    color="#b96555",
    alpha=0.15,
    label="7日波动区间 (±1σ)"
)

# 4. 坐标轴格式化
ax.xaxis.set_major_locator(mdates.WeekdayLocator(interval=2))
ax.xaxis.set_major_formatter(mdates.DateFormatter("%Y-%m-%d"))
fig.autofmt_xdate(rotation=30, ha="right")

ax.set_title("电力负荷时间序列监测与趋势平滑实例", fontsize=14, pad=12)
ax.set_xlabel("监测日期", fontsize=11)
ax.set_ylabel("负荷数值 (MW)", fontsize=11)
ax.grid(True, linestyle=":", alpha=0.5)
ax.legend(loc="upper left", frameon=True)

plt.tight_layout()
plt.show()

三、地理地图数据可视化实例

绘制地图不仅是画出经纬度点,更重要的是理解“地理图层结构”与“坐标参考系(CRS)”。一个标准的地图可视化由几何矢量边界、数据属性字段以及投影对齐系统组成。

Python绘制时间序列与地理地图数据可视化实例
图 2:地理空间数据图层堆叠逻辑与坐标参考系统(CRS)匹配原理

3.1 地理区域分级色彩图(Choropleth)完整示例

以下示例演示如何构建包含几何形状的 GeoDataFrame,为各区域绑定指标,并绘制带有颜色映射图例(Colorbar)的标准分级统计地图:

import geopandas as gpd
import matplotlib.pyplot as plt
from shapely.geometry import Polygon, Point

# 1. 模拟构建四个相邻区域的地理多边形(Polygon)
poly1 = Polygon([(116.2, 39.9), (116.4, 39.9), (116.4, 40.1), (116.2, 40.1)])
poly2 = Polygon([(116.4, 39.9), (116.6, 39.9), (116.6, 40.1), (116.4, 40.1)])
poly3 = Polygon([(116.2, 39.7), (116.4, 39.7), (116.4, 39.9), (116.2, 39.9)])
poly4 = Polygon([(116.4, 39.7), (116.6, 39.7), (116.6, 39.9), (116.4, 39.9)])

gdf_regions = gpd.GeoDataFrame({
    "region_name": ["西北区", "东北区", "西南区", "东南区"],
    "business_index": [78.5, 92.0, 64.2, 85.3],
    "geometry": [poly1, poly2, poly3, poly4]
}, crs="EPSG:4326")

# 2. 模拟散点业务事件(经纬度点)
pts = [Point(116.32, 39.95), Point(116.51, 40.02), Point(116.28, 39.81), Point(116.45, 39.88)]
gdf_points = gpd.GeoDataFrame({
    "site_id": ["S1", "S2", "S3", "S4"],
    "alerts": [5, 18, 2, 9],
    "geometry": pts
}, crs="EPSG:4326")

# 3. 绘制分级设色多边形与事件散点
fig, ax = plt.subplots(figsize=(8, 7), dpi=120)

# 底层面要素:根据 business_index 上色
gdf_regions.plot(
    column="business_index",
    cmap="YlOrRd",
    linewidth=0.8,
    edgecolor="#30363c",
    legend=True,
    legend_kwds={"label": "区域综合业务景气度", "orientation": "horizontal", "shrink": 0.7, "pad": 0.05},
    ax=ax
)

# 顶层点要素:点大小映射告警量 alerts
gdf_points.plot(
    ax=ax,
    color="#30363c",
    markersize=gdf_points["alerts"] * 15,
    alpha=0.85,
    label="重点监测站点"
)

# 标注文字
for idx, row in gdf_regions.iterrows():
    centroid = row.geometry.centroid
    ax.text(centroid.x, centroid.y, row["region_name"], ha="center", va="center", fontsize=10, weight="bold")

ax.set_title("区域业务指数分级与重点站点空间分布", fontsize=13, pad=12)
ax.set_xlabel("经度 (Longitude)", fontsize=10)
ax.set_ylabel("纬度 (Latitude)", fontsize=10)
ax.legend(loc="upper right")
ax.grid(True, linestyle="--", alpha=0.3)

plt.tight_layout()
plt.show()

四、时空联合分析:结合时间序列与地理特征

真实业务场景中,时间序列与地理空间往往不是孤立的。例如监测不同区域的月度指标演变、气象站点的气温时序变化等。实现时空联合可视化的最佳实践包括:

  • 多子图小面板(Small Multiples):通过固定空间范围的网格切片展示不同时间切片,利于快速横向比对空间格局演化。
  • 联动双面板视图(Linked Dual-Panel):主界面左侧为空间多边形/散点分布图,右侧为选定区域或全部区域的时间序列走势对比图。
Python绘制时间序列与地理地图数据可视化实例
图 3:时空数据可视化技术方案对比与选型决策维度

4.1 空间-时序联动双视窗代码实例

下面代码构建了一个综合图表:左视窗展示区域最新空间评分分级,右视窗展示各区域近半年的历史演化时序曲线,两边颜色完全统一对应。

import pandas as pd
import numpy as np
import geopandas as gpd
import matplotlib.pyplot as plt
from shapely.geometry import box

# 1. 生成空间网格(三个大区)
regions = ["华北区", "华东区", "华南区"]
polys = [
    box(115, 38, 120, 42),
    box(118, 30, 123, 34),
    box(112, 22, 117, 26)
]
gdf = gpd.GeoDataFrame({"region": regions, "geometry": polys}, crs="EPSG:4326")

# 2. 生成各区域的月度时序指标
dates = pd.date_range("2024-01-01", periods=6, freq="MS")
palette = {"华北区": "#30363c", "华东区": "#b96555", "华南区": "#5a646e"}

ts_data = {
    "华北区": [62, 65, 68, 71, 75, 79],
    "华东区": [80, 83, 82, 88, 91, 95],
    "华南区": [70, 72, 71, 74, 76, 78]
}

# 3. 创建双栏子图
fig, (ax_geo, ax_ts) = plt.subplots(1, 2, figsize=(14, 6), dpi=120)

# 绘制左侧地图
for idx, row in gdf.iterrows():
    color = palette[row["region"]]
    gpd.GeoSeries(row.geometry).plot(ax=ax_geo, color=color, edgecolor="#ffffff", linewidth=2, alpha=0.85)
    c = row.geometry.centroid
    ax_geo.text(c.x, c.y, row["region"], color="#ffffff", weight="bold", ha="center", va="center", fontsize=11)

ax_geo.set_title("各区域地理区位与空间分布", fontsize=13, pad=10)
ax_geo.set_xlabel("经度")
ax_geo.set_ylabel("纬度")
ax_geo.grid(True, linestyle=":", alpha=0.4)

# 绘制右侧时序图
for r_name in regions:
    ax_ts.plot(dates, ts_data[r_name], marker="o", linewidth=2.2, color=palette[r_name], label=r_name)

ax_ts.set_title("各区域月度景气指数时序走势对比", fontsize=13, pad=10)
ax_ts.set_xlabel("月份")
ax_ts.set_ylabel("综合指数 (分)")
ax_ts.grid(True, linestyle=":", alpha=0.5)
ax_ts.legend(loc="upper left")

plt.tight_layout()
plt.show()

五、生产实践注意事项与常见排坑清单

避坑要点:
  1. 中文乱码与负号方块:Linux及原生环境常缺少中文字体,需在脚本开头显式配置 plt.rcParams['font.sans-serif'] = ['SimHei', 'PingFang SC', 'Microsoft YaHei'],以及 plt.rcParams['axes.unicode_minus'] = False。
  2. 时间序列聚合漏项:使用 resample() 聚合时,若某天完全无数据,Pandas默认会生成NaN行。直接绘图会导致折线断裂。可使用 .interpolate(method='linear') 或 .fillna(method='ffill') 处理。
  3. 多边形有效性(Invalid Geometry):GIS数据经常存在“自相交”(Self-intersection)导致绘图或空间连接失败。可在处理前调用 gdf['geometry'] = gdf['geometry'].buffer(0) 快速修复非法拓扑。
  4. DPI与输出失真:在输出高精度出版物或网页嵌入图时,保存必须指定分辨率,例如 plt.savefig("output.png", dpi=300, bbox_inches='tight'),避免标签被边界截断。

六、全流程质量总结

一个健壮的时空可视化项目,从输入到最终交付物,应当遵循完整严密的规范。以下全流程总结清单可作为交付前的自检标准:

Python绘制时间序列与地理地图数据可视化实例
图 4:时间序列与地理地图可视化全流程工程质量自检全景

通过上述对时间序列分析、地理图层构建以及时空联动双视窗的完整实例演练,读者可以建立起结构化处理复杂时空多维数据的直观能力,并在业务报表、监控大屏及学术科研中高效交付专业的可视化结果。

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。