☰
中美疫情数据可视化源码拆包:20个文件全链路解析与避坑指南
2026/10/1 11:18:05 网站建设 项目流程

简介:这份资源面向数据分析初学者与可视化爱好者,提供一套基于Python的中美疫情数据可视化分析完整源码,可用于课程设计、练手项目或数据分析入门实践。压缩包共19个文件、约145KB,包含7个HTML可视化页面、6个Python分析脚本、4个Excel数据表、1个CSV历史数据及1个说明文本,覆盖数据读取、清洗、预测建模到网页图表展示的完整链路。内容涉及国内与全球疫情态势、中美对比、中国及美国未来14天新增预测等模块,脚本与页面一一对应,便于理解从原始数据到可视化结果的实现过程。目前已有296人学习下载,适合希望掌握Python数据处理与HTML图表呈现、并需要可运行案例参考的读者。

1. 中美疫情数据可视化源码拆包:20 个文件里到底藏着什么

拿到一个压缩包,解压完第一件事不是急着跑代码,而是先看目录结构。这个包一共 20 个文件,7 个 HTML、6 个 Python 脚本、4 个 Excel、2 个说明文件、1 个 CSV,外加一个upload.zip的原始壳。很多人看到「中美疫情数据可视化」这几个字,第一反应是「是不是又要爬数据」,其实不是——数据已经躺在China.xlsx、America.xlsx、world.xlsx、history.csv里了,脚本干的是清洗、聚合、预测和出图。它解决的核心问题是:把中美两国的累计确诊、新增趋势、省份维度、未来 14 天预测,一次性做成能直接打开的 HTML 看板。适合谁?适合正在做课程设计、想拿一份能跑通的数据分析项目练手的人,也适合已经会pandas但不知道怎么把结果落到网页上的从业者。下面我按「先跑通、再拆解、最后避坑」的顺序,把这份源码从头到尾过一遍。

2. 环境准备与数据文件结构:先让脚本认识你的目录

2.1 Python 环境与依赖库的最小集合

这份源码没有requirements.txt,但根据脚本里的 import 和实际运行需要,核心依赖就四个:pandas、numpy、matplotlib、openpyxl。预测部分用的是sklearn的线性回归,所以还要加一个scikit-learn。如果你用的是vscode python 环境配置,建议直接建虚拟环境,别往全局 site-packages 里塞。

# 创建虚拟环境,Python 3.8 以上都行 python -m venv venv # Windows 激活 venv\Scripts\activate # macOS / Linux 激活 source venv/bin/activate # 一次性装齐依赖 pip install pandas numpy matplotlib openpyxl scikit-learn

逻辑说明:pandas负责读 Excel 和 CSV,numpy做数值运算,matplotlib出静态图,openpyxl是pandas.read_excel的底层引擎,不装会直接报ImportError。scikit-learn只在China_xz_predict.py和America_xz_predict.py里用到,做的是最简单的线性回归拟合。参数上没有版本硬约束,但pandas建议 1.3 以上,否则read_excel对.xlsx的兼容性会出玄学问题。

2.2 数据文件的字段与对应关系

解压后根目录下会看到这些文件,先别改名字,脚本里全是硬编码路径:

文件名类型用途关键字段
China.xlsxExcel中国全国逐日数据日期、累计确诊、新增
China_province.xlsxExcel中国分省数据省份、累计、新增
America.xlsxExcel美国全国逐日数据日期、累计确诊、新增
world.xlsxExcel全球国家维度国家、累计、新增
history.csvCSV历史时间序列date、country、confirmed
China——province.pyPython中国分省可视化读China_province.xlsx
World.pyPython全球对比图读world.xlsx
Compare.pyPython中美对比图读China.xlsx+America.xlsx
pr.pyPython预测结果出图读预测中间结果
China_xz_predict.pyPython中国 14 天预测线性回归
America_xz_predict.pyPython美国 14 天预测线性回归

注意China——province.py里用的是中文破折号「——」,不是下划线,复制文件名的时候别手抖。readme.txt里只写了文件清单,没有写运行顺序,这是这份源码第一个不友好的地方。

2.3 运行顺序:先预测,再对比,最后出 HTML

很多人上来就双击index.html,结果页面空白,因为 HTML 里引用的图表还没生成。正确顺序是:

  1. 先跑China_xz_predict.py和America_xz_predict.py,生成未来 14 天预测数据;
  2. 再跑Compare.py,生成中美对比图;
  3. 跑China——province.py和World.py,补充分省和全球维度;
  4. 最后跑pr.py,把预测图落到 HTML 能引用的位置;
  5. 打开index.html或中美疫情对比.html查看。
# 以 China_xz_predict.py 为例,核心逻辑拆解 import pandas as pd import numpy as np from sklearn.linear_model import LinearRegression # 读取中国疫情数据 df = pd.read_excel('China.xlsx') # 把日期转成序号,线性回归不能直接吃 datetime df['day_index'] = np.arange(len(df)) # 特征和标签 X = df[['day_index']].values y = df['新增'].values # 拟合 model = LinearRegression() model.fit(X, y) # 预测未来 14 天 future_days = np.arange(len(df), len(df) + 14).reshape(-1, 1) pred = model.predict(future_days) print(pred)

