使用Python的imageio库生成GIF仅显示首图问题排查
问题排查与修复方案
一、先确认image列表是否正确填充
在循环结束后添加调试代码,验证列表长度和内容:
print(f"image列表长度: {len(image)}") for idx, img in enumerate(image): print(f"第{idx+1}帧图片尺寸: {img.shape}")
如果输出长度不是3,说明图片读取存在异常;如果各帧尺寸不一致,可能导致GIF渲染时只显示首帧。
二、修复路径问题(关键)
你创建了folder变量指定图片存储目录,但保存和读取图片时未使用该路径,可能引发路径不一致导致的读取异常(即使你生成了3张PNG,也可能读取到重复文件)。修改如下:
# 替换原filename及保存、读取代码 filename = os.path.join(folder, f'Рейтинг_{month}.png') plt.savefig(filename, bbox_inches='tight') # 避免标题/标签被裁剪 image.append(iio.imread(filename))
三、调整GIF播放参数
你设置的duration=20是毫秒级(仅0.02秒),播放速度过快可能造成“只显示第一张”的视觉误判。建议调整为合理值,比如2000(2秒/帧),同时添加循环参数:
iio.imwrite('barplot.gif', image, duration=2000, loop=0) # loop=0表示无限循环
四、验证循环内数据与绘图逻辑
确保每个月份的数据集有效,在循环内添加代码检查:
print(f"第{month}月数据行数: {len(df)}")
如果某月份无数据,会生成空图,但你已确认PNG正确,这一步可作为兜底验证。
修改后的完整代码
import pandas as pd import matplotlib.pyplot as plt import seaborn as sns import os import imageio.v3 as iio image = [] folder = 'C:/Users/admin/PycharmProjects/pythonProject2/Project/Seaborn' if not os.path.exists(folder): os.mkdir(folder) for month in range(1, 4): porosity_cutoff = 250 highlight_colour = 8 non_highlight_colour = 10 df = pd.read_csv('../Список.csv') df = df.loc[df['Месяц'] == month].sort_values(by='Баллы', ascending=False) # 验证当月数据 print(f"第{month}月数据行数: {len(df)}") df['colours'] = df["Баллы"].apply(lambda x: highlight_colour if x >= porosity_cutoff else non_highlight_colour) ax = sns.barplot(data=df, x="Баллы", y="Участники", palette="Set1", hue=df['colours'], legend=False) plt.axvline(x=250, zorder=0, color='grey', ls='--', lw=1.5) plt.text(x=283, y=8, s='Порог допустимых баллов', ha='center', fontsize=11, bbox=dict(facecolor='white', edgecolor="grey", ls='--')) ax.set_title(f"Рейтинг за {month} месяц", size=30) ax.set_ylabel("Участники", size=20) ax.set_xlabel("Баллы", size=20) for i in ax.containers: ax.bar_label(i, color="white", padding=-30, fontsize=12) # 使用指定目录保存图片 filename = os.path.join(folder, f'Рейтинг_{month}.png') plt.savefig(filename, bbox_inches='tight') image.append(iio.imread(filename)) plt.close() # 验证image列表 print(f"image列表长度: {len(image)}") for idx, img in enumerate(image): print(f"第{idx+1}帧图片尺寸: {img.shape}") # 生成GIF,调整播放时长 iio.imwrite('barplot.gif', image, duration=2000, loop=0)
排查逻辑总结
- 优先确认
image列表是否包含3张有效图片; - 确保图片保存与读取路径一致,避免因路径问题读取重复文件;
- 调整GIF播放时长,排除速度过快导致的视觉误判;
- 验证循环内数据,确保每张图的数据源不同。
内容的提问来源于stack exchange,提问作者CODDY
相关产品推荐
相关产品推荐

