Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

วิธีสร้าง Animation จากลำดับกราฟ Matplotlib แบบ Time-Ordered

การสร้าง Animation จากลำดับกราฟ (Sequence of Plots) ที่เรียงตามเวลา ใน Matplotlib สามารถทำได้โดยใช้ FuncAnimation ร่วมกับการอัปเดตข้อมูลบน Axes เดียวกัน

หลักการทำงาน

  1. สร้าง Figure และ Axes
  2. เตรียมข้อมูลหลายเฟรม (หรือสร้างข้อมูลสุ่มในฟังก์ชัน animate)
  3. สร้าง Artist เริ่มต้น (เช่น imshow, plot, contourf)
  4. ใน animate(frame) อัปเดตข้อมูลของ Artist ด้วย set_data(), set_array() ฯลฯ
  5. ใช้ FuncAnimation วนลูปเรียก animate

ตัวอย่าง: Animation ของ Random Heatmap (imshow)

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

plt.rcParams["figure.figsize"] = [8, 6]
plt.rcParams["figure.autolayout"] = True

fig, ax = plt.subplots()

# ข้อมูลเริ่มต้น
data = np.random.randn(10, 10)
im = ax.imshow(data, cmap='plasma', vmin=-3, vmax=3, animated=True)
plt.colorbar(im, ax=ax, label='Value')

# Title แบบไดนามิก
title = ax.set_title("Frame 0")

def animate(frame):
    # สร้างข้อมูลใหม่ (ในทางปฏิบัติอาจโหลดจากไฟล์/Stream)
    new_data = np.random.randn(10, 10)
    
    # อัปเดตข้อมูลของ imshow (เร็วกว่าสร้างใหม่)
    im.set_array(new_data)
    
    # อัปเดต Title
    title.set_text(f"Frame {frame}")
    
    return im, title

ani = animation.FuncAnimation(
    fig, animate,
    frames=100,
    interval=200,      # 200 ms = 5 FPS
    blit=True,         # ใช้ blitting เพื่อประสิทธิภาพ
    repeat=True
)

plt.show()

ตัวอย่าง: Animation ของ Line Plot แบบ Streaming

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

plt.rcParams["figure.figsize"] = [10, 5]
plt.rcParams["figure.autolayout"] = True

fig, ax = plt.subplots()
x = np.linspace(0, 10, 200)
line, = ax.plot([], [], 'b-', linewidth=2)
ax.set_xlim(0, 10)
ax.set_ylim(-2, 2)
ax.grid(True, alpha=0.3)

# Buffer เก็บข้อมูล (Simulate Streaming)
buffer_size = 200
y_buffer = np.zeros(buffer_size)

def animate(frame):
    global y_buffer
    
    # Shift buffer และเพิ่มค่าใหม่ (Simulate real-time data)
    y_buffer = np.roll(y_buffer, -1)
    y_buffer[-1] = np.sin(frame * 0.1) + 0.5 * np.random.randn()
    
    line.set_ydata(y_buffer)
    ax.set_title(f"Real-time Streaming Data - Frame {frame}")
    
    return line,

ani = animation.FuncAnimation(fig, animate, frames=200, interval=50, blit=True)
plt.show()

ผลลัพธ์

Animation แสดงข้อมูลเปลี่ยนแปลงตามเวลา แบบ Real-time Streaming หรือ Time-series Visualization

เคล็ดลับประสิทธิภาพ

  • ใช้ blit=True และ return tuple ของ Artist ที่เปลี่ยนแปลงเท่านั้น
  • ใช้ set_data(), set_array(), set_ydata() แทนการสร้าง Plot ใหม่ทุกเฟรม
  • กำหนด animated=True ให้ Artist ที่จะอัปเดต
  • สำหรับการ Export ใช้ ani.save('animation.mp4', writer='ffmpeg') หรือ writer='pillow' สำหรับ GIF