简介:这是一套面向高校学生与Python初学者的疫情数据可视化分析系统完整源码,适用于课程设计、期末大作业及数据可视化练手场景。项目支持省、市、县三级地图下钻交互,可动态播放各级区域疫情随时间变化的趋势,并提供全国省市混合热力图、时间序列分析、地区与时间维度组合查询,以及确诊患者小区地理位置3D可视化,同时兼容移动端设备。压缩包共907个文件,约22.09MB,其中243个py文件承载核心分析与可视化逻辑,397个json提供各级疫情数据,另有html、vue、js、css等前端页面资源,以及png、gif、ttf等图表与字体素材,结构完整、开箱即用。该资源已有315人学习下载,评审分达95分以上,经过严格调试可稳定运行,适合直接参考或二次开发,帮助读者快速掌握地图下钻、动态播放与热力图等可视化实现思路。
1. 从一份「疫情数据可视化分析系统」压缩包说起:它到底能帮你交掉什么作业
期末周临近,很多同学手里都会拿到一个叫「基于python的疫情数据可视化分析系统源码+全部数据(期末大作业).zip」的压缩包。先别急着双击解压然后对着满屏文件夹发懵,这个标题其实已经把三件事说清楚了:用 Python 写、处理的是疫情数据、最终产出是可视化分析系统。它解决的不是「从零发明一个算法」,而是让你在有限时间里交出一份结构完整、能跑起来、图表能看、数据有来源的课程设计。适合谁?适合刚学完 Python 基础语法、被要求做课程设计或期末大作业,但还没独立做过完整数据项目的同学。这篇文章不假设你手里有那份源码,而是按这类项目最常见的做法,把环境、数据、清洗、可视化、排错整条链路讲透,你照着做就能复现一套自己的版本。
2. 先搞清楚这类系统在做什么:数据从哪来、图表画给谁看
2.1 疫情数据可视化系统的三层结构
这类项目看着花哨,拆开其实就三层。最底下是数据层,负责拿到原始疫情数据,通常是 CSV 或 Excel,字段一般包含日期、省份或国家、累计确诊、新增确诊、治愈、死亡这几列。中间是处理层,用 pandas 把原始表读进来,做日期解析、缺失值处理、按地区聚合、算新增和累计。最上面是展示层,用 matplotlib、pyplot 或 pyecharts 把处理好的数据画成折线图、柱状图、地图或热力图。
很多人一上来就写画图代码,结果数据没对齐,图出来是错的,这就是典型的顺序颠倒。正确顺序永远是先确认数据长什么样,再决定怎么清洗,最后才想画什么图。可视化只是结果,数据质量才是这个系统能不能拿得出手的关键。
从课程设计评分角度看,老师通常看四点:数据是否有真实来源、清洗逻辑是否合理、图表是否覆盖多个维度、代码结构是否清晰。你把这四点做到,分数就不会低。至于界面用 tkinter、streamlit 还是纯脚本输出图片,反而是次要的,常见做法是先用脚本跑通,再套一层简单界面。
2.2 环境准备:python 安装、vscode python 环境配置与依赖清单
动手前先把环境弄干净。python 安装教程网上一搜一大把,但踩坑最多的就是版本和路径。我一般建议用 Python 3.9 到 3.11 之间的版本,太新的版本有些可视化库轮子还没跟上,太老的又缺特性。安装时务必勾选「Add Python to PATH」,否则后面命令行里敲 python 会提示找不到命令。
编辑器用 vscode 或 pycharm 都行,vscode 配置 python 环境的核心是选对解释器:按 Ctrl+Shift+P,输入 Python: Select Interpreter,选中你刚装的那个版本。这一步没做对,后面 pip 装的库和编辑器用的库就不是同一套,会出现「命令行能跑、编辑器报 ModuleNotFoundError」的玄学问题。
依赖不用多,四个就够起步:
pip install pandas matplotlib pyecharts openpyxlpandas 负责数据处理,matplotlib 画基础静态图,pyecharts 画交互式图表和地图,openpyxl 让 pandas 能读 xlsx 文件。装完用下面这段代码验证环境是否正常:
import pandas as pd import matplotlib.pyplot as plt import pyecharts # 打印版本,确认库都装上了 print("pandas:", pd.__version__) print("matplotlib:", plt.matplotlib.__version__) print("pyecharts:", pyecharts.__version__) # 造一个最小数据集,验证中文显示和画图链路 df = pd.DataFrame({"日期": ["2022-01-01", "2022-01-02"], "新增": [10, 20]}) df["日期"] = pd.to_datetime(df["日期"]) plt.plot(df["日期"], df["新增"]) plt.title("test") plt.show()这段代码的作用是三重验证:库能不能导入、版本是否打印得出来、matplotlib 能不能弹窗画图。如果 plt.show() 没反应,多半是后端问题,加一行plt.switch_backend("TkAgg")通常能解决。中文显示成方框的话,在画图前设置plt.rcParams["font.sans-serif"] = ["SimHei"]和plt.rcParams["axes.unicode_minus"] = False。
提示:不要一次性装几十个库。依赖越多,版本冲突概率越大,期末周你没时间排查这种问题。
3. 数据清洗这一步做扎实:pandas 读取、缺失值与日期对齐
3.1 用 pandas 读数据并做第一轮体检
拿到数据文件后,第一件事不是画图,是体检。下面这段代码是每次开新项目我都会先跑的模板:
import pandas as pd # 读取数据,注意编码,中文数据常见 utf-8 或 gbk df = pd.read_csv("疫情数据.csv", encoding="utf-8") # 第一轮体检:形状、列名、前几行、类型、缺失情况 print("数据形状:", df.shape) print("列名:", df.columns.tolist()) print(df.head()) print(df.dtypes) print("缺失值统计:\n", df.isnull().sum())逻辑说明:shape 告诉你多少行多少列,心里有数;columns 确认字段名,因为后面所有代码都靠列名索引,名字对不上直接报 KeyError;head 看真实内容,防止表头错位;dtypes 看日期列是不是被读成了字符串;isnull 定位缺失集中在哪几列。
参数说明:encoding 是关键参数。如果报 UnicodeDecodeError,把 utf-8 换成 gbk 再试,这是中文数据最常见的翻车点。如果文件是 Excel,把 read_csv 换成pd.read_excel("疫情数据.xlsx"),此时依赖 openpyxl。
体检完你大概率会发现两个问题:日期列是字符串,数值列里混着「暂无」这类文本。这两个不处理,后面全盘皆输。
3.2 日期解析、缺失值填充与按地区聚合
清洗的核心就三招:转类型、补缺失、做聚合。
import pandas as pd df = pd.read_csv("疫情数据.csv", encoding="utf-8") # 1. 日期列转成 datetime 类型,无法解析的变成 NaT df["日期"] = pd.to_datetime(df["日期"], errors="coerce") # 2. 数值列强制转数字,非数字变 NaN,再填充 for col in ["新增确诊", "累计确诊", "治愈", "死亡"]: df[col] = pd.to_numeric(df[col], errors="coerce") df[col] = df[col].fillna(0) # 缺失按 0 处理,也可用前向填充 # 3. 丢掉日期解析失败的行 df = df.dropna(subset=["日期"]) # 4. 按日期和地区聚合,防止同一天同一地区出现多行 df = df.groupby(["日期", "地区"], as_index=False).sum() # 5. 按日期排序,画折线图必须有序 df = df.sort_values("日期").reset_index(drop=True) print(df.head()) print("清洗后形状:", df.shape)逻辑说明:errors="coerce" 是保命参数,它让无法解析的值变成 NaT 而不是直接抛异常,你能先跑通再回头查脏数据。to_numeric 同理,把「暂无」这类文本转成 NaN。fillna(0) 是一种选择,但要注意:累计确诊用 0 填充可能失真,更稳妥的是用df[col].ffill()前向填充,因为累计值通常单调不减。groupby 是为了防止数据源里同一天同一地区有多条记录,直接画图会重复计算。
参数说明:groupby 里的 as_index=False 让结果保持普通列结构,方便后续索引;sum() 对数值列求和,如果表里还有非数值列要先筛掉。sort_values 不能省,折线图对顺序极其敏感,乱序画出来是锯齿状的鬼画符。
注意:清洗完一定要再打印一次 head 和 shape,确认行数变化合理。如果从一万行掉到几十行,说明你的解析或去重逻辑误杀了。
4. 把数据画成能交差的图:matplotlib 与 pyecharts 两条路线
4.1 折线图、柱状图与多子图布局
静态图用 matplotlib,适合放进报告。下面这段画全国每日新增趋势加地区对比:
import pandas as pd import matplotlib.pyplot as plt plt.rcParams["font.sans-serif"] = ["SimHei"] plt.rcParams["axes.unicode_minus"] = False df = pd.read_csv("清洗后数据.csv", encoding="utf-8", parse_dates=["日期"]) # 全国每日新增趋势 national = df.groupby("日期", as_index=False)["新增确诊"].sum() fig, axes = plt.subplots(1, 2, figsize=(14, 5)) axes[0].plot(national["日期"], national["新增确诊"], color="#c0392b") axes[0].set_title("全国每日新增确诊趋势") axes[0].set_xlabel("日期") axes[0].set_ylabel("新增确诊") axes[0].tick_params(axis="x", rotation=45) # 取累计确诊最高的前 8 个地区做柱状对比 top = df.groupby("地区", as_index=False)["累计确诊"].max() top = top.sort_values("累计确诊", ascending=False).head(8) axes[1].bar(top["地区"], top["累计确诊"], color="#2980b9") axes[1].set_title("累计确诊前 8 地区") axes[1].tick_params(axis="x", rotation=45) plt.tight_layout() plt.savefig("疫情分析图.png", dpi=150) plt.show()逻辑说明:先按日期聚合出全国数据,再按地区取累计最大值排序取前八。subplots 一次生成两个子图,左边趋势右边对比,报告里一张图讲两件事。tight_layout 自动调整间距,防止标签被裁掉。savefig 的 dpi 设 150,打印和截图都够清晰。
参数说明:figsize 控制画布尺寸,宽 14 高 5 适合横向排版;rotation=45 让 x 轴日期不重叠;color 用十六进制色值比默认色好看,报告观感直接提升一档。
4.2 用 pyecharts 做地图和交互式图表
如果想让作业更出彩,地图是加分项。pyecharts 画中国地图按地区着色:
import pandas as pd from pyecharts.charts import Map from pyecharts import options as opts df = pd.read_csv("清洗后数据.csv", encoding="utf-8") # 取每个地区累计确诊最大值 data = df.groupby("地区")["累计确诊"].max().reset_index() data_list = [list(z) for z in zip(data["地区"], data["累计确诊"])] c = ( Map() .add("累计确诊", data_list, "china") .set_global_opts( title_opts=opts.TitleOpts(title="各地区累计确诊分布"), visualmap_opts=opts.VisualMapOpts(max_=int(data["累计确诊"].max())), ) ) c.render("疫情地图.html")逻辑说明:Map 组件要求数据是「地区名, 数值」的列表格式,所以先 groupby 再 zip 成列表。add 的第三个参数 "china" 指定地图范围。visualmap_opts 的 max_ 控制颜色映射上限,不设的话颜色分布会失真。render 输出 html,浏览器打开就是交互式地图,鼠标悬停显示数值。
参数说明:地区名必须和 pyecharts 内置地图的名称完全一致,比如「北京」不能写成「北京市」,否则该地区不会着色,这是最常见的翻车点。如果数据里是「北京市」,清洗时用df["地区"] = df["地区"].str.replace("省|市", "", regex=True)统一。
提示:地图类图表对地区名匹配极其敏感,画之前先打印一遍地区唯一值,和地图标准名逐个核对。
5. 避坑与排查:这类期末大作业最容易翻车的 5 个地方
5.1 中文乱码与负号显示异常
现象:图表标题、坐标轴中文全是方框,负号也变成方块。原因:matplotlib 默认字体不支持中文。解决:画图前加plt.rcParams["font.sans-serif"] = ["SimHei"]和plt.rcParams["axes.unicode_minus"] = False。如果系统没有 SimHei,换成 Microsoft YaHei 或你系统里有的中文字体。pyecharts 不受这个影响,它用浏览器字体渲染。
5.2 日期列没转类型导致折线图乱序
现象:折线图锯齿状上下跳,趋势完全看不出。原因:日期还是字符串,排序按字典序而非时间序。解决:pd.to_datetime转类型后再sort_values("日期")。这个坑我见过太多次,图错了还以为是数据问题,其实是排序问题。
5.3 地区名与地图标准名不匹配
现象:地图上某些省份是灰色,明明数据里有。原因:数据里写「广东省」,地图认「广东」。解决:清洗阶段统一去掉「省」「市」「自治区」后缀,再和地图标准名核对。写个映射字典最稳,别指望自动匹配百分百成功。
5.4 累计值用 sum 聚合导致数字翻倍
现象:累计确诊算出来比官方数据大一倍。原因:数据源里同一天同一地区有多行,groupby 时对累计列用了 sum。解决:累计类字段应该取 max 或 last,只有新增类字段才用 sum。聚合前先想清楚每列的业务含义,这是血泪经验。
5.5 依赖版本冲突导致 import 报错
现象:昨天还能跑,今天 import pyecharts 就报错。原因:pip 装别的库时把依赖升级或降级了。解决:用虚拟环境隔离,python -m venv venv建环境,激活后再装依赖。期末周最怕环境崩,虚拟环境就是后悔药。
6. 让作业从「能跑」到「能拿高分」:三个进阶技巧
第一个技巧是加一层数据校验。在清洗后加一段断言,检查累计确诊是否单调不减、新增是否为负。数据里出现负新增通常是订正导致的,处理方式是把它归零或单独标注。这段校验代码不长,但能让老师看出你懂数据质量:
# 校验:累计确诊不应下降,新增不应为负 df = df.sort_values(["地区", "日期"]) df["累计_diff"] = df.groupby("地区")["累计确诊"].diff() bad = df[df["累计_diff"] < 0] print("累计下降的异常行数:", len(bad)) df["新增确诊"] = df["新增确诊"].clip(lower=0) # 负新增归零clip 的 lower=0 把负值截断为零,简单有效。bad 那几行可以单独导出,报告里写一句「已识别并处理 N 条订正记录」,专业度立刻不一样。
第二个技巧是把分析结论写进图表标题和注释。很多同学图很漂亮但没结论,老师看不出你分析了什么。比如折线图标题写成「全国每日新增在 X 月出现峰值后回落」,比「全国每日新增趋势」有信息量得多。图表是论据,结论才是论点。
第三个技巧是代码结构分层。别把所有代码堆在一个文件里,拆成load_data.py、clean_data.py、visualize.py三个模块,主程序 import 调用。这样老师翻代码时一眼能看出你的工程思维。下面是一个最小分层示例:
# clean_data.py import pandas as pd def clean(path): df = pd.read_csv(path, encoding="utf-8") df["日期"] = pd.to_datetime(df["日期"], errors="coerce") for col in ["新增确诊", "累计确诊"]: df[col] = pd.to_numeric(df[col], errors="coerce").fillna(0) df = df.dropna(subset=["日期"]) df = df.groupby(["日期", "地区"], as_index=False).sum() return df.sort_values("日期").reset_index(drop=True)# main.py from clean_data import clean from visualize import draw_trend df = clean("疫情数据.csv") draw_trend(df, "全国趋势.png")函数职责单一,参数就是文件路径,换数据源不用改逻辑。这种写法在课程设计里属于降维打击,因为大部分同学还在一个文件里从头写到尾。
最后说个我自己的习惯:每次交作业前,把项目在一个全新虚拟环境里从零装依赖跑一遍。能跑通,才算真的完成。我吃过亏,本地环境装了一堆库所以能跑,换台电脑就崩,答辩现场打开报错,那场面不想再经历第二次。希望帮到你。
本文还有配套的精品资源,点击获取