数据可视化:matplotlib animation 绘制动画

1. 用 matplotlib animation 绘制动画

ref: https://matplotlib.org/3.1.1/api/animation_api.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import matplotlib.animation as animation
import matplotlib.pyplot as plt
import numpy as np

# 数据集:X轴数据固定;Y轴的数据更新
X = np.arange(0, 10, 0.01) # X shape: (N,)
Ys = [np.sin(X + k / 10) for k in range(100)] # Ys shape: (k, N)


def my_ani(x, ys):
fig, ax = plt.subplots()
ax.set_title('y = sin(x + k/10)')
ax.set_xlim([0, 10]), ax.set_xlabel('X')
ax.set_ylim([-1, 1]), ax.set_ylabel('Y')

line, = ax.plot(x, ys[0])
ano = plt.annotate('k: 0', (1, 1))

def animate(i):
line.set_ydata(ys[i]) # update the y data.
ano.set_text('k: %d' % i) # update the annotate.
return line,

# animation.FuncAnimation 参数说明
# fig: figure 对象
# func: 动画函数,自定义函数 animate
# frames: 总帧数
# interval: 间隔时间,ms
ani = animation.FuncAnimation(fig, animate, frames=30, interval=50)
# ani.save('sin_ani.mp4', dpi=300, writer='ffmpeg') # scoop install ffmpeg
# ani.save('sin_ani.gif', dpi=300, writer='pillow') # pip install pillow
plt.show()


my_ani(X, Ys)

2. 也用 plot 的方法显示动画,保存不太方便

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import matplotlib.pyplot as plt
import numpy as np

# 数据集:X轴数据固定;Y轴的数据更新
X = np.arange(0, 10, 0.01) # X shape: (N,)
Ys = [np.sin(X + k / 10) for k in range(100)] # Ys shape: (k, N)

plt.ion()
plt.show()
for i in range(len(Ys)):
plt.cla()

plt.title('y = sin(x + k/10)')
plt.xlim(0, 10)
plt.ylim(-1, 1)

plt.plot(X, Ys[i], 'r', alpha=0.7, linewidth=0.7)
plt.text(1, 1, 'k: %d' % i)

plt.draw()
plt.pause(0.05) # 间隔时间,s


title: 数据可视化:matplotlib animation 绘制动画(2)
date: 2020-10-08 16:42:45
tags: matplotlib
categories: sci

ref: https://matplotlib.org/3.1.1/api/animation_api.html

matplotlib animation 动画教程都是针对曲线类型的,

对于包含子图、或含有类似直方图等图形的情况,就不适用了。

下面尝试实现包含多个子图,同时有直方图的动画效果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import matplotlib.animation as animation
import matplotlib.pyplot as plt
import numpy as np


X = np.arange(0, 10, 0.01) # X shape: (N,)
Ys = [np.sin(X + k/10.0) for k in range(100)] # Ys shape: (k, N)

fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(8, 4))

def animate(i):
axes[0].cla()
axes[0].plot(X, Ys[i])
axes[0].set_title(f'y = sin(x + {i}/10)')

axes[1].cla()
axes[1].hist(Ys[i], bins=50, orientation='horizontal')

ani = animation.FuncAnimation(fig, animate, frames=50, interval=50)
ani.save('matplotlib-animation-hist.gif')
plt.show()

ani.gif

ok!



title: 数据可视化:matplotlib animation 绘制 Lorenz 随机函数三维动画
date: 2022-11-08 19:42:49
tags: matplotlib
categories: sci

1. 创建 Lorenz 函数,生成随机数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint
from mpl_toolkits.mplot3d.axes3d import Axes3D
import matplotlib.animation as animation


# === define the lorenz system ===
# x, y, and z make up the system state
# t is time,
# sigma, rho, beta are the system parameters
def lorenz_system(current_state, t):
x, y, z = current_state