逻辑说明:这里用day_index替代真实日期,是因为LinearRegression只认数值。reshape(-1, 1)是把一维数组变成二维,否则sklearn会报Expected 2D array。参数上,future_days从len(df)开始,保证预测区间紧接历史数据末尾。这个脚本没有做训练集/测试集拆分,属于「能出图就行」的写法,后面避坑章节会讲它的局限。

3. 可视化脚本逐个拆:从 Excel 到 HTML 的完整链路

3.1 Compare.py:中美对比图的双轴处理

Compare.py的任务是把中国和美国的累计确诊放在同一张图里。难点在于两国数据量级差异大,早期中国高、后期美国高,单轴会压扁其中一条线。常见做法是用双 Y 轴,或者取对数。

import pandas as pd import matplotlib.pyplot as plt # 读数据 china = pd.read_excel('China.xlsx') america = pd.read_excel('America.xlsx') # 取累计确诊列,假设列名是 '累计确诊' china_cum = china['累计确诊'].values america_cum = america['累计确诊'].values # 双轴图 fig, ax1 = plt.subplots(figsize=(12, 6)) ax1.plot(china_cum, color='red', label='China') ax1.set_ylabel('China Confirmed', color='red') ax2 = ax1.twinx() ax2.plot(america_cum, color='blue', label='America') ax2.set_ylabel('America Confirmed', color='blue') plt.title('China vs America COVID-19 Cumulative') fig.tight_layout() plt.savefig('compare.png', dpi=150)

逻辑说明:ax1.twinx()创建共享 X 轴但独立 Y 轴的第二个坐标系,这样两条线各用各的刻度,不会被压扁。dpi=150是输出分辨率,低于 100 网页上会糊。tight_layout()防止 Y 轴标签被裁掉。这里没有写plt.show(),因为脚本是在后台跑的,直接存图给 HTML 用。

3.2 China——province.py:分省数据的聚合与排序

分省脚本读的是China_province.xlsx,字段是省份、累计、新增。要做的是按累计确诊降序排列,取前 10 个省份画横向柱状图。

import pandas as pd import matplotlib.pyplot as plt # 读分省数据 df = pd.read_excel('China_province.xlsx') # 按累计确诊降序,取前 10 top10 = df.sort_values('累计', ascending=False).head(10) # 横向柱状图 plt.figure(figsize=(10, 6)) plt.barh(top10['省份'], top10['累计'], color='steelblue') plt.xlabel('Cumulative Confirmed') plt.title('Top 10 Provinces in China') plt.gca().invert_yaxis() # 让最高的省份在最上面 plt.tight_layout() plt.savefig('province_top10.png', dpi=150)

逻辑说明:sort_values的ascending=False表示降序,head(10)取前 10。barh是横向柱状图,invert_yaxis()把 Y 轴翻转,否则最高的柱子会跑到最下面,读图反直觉。参数上,figsize的宽高比按 10:6 给,网页嵌入时不会变形。

3.3 World.py 与 pr.py:全球维度与预测图输出

World.py读world.xlsx,逻辑和分省类似,只是把省份换成国家。pr.py比较特殊,它不直接读原始 Excel,而是读预测脚本生成的中间结果,然后画未来 14 天的折线图。

# pr.py 的核心片段 import pandas as pd import matplotlib.pyplot as plt # 读预测结果,假设预测脚本存成了 predict_result.csv pred_df = pd.read_csv('predict_result.csv') plt.figure(figsize=(12, 6)) plt.plot(pred_df['date'], pred_df['predicted'], marker='o', linestyle='--', color='orange') plt.xlabel('Date') plt.ylabel('Predicted New Cases') plt.title('14-Day Prediction') plt.xticks(rotation=45) plt.tight_layout() plt.savefig('prediction.png', dpi=150)

逻辑说明:marker='o'让每个预测点带圆点,linestyle='--'用虚线区分预测和历史。rotation=45防止日期标签重叠。这里的关键是predict_result.csv必须由预测脚本先生成,否则pr.py会直接报FileNotFoundError。

3.4 HTML 文件的角色:图表容器与导航

7 个 HTML 里,index.html是入口,中美疫情对比.html、国内疫情情况.html、全球疫情情况.html是三个主看板,疫情预测分析.html、中国未来14天新增预测.html、美国未来14天新增预测.html是预测专题。它们本身不含数据,只是用<img>标签引用 Python 生成的 PNG。所以如果你改了 Python 脚本的输出路径,HTML 里的src也要同步改,否则页面就是一堆裂图。

4. 避坑与常见问题排查:跑不通时先看这几条

4.1 报错FileNotFoundError: China.xlsx

现象:脚本一运行就提示找不到 Excel 文件。原因:脚本用的是相对路径,而你的工作目录不是脚本所在目录。解决:要么在终端里cd到脚本目录再运行,要么在代码开头加import os; os.chdir(os.path.dirname(os.path.abspath(__file__)))。我一般会在每个脚本头部都加这一行,省得来回切目录。

