You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于Excel年份数据实现Matplotlib动态气泡散点图?

你的思路没问题,Matplotlib完全可以实现动态年份气泡图!

你的核心方向是对的——通过逐帧绘制不同年份的数据来实现气泡随年份变化的动画,但现有代码里的动画逻辑有点小问题,主要是animate函数的调用方式和数据过滤的写法不对。下面给你梳理修正方案:

先指出你现有代码的几个关键问题:

  • FuncAnimation会自动逐帧调用animate函数,不需要在animate里自己循环所有年份;
  • 每次绘制新帧前没有清空坐标轴,会导致所有年份的点叠加在一起;
  • 文本标注没有跟着当前年份更新,会显示所有年份的标签。

修正后的完整代码

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from matplotlib.animation import FuncAnimation

# 读取数据
data = pd.read_excel('sample.xls', sheet_name=0)
# 获取唯一年份并排序,保证动画按时间顺序播放
unique_years = sorted(data['Year'].unique())

# 初始化图表
fig, ax = plt.subplots(figsize=(10, 6))
# 提前设置轴的固定范围(根据你的数据调整,避免动画过程中轴跳来跳去)
ax.set_xlim(data['lifeExpec'].min() - 2, data['lifeExpec'].max() + 2)
ax.set_ylim(data['GDPperCapita'].min() - 5000, data['GDPperCapita'].max() + 5000)
ax.set_xlabel('Life Expectancy')
ax.set_ylabel('GDP per Capita')

# 为Region创建固定的颜色映射,避免每帧颜色变化
region_codes = data['Region'].astype('category').cat.codes
region_unique = data['Region'].unique()
cmap = cm.viridis
norm = plt.Normalize(region_codes.min(), region_codes.max())

def animate(frame):
    # 根据当前帧索引获取对应年份的数据
    current_year = unique_years[frame]
    year_data = data[data['Year'] == current_year]
    
    # 清空当前轴内容,准备绘制新帧
    ax.clear()
    # 重新设置轴标签和标题(清空后需要重新设置)
    ax.set_xlim(data['lifeExpec'].min() - 2, data['lifeExpec'].max() + 2)
    ax.set_ylim(data['GDPperCapita'].min() - 5000, data['GDPperCapita'].max() + 5000)
    ax.set_xlabel('Life Expectancy')
    ax.set_ylabel('GDP per Capita')
    ax.set_title(f'Year: {current_year}')
    
    # 绘制当前年份的散点图(气泡图)
    scatter = ax.scatter(
        x=year_data['lifeExpec'],
        y=year_data['GDPperCapita'],
        s=year_data['PopX1000']/4,
        c=year_data['Region'].astype('category').cat.codes,
        cmap=cmap,
        norm=norm,
        edgecolors='none',
        alpha=0.7
    )
    
    # 添加当前年份的州标签
    for idx, row in year_data.iterrows():
        ax.text(
            x=row['lifeExpec'],
            y=row['GDPperCapita'],
            s=row['State'],
            fontsize=10,
            ha='center',
            va='center'
        )
    
    return scatter,

# 创建动画,frames是总帧数(即年份数量),interval是每帧间隔毫秒
anim = FuncAnimation(
    fig,
    animate,
    frames=len(unique_years),
    interval=1000,  # 1秒切换一次年份,可按需调整
    blit=True
)

# 如果你想保存动画,可以用下面的代码(需要安装ffmpeg)
# anim.save('life_gdp_animation.mp4', writer='ffmpeg', dpi=100)

plt.show()

关键逻辑说明:

  1. 数据过滤:通过year_data = data[data['Year'] == current_year]获取当前年份的切片数据,这就是你之前困惑的按年份筛选的正确写法;
  2. 帧更新逻辑:每帧先清空坐标轴,再绘制当前年份的气泡和标签,确保画面只显示当前年份的内容;
  3. 固定轴范围:提前设置x、y轴的范围,避免动画过程中轴的边界频繁变化,提升观看体验;
  4. 固定颜色映射:让同一Region的颜色保持一致,避免每帧颜色混乱。

放心,这个方案完全可以实现你想要的“气泡随年份变化移动并改变大小”的效果!

内容的提问来源于stack exchange,提问作者Geralt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:39:09