ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Python天气预报数据可视化:从API取数到交互大屏的实战指南

Python天气预报数据可视化:从API取数到交互大屏的实战指南 简介面向Python课程期末大作业或课程设计的高分参考项目基于实时气象数据处理与算法模型完成天气趋势预测并结合Matplotlib/Plotly等可视化工具绘制折线图、热力图、地图等展示结果。压缩包共24个文件、约1.42MB包含4个Python源码模块、4个CSV训练与测试数据、1个Pickle模型文件、1个HTML可视化页面以及12张效果截图附带使用说明文档方便快速启动。项目紧扣实际业务链路从天气网数据获取、数据清洗转换、模型训练与预测到最终生成可视化报告均有独立代码模块支撑覆盖线性回归、时间序列等常见预测思路模块接口清晰用户可通过替换CSV数据快速实现不同城市或时间范围的预测实验便于逐块学习、二次开发或迁移到自己的课题中。已有62人浏览学习下载后无需修改即可直接运行特别适合需要快速交付高质量期末作业同时希望系统掌握数据分析、机器学习与可视化完整流程的学生。1. 为什么这个期末大作业的关键在数据链路而不是图表有多炫一到期末拿到“Python实现的天气预报与数据可视化”这类题目的同学容易陷入同一个误区模板下载了一堆代码没跑通报告写了十几页被问一句“数据从哪儿来的”就卡壳。这类期末大作业的分数恰恰不在图有多炫而在数据链路是不是完整。所谓数据链路就是从调用天气接口取数到落成CSV再到画出趋势图与交互式大屏每一步都能讲清为什么这么做。这个项目适合有一定Python语法基础、要交代码和报告的同学也适合想从“跟着书敲例子”过渡到“独立完成一个小工程”的人。下面这套做法数据获取走开放天气API不碰网页解析可视化用Matplotlib和Pyecharts组合最后加一个预测验证环节把作品从“能跑”抬到“值得看”。2. 天气数据从哪来用高德开放平台API代替网页爬虫讲清三个选型理由第一步不是写绘图代码而是把数据源定下来。很多同学一看到“天气”就想到爬中国天气网这能跑通但代价不小页面里混着大量HTML、CSS和JavaScript爬下来之后要花力气定位真正的温度字段更麻烦的是网站一旦调整页面结构你上周还能跑的解析代码这周就废了。对期末大作业来说直接用天气API是更省时间、也更不容易翻车的路线。2.1 网页爬虫、高德天气API与和风天气大作业数据源怎么选常见做法是三种自己写爬虫解析网页、接高德开放平台天气API、接和风天气API。三者的差异用一个表格就能看明白数据源方式获取成本返回格式主要翻车点网页爬虫需要写页面解析逻辑HTML中混着脚本与样式页面改版就失效字符集还可能乱高德天气API注册账号创建Key后直接调JSON字段固定需要把城市名转成adcode城市编码和风天气API注册账号文档规范JSON字段更细部分能力需要实名认证流程多一步我的建议是优先考虑高德天气API。原因有三个第一返回的JSON字段是服务端约定好的不随网页改版变化写一次解析就能长期复用第二高德的行政区划编码adcode体系在同一个平台上就能查做多城市对比时不需要额外对接第三对期末作业的使用量来说个人申请的额度完全够用。很多同学把这类需求叫“python爬虫可视化界面”其实API调用比爬虫更稳妥代码更短答辩时也更容易说清楚数据来源。2.2 高德天气API最小调用注册、申请Key与第一个能跑的GET请求具体接入分三步。第一步进入高德开放平台注册账号并登录第二步在“应用管理”里创建应用应用类型选“Web服务”创建成功后拿到Key第三步打开你的Python编辑器把下面的代码保存成fetch_weather_base.py跑一遍。import requests AMAP_KEY 你的高德Web服务Key def get_weather(city_code: str, extensions: str all) - dict: url https://restapi.amap.com/v3/weather/weatherInfo params { key: AMAP_KEY, city: city_code, extensions: extensions, output: JSON, } # timeout 设为10秒避免请求卡死拖住整个脚本 resp requests.get(url, paramsparams, timeout10) resp.raise_for_status() data resp.json() if data[status] ! 1: raise RuntimeError(f天气接口返回异常{data.get(info)}) # extensionsall 时返回 forecastsbase 时返回 lives if extensions all: return data[forecasts][0] return data[lives][0] if __name__ __main__: forecast get_weather(110000) print(forecast[city], forecast[casts])代码里有几个参数值得单独说明。key是你在控制台创建的那个字符串注意创建应用时选“Web服务”如果选成Web端JS API后面请求会被拒绝。city传的是行政区划编码北京是110000上海是310000不能直接传“北京”两个字。extensions有两个取值base返回实时天气all返回未来几天的逐日预报。status字段等于1表示成功等于0时要把info里的错误信息打出来看。2.3 把预报数据写入CSV字段命名决定后续画图的难度接口返回的是嵌套JSON直接拿给matplotlib画图不方便所以下一步是把预报数组落成本地CSV。我一般不用JSON文件因为CSV用Excel能直接打开pandas读取也方便报告中要贴数据表格时更顺手。import csv def save_casts(casts: list, filename: str) - None: with open(filename, w, newline, encodingutf-8) as f: writer csv.writer(f) writer.writerow([ date, week, day_weather, temp_max, night_weather, temp_min ]) for cast in casts: writer.writerow([ cast[date], cast[week], cast[dayweather], cast[tempmax], cast[nightweather], cast[tempmin] ])字段名我建议统一用英文后续在pandas里引用时少一层编码问题。高德返回的tempmax是预报中的最高温度tempmin是最低温度dayweather是白天天气的文字描述比如“晴”或“多云”。如果你想做多城市对比就在CSV里增加一列city如果只做单城市趋势上面的字段已经够画两张图了。写入时把encoding设为utf-8第四节的Excel乱码问题就是从这里埋下的下面会讲。2.4 支持多城市对比城市编码与批量请求只画一个城市期末作业的分量往往不够。我建议至少取三到四个城市做一张对比图。关键点是城市编码不能猜直接查adcode表或者用字典维护一份常用的城市映射。AMAP_CITY_CODES { 北京: 110000, 上海: 310000, 广州: 440100, 成都: 510100, } def fetch_multi_cities(city_names: list) - dict: result {} for name in city_names: code AMAP_CITY_CODES.get(name) if not code: print(f缺少城市编码{name}) continue forecast get_weather(code, all) # 只保留前三天的预报避免表格太宽 result[name] forecast[casts][:3] return result这段代码的价值在于演示“批量请求”的思路。有些同学会犯一个错误把拼音beijing当作city参数传进去接口不会报错但返回的不是北京数据而是空列表。遇到这种情况先去高德控制台查adcode别在代码里猜编码。多城市数据结构化之后第3章画柱状图的数据来源就齐了。3. 把数据画成图Matplotlib趋势图与ECharts数据可视化大屏的两条落地路线数据落地之后才轮到可视化。期末作业里常见的翻车不是不会画图而是不知道每张图想说明什么结论。我建议按两条线并行Matplotlib出静态图打印到报告里Pyecharts出交互式HTML答辩现场直接演示。两者并不冲突反而能让项目看起来更完整。3.1 先做一步数据整理把CSV读成pandas DataFrame大多数开源数据可视化的第一步都不是画图而是读数据。pandas读CSV之后需要确认每一列的数据类型尤其是温度列接口返回的是字符串不转成数值折线图纵轴会按文本排列图就废了。import pandas as pd def load_weather_data(csv_path: str) - pd.DataFrame: df pd.read_csv(csv_path) df[date] pd.to_datetime(df[date]) df[temp_max] pd.to_numeric(df[temp_max], errorscoerce) df[temp_min] pd.to_numeric(df[temp_min], errorscoerce) return df这里重点看errorscoerce这个参数。它表示解析失败时把值置为NaN而不是让整列转换报错。处理真实天气数据时偶尔会遇到空字符串或异常字符没这个参数一行脏数据就能让整个脚本中断。日期列转成datetime类型之后Matplotlib在x轴上的刻度显示会更规范。3.2 用Matplotlib画5日温度趋势中文配置和字体踩坑提前处理Matplotlib默认字体不支持中文图里的标题、图例会变成一个个方框。解决方法是提前配置全局字体不要等到图表生成之后再去改。import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False def plot_trend(df: pd.DataFrame, output: str outputs/temperature_trend.png): plt.figure(figsize(10, 5)) plt.plot(df[date], df[temp_max], markero, label最高温度) plt.plot(df[date], df[temp_min], markers, label最低温度) # 把白天的天气词写在最高温点上方方便看图时对照天气 for x, y, text in zip(df[date], df[temp_max], df[day_weather]): plt.text(x, y 1, text, hacenter, fontsize9) plt.title(未来5日温度趋势) plt.xlabel(日期) plt.ylabel(气温℃) plt.legend() plt.grid(True, linestyle--, alpha0.5) plt.tight_layout() plt.savefig(output, dpi200) plt.show()参数说明markero让每个数据点显示圆形标记报告里的折线图更容易读linestyle--把网格线设成虚线避免干扰数据曲线dpi200是为打印准备的如果只放PPTdpi150就够。plt.text(x, y 1, text)是在最高温点上方1℃的位置写天气文字如果不知道当天是晴还是雨老师看趋势图还得回头查数据表写上这个细节就能让图自己说话。3.3 用Pyecharts搭建ECharts数据可视化交互页面从单图到组合大屏如果项目里只有Matplotlib静态图视觉效果上限不高。Pyecharts封装了ECharts能在Python里直接生成交互式HTML鼠标悬停显示数值、缩放、切换系列都是现成的答辩演示时非常加分。from pyecharts.charts import Bar, Line, Page from pyecharts import options as opts def build_dashboard(df: pd.DataFrame, city_avg: dict): bar ( Bar() .add_xaxis(list(city_avg.keys())) .add_yaxis(平均最高温℃, [round(v, 1) for v in city_avg.values()]) .set_global_opts( title_optsopts.TitleOpts(title多城市平均最高温对比), yaxis_optsopts.AxisOpts(name温度℃) ) ) line ( Line() .add_xaxis(df[date].astype(str).tolist()) .add_yaxis(最高温, df[temp_max].round(1).tolist()) .add_yaxis(最低温, df[temp_min].round(1).tolist()) .set_global_opts(title_optsopts.TitleOpts(title目标城市温度变化趋势)) ) page Page(layoutPage.SimplePageLayout) page.add(bar, line) page.render(outputs/dashboard.html)这里要特别说明Page的用途。单独调用bar.render(a.html)只能生成一个图表而Page可以把柱状图和折线图放进同一个HTML页面答辩时用浏览器打开逐个往上翻演示节奏比连续切窗口舒服得多。Page.SimplePageLayout表示按照图表加入的先后顺序纵向排列。如果你的图表超过四个可以改用Page.DraggablePageLayout允许在页面上拖动图表位置但需要额外配置期末作业一般用Simple就够了。4. 按高分作业标准组织代码与报告目录结构、main入口与答辩准备很多同学写完代码就交文件夹里散落着test.py、final.py、new_final.py这份代码即使能跑老师也不愿意多看。高分大作业的特征是“答辩时能用一段话讲清楚项目怎么组织”。下面这套结构是我带学生做课程设计时常用的模板。4.1 一段话能讲清的项目结构才是好结构推荐目录与模块职责weather_project/ ├── data/ │ └── weather_forecast.csv ├── src/ │ ├── __init__.py │ ├── fetch_weather.py │ └── visualize.py ├── outputs/ │ ├── temperature_trend.png │ └── dashboard.html ├── main.py └── requirements.txtdata目录存放原始CSVsrc目录存代码fetch_weather.py负责所有网络请求和CSV落盘visualize.py负责所有绘图outputs目录放生成的图片和HTMLmain.py是程序入口requirements.txt写第三方库依赖。模块拆分的逻辑是“数据采集”和“数据可视化”互不干扰你在答辩时说“程序分三层采集层负责拿数据分析层负责转数据可视化层负责出图”这句话即使没有PPT老师也能立刻抓住项目框架。4.2 可运行入口main.py三步串联数据、分析与可视化from src.fetch_weather import get_weather, save_casts from src.visualize import plot_trend, build_dashboard import pandas as pd def main(): city_code 110000 forecast get_weather(city_code, all) save_casts(forecast[casts], data/weather_forecast.csv) df pd.read_csv(data/weather_forecast.csv) df[temp_max] pd.to_numeric(df[temp_max]) df[temp_min] pd.to_numeric(df[temp_min]) plot_trend(df) build_dashboard(df, {北京: df[temp_max].mean()}) print(数据采集完成图表已生成到 outputs 目录) if __name__ __main__: main()main.py的逻辑很直白拿数、存数、出图。df[temp_max].mean()直接算出该城市的平均最高温传给柱状图省得再手动填一个数。注意if __name__ __main__这行必须保留它是Python程序的标准入口判断大作业里如果漏了这行代码在被其他模块导入时会直接执行这是新手常犯的错误。4.3 requirements.txt 与两种编辑器环境PyCharm和VS Code怎么配项目要能在另一台电脑上复现光有py文件还不够。requirements.txt里写清楚依赖库安装时一句命令就能搞定。requests2.31.0 pandas2.0.3 matplotlib3.7.2 pyecharts2.0.5版本号我建议锁死避免别人在你交作业前突然装上一个大版本图表API不兼容。环境配置上PyCharm和VS Code都行PyCharm里打开项目后创建虚拟环境VS Code里选好Python解释器两者本质没区别。装完依赖之后先跑一行验证命令python -c import requests, pandas, matplotlib, pyecharts没有报错说明环境通了。代码还没写之前先把环境验证这一步做完能省掉后面一半的“跑不起来”。4.4 期末报告怎么组织把每一步踩坑都变成“问题与解决”报告不用动辄几十页但结构要完整。我推荐按下面这张表组织报告章节建议内容篇幅建议引言为什么选天气预报这个题目预期解决什么问题1页数据获取高德API的申请流程、请求参数、CSV存储设计2页可视化设计折线图、柱状图、交互页面的选型理由3页遇到的问题与解决中文乱码、Key类型错误、编码问题等2页总结与展望还能怎么扩展比如加入预测或更多数据源1页其中“遇到的问题与解决”是答辩时最容易出彩的部分。老师通常不会逐行读代码但会问“你遇到过什么坑”这时候直接讲第5章里的任一条都比空谈“我学到了很多”有说服力。5. 跑代码时常见的5个坑从Key类型到中文乱码的排查清单下面这些坑都是初学者在这个项目里最容易遇到的现象、原因和解决方式。建议先看现象对号入座再看原因最后把解决步骤抄进报告。5.1 图里的中文变成方框标题和坐标轴全是“□□”现象Matplotlib生成的图中title、label全部显示为方块字母和数字正常。原因Matplotlib默认字体不含中文字符SimHei等中文字体没有被加载。解决在绘图代码顶部加两行配置plt.rcParams[font.sans-serif] [SimHei]和plt.rcParams[axes.unicode_minus] False。如果你在Linux服务器上跑系统里没有SimHei需要先把中文字体文件放到/usr/share/fonts目录并刷新字体缓存这个操作放在环境配置阶段做。第二种应急方案是把图上的中文全部改成英文但这会降低报告的可读性不推荐。5.2 接口报错INVALID_USER_KEY请求始终失败现象调用get_weather(110000)后返回的JSON里status是0info是INVALID_USER_KEY。原因控制台里创建Key时应用类型选错了。如果选成“Web端(JS API)”Key只能在浏览器里用Python后端调用时会被拒绝。解决回到高德控制台应用管理里看Key对应的平台类型删掉重建成“Web服务”重新复制Key填到代码里。另一种情况是Key复制时多复制了空格把密钥前后的空格去掉。5.3 只拿到实时天气没有逐日预报现象代码跑通但get_weather返回的数据里只有一条当天实时天气没有casts数组。原因请求参数extensions传了base。base返回实时天气all才返回逐日预报。解决把extensions改成all。如果你两个都想要就分别请求两次。注意all返回的数据量比base大响应时间会稍微长一点这个差异在代码注释里写清楚。5.4 Excel打开CSV文件中文全是乱码现象记事本打开CSV正常Excel打开后中文变成乱码。原因Python写入时用了utf-8编码Excel在多数中文环境下默认按GBK解码两边对不上。解决写CSV时把编码改成utf-8-sig。这个编码会在文件头部加一个BOM标记Excel看到BOM就能自动识别。具体改法是open(filename, w, newline, encodingutf-8-sig)。如果CSV已经生成了用记事本打开另存为在右下角把编码改成“带BOM的UTF-8”再保存。5.5 Pyecharts生成的HTML页面打开是空白现象dashboard.html在浏览器里打开整个页面空白按F12能看到JavaScript报错。原因Pyecharts生成的HTML依赖本地JS库文件某些浏览器或本地安全策略限制了文件加载。解决换用Chrome浏览器打开多数情况下能解决。如果还是空白不用在HTML上死磕把关键图表用Matplotlib另存成PNG放进报告HTML在答辩时作为补充演示。这里的原则是报告里必须有静态图HTML是加分项不要把答辩效果押在一个可能加载失败的页面上。6. 加一个温度趋势预测并用真实值验证比别人多一个“数据分析闭环”大部分同学的作业止步于“画图”但高分作业往往多走半步用已有数据做一点预测并拿后来的真实值验证误差。这一步不需要复杂算法重点是体现“数据分析闭环”的意识。6.1 用最近几天的数据预测下一天最高温把每天的预报追加到CSV里积累一周之后用numpy.polyfit做一元线性拟合预测下一天的最高温度。import numpy as np def predict_next_high(temp_list: list) - float: x np.arange(len(temp_list)) k, b np.polyfit(x, temp_list, 1) return k * len(temp_list) bnp.polyfit(x, temp_list, 1)返回两个系数k是斜率b是截距。把x len(temp_list)代入k * x b得到的就是下一天的外推值。这个模型假设温度在短周期内线性变化虽然粗糙但用来演示“拟合-外推-验证”的流程完全够用。6.2 把预测值和真实值做误差对比真实值从哪里来等第二天接口返回新预报后把temp_max拿出来和前一天预测的值做差。real_high 28.0 pred_high 27.2 error abs(real_high - pred_high) print(f预测误差{error:.1f}℃)把这个误差记录到报告里连续测五天算出平均误差。只要误差在一个可解释的范围内答辩时的效果就远超一张静态图。老师问“预测准不准”时你就能回答“我连续验证了五天平均误差在1.5℃以内。”这句话比任何华丽图表都值钱。我一直和学生说预测准不准不是目的让老师看见你知道“一个结论要被验证”才是这个环节真正的意义。希望帮到你。本文还有配套的精品资源点击获取
返回列表