4.2 中文列名读取后变成乱码

现象:df.columns打印出来是\u7d2f\u8ba1这种转义。原因:Excel 文件编码和pandas默认读取方式不匹配,或者文件本身是旧版.xls被强行改了后缀。解决:先确认文件确实是.xlsx,然后用pd.read_excel('China.xlsx', engine='openpyxl')显式指定引擎。如果还是乱码,用 Excel 打开另存为一次,选 UTF-8 编码的 CSV 再读。

4.3 预测结果是一条直线

现象:未来 14 天预测图完全水平,没有任何波动。原因:China_xz_predict.py用的是线性回归,而疫情新增数据本身是非线性的,线性拟合在趋势拐点后会给出常数。解决:这是算法选型问题,不是代码 bug。想改善的话,把LinearRegression换成PolynomialFeatures(degree=2)做多项式回归,或者直接用ARIMA。但要注意,这份源码的定位是教学演示,不是预测精度竞赛。

4.4 HTML 打开后图表不显示

现象:浏览器里只有文字,图片位置是裂图图标。原因:PNG 文件还没生成,或者 HTML 里的src路径和实际输出路径不一致。解决:先按第 2.3 节的顺序把所有 Python 脚本跑一遍,确认根目录下出现了compare.png、province_top10.png、prediction.png等文件。然后右键 HTML 用文本编辑器打开,检查<img src="...">里的文件名是否和实际一致。注意大小写,Compare.png和compare.png在 Linux 下是两个文件。

4.5sklearn安装后仍报ModuleNotFoundError

现象:pip install scikit-learn显示成功,但import sklearn还是失败。原因:虚拟环境没激活,或者pip和python指向了不同的解释器。解决:用python -m pip install scikit-learn代替直接pip install,强制用当前 Python 解释器安装。装完用python -c "import sklearn; print(sklearn.__version__)"验证。

5. 进阶技巧:把静态图换成可交互看板

5.1 用 Pyecharts 替换 Matplotlib 出图

Matplotlib 出的是静态 PNG,放大就糊,而且不能 hover 看数值。如果你想让这份源码的展示效果上一个台阶,可以把出图部分换成pyecharts,直接生成交互式 HTML。

from pyecharts.charts import Line from pyecharts import options as opts import pandas as pd df = pd.read_excel('China.xlsx') x_data = df['日期'].astype(str).tolist() y_data = df['新增'].tolist() line = ( Line() .add_xaxis(x_data) .add_yaxis('新增确诊', y_data, is_smooth=True) .set_global_opts( title_opts=opts.TitleOpts(title='中国疫情新增趋势'), datazoom_opts=opts.DataZoomOpts(), # 底部缩放条 tooltip_opts=opts.TooltipOpts(trigger='axis') # 鼠标悬停显示数值 ) ) line.render('china_trend.html')

逻辑说明:is_smooth=True让折线平滑,DataZoomOpts加底部缩放条,TooltipOpts(trigger='axis')实现鼠标悬停显示同一天的所有数值。render直接输出独立 HTML,不需要再嵌到原页面里。参数上,x_data必须转成字符串,否则pyecharts对Timestamp的处理会出问题。

5.2 预测模型的替换方案与验证方法

线性回归在这份源码里只是「能跑通」的级别。如果你想验证预测到底靠不靠谱,可以做一个简单的回测:用前 80% 的数据训练,后 20% 做测试,算 MAE。

from sklearn.linear_model import LinearRegression from sklearn.metrics import mean_absolute_error import numpy as np import pandas as pd df = pd.read_excel('China.xlsx') df['day_index'] = np.arange(len(df)) X = df[['day_index']].values y = df['新增'].values # 80% 训练,20% 测试 split = int(len(df) * 0.8) X_train, X_test = X[:split], X[split:] y_train, y_test = y[:split], y[split:] model = LinearRegression() model.fit(X_train, y_train) pred = model.predict(X_test) mae = mean_absolute_error(y_test, pred) print(f'MAE: {mae:.2f}')

逻辑说明:split是切分点,X_train和y_train是训练集,X_test和y_test是测试集。mean_absolute_error算的是预测值和真实值的平均绝对误差,数值越小越好。如果 MAE 大得离谱,说明线性回归不适合这份数据,换模型比调参更有效。

5.3 一个我踩过的坑:日期格式不统一

China.xlsx里的日期是2020-01-01格式,America.xlsx里可能是01/01/2020,history.csv里又是2020/1/1。三个文件三种格式,直接合并会报ValueError。我一般会写一个统一的清洗函数:

def parse_date(s): return pd.to_datetime(s, infer_datetime_format=True, errors='coerce')

infer_datetime_format=True让 pandas 自己猜格式,errors='coerce'把解析失败的变成NaT,避免整个脚本崩掉。从那以后我每次拿到多来源数据,都强制先跑一遍日期格式检查,确认df['date'].dtype是datetime64[ns]再往下做。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询