熟悉python数据分析的朋友一定对matplotlib库不陌生,这是做数据可视化最常用的包之一。虽然我们经常使用mattplotlib做一些静态的图表,比如折线图,柱状图,饼图等等,但是某些时候,我们需要让我们的图表动起来。最近因为工作上的需要,我尝试构建了动态柱状图,来描述各个数据在时间维度上的变化情况。主要用到的就是matplotlib中的animation模块。下面我就来介绍一下我的基本需求以及如何用该模块来实现需求。
给定4个基本渠道,我希望通过柱状图的形式来描述各个渠道指标随着时间的变化。比如初始值列表为[3000,8000,10000,6000],在第一个时刻变为[2800,8000,10000,6000], 即第一个渠道下降200,在第二个时刻变为[2800,8000,9800,6000],即第三个渠道下降200。在后续的各个时刻,各个渠道的指标会不断变化。那么如何通过animation来实现它呢?话不多说,直接上代码。
import matplotlib.pyplot as plt
import matplotlib.animation as animation
fig,ax=plt.subplots(figsize=(10,6))
def init(): #初始plot`
x=['a','b','c','d']
y=[3000,8000,10000,6000]
ax.set_ylim(0,12000)
init_plot=ax.bar(x,y,color=['red','blue','orange','green'],width=0.5)
for i,j in zip(x,y):
ax.text(i,j+0.05,'%.0f' % j,ha='center',va='bottom',fontsize=10)
ax.set_title(f'Remain Amount for {len(x)} Channels After 0 Coming Customers')
def animate(i): # 更新函数
x=['a','b','c','d']
# ys用于存储随着时间变化呈现值的变化情况
ys=[[2800,8000,10000,6000],
[2800,8000,9800,6000],
[2800,7800,9800,6000],
[2800,7800,9800,5800],
[2600,7800,9800,5800],
[2600,7800,9600,5800],
[2600,7800,9600,5600],
[2600,7600,9600,5600],
[2400,7600,9600,5600],
[2200,7600,9600,5600]]
ax.cla() # 清除之前的内容
ax.set_ylim(0,12000) #保证y轴不变
update_plot=ax.bar(x,ys[i],color=['red','blue','orange','green'],width=0.5)
idx=ys.index(ys[i])
for i,j in zip(x,ys[i]):
ax.text(i,j+0.05,'%.0f' % j,ha='center',va='bottom',fontsize=10)
ax.set_title(f'Remain Amount for {len(x)} Channels After {str(idx+1)} Coming Customers')
ani=animation.FuncAnimation(fig,animate,range(10),init_func=init,interval=500,repeat=False)
plt.show()
其中最核心的就是如下代码
ani=animation.FuncAnimation(fig,animate,range(10),init_func=init,interval=500,repeat=False)
其中的基本参数包括1.基于哪个窗口绘图(fig), 2.更新函数(animate) 3.更新的帧数(次数,这里我只有10组需要更新的数据) 4.初始绘图函数(init) 5.更新速度(interval, 越大停顿越久) 6.是否重复(repeat,即是否在一轮更新完成后再次重新更新)。当然还有其他可传入的参数,详情参考官网。
顺便说一下,如果需要在jupyter notebook中实现动态效果,需要添加如下语句
%matplotlib notebook
以上是代码运行完后的效果图,因为时间原因就不制作动图了,大家可以自行运行代码来感受动态变化的情形。如有任何疑问,欢迎留言。谢谢