当前位置: 首页 > 科技观察

用Python画出炫酷的gif动画,惊艳了大家

时间:2023-03-21 21:58:51 科技观察

在之前的一篇文章中,小编分享了如何使用Python中的gif模块制作出gif格式的图表,让人叹为观止。使用Python绘制动态可视化图表并保存为gif格式。今天介绍一种制作gif格式图表的新方法。调用的是matplotlib相关模块,步骤和方法都相当简单易懂。下载导入数据库我们这次使用的数据集是bokeh模块自带的数据集。可以通过下面这行代码直接下载importbokehbokeh.sampledata.download()然后导入后面要用到的数据集,我们选择的是1950年到现在不同年龄段人口比例的数据指定国家从bokeh.sampledata.populationimportdataimportnumpyasnpdata=filter_loc('UnitedStatesofAmerica')data.head()output先画几个静态图表我们可以先画几个静态图表,然后把这些图表组合成一个gif格式的动画,代码如下importseabornassnsimportmatplotlib.pyplotaspltimportmatplotlib.patheffectsasfx#绘制图表的函数defmake_plot(year):#根据年份过滤掉Datadf=data[data.Year==year]#制作图表fig,(ax1,ax2)=plt.subplots(1,2,sharey=True)ax1.invert_xaxis()fig.subplots_adjust(wspace=0)ax1。barh(df[df.Sex=='男性'].AgeGrp,df[df.Sex=='男性'].percent,label='男性')ax2.barh(df[df.Sex=='女性'].AgeGrp,df[df.Sex=='女性'].percent,label='女性',color='C1')country=df.Location.iloc[0]ifcountry=='UnitedStatesofAmerica':country=='美国'fig.suptitle(f'...')fig.supxlabel('...')fig.legend(bbox_to_anchor=(0.9,0.88),loc='upperright')ax1。set_ylabel('AgeGroups')returnfig我们自定义了一个绘制图表的函数,参数是年份,逻辑很简单,我们要根据年过滤出数据,然后根据过滤后的数据绘制图表。图表每年都不同。years=[iforiinset(data.Year)ifi<2022]years.sort()foryearinyears:fig=make_plot(year)fig.savefig(f'{year}.jpeg',bbox_inches='tight')这样输出,我们生成了几个静态图表,然后将它们组装成几个gif格式的图表。代码如下[im])ani=动画。ArtistAnimation(fig,ims,interval=600)ani.save('us_population.gif')output还有一种思路。有些人可能会觉得上面提到的方法有点麻烦。毕竟,我们需要先生成数字。十张静态图表,如果电脑的磁盘空间有点紧张,或者没有这样的地方存放这几十张图表,那么人们会怀疑是否可以一步完成。当然,这也是可能的。比如我们要画出1950年到2020年不同年龄段的人口比例分布,第一步首先要画出1950年,也就是起始年份,不同年龄段的人口比例分布图在那年。如图,代码如下fig,(ax1,ax2)=plt.subplots(1,2,sharey=True)df=data[data.Year==1955]y_pos=[iforiinrange(len(df[df.Sex=='男']))]male=ax1.barh(y_pos,df[df.Sex=='男'].percent,label='男',tick_label=df[df.Sex=='男'].AgeGrp)female=ax2.barh(y_pos,df[df.Sex=='Female'].percent,label='Female',color='C1',tick_label=df[df.Sex=='Male'].AgeGrp)ax1.invert_xaxis()fig.suptitle('......')fig.supxlabel('......(%)')fig.legend(bbox_to_anchor=(0.9,0.88),loc='upperright')ax1.set_ylabel('AgeGroups')output然后我们自定义一个绘制图表的函数,其中参数为年份,目的是通过年份筛选出对应的数据,绘制对应的图表defrun(year):#按年份筛选数据df=data[data.Year==year]#绘制不同性别的total_pop=df.Value.sum()df['percent']=df.Value/total_pop*100male.remove()y_pos=[iforiinrange(len(df[df.Sex=='Male']))]male.patches=ax1.barh(y_pos,df[df.Sex=='Male'].percent,label='男',color='C0',tick_label=df[df.Sex=='男'].AgeGrp)female.remove()female.patches=ax2.barh(y_pos,df[df.Sex=='女'].percent,label='女',color='C1',tick_label=df[df.Sex=='女'].AgeGrp)text.set_text(year)returnmale#,female然后我们调用animation.FuncAnimation()方法,ani=animation.FuncAnimation(fig,run,years,blit=True,repeat=True,interval=600)ani.save('filename.gif')输出这样你可以一步生成gif格式的图表,避免生成几十张静态图片gif动画放在一张大图表中,代码如下importmatplotlib.animationasanimation#Createanewcanvasfig,(ax,ax2,ax3)=plt.subplots(1,3,figsize=(10,3))ims=[]foryearinyears:im=ax.imshow(plt.imread(f'file1{year}.jpeg'),animated=True)im2=ax2.imshow(plt.imread(f'file2{year}.jpeg'),animated=True)im3=ax3.imshow(plt.imread(f'file3{year}.jpeg'),animated=True)ims.append([im,im2,im3])ani=animation.ArtistAnimation(fig,ims,interval=600)ani.save('comparison.gif')输出