dx_dt = sigma * (y - x)
dy_dt = x * (rho - z) - y
dz_dt = x * y - beta * z

return [dx_dt, dy_dt, dz_dt]


# define the initial system state, system parameters
initial_state = [-0.1, 0.01, 0.08]
sigma = 10.
rho = 50.
beta = 3.

start_time = 0
end_time = 10
num_points = 100 * (end_time - start_time)
time_points = np.linspace(start_time, end_time, num_points)

# === generate datas =========
xyz = odeint(lorenz_system, initial_state, time_points)
data = np.array(xyz).T * 0.01 # scale down to 0.01
print(data)

print(data[0])

2. 绘制二维图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# === 2d plot lorenz ====
def lorenz_2d_plot(data):
fig, axs = plt.subplots(3, 1, sharex='all')

xxx = range(len(data[2]))
axs[2].set_xlim(0, 1000)
axs[2].set_xlabel('time')

axs[0].plot(xxx, data[0], color='r', alpha=0.7, linewidth=0.7)
axs[0].set_ylabel('x')

axs[1].plot(xxx, data[1], color='g', alpha=0.7, linewidth=0.7)
axs[1].set_ylabel('y')

axs[2].plot(xxx, data[2], color='b', alpha=0.7, linewidth=0.7)
axs[2].set_ylabel('z')

fig.tight_layout()
fig.savefig('matplotlib_lorenz-2d.png', dpi=300, bbox_inches='tight')
plt.show()

lorenz_2d_plot(data)

lorenz-2d

3. 绘制三维图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# === 3d plot lorenz ====
def lorenz_3d_plot(data):
fig = plt.figure()
ax = Axes3D(fig)

ax.xaxis.set_pane_color((1, 1, 1, 1))
ax.yaxis.set_pane_color((1, 1, 1, 1))
ax.zaxis.set_pane_color((1, 1, 1, 1))

ax.set_title('Lorenz')

ax.set_xlim3d([-0.5, 0.5]), ax.set_xlabel('X')
ax.set_ylim3d([-0.5, 0.5]), ax.set_ylabel('Y')
ax.set_zlim3d([0.0, 1.0]), ax.set_zlabel('Z')

# ax.view_init(30, -60) # default view

ax.plot(data[0], data[1], data[2], color='r', alpha=0.7, linewidth=0.75)
ax.set_title('Lorenz_3d')

fig.savefig('matplotlib_lorenz-3d.png', dpi=300, bbox_inches='tight')
plt.show()


lorenz_3d_plot(data)

lorenz-3d

4. 绘制三维动画

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# === 3d plot lorenz ====
def lorenz_3d_plot_ani(data):
fig = plt.figure()
ax = Axes3D(fig)

ax.xaxis.set_pane_color((1, 1, 1, 1))
ax.yaxis.set_pane_color((1, 1, 1, 1))
ax.zaxis.set_pane_color((1, 1, 1, 1))

ax.set_title('Lorenz_3d_animation')

ax.set_xlim3d([-0.5, 0.5]), ax.set_xlabel('X')
ax.set_ylim3d([-0.5, 0.5]), ax.set_ylabel('Y')
ax.set_zlim3d([0.0, 1.0]), ax.set_zlabel('Z')

# ax.view_init(30, -60) # default view

# === Animation Functions ===
def update_line(num, data, line):
line.set_data(data[0:2, :num])
line.set_3d_properties(data[2, :num])
return line

# initial with the start point
line, = ax.plot(data[0][0:1], data[1][0:1], data[2][0:1], color='r', alpha=0.7, linewidth=0.75)
ani = animation.FuncAnimation(fig, update_line, 1000, fargs=(data, line), interval=1)

# ani.save('matplotlib_lorenz_3d_ani.mp4', fps=24, dpi=300)
ani.save('03_lorenz_3d_ani.gif')
plt.show()


lorenz_3d_plot_ani(data)

lorenz-3d-animation
ok!