在阅读技术博客的过程中,我们会发现很多知识和结果讲解透彻的博主都可以制作动态图表。他们的照片是如何制作的?它困难吗?本文介绍一种用Python制作动态图表的简单方法。在数据爆炸的时代,数据科学家和分析师在需要对数据有更深入的理解和分析的同时,也需要将结果有效地传达给他人。如何让目标受众更直观地理解?当然是对数据进行可视化,最好动态可视化。本文将以折线图、条形图和饼图为例,系统地讲解如何让你的数据图表动起来。这些动态图表是由什么组成的?接触过数据可视化的同学应该对Python中的Matplotlib库不陌生。它是一个基于Python的开源数据绘图包,仅需几行代码即可帮助开发者生成直方图、功率谱、柱状图、散点图等。这个库中有一个非常有用的扩展包——FuncAnimation,它可以让我们的静态图表动起来。FuncAnimation是Matplotlib库中Animation类的一部分,后面会展示几个例子。如果是第一次接触,可以将这个函数简单理解为一个While循环,不断在“画布”上重新绘制目标数据图。如何使用函数动画?该过程从以下两行代码开始:importmatplotlib.animationasanianimator=ani.FuncAnimation(fig,chartfunc,interval=100)从这里我们可以看到FuncAnimation的几个输入:fig是用于“绘制图表”的图形对象;chartfunc是一个以数字为输入的函数,其含义是时间序列上的时间;interval比较好理解,就是帧与帧之间的间隔延迟,单位是毫秒,默认值是200。这是三个关键的输入。当然,还有更多的可选输入。有兴趣的读者可以查看原文,这里不再赘述。接下来就是对数据图表进行参数化,将其转化为函数,然后将函数时间序列中的点作为输入。设置完成后,就可以正式开始了。在开始之前,您仍然需要确认您是否了解基本的数据可视化。也就是说,我们首先要将数据可视化,然后再进行动态处理。按照下面的代码进行基本调用。此外,将采用大规模流行病的传播数据作为病例数据(包括每天的死亡人数)。importmatplotlib.animationasaniimportmatplotlib.pyplotaspltimportnumpyasnpimportpandasasspdurl='https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_delaths_global.csv'df=ff.interestinread['国家/地区'].isin(['英国','美国','意大利','德国'])&df['省/州'].isna()]df_interest.rename(index=lambdax:df_interest.at[x,'国家/地区'],inplace=True)df1=df_interest.transpose()df1=df1.drop(['省/州','国家/地区','Lat','Long'])df1=df1.loc[(df1!=0).any(1)]df1.index=pd.to_datetime(df1.index)绘制三种常见的动态图表和绘制动态线类型图如下所示。需要做的第一件事是定义图表的项目。这些基本项在设置后将保持不变。它们包括:创建图形对象、x和y标签、设置线条颜色和图形边距等:importnumpyasnpimportmatplotlib.pyplotaspltcolor=['red','green','blue','orange']fig=plt.figure()plt.xticks(rotation=45,ha="right",rotation_mode="anchor")#rotatethex-axisvaluesplt.subplots_adjust(bottom=0.2,top=0.9)#ensuringthedates(onthex-axis)fitinthescreenplt.ylabel('NoofDeaths')plt.xlabel('Dates')接下来设置曲线函数,然后用.FuncAnimation让它动起来:defbuildmebarchart(i=int):plt.legend(df1.columns)p=plt.plot(df1[:i].index,df1[:i].values)#noteitonlyreturnsthedataset,uptothepointiforiinrange(0,4):p[i].set_color(color[i])#setthecolourofeachcurveimportmatplotlib.animationasanianimator=ani.FuncAnimation(fig,buildmebarchart,interval=100)plt.show()动态饼图可以观察到代码结构看起来和折线图差别不大,但还是有细微的差别。importnumpyasnpimportmatplotlib.pyplotaspltfig,ax=plt.subplots()explode=[0.01,0.01,0.01,0.01]#popouteachslicefromthepiedefgetmepie(i):debsolute_value(val):#turn%backtoanumbera=np.round(val/100.*df1.head)(i).max().sum(),0)returnint(a)ax.clear()plot=df1.head(i).max().plot.pie(y=df1.columns,autopct=absolute_value,label='',explode=explode,shadow=True)plot.set_title('TotalNumberofDeathsn'+str(df1.index[min(i,len(df1.index)-1)].strftime('%y-%m-%d')),fontsize=12)importmatplotlib.animationasanianimator=ani.FuncAnimation(fig,getmepie,interval=200)plt.show()主要区别在于动态饼图的代码会返回一组值每次都循环,但是折线图返回的是整个时间序列到我们点为止。返回时间序列由df1.head(i)实现,.max()保证我们只得到最新的数据,因为疫情造成的死亡总人数只有两个变化:维持现有人数或继续增加上升。df1.head(i).max()动态条形图创建动态条形图的难度与上面两种情况相差不大。在本例中,作者定义了水平和垂直两种条形图,读者可以根据自己的实际需要选择图表类型和定义可变条形图。fig=plt.figure()bar=''defbuildmebarchart(i=int):iv=min(i,len(df1.index)-1)#theloopiteratesanextraonetime,whichcausesthedataframestogooutofbounds.Thiswastheeasiest(mostlazy)waytosolvethis:)objects=df1.max对象=df1.max().indexy_pos=np.arange(len(objects))performance=df1.iloc[[iv]].values.tolist()[0]ifbar=='vertical':plt.bar(y_pos,performance,align='center',color=['red','green','blue','orange'])plt.xticks(y_pos,objects)plt.ylabel('Deaths')plt.xlabel('Countries')plt.title('DeathsperCountryn'+str(df1.index[iv].strftime('%y-%m-%d')))else:plt.barh(y_pos,performance,align='center',color=['红色','绿色','蓝色','橙色'])plt.yticks(y_pos,对象)plt.xlabel('死亡')plt.ylabel('国家')animator=ani.FuncAnimation(图,buildmebarchart,interval=100)plt.show()制作完成后,存储这些动态图片就很简单了,可以直接使用下面的代码:animator.save(r'C:tempmyfirstAnimation.gif')有兴趣的读者要获取详细信息请参考:https://matplotlib.org/3.1.1/api/animation_api.html。
