计算机及通信技术的发展极大丰富了多媒体内容的发展,文不如图、图不如动图;BI近些年也逐渐发展,人们已不满足于看静态的图表。短视频的火热也给了动态图更多的发展空间。动态图和交互图表能更生动地表现数据变化及数据联系,传达更多的信息。
Python用Matplotlib就可以实现热门的动态排序图。只需要用好一个函数:FuncAnimation(fig,func,frames)
效果:
Python实现动态排序图
动态排序图也称为Bar Chart Race。它通过一系列的条形图营造出你追我赶的热闹场面,看尽事件的变迁。特别适合的应用场景是各种排名的变化,如城市排名变化、某些主题搜索指数变化、××沉浮史等。把这类图拆解一下看到的是一系列条形图和条柱之间的交换动态效果。
直接用ax.barh(y,width,color)和FuncAnimation(fig,func,frames)来绘制,条形图是从下往上画的,因此正序排序后正好是最高的柱在最上面,不需要额外调转。
具体代码如下。
fig,ax=plt.subplots()def race_bar(i): idx=str(i) wdf=df.sort_values(by=idx) width=list(wdf[idx]) yw=list(wdf['tag']) ax.clear() rs=ax.barh(yw,width,color=wdf['color']) ax.set_xlim(0,wdf[idx].max()+200) ax.set_title('A to G Animation') ax.text(wdf[idx].max()+20,1,'{0}'.format(i),fontsize=30) #绘制当前条形图对应时间周期 ax.tick_params(top=True, bottom=False, labeltop=True, labelbottom=False) c=0 for r in rs: ax.annotate('{0}'.format(yw[c]),xy=(r.get_width()-40,r.get_y()+r.get_height()/2-0.16)) ax.annotate('{0}'.format(width[c]),xy=(r.get_width()+5,r.get_y()+r.get_height()/2-0.16)) c+=1amt=anm.FuncAnimation(fig,race_bar,frames=range(3,13),interval=600)#整体结构和插入排序一脉相承
为了更好地获得具有你追我赶、一同向前的效果,且防止数据变化太过跳脱,防止出现前一秒还是第一、突然掉到最后一名的剧烈变动情况,生成df时,不是全部使用随机函数生成随机数,此处使用的方法是第一次随机生成数据,下一帧的数据在当前数据基础上加[-50,100]的值,本处设定是当前数x[i]是偶数时,x[i+1]=x[i]+randint(20,200),奇数时x[i+1]=x+randint(-30,100)。生成数据集的代码如下:
df=pd.DataFrame({'tag':list('ABCDEFG'),'color':['#1EAFAE', '#A3FFFF', '#69FFFF', '#BA5C25', '#FFA069', '#9E5B3A', '#D7CE88']})df['3']=df['tag'].apply(lambda x:random.randint(50,600)) #初始列for i in range(4,13): idx=str(i-1) #偶数增幅,奇数在原来基础上[-30,50+5*i]变动 df['{0}'.format(i)]=df[idx].apply(lambda x:x+random.randint(20,100+i*6) if x%2==0 else x+random.randint(-30,50+i*5))
网上可以找到各种年度季度排名的公开数据集,一些讲动态排序图的教程也给出了数据集。