大家好。关于动态图表,相信大家都或多或少接触过。如果代码水平比较好,可以选择Matplotlib。当然你也可以使用pyecharts的相关功能,但是这些工具都是专注于制作图表的,就是你需要自己对图表的数据进行转换。今天介绍的可视化库完美的结合了Pandas的数据格式,辅以Matplotlib的强大功能,让我们制作动画变得更加简单。画廊介绍这个强大的视觉画廊是pandas_alive。虽然目前在GitHub上的star数不是很高,但相信凭借其强大的功能,它的出现是迟早的事情。项目安装:和一般的Python库一样,直接使用pip安装即可。这里需要注意一点,Matplotlib是用来制作动画的,所以需要手动安装Matplotlib的依赖工具imagemagick,它是一个图像处理工具。有兴趣的同学可以自行查看项目功能:这里这个可视化库可以支持多种图表类型,包括动态条形图、动态曲线图、气泡图、饼图、地图等,这些图表几乎可以满足我们日常使用。下面就简单介绍一下如何制作动态图表。第一个是动态条形图。基本上4行代码就搞定了。还有两行importimportpandas_aliveimportpandasaspdcovid_df=pd.read_csv('covid19.csv',index_col=0,parse_dates=[0])Howaboutcovid_df.diff().fillna(0).plot_animated(filename='line_chart.gif',kind='line',period_label={'x':0.25,'y':0.9}),是不是超级方便?让我们看看如何制作其他图表!01动态条形图importpandas_aliveimportpandasaspdcovid_df=pd.read_csv('covid19.csv',index_col=0,parse_dates=[0])covid_df.plot_animated(filename='examples/perpendicular-example.gif',perpendicular_bar_func='mean')02动态直方图导入pandas_aliveimportpandasaspdcovid_df=pd.read_csv('covid19.csv',index_col=0,parse_dates=[0])covid_df.plot_animated(filename='examples/example-barv-chart.gif',orientation='v')03动态曲线图importpandas_aliveimportpandasaspdcovid_df=pd.read_csv('covid19.csv',index_col=0,parse_dates=[0])covid_df.diff().fillna(0).plot_animated(filename='examples/example-line-chart.gif',kind='line',period_label={'x':0.25,'y':0.9})04动态平面积图importpandas_aliveimportpandasaspdcovid_df=pd.read_csv('covid19.csv',index_col=0,parse_dates=[0])covid_df.sum(axis=1).fillna(0).plot_animated(filename='examples/example-bar-chart.gif',kind='bar',period_label={'x':0.1,'y':0.9},enable_progress_bar=True,steps_per_period=2,interpolate_period=True,period_length=200)05动态散点图importpandasaspdimportpandas_alivemax_temp_df=pd.read_csv("data/Newcastle_Australia_Max_Temps.csv",parse_dates={"时间戳":["年","月","日"]},)min_temp_df=pd.read_csv("data/Newcastle_Australia_Min_Temps.csv",parse_dates={"时间戳":["年","月","日"]},)merged_temp_df=pd.merge_asof(max_temp_df,min_temp_df,on="Timestamp")merged_temp_df.index=pd.to_datetime(merged_temp_df["Timestamp"].dt.strftime('%Y/%m/%d'))keep_columns=["最低温度(摄氏度))","最高温度(摄氏度)"]merged_temp_df[keep_columns].resample("Y").mean().plot_animated(filename='examples/example-scatter-chart.gif',kind="scatter",title='Max&MinTemperatureNewcastle,Australia')06动态饼图importpandas_aliveimportpandasaspdcovid_df=pd.read_csv('covid19.csv',index_col=0,parse_dates=[0])covid_df.plot_animated(filename='examples/example-pie-chart.gif',kind="pie",rotatelabels=True,period_label={'x':0,'y':0})07动态气泡图importpandas_alivemulti_index_df=pd.read_csv("data/multi.csv",header=[0,1],index_col=0)multi_index_df.index=pd.to_datetime(multi_index_df.index,dayfirst=True)map_chart=multi_index_df.plot_animated(kind="bubble",文件名="examples/example-bubble-chart.gif",x_data_label="经度",y_data_label="纬度tude",size_data_label="Cases",color_data_label="Cases",vmax=5,steps_per_period=3,interpolate_period=True,period_length=500,dpi=100)08动态地理图表importgeopandasimportpandas_aliveimportcontextilygdf=geopandas.read_file('data/nsw-covid19-cases-by-postcode.gpkg')gdf.index=gdf.postcodegdf=gdf.drop('postcode',axis=1)map_chart=gdf.plot_animated(filename='examples/example-geo-point-chart.gif',basemap_format={'source':contextily.providers.Stamen.Terrain})09行政区域动态图importgeopandasimportpandas_aliveimportcontextilygdf=geopandas.read_file('data/italy-covid-region.gpkg')gdf.index=gdf.regiongdf=gdf.drop('region',axis=1)map_chart=gdf.plot_animated(filename='examples/example-geo-polygon-chart.gif',basemap_format={'source':contextily.providers.Stamen.Terrain})10多动图组importpandas_aliveimportpandasaspdcovid_df=pd.read_csv('covid19.csv',index_col=0,parse_dates=[0])animated_line_chart=covid_df.diff().fillna(0).plot_animated(kind='line',period_label=False,add_legend=False)animated_bar_chart=covid_df.plot_animated(n_visible=10)pandas_alive.animate_multiple_plots('examples/example-bar-and-line-chart.gif',[animated_bar_chart,animated_line_chart],enable_progress_bar=True)11城市人口变化importpandas_aliveurban_df=pandas_alive.load_dataset("urban_pop")animated_line_chart=(urban_df.sum(axis=1).pct_change().fillna(method='bfill').mul(100).plot_animated(kind="line",title="人口总变化百分比",period_label=False,add_legend=False))animated_bar_chart=urban_df.plot_animated(n_visible=10,title='Top10PopulousCountries',period_fmt="%Y")pandas_alive.animate_multiple_plots('examples/example-bar-and-line-urban-chart.gif',[animated_bar_chart,animated_line_chart],title='城市人口1977-2018',adjust_subplot_top=0.85,enable_progress_bar=True)12意大利疫情importgeopandasimportpandasaspdimportpandas_aliveimportcontextilyimportmatplotlib.pyplotaspltregion_gdf=geopandas.read_file('data\geo-data\italy-with-regions')region_gdf.NOME_REG=region_gdf.NOME_REG.str.lower().str.title()region_gdf=region_gdf.replace('特伦蒂诺-上阿迪杰/Sudtirol','特伦蒂诺-上阿迪杰')region_gdf=region_gdf.replace("ValleD'Aosta/ValléeD'Aoste\r\nValleD'Aosta/ValleD'Aoste","Valled'Aosta")italy_df=pd.read_csv('data\RegionalData-Sheet1.csv',index_col=0,header=1,parse_dates=[0])italy_df=italy_df[italy_df['Region']!='NA']cases_df=italy_df.iloc[:,:3]cases_df['Date']=cases_df.indexpivoted=cases_df.pivot(values='Newpositives',index='Date',columns='Region')旋转。columns=pivoted.columns.astype(str)pivoted=pivoted.rename(columns={'nan':'UnknownRegion'})cases_gdf=pivoted.Tcases_gdf['geometry']=cases_gdf.index.map(region_gdf.set_index('NOME_REG')['geometry'].to_dict())cases_gdf=cases_gdf[cases_gdf['geometry'].notna()]cases_gdf=geopandas.GeoDataFrame(cases_gdf,crs=region_gdf.crs,geometry=cases_gdf.geometry)gdf=cases_gdfmap_chart=gdf.plot_animated(basemap_format={'source':contextily.providers.Stamen.Terrain},cmap='viridis')cases_df=pivotedfromdatetimeimportdatetimebar_chart=cases_df.sum(axis=1).plot_animated(kind='line',label_events={'SchoolsClose':datetime.strptime("4/03/2020","%d/%m/%Y"),'第一阶段封锁':datetime.strptime("11/03/2020","%d/%m/%Y"),'1M全球案例':datetime.strptime("02/04/2020","%d/%m/%Y"),'100k全球死亡':datetime.strptime("10/04/2020","%d/%m/%Y"),'制造业重新开放':datetime.strptime("26/04/2020","%d/%m/%Y"),'第二阶段封锁':datetime.strptime("4/05/2020","%d/%m/%Y"),},fill_under_line_color="blue",add_legend=False)map_chart.ax.set_title('位置案例')line_chart=(cases_df.sum(axis=1).cumsum().fillna(0).plot_animated(kind="line",period_label=False,title="累计总计lCases",add_legend=False))defcurrent_total(values):total=values.sum()s=f'Total:{int(total)}'返回{'x':.85,'y':.1,'s':s,'ha':'right','size':11}race_chart=cases_df.cumsum().plot_animated(n_visible=5,title="CasesbyRegion",period_label=False,period_summary_func=current_total)importtimetimestr=time.strftime("%d/%m/%Y")plots=[bar_chart,race_chart,map_chart,line_chart]#否则标题重叠,adjust_subplotdoesnothingfrommatplotlibimportrcParamsfrommatplotlib.animationimportFuncAnimationrcParams.update({"figure.autolayout":False})#makesurefiguresare`Figure()`instancesfigs=plt.Figure()gs=figs.add_gridspec(2,3,hspace=0.5)f3_ax1=figs.add_subplot(gs[0,:])f3_ax1.set_title(bar_chart.title)bar_chart.ax=f3_ax1f3_ax2=figs.add_subplot(gs[1,0])f3_ax2.set_title(race_chart.title)race_chart.ax=f3_ax2f3_ax3=figs.add_subplot(gs[1,1])f3_ax3.set_title(map_chart.title)map_chart.ax=f3_ax3f3_ax4=figs.add_subplot(gs[1,2])f3_ax4.set_title(line_chart.title)line_chart.ax=f3_ax4axes=[f3_ax1,f3_ax2,f3_ax3,f3_ax4]timestr=cases_df.index.max().strftime("%d/%m/%Y")figs.suptitle(f"意大利COVID-19确诊病例截至{timestr}")pandas_alive.animate_multiple_plots('examples/italy-covid.gif',plots,figs,enable_progress_bar=True)
