0


数据可视化之美-动态图绘制(以Python为工具)

可视化是数据描述的图形表示,旨在一目了然地揭示数据中的复杂信息。数据可视化在讲故事中的重要性不言而喻。

在可视化当中,我们常用的方式有点、线、面,或者说这几者组合。部分绘图结果可见下面链接:
Python 画点线图、Python 画柱状图、Python 画柱状图(总结)

在可视化中最为复杂的要数动态图的绘制,动态图能表达出更多的信息(如时间维),包含二维(x,time)、三维(x,y,time)、四维(x,y,z,time)数据中的信息。

同时,动画可以有趣地展示某种现象。相比于静态图表,人们更容易被动画和交互式的图表所吸引。

由于博主本身专业的限制,只重点关注了地学的相关文献、代码,其他专业也可借鉴本文中的相关动态图制作方法。

动图可视化作品举例

在日常学习生活中,可以发现有非常多精彩的动态图可视化作品,这些动态图为工作的展现、数据的说明都起到锦上添花的效果。见下:

Example1:


该图基于MITgcm模式输出数据绘制

Example2:

在这里插入图片描述

该动图的左边反映的是缺氧区域随时间的变化,右边反映的是空间的变化

Example3:

在这里插入图片描述
新冠肺炎初期死亡人数的变化
该项目链接:GitHub bar_chart_race

这种动图也可用pandas_alive绘制,见下
在这里插入图片描述

Example4:

在这里插入图片描述

This animation shows the transport of air parcels continuously emitted from four point sources inside the canopy during a period of 2.5 hours for the simulation
该动图来源于SCI论文《地形对茂密森林内排放的气体在冠层内运输的影响》 Effects of topography on in-canopy transport of gases emitted within dense forests

接下来重点介绍GIF图的生成,需要注意的是,GIF的生成一般是需要安装imagemagick(图片处理工具),用pillow也行(但相对较有瑕疵)。

举例说明:基于matplotlib中的anamation

Test1:移动的sin曲线(通过更新数据方式)

import numpy as np
from matplotlib import pyplot as plt
from matplotlib.animation import FuncAnimation
plt.style.use('seaborn-pastel')
fig = plt.figure()
ax = plt.axes(xlim=(0,4), ylim=(-2,2))# 创建了一个图像窗口,设置了坐标轴的范围
line,= ax.plot([],[], lw=3)# 建了一个空的line对象,之后将通过更新line的数据,实现动画效果。definit():# 初始化函数init,这个函数其实什么也没干,给了line对象空的数据
    line.set_data([],[])return line,defanimate(i):# 动画函数animate,入参i是动画帧序号,根据i计算新的sin曲线数据,更新到line对象。
    x = np.linspace(0,4,1000)
    y = np.sin(2* np.pi *(x -0.01* i))
    line.set_data(x, y)return line,
anim = FuncAnimation(fig, animate, init_func=init,
                               frames=100, interval=20, blit=True)# 利用之前所说的FuncAnimation()函数创建了对象anim,初始化时传入了figure对象,init()函数和animate()函数,以及帧数和更新时间。# 循环一个周期,也就是100帧,就可以实现前后相接的循环效果了
anim.save('sine_wave_pillow.gif', writer='pillow')# writer 根据实际安装可选择

在这里插入图片描述
(备注: 这里保存GIF参数选用pillow,坐标轴显示不清晰,可选用imagemagick)

Test2:示波器上的李萨如图形(通过更新数据方式)

李萨如图形见下:
在这里插入图片描述

import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
plt.style.use('dark_background')
fig = plt.figure()
ax = plt.axes(xlim=(-50,50), ylim=(-50,50))
line,= ax.plot([],[], lw=2)# initialization functiondefinit():# creating an empty plot/frame
    line.set_data([],[])return line,# lists to store x and y axis points
xdata, ydata =[],[]#simulate ghost effect of oscilloscopedefghostImage(x,y):
    xdata.append(x)
    ydata.append(y)iflen(xdata)>60:del xdata[0]del ydata[0]return xdata,ydata
