如何实现以美国、加拿大、中国为输入的新冠病例时间序列子图生成函数
最佳实现:美加中三国新冠病例时间序列子图
你的思路方向是对的!用循环生成子图确实是高效的方式,不过我们可以优化代码的可控性、可读性和可视化效果,下面是针对这个任务的最佳实现方案和实用技巧:
核心优化思路
与其依赖groupby的自动分组,不如明确指定目标国家列表,这样既能保证子图顺序完全符合你的需求,也能避免处理无关国家的数据。同时结合数据标准化和可视化细节优化,让图表更具对比性和可读性。
完整实现代码
import pandas as pd import matplotlib.pyplot as plt from sklearn.preprocessing import StandardScaler # 假设cases_raw是行索引为国家、列为日期的宽格式数据 target_countries = ['US', 'China', 'Canada'] # 筛选目标国家数据,整理成便于处理的格式 df = cases_raw.loc[target_countries].reset_index().rename(columns={'index': 'Country'}) # 可选:数据标准化(消除基数差异,聚焦趋势对比) scaler = StandardScaler() scaled_values = scaler.fit_transform(df.drop('Country', axis=1)) scaled_df = pd.DataFrame(scaled_values, columns=df.columns[1:], index=df['Country']) # 创建1行3列的子图,共享y轴以强化横向对比 fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(18, 6), sharey=True) # 循环遍历国家和对应的子图 for country, ax in zip(target_countries, axes.flatten()): # 选择使用标准化数据还是原始数据(二选一即可) # 原始数据方式: # case_data = df[df['Country'] == country].drop('Country', axis=1).T # 标准化数据方式: case_data = scaled_df.loc[country].T # 绘制时间序列折线图 case_data.plot(ax=ax, legend=False, color='#2ca02c') # 设置子图标题与坐标轴标签 ax.set_title(f'COVID-19 Cases: {country}', fontsize=12, pad=10) ax.set_xlabel('Date', fontsize=10) # 仅给第一个子图设置y轴标签(共享y轴无需重复) if ax == axes[0]: ax.set_ylabel('Scaled Case Count', fontsize=10) # 添加半透明网格提升可读性 ax.grid(alpha=0.3, linestyle='--') # 自动调整子图间距,避免元素重叠 plt.tight_layout() plt.show()
关键实用技巧
- 可控的数据源筛选:用
target_countries列表精准筛选数据,相比groupby更可靠——毕竟分组后的国家顺序不一定是你想要的US→China→Canada,手动指定能完全掌控子图顺序。 - 数据标准化的价值:因为各国新冠病例的初始基数差异极大,标准化后能让你更清晰地对比趋势变化幅度,而不是被绝对值差异干扰。如果需要展示真实数值,直接改用原始数据即可。
- 共享坐标轴的优势:
sharey=True让三个子图的y轴刻度完全一致,避免视觉上的误导,能更直观地横向对比三国的病例走势。 - 代码复用性提升:通过循环遍历国家列表和子图,避免重复编写三次绘图逻辑——后续要添加其他国家,只需修改
target_countries列表即可,无需改动大量代码。 - 可视化细节优化:
plt.tight_layout()自动调整子图间距,防止标题、坐标轴标签互相重叠- 仅给第一个子图设置y轴标签,避免重复冗余
- 半透明网格能辅助读者读取数据点的数值,同时不会干扰折线的视觉焦点
对你当前代码的小建议
你当前单独提取A、B、C三个国家变量的写法可以简化,直接通过目标列表筛选数据即可;另外country_groups.groups.keys()的顺序不可控,建议替换为手动指定的国家列表,保证子图顺序符合预期。
内容的提问来源于stack exchange,提问作者Jeffrey
相关产品推荐
相关产品推荐

