希思罗机场天气数据可视化分析系统 --- 技术文档
一、项目概述
1.1 项目简介
本系统是一个基于 Flask 框架的 Web 应用,对英国伦敦希思罗机场 1979---2023 年共 45 年的气象观测数据进行可视化分析。系统提供温度、降水、日照、综合气象、深度分析等多维度图表展示,并配备日期查询、年份对比、相关性矩阵、天气日历、极端记录等实用分析工具。
1.2 技术栈
| 层级 |
技术 |
版本 |
| 后端框架 |
Flask |
3.x |
| 数据库 |
SQLite |
3 (内置) |
| 前端框架 |
Bootstrap |
5.3.0 |
| 图表库 |
ECharts |
5.4.3 |
| 图标库 |
Bootstrap Icons |
1.10.5 |
| 字体 |
Google Fonts (Inter) |
--- |
| 密码加密 |
Werkzeug (pbkdf2) |
随 Flask |
| 数据计算 |
NumPy |
--- |
1.3 数据来源
伦敦希思罗机场气象站每日观测数据,来源为欧洲气候评估数据集(ECA&D),覆盖 1979 年 1 月 1 日至 2023 年 12 月 31 日,共计 16,436 条记录。






































二、项目结构
复制代码
weather/
├── app.py # Flask 主应用(1123 行,46 个路由)
├── init_db.py # 数据库初始化脚本(130 行)
├── weather.db # SQLite 数据库文件
├── london_weather_data_1979_to_2023.csv# 原始数据集
├── static/
│ ├── css/
│ │ └── style.css # 全局样式表
│ ├── js/
│ │ └── charts.js # ECharts 通用工具函数
│ └── images/
│ └── airport-bg.jpg # 登录页背景图
└── templates/
├── base.html # 基础布局模板(导航栏 + 页脚 + Toast)
├── login.html # 登录页(独立模板,毛玻璃风格)
├── register.html # 注册页(独立模板,毛玻璃风格)
├── index.html # 首页 / 数据概览
├── profile.html # 个人中心
├── data_manage.html # 数据管理(管理员)
├── admin_users.html # 用户管理(管理员)
├── analysis_temperature.html # 温度分析(7 图表)
├── analysis_precipitation.html # 降水分析(6 图表)
├── analysis_sunshine.html # 日照与辐射分析(5 图表)
├── analysis_comprehensive.html # 综合气象分析(7 图表)
├── analysis_advanced.html # 深度分析(6 图表)
├── tools_date_query.html # 日期查询 + CSV 导出
├── tools_correlation.html # 气象要素相关性矩阵
├── tools_year_compare.html # 年份对比工具
├── tools_weather_calendar.html # 天气日历热力图
└── tools_extreme_records.html # 极端天气记录排行
三、数据库设计
3.1 数据表 users --- 用户表
| 字段 |
类型 |
约束 |
说明 |
| id |
INTEGER |
PRIMARY KEY AUTOINCREMENT |
用户 ID |
| username |
TEXT |
NOT NULL UNIQUE |
用户名 |
| password |
TEXT |
NOT NULL |
密码哈希 (pbkdf2) |
| email |
TEXT |
--- |
邮箱 |
| nickname |
TEXT |
--- |
昵称 |
| avatar |
TEXT |
DEFAULT 'default.png' |
头像文件名 |
| role |
TEXT |
DEFAULT 'user' |
角色:admin / user |
| created_at |
TIMESTAMP |
DEFAULT CURRENT_TIMESTAMP |
注册时间 |
| last_login |
TIMESTAMP |
--- |
最后登录时间 |
默认管理员账号: 用户名 admin,密码 admin123
3.2 数据表 weather --- 气象数据表
| 字段 |
类型 |
说明 |
原始单位 |
存储单位 |
| id |
INTEGER |
主键 |
--- |
--- |
| date |
TEXT |
日期 (YYYYMMDD) |
--- |
--- |
| year |
INTEGER |
年份 |
--- |
--- |
| month |
INTEGER |
月份 |
--- |
--- |
| day |
INTEGER |
日 |
--- |
--- |
| season |
TEXT |
季节(春/夏/秋/冬) |
--- |
--- |
| tx |
REAL |
日最高温度 |
0.1°C |
°C |
| tn |
REAL |
日最低温度 |
0.1°C |
°C |
| tg |
REAL |
日平均温度 |
0.1°C |
°C |
| ss |
REAL |
日照时长 |
0.1h |
h |
| sd |
REAL |
积雪深度 |
cm |
cm |
| rr |
REAL |
降水量 |
0.1mm |
mm |
| qq |
REAL |
太阳辐射 |
W/m² |
W/m² |
| pp |
REAL |
气压 |
0.1hPa |
hPa |
| hu |
REAL |
相对湿度 |
% |
% |
| cc |
REAL |
云量 |
okta |
okta |
索引:
idx_year ON weather(year)
idx_month ON weather(month)
idx_season ON weather(season)
idx_date ON weather(date)
3.3 数据导入流程
init_db.py 负责数据库初始化:
- 删除旧数据库文件(如存在)
- 创建
users 表并插入默认管理员
- 创建
weather 表及索引
- 逐行读取 CSV 文件,进行单位换算(0.1°C → °C、0.1mm → mm 等)
- 根据月份自动判定季节(3-5 月春、6-8 月夏、9-11 月秋、12-2 月冬)
- 批量插入所有记录
四、后端架构
4.1 核心模块 app.py
复制代码
app.py 结构:
├── 导入与配置(1-12 行)
├── 数据库工具函数(15-34 行)
│ ├── get_db() --- 获取 SQLite 连接
│ ├── query_db() --- 查询返回字典列表
│ └── execute_db() --- 执行写操作
├── 装饰器(43-63 行)
│ ├── login_required --- 登录检查
│ └── admin_required --- 管理员权限检查
├── 认证路由(70-151 行)
│ ├── /login --- 登录
│ ├── /register --- 注册
│ └── /logout --- 登出
├── 页面路由(157-420 行)
│ ├── 首页、分析页面、数据管理、个人中心、管理员用户管理
│ └── 工具页面(日期查询、相关性、年份对比、天气日历、极端记录)
├── 数据概览 API(425-445 行)
├── 温度分析 API(450-530 行) --- 7 个端点
├── 降水分析 API(535-625 行) --- 6 个端点
├── 日照与辐射 API(630-690 行) --- 5 个端点
├── 综合气象 API(695-780 行) --- 7 个端点
├── 深度分析 API(785-880 行) --- 7 个端点
└── 工具 API(885-1100 行) --- 6 个端点
4.2 权限控制
系统采用两级角色模型:
| 角色 |
权限 |
user(普通用户) |
查看首页、所有分析页面、所有工具页面、个人中心 |
admin(管理员) |
在普通用户基础上,增加数据管理(CRUD)和用户管理 |
权限实现:
login_required 装饰器:检查 session['user_id'] 是否存在
admin_required 装饰器:在登录检查基础上,额外验证 session['role'] == 'admin'
- 前端模板通过
{% if session.get('role') == 'admin' %} 控制菜单和按钮的显示
4.3 API 端点汇总
系统共提供 39 个 API 端点,全部返回 JSON 格式数据:
数据概览(1 个)
| 端点 |
说明 |
GET /api/overview |
总记录数、年份范围、平均温度、总降水量、日均日照、极端温度、平均湿度 |
温度分析(7 个)
| 端点 |
说明 |
GET /api/yearly_temperature |
年度平均最高/最低/平均温度及极端值 |
GET /api/monthly_temperature |
月度平均温度 |
GET /api/temperature_range |
年度日温差(平均/最大/最小) |
GET /api/seasonal_temperature |
季节性温度(按年×季分组) |
GET /api/monthly_temperature_heatmap |
月度温度热力图数据(年×月矩阵) |
GET /api/temperature_distribution |
温度频率直方图(2°C 间隔) |
GET /api/temperature_anomaly |
温度距平(每年均温 - 总均温) |
降水分析(6 个)
| 端点 |
说明 |
GET /api/yearly_precipitation |
年度总降水、日均降水、降水日数 |
GET /api/monthly_precipitation |
月度平均降水、月均总降水、月均降水日数 |
GET /api/precipitation_distribution |
降水强度分类统计(无/微量/小雨/中雨/大雨/暴雨) |
GET /api/precipitation_anomaly |
降水距平 |
GET /api/dry_spell_analysis |
连续干旱日数(每年最长/平均) |
GET /api/monthly_precipitation_heatmap |
月度降水量热力图(年×月) |
日照与辐射(5 个)
| 端点 |
说明 |
GET /api/yearly_sunshine |
年度总日照、日均日照、晴天日数 |
GET /api/monthly_sunshine |
月度日照 |
GET /api/radiation_analysis |
年度太阳辐射(平均/最大/最小) |
GET /api/monthly_radiation |
月度辐射 |
GET /api/radiation_sunshine_correlation |
辐射-日照-温度月度相关 |
综合气象(7 个)
| 端点 |
说明 |
GET /api/yearly_pressure |
年度气压(平均/极值/振幅) |
GET /api/monthly_pressure |
月度气压 |
GET /api/humidity_analysis |
年度湿度 |
GET /api/monthly_humidity |
月度湿度 |
GET /api/cloud_cover_analysis |
年度云量 + 晴天/阴天日数 |
GET /api/monthly_cloud |
月度云量 |
GET /api/snow_analysis |
年度降雪(降雪日数/平均深度/最大深度) |
深度分析(7 个)
| 端点 |
说明 |
GET /api/temp_precip_scatter |
温度-降水量散点(采样 3000 点) |
GET /api/humidity_temp_correlation |
湿度-温度相关 |
GET /api/extreme_weather |
年度极端天气日数(高温/霜冻/暴雨/降雪/温暖) |
GET /api/decade_comparison |
年代际对比(5 个年代段) |
GET /api/growing_season |
生长季分析(>5°C/>10°C/>0°C 日数) |
GET /api/pressure_precip_correlation |
气压-降水相关(5 级气压对应降水概率) |
GET /api/wind_speed_estimation |
气压振幅-云量月度趋势 |
分析工具(6 个)
| 端点 |
说明 |
GET /api/date_query?start=&end= |
按日期范围查询完整气象数据 |
GET /api/export_csv?start=&end= |
导出 CSV 文件下载 |
GET /api/correlation_data |
9×9 Pearson 相关系数矩阵 + 4 组散点采样 |
GET /api/year_compare?year1=&year2= |
两年月度多维度对比 |
GET /api/weather_calendar?year= |
某年逐日气象数据(日历热力图用) |
GET /api/extreme_records |
历史极端记录 TOP10(高温/低温/降水/干旱/日照) |
五、前端架构
5.1 页面体系
复制代码
登录页(独立模板) ──→ 首页(数据概览)
│
┌─────────────────┼─────────────────┐
▼ ▼ ▼
5 个分析页面 5 个工具页面 管理功能
├─ 温度分析 ├─ 日期查询 ├─ 数据管理(管理员)
├─ 降水分析 ├─ 相关性矩阵 ├─ 用户管理(管理员)
├─ 日照与辐射 ├─ 年份对比 └─ 个人中心
├─ 综合气象 ├─ 天气日历
└─ 深度分析 └─ 极端记录
5.2 基础布局 base.html
所有登录后的页面均继承自 base.html,包含:
- 顶部导航栏:品牌标识、数据概览、数据分析下拉菜单、分析工具下拉菜单、数据管理(管理员)、用户下拉菜单
- Flash 消息系统:自定义毛玻璃风格 Toast 浮窗,支持 success/danger/warning/info 四种类型,自动 3 秒后滑出消失
- 页脚:版权信息
- 全局依赖:Bootstrap 5.3 CSS/JS、Bootstrap Icons、Google Fonts、ECharts 5.4.3
5.3 登录/注册页
独立模板(不继承 base.html),采用毛玻璃设计风格:
- 背景:机场实景图片 + 深色半透明遮罩
- 登录卡片:
backdrop-filter: blur(8px),深色半透明背景,白色微光边框
- 输入框:Bootstrap
input-group 组件,图标 + 输入框组合
- 动画:淡入效果
5.4 图表通用工具 charts.js
javascript
复制代码
// 颜色常量
COLORS = { primary, success, danger, warning, info, purple, pink, indigo, teal, orange, series[] }
// 通用图表配置
COMMON_OPTION = { tooltip, grid, toolbox(保存图片/区域缩放/还原) }
// 工具函数
fetchJSON(url) --- fetch 封装,返回 JSON
initChart(domId) --- 初始化 ECharts 实例
createGradient(stops) --- 创建线性渐变
setupResize() --- 监听窗口 resize 自动调整图表大小
5.5 全局样式 style.css
| 模块 |
说明 |
| CSS 变量 |
定义主色调、阴影、圆角、过渡等全局变量 |
| 导航栏 |
渐变背景、滚动时缩小、毛玻璃效果 |
| Hero 区域 |
深蓝渐变背景 + 点阵纹理 |
| 概览卡片 |
4 列网格、毛玻璃背景、悬停上浮 |
| 图表卡片 |
白色背景、圆角、悬停阴影增强 |
| 图表分析 |
浅蓝渐变背景,放置分析结论文字 |
| 响应式 |
992px/768px/576px 三档断点 |
| 动画 |
fadeInUp 交错入场动画 |
| 自定义滚动条 |
WebKit 浏览器圆角滚动条 |
5.6 图表清单(共 31 个)
温度分析页(7 个)
| 图号 |
图表名称 |
图表类型 |
数据源 |
| 图1 |
年度平均温度趋势 |
多折线图 |
/api/yearly_temperature |
| 图2 |
月度温度分布 |
柱状图+折线 |
/api/monthly_temperature |
| 图3 |
温度日较差分析 |
多折线图 |
/api/temperature_range |
| 图4 |
季节温度变化趋势 |
多折线图 |
/api/seasonal_temperature |
| 图5 |
温度热力图 |
热力图(年×月) |
/api/monthly_temperature_heatmap |
| 图6 |
温度频率分布 |
直方图 |
/api/temperature_distribution |
| 图7 |
温度距平分析 |
柱状图(正负色) |
/api/temperature_anomaly |
降水分析页(6 个)
| 图号 |
图表名称 |
图表类型 |
数据源 |
| 图8 |
年度降水量与降水日数 |
柱状图+折线 |
/api/yearly_precipitation |
| 图9 |
月度降水量分布 |
柱状图+折线 |
/api/monthly_precipitation |
| 图10 |
日降水量强度分布 |
环形饼图 |
/api/precipitation_distribution |
| 图11 |
降水距平分析 |
柱状图(正负色) |
/api/precipitation_anomaly |
| 图12 |
连续干旱日数分析 |
柱状图+折线 |
/api/dry_spell_analysis |
| 图13 |
月度降水量热力图 |
热力图(年×月) |
/api/monthly_precipitation_heatmap |
综合气象页(7 个)
| 图表名称 |
图表类型 |
数据源 |
| 年度气压变化趋势 |
多折线图 |
/api/yearly_pressure |
| 月度气压分布 |
柱状图+折线 |
/api/monthly_pressure |
| 年度湿度变化 |
多折线图 |
/api/humidity_analysis |
| 月度湿度分布 |
柱状图 |
/api/monthly_humidity |
| 云量与晴天/阴天日数 |
柱状图+折线 |
/api/cloud_cover_analysis |
| 月度云量分析 |
柱状图+折线 |
/api/monthly_cloud |
| 降雪分析 |
柱状图+折线 |
/api/snow_analysis |
深度分析页(6 个)
| 图表名称 |
图表类型 |
数据源 |
| 温度-降水量散点图 |
散点图 |
/api/temp_precip_scatter |
| 湿度-温度相关性 |
散点图+折线 |
/api/humidity_temp_correlation |
| 极端天气日数统计 |
堆叠面积图 |
/api/extreme_weather |
| 年代际气候对比 |
分组柱状图 |
/api/decade_comparison |
| 生长季长度变化 |
面积图 |
/api/growing_season |
| 气压与降水概率 |
柱状图+折线 |
/api/pressure_precip_correlation |
首页预览(3 个)
| 图表名称 |
图表类型 |
数据源 |
| 年度平均温度趋势 |
多折线图 |
/api/yearly_temperature |
| 年度降水量趋势 |
柱状图+折线 |
/api/yearly_precipitation |
| 月度平均温度雷达图 |
雷达图 |
/api/monthly_temperature |
工具页面图表(8 个)
| 页面 |
图表名称 |
图表类型 |
| 日期查询 |
温度变化曲线 |
折线图 |
| 日期查询 |
降水量柱状图 |
柱状图 |
| 相关性矩阵 |
相关系数热力图 |
热力图 |
| 相关性矩阵 |
4 组散点图 |
散点图 |
| 年份对比 |
温度/降水/日照/气压/湿度对比 |
双折线图(5 组) |
| 天气日历 |
日历热力图 |
ECharts calendar |
| 天气日历 |
逐日变化曲线 |
折线图/柱状图 |
| 天气日历 |
月度汇总 |
柱状图 |
六、功能模块详解
6.1 数据概览(首页)
概览指标卡片(8 个): 总记录数、覆盖年份、年均温度、年均降水量、日均日照、极端高温、极端低温、平均湿度
快捷导航(6 个入口卡片): 温度分析、降水分析、日照与辐射、综合气象、深度分析、数据管理(管理员可见)
分析工具入口(5 个卡片): 日期查询、相关性分析、年份对比、天气日历、极端记录
快速预览图表(3 个): 温度趋势、降水趋势、温度雷达图
6.2 五大分析模块
每个分析页面包含:
- Hero 区域(标题 + 描述)
- 图表卡片(图表 + 分析结论文字)
- 交错入场动画
6.3 分析工具
6.3.1 日期查询
- 日期范围选择器 + 7 个快捷年份按钮
- 查询后展示:统计摘要(6 个指标卡片)+ 温度曲线 + 降水柱状图 + 数据表格
- 支持导出 CSV 文件(含 BOM 头,兼容 Excel 中文)
6.3.2 相关性矩阵
- 9 个气象要素(最高温/最低温/平均温/日照/降水/辐射/气压/湿度/云量)的 Pearson 相关系数
- 9×9 热力图,颜色映射 [-1, 1]
- 4 组典型散点图:温度-湿度、温度-降水、气压-降水、日照-温度(各 2000 采样点)
6.3.3 年份对比
- 下拉选择任意两个年份
- 年度概况卡片对比(8 项指标 × 2 年)
- 5 组月度对比折线图:温度、降水、日照、气压、湿度
6.3.4 天气日历
- ECharts 日历热力图(类似 GitHub 贡献图)
- 支持切换指标(温度/降水/日照/云量)和年份(8 个选项)
- 配套逐日变化曲线 + 月度汇总柱状图
6.3.5 极端记录
- 3 个极值概览卡片(历史最高温、最低温、单日最大降水)
- 6 个 TOP10 排行榜:高温、低温、单日降水、最长连续干旱、最湿年份、最晴朗年份
6.4 数据管理(管理员)
- 分页表格展示(每页 20 条),支持按年份/月份/季节筛选
- 新增数据:日期自动解析年月日和季节
- 编辑数据:修改温度、降水、日照等 10 个气象指标
- 删除数据:单条删除
6.5 用户管理(管理员)
- 统计卡片:总用户数、管理员数、普通用户数
- 用户列表:显示用户名、昵称、邮箱、角色、注册时间、最后登录
- 操作:切换角色(admin/user)、重置密码(重置为
123456)、删除用户
- 安全限制:不能删除自己、不能修改自己的角色
6.6 个人中心
- 查看个人信息(用户名、昵称、邮箱、角色、注册时间)
- 修改昵称和邮箱
- 修改密码(需验证原密码)
七、部署与运行
7.1 环境要求
- Python 3.8+
- pip (Python 包管理器)
7.2 依赖安装
bash
复制代码
pip install flask numpy
sqlite3、csv、io、os、random、functools、datetime 为 Python 标准库,无需额外安装。werkzeug 随 Flask 一起安装。
7.3 数据库初始化
首次运行时,系统检测到 weather.db 不存在会自动调用 init_db.py 初始化数据库。也可手动执行:
bash
复制代码
python init_db.py
该脚本会:
- 创建
users 表并插入默认管理员 (admin / admin123)
- 创建
weather 表及索引
- 从 CSV 文件导入 16,436 条气象记录
7.4 启动应用
bash
复制代码
python app.py
默认监听 0.0.0.0:5000,浏览器访问 http://localhost:5000
7.5 默认账号
| 角色 |
用户名 |
密码 |
| 管理员 |
admin |
admin123 |
八、安全设计
8.1 认证与会话
- 基于 Flask
session 的服务端会话管理
- 密码使用 Werkzeug 的
generate_password_hash (pbkdf2:sha256) 加密存储
- 支持"记住我"功能(控制 session 是否持久化)
8.2 权限控制
- 路由级权限:
login_required 和 admin_required 装饰器
- 模板级权限:Jinja2 条件渲染隐藏无权菜单
- API 端点暂无权限限制(仅需登录即可访问数据 API)
8.3 输入校验
- 注册:用户名长度 3-20 字符、密码不少于 6 位、两次密码一致、用户名唯一性检查
- 数据管理:日期格式校验、数值类型安全转换(
parse_float 函数)
8.4 SQL 注入防护
- 所有 SQL 查询使用参数化占位符
?,避免字符串拼接
data_manage 的筛选条件通过白名单字段构建
九、设计规范
9.1 配色方案
| 用途 |
色值 |
说明 |
| 主色 |
#2563eb |
蓝色,用于按钮、链接、图表主色 |
| 成功 |
#10b981 |
绿色,用于成功提示 |
| 危险 |
#ef4444 |
红色,用于错误、高温 |
| 警告 |
#f59e0b |
橙色,用于警告、日照 |
| 信息 |
#06b6d4 |
青色,用于低温、信息 |
| 背景 |
#f1f5f9 |
浅灰,页面底色 |
| 深色 |
#1e293b |
导航栏、页脚 |
9.2 圆角规范
- 卡片/容器:
12px
- 按钮:
8px
- Toast:
14px
- 概览卡片:
16px
9.3 响应式断点
| 断点 |
宽度 |
调整 |
| 大屏 |
> 992px |
默认布局 |
| 中屏 |
≤ 992px |
图表高度 350px,概览卡片上边距 |
| 小屏 |
≤ 768px |
图表高度 300px,概览卡片 2 列 |
| 超小屏 |
≤ 576px |
概览卡片 1 列,图表头部纵向排列 |
十、文件清单
| 文件 |
行数 |
职责 |
app.py |
1123 |
Flask 主应用,路由 + API + 业务逻辑 |
init_db.py |
130 |
数据库初始化,CSV 导入 |
style.css |
450 |
全局样式 |
charts.js |
54 |
ECharts 通用工具函数 |
base.html |
178 |
基础布局模板 |
index.html |
287 |
首页 |
login.html |
~150 |
登录页(独立模板) |
register.html |
~170 |
注册页(独立模板) |
profile.html |
~120 |
个人中心 |
data_manage.html |
~180 |
数据管理 |
admin_users.html |
~100 |
用户管理 |
analysis_temperature.html |
~200 |
温度分析 |
analysis_precipitation.html |
~110 |
降水分析 |
analysis_sunshine.html |
~150 |
日照分析 |
analysis_comprehensive.html |
~180 |
综合气象 |
analysis_advanced.html |
~170 |
深度分析 |
tools_date_query.html |
~130 |
日期查询 |
tools_correlation.html |
~100 |
相关性矩阵 |
tools_year_compare.html |
~120 |
年份对比 |
tools_weather_calendar.html |
~110 |
天气日历 |
tools_extreme_records.html |
~100 |
极端记录 |