Python疫情数据可视化分析系统:从数据清洗到图表实战
简介这是一套面向高校学生与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 环境的核心是选对解释器按 CtrlShiftP输入 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, encodingutf-8) # 第一轮体检形状、列名、前几行、类型、缺失情况 print(数据形状:, df.shape) print(列名:, df.columns.tolist()) print(df.head()) print(df.dtypes) print(缺失值统计:\n, df.isnull().sum())逻辑说明shape 告诉你多少行多少列心里有数columns 确认字段名因为后面所有代码都靠列名索引名字对不上直接报 KeyErrorhead 看真实内容防止表头错位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, encodingutf-8) # 1. 日期列转成 datetime 类型无法解析的变成 NaT df[日期] pd.to_datetime(df[日期], errorscoerce) # 2. 数值列强制转数字非数字变 NaN再填充 for col in [新增确诊, 累计确诊, 治愈, 死亡]: df[col] pd.to_numeric(df[col], errorscoerce) df[col] df[col].fillna(0) # 缺失按 0 处理也可用前向填充 # 3. 丢掉日期解析失败的行 df df.dropna(subset[日期]) # 4. 按日期和地区聚合防止同一天同一地区出现多行 df df.groupby([日期, 地区], as_indexFalse).sum() # 5. 按日期排序画折线图必须有序 df df.sort_values(日期).reset_index(dropTrue) print(df.head()) print(清洗后形状:, df.shape)逻辑说明errorscoerce 是保命参数它让无法解析的值变成 NaT 而不是直接抛异常你能先跑通再回头查脏数据。to_numeric 同理把「暂无」这类文本转成 NaN。fillna(0) 是一种选择但要注意累计确诊用 0 填充可能失真更稳妥的是用df[col].ffill()前向填充因为累计值通常单调不减。groupby 是为了防止数据源里同一天同一地区有多条记录直接画图会重复计算。参数说明groupby 里的 as_indexFalse 让结果保持普通列结构方便后续索引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, encodingutf-8, parse_dates[日期]) # 全国每日新增趋势 national df.groupby(日期, as_indexFalse)[新增确诊].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(axisx, rotation45) # 取累计确诊最高的前 8 个地区做柱状对比 top df.groupby(地区, as_indexFalse)[累计确诊].max() top top.sort_values(累计确诊, ascendingFalse).head(8) axes[1].bar(top[地区], top[累计确诊], color#2980b9) axes[1].set_title(累计确诊前 8 地区) axes[1].tick_params(axisx, rotation45) plt.tight_layout() plt.savefig(疫情分析图.png, dpi150) plt.show()逻辑说明先按日期聚合出全国数据再按地区取累计最大值排序取前八。subplots 一次生成两个子图左边趋势右边对比报告里一张图讲两件事。tight_layout 自动调整间距防止标签被裁掉。savefig 的 dpi 设 150打印和截图都够清晰。参数说明figsize 控制画布尺寸宽 14 高 5 适合横向排版rotation45 让 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, encodingutf-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_optsopts.TitleOpts(title各地区累计确诊分布), visualmap_optsopts.VisualMapOpts(max_int(data[累计确诊].max())), ) ) c.render(疫情地图.html)逻辑说明Map 组件要求数据是「地区名, 数值」的列表格式所以先 groupby 再 zip 成列表。add 的第三个参数 china 指定地图范围。visualmap_opts 的 max_ 控制颜色映射上限不设的话颜色分布会失真。render 输出 html浏览器打开就是交互式地图鼠标悬停显示数值。参数说明地区名必须和 pyecharts 内置地图的名称完全一致比如「北京」不能写成「北京市」否则该地区不会着色这是最常见的翻车点。如果数据里是「北京市」清洗时用df[地区] df[地区].str.replace(省|市, , regexTrue)统一。提示地图类图表对地区名匹配极其敏感画之前先打印一遍地区唯一值和地图标准名逐个核对。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(lower0) # 负新增归零clip 的 lower0 把负值截断为零简单有效。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, encodingutf-8) df[日期] pd.to_datetime(df[日期], errorscoerce) for col in [新增确诊, 累计确诊]: df[col] pd.to_numeric(df[col], errorscoerce).fillna(0) df df.dropna(subset[日期]) df df.groupby([日期, 地区], as_indexFalse).sum() return df.sort_values(日期).reset_index(dropTrue)# main.py from clean_data import clean from visualize import draw_trend df clean(疫情数据.csv) draw_trend(df, 全国趋势.png)函数职责单一参数就是文件路径换数据源不用改逻辑。这种写法在课程设计里属于降维打击因为大部分同学还在一个文件里从头写到尾。最后说个我自己的习惯每次交作业前把项目在一个全新虚拟环境里从零装依赖跑一遍。能跑通才算真的完成。我吃过亏本地环境装了一堆库所以能跑换台电脑就崩答辩现场打开报错那场面不想再经历第二次。希望帮到你。本文还有配套的精品资源点击获取