用Python绘制超酷的gif动图,惊艳了所有人

x33g5p2x  于2022-05-16 转载在 Python  
字(3.3k)|赞(0)|评价(0)|浏览(686)
  1. 今天给大家来介绍一种制作gif格式图表的新方法,调用的是matplotlib的相关模块,其中的步骤与方法也是相当地简单易懂。

下载和导入数据库

我们这次用到的数据集是bokeh模块自带的数据集,通过下面这一行代码直接就可以下载

  1. import bokeh
  2. bokeh.sampledata.download()

然后导入后面要用到的数据集,我们挑选的是指定国家的1950年至今不同年龄阶段的人口所占比重的数据

  1. from bokeh.sampledata.population import data
  2. import numpy as np
  3. data = filter_loc('United States of America')
  4. data.head()

output

先绘制若干张静态的图表

我们可以先绘制若干张静态的图表,然后将这几张图表合成一张gif格式的动图即可,代码如下

  1. import seaborn as sns
  2. import matplotlib.pyplot as plt
  3. import matplotlib.patheffects as fx
  4. # 绘制图表的函数
  5. def make_plot(year):
  6.     
  7.     # 根据年份来筛选出数据
  8.     df = data[data.Year == year]
  9.         
  10.     # 制作图表
  11.     fig, (ax1, ax2) = plt.subplots(1, 2, sharey = True)
  12.     ax1.invert_xaxis()
  13.     fig.subplots_adjust(wspace = 0) 
  14.     
  15.     ax1.barh(df[df.Sex == 'Male'].AgeGrp, df[df.Sex == 'Male'].percent, label = 'Male')
  16.     ax2.barh(df[df.Sex == 'Female'].AgeGrp, df[df.Sex == 'Female'].percent, label = 'Female', color = 'C1')
  17.     
  18.     country = df.Location.iloc[0]
  19.     if country == 'United States of America': country == 'US'
  20.         
  21.     fig.suptitle(f'......')
  22.     fig.supxlabel('......')
  23.     fig.legend(bbox_to_anchor = (0.9, 0.88), loc = 'upper right')
  24.     ax1.set_ylabel('Age Groups')
  25.     
  26.     return fig

我们自定义了一个绘制图表的函数,其中的参数是年份,逻辑很简单,我们是想根据年份来筛选出数据,然后根据筛选出的数据来绘制图表,每一年的图表不尽相同

  1. years = [for i in set(data.Year) if i < 2022]
  2. years.sort()
  3. for year in years:
  4.     fig = make_plot(year)
  5.     fig.savefig(f'{year}.jpeg',bbox_inches = 'tight')

output

这样我们就生成了若干张静态的图表,然后集合成gif格式的图表几个,代码如下

  1. import matplotlib.animation as animation
  2. fig, ax = plt.subplots()
  3. ims = []
  4. for year in years:
  5.     im = ax.imshow(plt.imread(f'{year}.jpeg'), animated = True)
  6.     ims.append([im])
  7. ani = animation.ArtistAnimation(fig, ims, interval=600)
  8. ani.save('us_population.gif')

output

还有另外一种思路

可能看到这儿,有人会觉得上面提到的方法稍显麻烦,毕竟我们需要先生成数十张静态的图表,要是电脑的磁盘空间有点紧张的话,或者还没有这样的一个地方来存放这数十张的图表。于是乎就会疑问道,是不是可以一步到位的来。

当然也是可以的,例如我们打算绘制1950年到2020年不同年龄阶段的人口比例分布图,首先第一步在于我们先要绘制1950年,也就是起始年,该年不同年龄阶段的人口比例分布图,代码如下

  1. fig, (ax1, ax2) = plt.subplots(1, 2, sharey = True)
  2.    
  3. df = data[data.Year == 1955]
  4. y_pos = [for i in range(len(df[df.Sex == 'Male']))]
  5. male = ax1.barh(y_pos, df[df.Sex == 'Male'].percent, label = 'Male',
  6.                tick_label = df[df.Sex == 'Male'].AgeGrp)
  7. female = ax2.barh(y_pos, df[df.Sex == 'Female'].percent, label = 'Female', 
  8.                   color = 'C1', tick_label = df[df.Sex == 'Male'].AgeGrp)
  9. ax1.invert_xaxis()
  10. fig.suptitle('.......')
  11. fig.supxlabel('....... (%)')
  12. fig.legend(bbox_to_anchor = (0.9, 0.88), loc = 'upper right')
  13. ax1.set_ylabel('Age Groups')

output

然后我们自定义一个绘制图表的函数,其中参数为年份,目的在于通过年份来筛选出相对应的数据并且绘制出相对应的图表

  1. def run(year):
  2.     # 通过年份来筛选出数据
  3.     df = data[data.Year == year]
  4.     # 针对不同地性别来绘制
  5.     total_pop = df.Value.sum()
  6.     df['percent'] = df.Value / total_pop * 100
  7.     male.remove()
  8.     y_pos = [for i in range(len(df[df.Sex == 'Male']))]
  9.     male.patches = ax1.barh(y_pos, df[df.Sex == 'Male'].percent, label = 'Male', 
  10.                      color = 'C0', tick_label = df[df.Sex == 'Male'].AgeGrp)
  11.     female.remove()
  12.     female.patches = ax2.barh(y_pos, df[df.Sex == 'Female'].percent, label = 'Female',
  13.                  
  14.                  color = 'C1', tick_label = df[df.Sex == 'Female'].AgeGrp)
  15.     text.set_text(year)
  16.     return male#, female

然后我们调用animation.FuncAnimation()方法,

  1. ani = animation.FuncAnimation(fig, run, years, blit = True, repeat = True, 
  2.                               interval = 600)
  3. ani.save('文件名.gif')

output

这样就可以一步到位生成gif格式的图表,避免生成数十张繁多地静态图片了。

将若干张gif动图放置在一张大图当中

最后我们可以将若干张gif动图放置在一张大的图表当中,代码如下

  1. import matplotlib.animation as animation
  2. # 创建一个新的画布
  3. fig, (ax, ax2, ax3) = plt.subplots(1, 3, figsize = (10, 3))
  4. ims = []
  5. for year in years:
  6.     im = ax.imshow(plt.imread(f'文件1{year}.jpeg'), animated = True)
  7.     im2 = ax2.imshow(plt.imread(f'文件2{year}.jpeg'), animated = True)
  8.     im3 = ax3.imshow(plt.imread(f'文件3{year}.jpeg'), animated = True)
  9.     ims.append([im, im2, im3])
  10. ani = animation.ArtistAnimation(fig, ims, interval=600)
  11. ani.save('comparison.gif')

output

END -

  1. 对比Excel系列图书累积销量达15w册,让你轻松掌握数据分析技能,可以在全网搜索书名进行了解选购:

相关文章