# animation functiondefanimate(i):# t is a parameter
    t = i/100.0# x, y values to be plotted
    x =40*np.sin(2*2*np.pi*(t+0.3))
    y =40*np.cos(3*2*np.pi*t)# appending new points to x, y axes points list
   
    line.set_data(ghostImage(x,y))return line,# setting a title for the plot
plt.title('Creating a Lissajous figure with matplotlib')# hiding the axis details
plt.axis('off')# call the animator  
anim = animation.FuncAnimation(fig, animate, init_func=init,
                            frames=400, interval=20, blit=True)# save the animation as gif file
anim.save('figure.gif',writer='pillow')

在这里插入图片描述

Test3:二维动画绘制(通过叠加图像形式)

预先计算的【图像列表】的动画图像

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

fig = plt.figure()deff(x, y):return np.sin(x)+ np.cos(y)

x = np.linspace(0,2* np.pi,120)
y = np.linspace(0,2* np.pi,100).reshape(-1,1)# ims is a list of lists, each row is a list of artists to draw in the# current frame; here we are just animating one artist, the image, in# each frame
ims =[]for i inrange(60):
    x += np.pi /15.
    y += np.pi /20.
    im = plt.imshow(f(x, y), animated=True)
    ims.append([im])

ani = animation.ArtistAnimation(fig, ims, interval=50, blit=True,
                                repeat_delay=1000)

ani.save('test_2d.gif', writer='pillow')

在这里插入图片描述

Test4:二维动画绘制(通过替换数据的形式)

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation   #导入负责绘制动画的接口

fig, ax = plt.subplots()
x = np.linspace(-10*np.pi,10*np.pi,300)
y = np.linspace(-10*np.pi,10*np.pi,300)
X,Y = np.meshgrid(x,y)
img = plt.imshow(np.sin(X),cmap='ocean')
nums =1000#需要的帧数definit():
    ax.set_xlim(0,100)
    ax.set_ylim(0,100)return img

defupdate(step):
    z = np.cos((0.5*X*(np.cos(0.01*step)+0.1))+step)+np.sin(0.5*(Y*(np.sin(0.01*step)+0.1))+step)# z = np.cos((X*(np.cos(0.01*step)+0.2))+step)+np.sin((Y*(np.sin(0.01*step)+0.2))+step)
    img.set_data(z)#设置新的 x,yreturn img

ani = FuncAnimation(fig, update, frames=nums,#nums输入到frames后会使用range(nums)得到一系列step输入到update中去
                    init_func=init,interval=100)# plt.show()
ani.save('example4.gif', writer='pillow')

在这里插入图片描述

备注:以上皆是利用matplotlib中的anamation绘制,还可以利用上文提到的pandas_alive进行绘制

举例说明:基于pandas_alive

Test5:x轴显示固定

import pandas as pd
import pandas_alive

elec_df = pd.read_csv("data/Aus_Elec_Gen_1980_2018.csv",index_col=0,parse_dates=[0],thousands=',')

elec_df.fillna(0).plot_animated('./fixed-example.gif',period_fmt="%Y",title='Australian Electricity Generation Sources 1980-2018',fixed_max=True,fixed_order=True)

在这里插入图片描述

Test6:多子图动态图

import pandas as pd
import pandas_alive

covid_df = pd.read_csv('data/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('./example-bar-and-line-chart.gif',[animated_bar_chart, animated_line_chart], enable_progress_bar=True)

在这里插入图片描述

Reference:

[1] 数据可视化: matplotlib绘制动态图及3维动画

[2] 【matplotlib】绘制动态图像

[3] GitHub pandas_alive


本文转载自: https://blog.csdn.net/weixin_45492560/article/details/124541495
版权归原作者 CaiBirdHu 所有, 如有侵权,请联系我们删除。

“数据可视化之美-动态图绘制(以Python为工具)”的评论:

还没有评论