基于Python的中国航空航班数据可视化分析系统
项目概述
这是一个功能完整的航空数据可视化分析系统,采用现代化的Web技术栈,为用户提供直观、交互式的航班数据分析体验。
技术栈
- 后端: FastAPI + Python
- 前端: Bootstrap 5 + ECharts + jQuery
- 数据库: SQLite
- 认证: JWT Token
- 数据处理: Pandas
系统架构
前端界面层 ←→ 业务逻辑层 ←→ 数据存储层
HTML+CSS+JS FastAPI+Python SQLite+CSV
核心功能
1. 用户管理系统
- 用户注册、登录、权限管理
- JWT Token身份认证
- 个人中心功能
2. 数据分析功能
- 航线分析:城市间航班分布
- 航空公司分析:市场份额、准点率对比
- 城市分析:航空运输情况热力图
- 班期分析:一周航班分布统计
- 价格分析:票价分布和趋势
- 延误分析:准点率和延误时间
3. 数据可视化
- 中国地图航线分布图
- 飞线图展示城市间连接
- 多种图表类型:柱状图、折线图、饼图、散点图
- 交互式操作和实时数据更新
目录结构
航空数据可视化系统/
├── main.py # FastAPI主应用
├── requirements.txt # Python依赖
├── airplane_system.db # SQLite数据库
├── data/ # 数据文件
│ ├── air_data.csv # 航空数据
│ ├── airplane.csv # 航班数据
│ └── analyze.ipynb # 数据分析
├── static/ # 静态资源
│ ├── css/ # 样式文件
│ ├── js/ # JavaScript文件
│ └── webfonts/ # 字体文件
├── templates/ # HTML模板
│ ├── base.html # 基础模板
│ ├── dashboard.html # 仪表板
│ ├── routes.html # 航线分析
│ ├── airlines.html # 航空公司
│ ├── cities.html # 城市分析
│ ├── schedule.html # 班期分析
│ ├── price.html # 价格分析
│ ├── delay.html # 延误分析
│ └── admin_*.html # 管理页面
└── README.md # 项目说明
核心代码实现
用户认证系统
# JWT Token实现
from fastapi import HTTPException, Depends
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
import jwt
from datetime import datetime, timedelta
SECRET_KEY = "your-secret-key"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30
def create_access_token(data: dict):
to_encode = data.copy()
expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
to_encode.update({"exp": expire})
encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
return encoded_jwt
def verify_token(credentials: HTTPAuthorizationCredentials = Depends(HTTPBearer())):
try:
payload = jwt.decode(credentials.credentials, SECRET_KEY, algorithms=[ALGORITHM])
username: str = payload.get("sub")
if username is None:
raise HTTPException(status_code=401, detail="Invalid token")
return username
except jwt.ExpiredSignatureError:
raise HTTPException(status_code=401, detail="Token expired")
except jwt.JWTError:
raise HTTPException(status_code=401, detail="Invalid token")
数据库设计
# SQLite数据库初始化
import sqlite3
import pandas as pd
def init_database():
conn = sqlite3.connect('airplane_system.db')
cursor = conn.cursor()
# 创建用户表
cursor.execute('''
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE NOT NULL,
hashed_password TEXT NOT NULL,
email TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
# 创建航班数据表
cursor.execute('''
CREATE TABLE IF NOT EXISTS flights (
id INTEGER PRIMARY KEY AUTOINCREMENT,
departure_city TEXT NOT NULL,
arrival_city TEXT NOT NULL,
airline TEXT NOT NULL,
flight_number TEXT NOT NULL,
departure_airport TEXT NOT NULL,
arrival_airport TEXT NOT NULL,
departure_airport_lat REAL,
departure_airport_lng REAL,
arrival_airport_lat REAL,
arrival_airport_lng REAL,
on_time_rate REAL,
avg_delay_time REAL,
monday INTEGER DEFAULT 0,
tuesday INTEGER DEFAULT 0,
wednesday INTEGER DEFAULT 0,
thursday INTEGER DEFAULT 0,
friday INTEGER DEFAULT 0,
saturday INTEGER DEFAULT 0,
sunday INTEGER DEFAULT 0,
price REAL,
passengers INTEGER
)
''')
conn.commit()
conn.close()
数据分析API
# 航线分析接口
@app.get("/api/routes/analysis")
async def get_routes_analysis():
conn = sqlite3.connect('airplane_system.db')
cursor = conn.cursor()
cursor.execute('''
SELECT
departure_city,
arrival_city,
COUNT(*) as flight_count,
AVG(price) as avg_price,
AVG(on_time_rate) as avg_on_time_rate
FROM flights
GROUP BY departure_city, arrival_city
ORDER BY flight_count DESC
LIMIT 50
''')
routes_data = cursor.fetchall()
conn.close()
return {
"routes": [
{
"departure": route[0],
"arrival": route[1],
"flight_count": route[2],
"avg_price": round(route[3], 2) if route[3] else 0,
"avg_on_time_rate": round(route[4], 2) if route[4] else 0
}
for route in routes_data
]
}
# 航空公司分析接口
@app.get("/api/airlines/analysis")
async def get_airlines_analysis():
conn = sqlite3.connect('airplane_system.db')
cursor = conn.cursor()
cursor.execute('''
SELECT
airline,
COUNT(*) as flight_count,
AVG(price) as avg_price,
AVG(on_time_rate) as avg_on_time_rate,
AVG(avg_delay_time) as avg_delay_time
FROM flights
GROUP BY airline
ORDER BY flight_count DESC
''')
airlines_data = cursor.fetchall()
conn.close()
return {
"airlines": [
{
"name": airline[0],
"flight_count": airline[1],
"avg_price": round(airline[2], 2) if airline[2] else 0,
"avg_on_time_rate": round(airline[3], 2) if airline[3] else 0,
"avg_delay_time": round(airline[4], 2) if airline[4] else 0
}
for airline in airlines_data
]
}
前端界面实现
<!-- 响应式导航栏 -->
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container">
<a class="navbar-brand" href="/">
<i class="fas fa-plane"></i> 航空数据分析系统
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav me-auto">
<li class="nav-item">
<a class="nav-link" href="/dashboard">
<i class="fas fa-chart-line"></i> 仪表板
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/routes">
<i class="fas fa-route"></i> 航线分析
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/airlines">
<i class="fas fa-building"></i> 航空公司
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/cities">
<i class="fas fa-city"></i> 城市分析
</a>
</li>
</ul>
<ul class="navbar-nav">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="userDropdown" role="button" data-bs-toggle="dropdown">
<i class="fas fa-user"></i> {{ current_user }}
</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="/profile">个人中心</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="/logout">退出登录</a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
数据可视化图表
// 初始化仪表板图表
function initDashboardCharts() {
const flightStatsChart = echarts.init(document.getElementById('flightStatsChart'));
const flightStatsOption = {
title: {
text: '航班数据概览',
left: 'center'
},
tooltip: {
trigger: 'axis'
},
legend: {
data: ['航班数量', '平均价格', '准点率'],
top: 30
},
xAxis: {
type: 'category',
data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
},
yAxis: [
{
type: 'value',
name: '航班数量',
position: 'left'
},
{
type: 'value',
name: '价格/准点率',
position: 'right'
}
],
series: [
{
name: '航班数量',
type: 'bar',
data: [1200, 1320, 1010, 1340, 900, 2300, 2100]
},
{
name: '平均价格',
type: 'line',
yAxisIndex: 1,
data: [820, 932, 901, 934, 1290, 1330, 1320]
},
{
name: '准点率',
type: 'line',
yAxisIndex: 1,
data: [95.2, 94.8, 96.1, 93.5, 94.2, 95.8, 96.3]
}
]
};
flightStatsChart.setOption(flightStatsOption);
}
// 初始化中国地图
function initChinaMap() {
const mapChart = echarts.init(document.getElementById('chinaMap'));
fetch('/static/js/china.json')
.then(response => response.json())
.then(chinaJson => {
echarts.registerMap('China', chinaJson);
const mapOption = {
title: {
text: '中国航线分布图',
left: 'center'
},
tooltip: {
trigger: 'item',
formatter: '{b}: {c} (航班数量)'
},
visualMap: {
min: 0,
max: 1000,
left: 'left',
top: 'bottom',
text: ['高', '低'],
calculable: true
},
series: [
{
name: '航班数量',
type: 'map',
map: 'China',
roam: true,
emphasis: {
label: {
show: true
}
},
data: [
{name: '北京', value: 850},
{name: '上海', value: 720},
{name: '广州', value: 680},
{name: '深圳', value: 520},
{name: '成都', value: 480}
]
}
]
};
mapChart.setOption(mapOption);
});
}
数据可视化展示
项目展示
🐼 项目源码获取,码界筑梦坊各平台同名,博客底部含联系方式卡片,欢迎咨询!
1. 航线分布地图
- 中国地图可视化展示各城市航班密度分布
- 支持交互式缩放和平移操作
- 热力图效果用颜色深浅表示航班数量
2. 航线飞线图
- 动态飞线展示城市间的航线连接
- 支持按航空公司、航线类型筛选
- 3D立体感和动态效果
3. 数据分析图表
- 柱状图:航班数量、价格分布等
- 折线图:趋势分析、时间序列数据
- 饼图:市场份额、比例分析
- 散点图:相关性分析
4. 实时数据更新
- AJAX异步加载实现无刷新数据更新
- 响应式布局适配不同屏幕尺寸
- 丰富的交互式操作体验
部署与运行
环境要求
- Python 3.8+
- 现代浏览器(Chrome、Firefox、Safari、Edge)
- 至少2GB可用内存
- 网络连接(用于加载地图数据)
安装步骤
- 克隆项目
git clone <项目地址>
cd 航空数据可视化系统
- 创建虚拟环境
python -m venv venv
source venv/bin/activate # Linux/Mac
# 或
venv\Scripts\activate # Windows
- 安装依赖
pip install -r requirements.txt
-
准备数据文件
确保data/airplane.csv
文件存在,包含必要的航班数据字段 -
启动系统
python main.py
- 访问系统
打开浏览器访问http://localhost:8000
生产环境部署
使用Gunicorn部署
pip install gunicorn
gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000
使用Docker部署
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["python", "main.py"]
开发心得与总结
技术选型思考
- FastAPI vs Flask: 选择FastAPI是因为其现代化的异步支持、自动API文档生成和更好的性能表现
- SQLite vs PostgreSQL: 对于原型开发和中小型应用,SQLite提供了简单性和零配置的优势
- ECharts vs D3.js: ECharts提供了更丰富的开箱即用图表,特别适合地图可视化
架构设计亮点
- 前后端分离: 清晰的API设计,便于后续扩展和维护
- 模块化设计: 功能模块独立,代码结构清晰
- 响应式设计: 支持多设备访问,提升用户体验
性能优化策略
- 数据库索引: 为常用查询字段添加索引
- 数据缓存: 对静态数据实现缓存机制
- 异步处理: 使用FastAPI的异步特性提升并发性能
安全性考虑
- 密码加密: 使用bcrypt进行密码哈希
- JWT认证: 无状态的用户认证机制
- 输入验证: 严格的数据输入验证和清理
可扩展性设计
- 插件化架构: 支持新功能模块的快速集成
- 多数据源支持: 可以轻松扩展支持其他数据格式
- API版本控制: 为后续API升级预留空间
未来发展方向
短期目标
- 添加更多图表类型(雷达图、桑基图等)
- 实现数据导出功能(Excel、PDF)
- 增加用户权限管理
- 优化移动端体验
中期目标
- 集成机器学习算法进行航班预测
- 添加实时数据更新功能
- 支持多语言国际化
- 实现数据备份和恢复功能
长期目标
- 构建微服务架构
- 支持大数据量处理(Hadoop、Spark)
- 开发移动端APP
- 集成AI助手功能
联系方式
码界筑梦坊 - 专注于技术分享与创新 各平台同名 页面底部含联系卡片
参考资料
许可证
本项目采用 MIT 许可证。
最后更新时间: 2025年8月
如果这篇文章对您有帮助,请给个⭐️支持一下!