城市生态环境数据可视化分析系统 — 技术文档
一、项目概述
| 项目信息 |
详情 |
| 项目编号 |
333 |
| 项目名称 |
基于Python的城市生态环境数据可视化分析系统 |
| 技术栈 |
FastAPI + Bootstrap 5 + ECharts + MySQL |
| 运行端口 |
8333 |
| 数据库名 |
design_333_city_environment |
| 默认管理员 |
admin / admin123 |
| Python版本 |
3.9+ |
1.1 系统简介
本系统是一个面向城市生态环境数据的多维可视化分析平台,涵盖空气质量、水质指标、噪声水平、绿化率、气象因素等 19 项环境指标,支持 20 个城市、15 种区域类型的数据分析。系统提供从基础数据浏览到高级统计建模的完整分析链路,包括描述性统计、回归分析、异常检测、聚类分析、时间序列预测等功能。
1.2 核心功能模块
| 模块 |
状态 |
说明 |
| 数据分析(analytics) |
✅ 启用 |
6 个基础分析页面 + 4 个扩展分析页面 |
| 数据管理(data_manage) |
✅ 启用 |
数据 CRUD + CSV 批量导入 |
| 统计检验(statistical_analysis) |
✅ 启用 |
正态性、t 检验、ANOVA、卡方检验 |
| 回归分析(regression) |
✅ 启用 |
多元线性回归 + VIF 诊断 |
| 异常检测(anomaly_detection) |
✅ 启用 |
IQR + Z-Score 异常标记 |
| 同比环比(comparative) |
✅ 启用 |
时段对比、增长趋势、移动平均 |
| 聚类分析(clustering) |
✅ 启用 |
K-Means / DBSCAN |
| 时间序列(timeseries) |
✅ 启用 |
季节分解 + ARIMA 预测 |
| 报告导出(report_export) |
✅ 启用 |
Excel / PDF 报告生成 |
二、技术架构
2.1 整体架构
┌─────────────────────────────────────────────────────┐
│ 浏览器(前端) │
│ Bootstrap 5 + ECharts + Jinja2 模板渲染 │
└───────────────────────┬─────────────────────────────┘
│ HTTP
┌───────────────────────▼─────────────────────────────┐
│ FastAPI 路由层 │
│ main.py — 路由分发、Session 鉴权、数据转换 │
├─────────────┬──────────────┬────────────────────────┤
│ database.py│ shared/*.py │ templates/*.html │
│ MySQL CRUD │ 纯Python分析 │ Jinja2 前端模板 │
└─────────────┴──────────────┴────────────────────────┘
2.2 目录结构
code/
├── main.py # FastAPI 主应用(33 个路由)
├── database.py # MySQL 数据库操作类
├── config.yaml # 项目配置文件
├── run.py # 启动入口
├── requirements.txt # Python 依赖
├── data/
│ └── city_environmental_data.csv # 原始数据集(22列)
├── shared/ # 核心分析模块(纯Python,框架无关)
│ ├── analysis_core.py # 基础数据分析(分布、相关性)
│ ├── stats_core.py # 统计检验(正态、t检验、ANOVA、卡方)
│ ├── regression_core.py # 回归分析(线性/多元、VIF诊断)
│ ├── anomaly_core.py # 异常检测(IQR、Z-Score)
│ ├── comparative_core.py # 同比环比(时段对比、增长趋势)
│ ├── clustering_core.py # 聚类分析(K-Means、DBSCAN)
│ ├── timeseries_core.py # 时间序列(分解、ARIMA预测)
│ └── report_core.py # 报告导出(Excel、PDF)
├── templates/ # Jinja2 模板(24 个文件)
│ ├── base.html # 基础布局(导航栏、全局样式)
│ ├── index.html # 首页
│ ├── login.html # 登录页
│ ├── register.html # 注册页
│ ├── profile.html # 个人资料
│ ├── edit_profile.html # 编辑资料
│ ├── change_password.html # 修改密码
│ ├── analytics.html # 分析概览
│ ├── city_distribution.html # 城市分布
│ ├── air_quality.html # 空气质量
│ ├── water_quality.html # 水质分析
│ ├── environment_factors.html # 环境因素
│ ├── correlations.html # 相关性分析
│ ├── stat_analysis.html # 统计检验
│ ├── regression_analysis.html # 回归分析
│ ├── anomaly_analysis.html # 异常检测
│ ├── comparative_analysis.html # 同比环比
│ ├── clustering.html # 聚类分析
│ ├── timeseries.html # 时间序列
│ ├── reports.html # 报告导出
│ ├── data_manage.html # 数据管理
│ ├── data_manage_edit.html # 数据编辑
│ ├── admin/dashboard.html # 管理控制台
│ └── admin/users.html # 用户管理
├── static/
│ ├── css/
│ │ ├── bootstrap.min.css
│ │ ├── bootstrap-icons.css # 精简版(约400图标)
│ │ └── style.css # 主题样式(CSS变量驱动)
│ ├── js/
│ │ ├── bootstrap.bundle.min.js
│ │ └── echarts.min.js
│ ├── fonts/
│ └── image/
├── reports/ # 生成的报告存储目录
└── docs/ # 项目文档
├── 技术文档.md
├── api.md # API 接口文档
├── design-system.md # UI 设计系统
├── dev-rules.md # 开发规范
└── acceptance-report.md # 验收报告
2.3 依赖清单
| 分类 |
依赖包 |
用途 |
| Web框架 |
fastapi, uvicorn, starlette |
HTTP 服务、ASGI |
| 模板 |
jinja2 |
服务端页面渲染 |
| 表单 |
python-multipart |
文件上传、表单解析 |
| 鉴权 |
passlib[bcrypt] |
密码哈希 |
| 配置 |
PyYAML |
读取 config.yaml |
| 数据库 |
pymysql |
MySQL 连接 |
| 数据处理 |
pandas, numpy |
数据清洗、计算 |
| 统计分析 |
scipy |
统计检验(正态、t、F、卡方) |
| 机器学习 |
scikit-learn |
聚类(K-Means、DBSCAN)、异常检测 |
| 时间序列 |
statsmodels |
季节分解、ARIMA 预测 |
| 报告导出 |
openpyxl, reportlab |
Excel / PDF 生成 |
2.4 演示图片









































三、数据集说明
3.1 数据概况
- 文件:
data/city_environmental_data.csv
- 编码: UTF-8 with BOM
- 记录数: 10,000 条
- 城市数: 20 个(北京、上海、广州、深圳、成都、杭州、武汉、南京、重庆、天津、苏州、西安、长沙、青岛、郑州、大连、厦门、昆明、合肥、福州)
- 区域类型: 15 种(城区、郊区、新区、开发区、工业区、商业区、住宅区、生态区、科技园区、文教区、港口区、旅游区、农业区、物流区、金融区)
3.2 字段清单
| 字段名 |
中文名 |
类型 |
单位 |
数值范围 |
| id |
编号 |
自增主键 |
— |
— |
| city_name |
城市名称 |
分类 |
— |
20 个城市 |
| district |
区域 |
分类 |
— |
15 种类型 |
| date |
日期 |
文本 |
— |
— |
| aqi |
空气质量指数 |
数值 |
— |
10~300 |
| pm2_5 |
PM2.5浓度 |
数值 |
μg/m³ |
3~250 |
| pm10 |
PM10浓度 |
数值 |
μg/m³ |
5~400 |
| so2 |
二氧化硫浓度 |
数值 |
μg/m³ |
1~100 |
| no2 |
二氧化氮浓度 |
数值 |
μg/m³ |
5~120 |
| co |
一氧化碳浓度 |
数值 |
mg/m³ |
0.1~5.0 |
| o3 |
臭氧浓度 |
数值 |
μg/m³ |
10~300 |
| water_quality_index |
水质指数 |
数值 |
— |
1~5 |
| ph_value |
pH值 |
数值 |
— |
5~10 |
| turbidity |
浊度 |
数值 |
NTU |
0.5~20 |
| dissolved_oxygen |
溶解氧 |
数值 |
mg/L |
2~15 |
| nitrogen_compound |
氮化物浓度 |
数值 |
mg/L |
0~10 |
| noise_level |
噪声水平 |
数值 |
dB |
30~90 |
| green_coverage_rate |
绿化覆盖率 |
数值 |
% |
10~60 |
| temperature |
温度 |
数值 |
℃ |
-10~42 |
| humidity |
湿度 |
数值 |
% |
15~100 |
| wind_speed |
风速 |
数值 |
m/s |
0~20 |
| rainfall |
降雨量 |
数值 |
mm |
— |
四、数据库设计
4.1 users 表(用户表)
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(100) UNIQUE NOT NULL,
email VARCHAR(200) UNIQUE NOT NULL,
password_hash VARCHAR(200) NOT NULL,
role VARCHAR(20) DEFAULT 'user',
status VARCHAR(20) DEFAULT 'active',
avatar VARCHAR(500) DEFAULT '',
last_login_at DATETIME NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
4.2 data 表(环境数据表)
根据 config.yaml 中的 features 配置动态建表,包含所有 22 个字段的对应列。系统启动时自动检测列结构,若与配置不一致则重建表。
4.3 数据库操作方法汇总
| 方法名 |
功能 |
权限 |
init_database() |
建表、初始化默认管理员 |
系统 |
register_user() |
注册新用户 |
公开 |
authenticate_user() |
登录认证(更新 last_login_at) |
公开 |
get_user_by_id() |
获取用户信息 |
登录 |
update_profile() |
修改邮箱、头像 |
登录 |
change_password() |
修改密码(需旧密码) |
登录 |
get_all_users() |
获取全部用户列表 |
管理员 |
update_user_role() |
修改角色 |
管理员 |
update_user_status() |
启用/禁用用户 |
管理员 |
reset_password() |
重置密码 |
管理员 |
delete_user() |
删除用户 |
管理员 |
get_user_count() |
用户总数 |
管理员 |
get_today_login_count() |
今日登录数 |
管理员 |
get_active_user_count() |
7日活跃用户数 |
管理员 |
get_recent_users() |
最近注册用户 |
管理员 |
get_dataset_data() |
分页查询数据(支持搜索) |
管理员 |
add_dataset_record() |
新增记录 |
管理员 |
get_dataset_record() |
获取单条记录 |
管理员 |
update_dataset_record() |
更新记录 |
管理员 |
delete_dataset_record() |
删除记录 |
管理员 |
get_dataset_count() |
数据总条数 |
管理员 |
import_csv() |
CSV 批量导入(200条/批) |
管理员 |
五、路由接口清单
5.1 认证与用户(11 个)
| 方法 |
路径 |
功能 |
权限 |
| GET |
/ |
首页 |
公开 |
| GET |
/login |
登录页 |
公开 |
| POST |
/login |
登录提交 |
公开 |
| GET |
/register |
注册页 |
公开 |
| POST |
/register |
注册提交 |
公开 |
| GET |
/logout |
退出登录 |
登录 |
| GET |
/profile |
个人资料 |
登录 |
| GET/POST |
/edit_profile |
编辑资料 |
登录 |
| GET/POST |
/change_password |
修改密码 |
登录 |
5.2 数据分析(2 + 9 个分析页)
| 方法 |
路径 |
功能 |
类型 |
| GET |
/analytics |
分析概览(卡片导航) |
— |
| GET |
/analytics/city_distribution |
城市分布分析 |
基础分析 |
| GET |
/analytics/air_quality |
空气质量分析 |
基础分析 |
| GET |
/analytics/water_quality |
水质分析 |
基础分析 |
| GET |
/analytics/environment_factors |
环境因素分析 |
基础分析 |
| GET |
/analytics/correlations |
相关性分析 |
基础分析 |
| GET |
/analytics/stat_tests |
统计检验分析 |
statistical |
| GET |
/analytics/regression_analysis |
回归分析 |
regression |
| GET |
/analytics/anomaly |
异常值检测 |
anomaly |
| GET |
/analytics/period_compare |
同比环比分析 |
comparative |
5.3 独立分析模块(7 个)
| 方法 |
路径 |
功能 |
| GET |
/clustering |
聚类分析页面 |
| POST |
/clustering/run |
执行聚类算法 |
| GET |
/timeseries |
时间序列分析页面 |
| POST |
/timeseries/forecast |
执行时序预测 |
| GET |
/reports |
报告导出页面 |
| POST |
/reports/generate |
生成 Excel/PDF 报告 |
| GET |
/reports/download/{filename} |
下载报告文件 |
5.4 数据管理(7 个)
| 方法 |
路径 |
功能 |
权限 |
| GET |
/data_manage |
数据列表(分页、搜索) |
管理员 |
| GET |
/data_manage/add |
新增数据表单 |
管理员 |
| POST |
/data_manage/add |
新增数据提交 |
管理员 |
| GET |
/data_manage/edit/{id} |
编辑数据表单 |
管理员 |
| POST |
/data_manage/edit/{id} |
编辑数据提交 |
管理员 |
| POST |
/data_manage/delete/{id} |
删除数据记录 |
管理员 |
| POST |
/data_manage/import_csv |
CSV 文件导入 |
管理员 |
5.5 管理后台(7 个)
| 方法 |
路径 |
功能 |
| GET |
/admin |
管理控制台(统计卡片) |
| GET |
/admin/users |
用户管理列表 |
| POST |
/admin/users/{id}/role |
修改用户角色 |
| POST |
/admin/users/{id}/status |
启用/禁用用户 |
| POST |
/admin/users/{id}/reset_password |
重置用户密码 |
| POST |
/admin/users/{id}/delete |
删除用户 |
| POST |
/admin/users/create |
创建新用户 |
六、分析模块详细说明
6.1 基础数据分析(analysis_core.py)
用于 5 个基础分析页面(城市分布、空气质量、水质、环境因素、相关性)。
| 方法 |
功能 |
输出 |
overview() |
数据概览 |
行数、列数、缺失值比例 |
numeric_distribution() |
数值分布直方图 |
labels、counts、统计量 |
category_distribution() |
分类分布 |
{value: count} |
correlation_matrix() |
相关性矩阵 |
皮尔逊相关系数矩阵 |
路由层(main.py)在传递给模板前会进行数据转换:
category_distribution 从 {value: count} 转为 {values: [], counts: []}
- 为每个数值分布补充
.values(采样原始值)和 .stats(描述性统计)
- 按分类列分组聚合数值列均值生成
group_stats
6.2 统计检验(stats_core.py)
| 方法 |
功能 |
输出关键字段 |
descriptive_stats() |
描述性统计 |
count, mean, std, min, q1, median, q3, max, skewness, kurtosis |
normality_test() |
Shapiro-Wilk 正态性检验 |
statistic (W值), p_value, is_normal |
ttest() |
独立样本 t 检验 |
statistic, p_value, significant |
anova() |
单因素方差分析 |
f_statistic, p_value, significant, groups |
chi_square() |
卡方独立性检验 |
chi2, dof, p_value, significant |
路由层自动补充:
- ANOVA:按 city_name 分组,检验第一个数值列的组间差异
- t 检验:取前两个城市对比第一个数值列
- 卡方检验:检验 city_name 与 district 之间的独立性
6.3 回归分析(regression_core.py)
| 方法 |
功能 |
输出关键字段 |
multiple_regression() |
多元线性回归 |
r_squared, adj_r_squared, f_statistic, coefficients, intercept |
diagnostics() |
回归诊断 |
vif(方差膨胀因子), residuals |
当前配置:
- 目标变量: aqi(空气质量指数)
- 预测变量: pm2_5, pm10, no2, temperature, wind_speed, green_coverage_rate
路由层补充计算 actual / predicted / residuals 数组用于散点图和残差图。
6.4 异常检测(anomaly_core.py)
| 方法 |
功能 |
输出关键字段 |
iqr_detection() |
IQR 四分位距法 |
outlier_count, outlier_pct, lower_bound, upper_bound |
zscore_detection() |
Z-Score 标准差法 |
outlier_count, outlier_pct |
summary() |
汇总检测结果 |
iqr + zscore 综合报告 |
检测列:aqi, pm2_5, pm10, water_quality_index, noise_level, temperature
路由层将数据转换为 {summary: {col: {...}}, details: {col: {iqr: {values, anomaly_indices, bounds}}}} 结构,散点图标记正常值(绿色)和异常值(红色),并显示 IQR 上下界虚线。
6.5 同比环比(comparative_core.py)
| 方法 |
功能 |
输出关键字段 |
period_comparison() |
时段对比 |
periods, values, yoy_pct, mom_pct |
growth_trend() |
增长趋势 |
labels, series[{values, growth_rates}] |
moving_average() |
移动平均 |
labels, original, averages[{window, values}] |
配置:
- 日期列: date
- 值列: aqi, water_quality_index, noise_level
- 聚合周期: month
- 移动平均窗口: 7日 / 30日
6.6 聚类分析(clustering_core.py)
| 方法 |
功能 |
输出关键字段 |
find_optimal_k() |
肘部法 + 轮廓系数确定最优 K |
elbow, silhouette, suggested_k |
kmeans() |
K-Means 聚类 |
k, silhouette_score, centers, scatter_data, profile |
dbscan() |
DBSCAN 密度聚类 |
n_clusters, n_noise, scatter_data, profile |
聚类特征列:aqi, pm2_5, pm10, water_quality_index, noise_level, green_coverage_rate, temperature
DBSCAN 噪声点(label=-1)在散点图中用灰色小圆点区分,轮廓系数排除噪声点后计算。
6.7 时间序列(timeseries_core.py)
| 方法 |
功能 |
输出关键字段 |
decompose() |
季节性分解 |
dates, observed, trend, seasonal, residual |
arima_forecast() |
ARIMA 预测 |
historical, forecast (含置信区间) |
moving_averages() |
多窗口移动平均 |
labels, original, averages |
配置:
- 日期列: date
- 可分析指标: aqi, water_quality_index
- 默认预测期数: 12 期
6.8 报告导出(report_core.py)
| 方法 |
功能 |
输出 |
generate_excel() |
生成 Excel 报告 |
.xlsx 文件路径 |
generate_pdf() |
生成 PDF 报告 |
.pdf 文件路径 |
list_reports() |
列出已生成报告 |
[{filename, format, size_kb, created}] |
报告内容可选:数据概览、空气质量分析、水质分析、相关性分析、统计检验、异常检测。
七、前端设计系统
7.1 主题色
| 变量名 |
色值 |
用途 |
--primary |
#059669 |
主色(翠绿) |
--primary-light |
#34D399 |
浅色变体 |
--primary-dark |
#047857 |
深色变体 |
--primary-darker |
#065F46 |
更深变体 |
--shadow-primary |
rgba(5,150,105,0.25) |
阴影色 |
--bg-main |
#f0fdf4 |
页面背景 |
7.2 ECharts 配色数组
所有图表页面统一使用:
var chartColors = ['#059669', '#10B981', '#34D399', '#6EE7B7', '#A7F3D0',
'#047857', '#065F46', '#064E3B', '#0D9488', '#14B8A6'];
7.3 核心组件
| 组件 |
CSS 类名 |
用途 |
| 页头 |
.page-header |
每页顶部图标 + 标题 + 描述 |
| 统计卡片 |
.stat-card |
数字指标展示(4色变体) |
| 图表容器 |
.chart-container |
ECharts 图表外框 |
| 卡片 |
.card |
Bootstrap 标准卡片 |
| 表格 |
.table |
数据展示表格 |
| 认证页 |
.auth-container |
登录/注册独立布局 |
| 空状态 |
.empty-state |
无数据占位提示 |
7.4 导航栏结构
┌─ 首页
├─ 数据分析 ▼
│ ├─ 分析概览
│ ├─ 城市分布
│ ├─ 空气质量
│ ├─ 水质分析
│ ├─ 环境因素
│ └─ 相关性分析
├─ 扩展分析 ▼
│ ├─ 统计检验
│ ├─ 回归分析
│ ├─ 异常检测
│ └─ 同比环比
├─ 聚类分析
├─ 时间序列
├─ 报告导出
└─ 用户菜单 ▼
├─ [管理员] 管理后台
├─ [管理员] 用户管理
├─ [管理员] 数据管理
├─ 个人资料
└─ 退出登录
八、数据流转机制
8.1 分析页面数据流
CSV 文件 → shared/*_core.py(纯Python分析)
→ main.py 路由层(数据结构转换)
→ Jinja2 模板(JSON 注入 <script>)
→ ECharts 渲染图表
核心设计原则:shared 模块返回自己的数据结构,main.py 路由层负责将其转换为前端模板期望的格式。这样 shared 模块可以跨项目复用,模板也可以独立开发。
8.2 分析页面类型分发
/analytics/{page_route} 路由通过 config.yaml 中每个分析页的 type 字段进行分发:
| type 值 |
分发目标 |
数据源 |
| 空或不设置 |
analysis_core.py |
CSV 直读 |
| statistical |
stats_core.py |
CSV 直读 |
| regression |
regression_core.py |
CSV 直读 |
| anomaly |
anomaly_core.py |
CSV 直读 |
| comparative |
comparative_core.py |
CSV 直读 |
8.3 字段中文映射
系统全局维护 FIELD_MAPPING 字典(从 config.yaml 的 features 构建),所有分析模板通过 fieldMapping JS 变量和 cn() 函数将英文字段名转为中文标签显示。
九、安全机制
9.1 认证与授权
| 机制 |
实现 |
| 密码存储 |
bcrypt 单向哈希(passlib) |
| 会话管理 |
Starlette SessionMiddleware(Cookie-based) |
| 角色控制 |
user(普通用户)/ admin(管理员) |
| 权限检查 |
require_login() / require_admin() 路由级检查 |
| 密码可见 |
登录/注册页面支持密码显示/隐藏切换 |
9.2 权限矩阵
| 功能 |
游客 |
普通用户 |
管理员 |
| 首页 |
✅ |
✅ |
✅ |
| 登录/注册 |
✅ |
— |
— |
| 数据分析 |
❌ |
✅ |
✅ |
| 聚类/时序/报告 |
❌ |
✅ |
✅ |
| 个人资料 |
❌ |
✅ |
✅ |
| 数据管理 |
❌ |
❌ |
✅ |
| 管理后台 |
❌ |
❌ |
✅ |
| 用户管理 |
❌ |
❌ |
✅ |
十、部署与运行
10.1 环境准备
CREATE DATABASE design_333_city_environment
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
cd F:\code\333-基于Python的城市生态环境数据可视化分析系统\code
pip install -r requirements.txt
python run.py
10.2 访问地址
| 地址 |
说明 |
| http://localhost:8333 |
系统首页 |
| http://localhost:8333/login |
登录页面 |
| http://localhost:8333/admin |
管理控制台 |
10.3 默认账号
| 角色 |
用户名 |
密码 |
| 管理员 |
admin |
admin123 |
10.4 配置说明
所有可变配置集中在 config.yaml,包括:
- 项目基本信息(名称、描述)
- 数据库连接参数
- 数据集文件名和字段定义
- 分析页面路由和列配置
- 模块启用/禁用开关
- 聚类/时序参数
修改配置后重启服务即可生效,无需修改代码。
十一、管理控制台
11.1 控制台统计卡片
| 指标 |
数据来源 |
| 注册用户 |
users 表总行数 |
| 数据记录 |
data 表总行数 |
| 今日登录 |
last_login_at 为当天的用户数 |
| 7日活跃 |
last_login_at 在最近 7 天内的用户数 |
11.2 用户管理功能
- 查看全部用户(用户名、邮箱、角色、状态、注册时间、最后登录)
- 修改角色(user ↔ admin)
- 启用/禁用账户
- 重置密码(默认重置为 123456)
- 删除用户
- 创建新用户
11.3 数据管理功能
- 分页浏览数据(20 条/页,省略号分页)
- 关键词搜索(城市/区域模糊匹配)
- 新增/编辑/删除单条记录
- CSV 文件批量导入(200 条/批事务提交)
十二、项目文档清单
| 文件 |
说明 |
docs/技术文档.md |
本文档,系统完整技术说明 |
docs/api.md |
API 接口文档(前后端契约) |
docs/design-system.md |
UI 设计系统(配色、字体、组件规范) |
docs/dev-rules.md |
开发规范(前端规范、后端规范、验收清单) |
docs/acceptance-report.md |
验收报告(16 项检查结果) |
docs/backend-log.md |
后端开发日志 |
docs/frontend-log.md |
前端开发日志 |
所有评论(0)