基于Django+Python的天气数据分析与可视化系统实战解析
基于DjangoPython的江西省天气数据分析与可视化系统毕设全解析每年的毕业季都会有一批学弟学妹被“大数据可视化”类选题折腾得寝食难安。如果你正在做或准备做“基于DjangoPython的江西省天气数据分析与可视化系统”这个方向的毕设或者纯粹想找一个能完整串联Python、Django、MySQL、ECharts的技术项目练手这篇文章值得你花十分钟看完。我把它从需求拆解、数据采集到可视化落地、远程部署调试的完整链路都过了一遍尽量用你已经踩过或者还没踩到但一定会踩的坑作为线索来讲不绕弯子。这个项目完全可以用一句话说清楚用Python写爬虫或对接API获取江西各地市的天气数据用Django做后端Web框架把历史天气数据的分析结果通过ECharts图表和后台管理界面呈现出来。它是一个典型的“数据采集→预处理→存储→分析→可视化→Web展示”全流程项目非常适合大数据方向的毕业设计也适合想入门Django全栈但不想做传统增删改查商城系统的开发者。1. 项目整体设计与思路拆解1.1 这个系统到底该做成什么样很多同学拿到这个题目第一反应就是“不就是查天气吗”然后照着网上天气API的demo做了一个只能查当前温度的页面结果开题答辩就被老师怼了回去没有数据分析没有可视化大屏没有历史趋势连数据库建模都看不出工作量。可千万别这么干。一个能拿得出手的江西省天气数据分析可视化系统至少要包含四层东西数据采集层能自动抓取或获取江西省11个地市南昌、九江、上饶、抚州、宜春、吉安、赣州、景德镇、萍乡、新余、鹰潭的历史天气数据包括最高温、最低温、天气现象、风力风向、空气质量等字段。数据的时间跨度建议至少覆盖近三年不然做趋势分析根本看不出规律。数据存储层用MySQL或者SQLite但强烈建议MySQL答辩时更有说服力设计合理的表结构把采集到的数据清洗后落库同时支持增量更新。数据分析层利用Pandas对数据库中的天气数据进行聚合分析比如按月/季度/年度统计各城市平均气温、极端天气分布、降水规律、入冬入夏时间等分析结果可以提前算好存表也可以实时计算。可视化展示层前端页面用ECharts做图表通过Django的视图函数从数据库取数渲染成折线图、柱状图、热力图、地图等形式再用Django Admin做后台管理界面让管理员可以手动维护数据。这四层结构是很经典的分层设计每一层都有独立的技术点可讲答辩时老师的提问基本逃不出这四块。1.2 技术选型背后的为什么先说Django。为什么这个题目特别适合用Django而不用Flask或FastAPI因为Django自带Admin后台、ORM、模板引擎、迁移机制这些对于毕设项目来说是巨大的加分项。Django Admin是最大杀器它能在你几乎不写前端代码的情况下白送你一个可以对数据表做增删改查的后台管理界面在答辩演示时看起来非常“完整”。你可以把采集到的天气数据、城市信息、用户操作记录都挂到Admin里统一管理这个观感比单独搞一个Vue后台要省力太多。再说ECharts。ECharts是百度开源的JavaScript可视化库对中文用户特别友好支持地图、折线、柱状、饼图、雷达图、热力图等几十种图表而且交互效果流畅完全免费。配合Django的模板渲染或者Ajax异步取数可以实现图表的动态更新。为什么不用Matplotlib因为Matplotlib输出的是静态图片虽然写代码简单但展示时缺少交互体验在大屏展示的场合下显得不够“大数据”。还有Pandas和NumPy这两个是数据分析阶段的主力工具。Pandas处理DataFrame做分组聚合、重采样、透视表都非常快。比如你要分析“江西过去三年各城市夏季平均最高温排序”用Pandas就是几行代码的事如果纯手写SQL循环那工作量就大了。1.3 项目目录结构与模块规划我建议你把项目规划成下面这种模块结构清晰好答辩weather_analysis/ # Django项目主配置目录 ├── manage.py ├── weather_analysis/ # settings/urls/wsgi ├── apps/ │ ├── data_collect/ # 数据采集模块爬虫或API对接 │ ├── data_analyze/ # 数据分析模块Pandas处理 │ └── dashboard/ # 可视化展示模块视图模板 ├── static/ # 静态文件ECharts/js/css ├── templates/ # Jinja2模板 ├── db.sqlite3 / MySQL配置 └── requirements.txt如果嫌拆分太多管理麻烦也可以只建一个weather的Django app然后在里面分views.py、models.py、analysis.py、collector.py四个模块。但无论怎么拆一定要让代码分层清晰这是答辩时的第一印象。2. 核心功能模块的实现细节2.1 天气数据采集API对接与爬虫方案怎么选数据采集是整个项目的地基数据质量差后面分析全白搭。对于江西省历史天气数据实际可行的方法有三种方法一调用免费天气API推荐作为辅助手段像和风天气、心知天气、高德天气这类平台都提供开发者API注册后可以拿到免费额度。它们的当前天气和逐天预报数据质量不错但历史数据接口通常需要付费而且免费版本请求次数有限。所以API适合做“当前实况天气”的展示模块以及定时增量更新当天天气。方法二爬取气象历史数据网站主力手段我实际做过的方案是爬取“天气后报”www.tianqihoubao.com这种提供历史天气查询的网站。它们是静态网页反爬措施不算严格用requests加BeautifulSoup就能搞定。具体来说访问“http://www.tianqihoubao.com/lishi/nanchang.html”这类页面页面里有一个月份的表格包含日期、天气状况、气温、风力风向四个字段直接解析HTML表格即可。需要注意爬虫代码要加User-Agent伪装和请求间隔time.sleep(1)以上不然很容易被网站封IP。另外这种网站的日期维度是从某一年开始的你可以逐月构造URL抓取比如nanchang201901.html代表南昌2019年1月翻页就是把月份1写个循环就能把近五年的数据全拉下来。方法三直接下载公开数据集最省事有些同学不想写爬虫也可以去Kaggle或国内的数据开放平台找中国城市历史天气数据集CSV。这种方式最省事但答辩时老师可能会问“数据哪来的”你得能说出来源和下载地址。而且CSV数据通常需要做大量的格式统一工作比如字段名不规范、日期格式不统一、存在缺失值这反而给你增加了数据清洗的难度。我给个混合推荐方案历史数据用爬虫抓一次全量之后每天用一个定时任务比如Django的manage.py自定义命令加cron调用API增量更新当天数据。这样既保证了数据量足够做分析又能体现系统的实时性两条技术路线都展示出来了。2.2 数据清洗与存储坑比你想的多爬下来或者下载下来的数据一定是脏的。举几个真实情况气温字段长这样“22℃ / 13℃”中间隔着空格和斜杠需要拆成high_temp和low_temp两列并转成整型。天气现象写着“多云~阴”需要拆分或归一化。风力风向字段“东南风3-4级转北风4-5级”直接存字符串可以但如果要做风力分析就必须提取最大风力等级。日期字段可能是“2019-01-01”也可能是“2019年01月01日”需要统一格式。有的城市某些月份的某几天数据缺失需要标记或者用前后值填充。这里要特别说一个容易被忽视的点城市名称映射表。江西省的11个地市级城市中景德镇、萍乡、新余、鹰潭这四个城市在爬虫网站上可能对应独立页面但有些数据源的URL不一定好拼建议你在MySQL里建一张城市表字段包含city_id、city_name、pinyin、province、sort_order方便前端地图和下拉框联动。Django的数据模型models.py我建议这样设计from django.db import models class City(models.Model): name models.CharField(城市名, max_length32, uniqueTrue) pinyin models.CharField(拼音, max_length64, blankTrue) longitude models.FloatField(经度, nullTrue, blankTrue) latitude models.FloatField(纬度, nullTrue, blankTrue) class Meta: db_table city verbose_name 城市 def __str__(self): return self.name class WeatherDaily(models.Model): city models.ForeignKey(City, on_deletemodels.CASCADE, verbose_name城市) date models.DateField(日期) weather models.CharField(天气现象, max_length64) high_temp models.IntegerField(最高气温) low_temp models.IntegerField(最低气温) wind_direction models.CharField(风向, max_length32, blankTrue) wind_level models.CharField(风力等级, max_length32, blankTrue) aqi models.IntegerField(AQI指数, nullTrue, blankTrue) create_time models.DateTimeField(入库时间, auto_now_addTrue) class Meta: db_table weather_daily unique_together (city, date) verbose_name 每日天气这里有两个关键设计一是unique_together约束避免同城同日期重复入库二是外键关联城市表后续按城市分组查询非常方便。另一张常用表是weather_analyze_result用来存放预计算好的分析结果比如每月各城市平均气温这样可视化页面查询时就不用临时跑大计算。2.3 Django ORM查询与数据分析联动数据入库后接着就是分析。一个常见的场景可视化大屏上展示“近一年南昌市每月平均最高气温折线图”。在视图函数里你当然可以from django.db.models.functions import TruncMonth from django.db.models import Avg data (WeatherDaily.objects .filter(city__name南昌, date__gtedate(2024, 1, 1)) .annotate(monthTruncMonth(date)) .values(month) .annotate(avg_highAvg(high_temp)) .order_by(month))Django ORM的annotate配合TruncMonth可以生成按月份分组的SQL效率还不错适合中小数据量场景。但如果你的分析逻辑涉及滑动平均、同比环比、季节划分这种比较复杂的操作建议把数据从ORM取出来之后转成Pandas的DataFrame再算。import pandas as pd qs (WeatherDaily.objects .filter(city__name南昌) .order_by(date) .values(date, high_temp, low_temp, weather)) df pd.DataFrame.from_records(qs) df[date] pd.to_datetime(df[date]) df.set_index(date, inplaceTrue) monthly_mean df.resample(M)[high_temp].mean()然后直接把monthly_mean转成JSON列表传给前端ECharts渲染。这样做的优势是扩展性极强你后面想加一个“连续高温天数统计”用Pandas的groupby和条件筛选就能搞定而且代码逻辑在答辩时非常好讲。3. 可视化系统与Django集成实操3.1 页面布局与图表设计的核心思想我见过的毕设可视化页面有两种极端一种是一页白底黑字塞满了表格另一种是五彩斑斓地堆了十多个图表但看不出重点。好的可视化大屏应该有清晰的视觉层次。我的建议是采用经典的“总—分—分”布局顶部区域显示系统标题、当前时间、全省天气概况的文字摘要。中间主区域江西省地图点击或者悬停地市可以显示该市的当日天气信息和最近一周温度趋势。左右两侧面板左侧放各城市温度对比柱状图和降水或天气现象饼状图右侧放历史气温趋势折线图、AQI空气质量分布图。底部区域可以放一个数据统计表格展示最近更新的天气数据记录顺便体现后台数据管理的存在感。这种布局在答辩演示时特别占优势因为老师一眼就能看到“数据地图趋势分析对比排行”全是可视化大屏的核心元素。3.2 Django与ECharts的三种集成方式把ECharts集成到Django里有三种常见方式我逐一说明你根据需求挑。方式一模板渲染注入初始数据在views.py中提前算好数据通过render(request, dashboard.html, {chart_data: json.dumps(data)})传给模板然后在模板的script标签里用var data {{ chart_data|safe }}取出来填充ECharts配置。这种方式适合首屏加载因为数据随HTML一起返回不需要额外的Ajax请求。注意|safe过滤器一定要加否则Django会转义JSON字符串里的引号导致JS报错。方式二Ajax异步取数在ECharts初始化后用fetch或axios请求Django提供的/api/chart/temperature_trend/这类JSON接口拿到数据后通过myChart.setOption({series: [{data: response.data}]})动态更新图表。这种方式适合做筛选联动比如用户切换城市或时间范围时重新请求。async function loadChart(cityName) { const resp await fetch(/api/temperature_trend/?city${cityName}); const data await resp.json(); tempChart.setOption({ xAxis: { data: data.dates }, series: [{ name: 最高气温, data: data.highs }] }); }方式三前端直接渲染完整配置最灵活如果不想后端参与太多逻辑可以让后端只返回原始数据所有ECharts的option配置都写在静态JS文件里。这样后端保持简单前端调整图表样式不用改Django代码。缺点是答辩时如果老师问“图表怎么配置的”你得去翻JS文件讲。我个人建议采用方式一 方式二结合首屏核心图表用模板注入保证加载速度筛选联动用Ajax实现动态交互。这种方式工作量和展示效果的性价比最高。3.3 Django Admin后台管理界面的实用配置Django Admin是白送的福利但默认的显示效果和操作逻辑比较原始花点心思配置一下会让整个系统档次提升不少。几个值得做的必选项在admin.py中注册模型时配置list_display显示关键字段比如城市、日期、最高气温、最低气温、AQI。设置list_filter按城市和时间过滤方便答辩现场演示数据检索。设置search_fields支持按日期、城市搜索并添加date_hierarchy date在页面顶部生成按日期的层级导航。配置list_per_page控制每页显示行数默认100条一页实在不友好。如果你愿意再花点时间可以覆盖Django Admin的base_site.html模板把页面标题改成“江西省天气数据分析系统后台管理”并在左边加一个“返回可视化大屏”的链接。这些细节不复杂但答辩时很加分老师会觉得你不仅会调接口还懂用户体验。4. Django常见报错与远程调试部署经验4.1 环境配置阶段的三个高频坑坑一Python版本与Django版本不匹配Django 4.x要求Python 3.10以上Django 3.2则兼容Python 3.6-3.10。如果你在服务器上装的是Python 3.8直接用pip install django可能会装到不支持当前Python版本的最新版Django导致site-packages里冲突。稳妥做法是pip install django4.2或在项目根目录的requirements.txt中锁定版本Django4.2.7 pandas2.0.3 mysqlclient2.2.0 requests2.31.0 beautifulsoup44.12.2坑二mysqlclient安装困难在Windows上装mysqlclient需要MySQL的C语言连接库很多同学在这一步直接崩溃。建议解决方案是用pymysql作为替代并在项目的__init__.py里写两行兼容代码import pymysql pymysql.install_as_MySQLdb()这样Django的ORM就能通过pymysql连接MySQL而项目代码不用改一行。Linux服务器上则可以直接apt-get install default-libmysqlclient-dev后正常安装mysqlclient。坑三时区设置导致时间数据偏移Django的settings.py里默认TIME_ZONE UTC如果你在视图里用datetime.now()拿当前时间入库后会发现和北京时间差了8小时。毕设项目务必要改成TIME_ZONE Asia/Shanghai USE_TZ True并在数据采集脚本中统一把本地时间转成标准时间再入库。4.2 远程调试与部署把项目跑在服务器上标题里提到了“远程调试”这说明你的毕设可能需要部署到云服务器上给老师演示或者你本机开发、服务器运行需要远程改代码排查问题。我分享一套最省心的远程调试部署路径。第一步准备一台云服务器阿里云或腾讯云的轻量应用服务器就行选Ubuntu 22.04系统2核4G配置足够跑这个项目。如果预算有限本地虚拟机或者WSL也能完成大部分验证。第二步在服务器上创建Python虚拟环境sudo apt update sudo apt install python3-venv nginx -y mkdir -p /home/ubuntu/weather_project cd /home/ubuntu/weather_project python3 -m venv venv source venv/bin/activate pip install -r requirements.txt第三步上传项目代码并用runserver验证本地代码可以先git push到私有仓库服务器上git clone。也可以直接用scp打包传上去但推荐git因为远程调试时改代码、拉代码方便。python manage.py migrate python manage.py createsuperuser python manage.py runserver 0.0.0.0:8000在浏览器里访问http://服务器IP:8000如果能看到页面说明基础部署成功。第四步用Nginx Gunicorn上线如果只是临时演示runserver也够用。但如果要正式给人访问还是建议用Gunicorn跑Django、Nginx做反向代理和静态文件服务。Gunicorn安装一行命令pip install gunicorn启动命令gunicorn weather_analysis.wsgi:application --bind 0.0.0.0:8000 --workers 3Nginx配置里把location /代理到8000端口location /static/指向项目static目录。注意Django项目要在settings.py里设置STATIC_ROOT BASE_DIR / staticfiles并执行python manage.py collectstatic。关于远程调试工具PyCharm Professional支持远程SSH解释器可以在本机断点调试服务器上的代码调试体验非常好。如果用社区版保守方案是在代码里加print或logging输出关键变量配合tail -f查看日志虽然原始但有效。4.3 数据库连接与迁移报错速查表我用表格总结几个实际开发中高概率碰到的报错方便你自查报错信息原因解决方案django.db.utils.OperationalError: (2003, Cant connect to MySQL server)MySQL服务没启动或主机地址不对确认本机MySQL已启动检查settings里HOST/PORTdjango.core.exceptions.ImproperlyConfigured: mysqlclient 1.4.3 or newer is requiredDjango检测到pymysql版本不符合在项目__init__.py中添加pymysql.version_info伪装或改用mysqlclientModuleNotFoundError: No module named MySQLdb系统缺少MySQLdb驱动安装mysqlclient或用pymysql安装别名TypeError: unsupported operand type(s) for -: str and str数据分析时两个字符串字段做减法检查温度字段是否已转intTemplateDoesNotExist: dashboard/index.htmlDjango找不到模板文件检查settings里TEMPLATES的DIRS配置和app内templates目录位置UnicodeDecodeError读取CSV报错文件编码不是UTF-8常见GBKpd.read_csv(file, encodinggbk)尝试4.4 答辩演示时的几个演示脚本做毕业设计不仅要能把系统开发出来还得会讲。我建议你在答辩前准备一套固定的演示流程大概五分钟包含以下动作打开可视化大屏首页简单介绍整体页面布局和功能模块。点击或悬停地图上的不同城市展示该城市的实时天气信息和一周温度趋势。进入“历史分析”页面选择时间范围和城市展示月均气温变化和降水分布图简单解读数据结论。进入后台管理界面展示天气数据表、城市表现场新增一条测试数据切回大屏查看图表变化。讲解数据采集模块可以现场跑一小段爬虫脚本抓取最新几天的天气数据入库再刷新页面看更新效果。这套流程走完老师对你的系统的功能完整性和逻辑闭环就有了直观印象。同时要注意把每个模块的代码量、思路讲清楚尤其是数据清洗和预处理部分这是体现你工作量和技术水平的最好地方。5. 这个项目后续还能怎么扩如果做完了基础版还有余力我强烈建议你至少扩展两个点能让项目评级上一个档次。扩展点一加入预测功能在历史数据基础上用statsmodels或Prophet做一个未来七天最高温预测模型前端多一个“预测对比”折线图实测值和预测值做对照。这个扩展让项目从“分析可视化”升级为“分析与预测”意义完全不同。扩展点二数据定时采集任务把采集脚本封装成Django自定义管理命令# weather_analysis/apps/data_collect/management/commands/collect_weather.py from django.core.management.base import BaseCommand class Command(BaseCommand): help 采集最新天气数据 def handle(self, *args, **options): # 调用你的采集函数 ...然后用crontab或APScheduler安排每天定时执行0 8 * * * cd /home/ubuntu/weather_project venv/bin/python manage.py collect_weather实现真正的“自动化更新”在答辩时讲这个调度设计比手摸爬虫显得专业许多。另外如果你对视觉效果有更高追求可以研究一下DataV或大屏模板——但你本身用了ECharts再套一套暗色主题、添加滚动表格和自动轮播基本就能接近企业级大屏的感觉这个投入产出比非常划算。这套项目我从数据采集到部署上线完整做过一遍第一版天真地以为把网页做出来就完事后来才发现数据清洗、图表联动、服务器部署才是真正的重头戏。如果你也是第一次做这种全栈类的数据可视化项目心态上一定要留有富余量哪一步卡住了就用拆解的方法一层层排查——技术问题99%都能靠看日志和搜索引擎解决真正难的其实是把自己的思路整理清楚然后在答辩时自信地讲出来。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →