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

วิธีสร้าง Animation ของ Colorbar ใน Matplotlib

การทำ Animation ของ Colorbar ใน Matplotlib ต้องอัปเดตทั้ง Image Data (imshow) และ Colorbar ให้ซิงค์กันในแต่ละเฟรม โดยใช้ FuncAnimation และสร้าง Colorbar ใหม่หรืออัปเดต Colormap ทุกเฟรม

หลักการ

  1. สร้าง Figure และ Axes หลัก
  2. ใช้ make_axes_locatable สร้าง Axes สำหรับ Colorbar (cax)
  3. สร้าง imshow และ colorbar เริ่มต้น
  4. ใน animate(): อัปเดตข้อมูล im.set_data(), im.set_cmap(), แล้วสร้าง Colorbar ใหม่ใน cax

ตัวอย่างโค้ด

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation
from mpl_toolkits.axes_grid1 import make_axes_locatable

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

fig, ax = plt.subplots()

# สร้าง Axes สำหรับ Colorbar (ขวา 5% กว้าง 5%)
divider = make_axes_locatable(ax)
cax = divider.append_axes('right', size='5%', pad='5%')

# ข้อมูลเริ่มต้น
data = np.random.rand(10, 10)
im = ax.imshow(data, cmap='viridis', animated=True)

# สร้าง Colorbar เริ่มต้น
cbar = fig.colorbar(im, cax=cax)
cbar.set_label('Intensity', fontsize=12)

# Title แบบไดนามิก
title = ax.set_title('Frame 0', fontsize=14, pad=15)

# รายการ Colormaps สำหรับสลับ
colormaps = ['viridis', 'plasma', 'inferno', 'magma', 'cividis', 'hot', 'coolwarm', 'turbo']

def animate(frame):
    # สร้างข้อมูลใหม่
    new_data = np.random.rand(10, 10)
    
    # สลับ Colormap
    cmap_name = colormaps[frame % len(colormaps)]
    
    # อัปเดต Image
    im.set_data(new_data)
    im.set_cmap(cmap_name)
    im.set_clim(0, 1)  # Fix color range
    
    # สร้าง Colorbar ใหม่ (ต้อง Clear cax ก่อน)
    cax.cla()
    cbar = fig.colorbar(im, cax=cax)
    cbar.set_label('Intensity', fontsize=12)
    
    # อัปเดต Title
    title.set_text(f'Frame {frame} | Colormap: {cmap_name}')
    
    return im, title

ani = animation.FuncAnimation(
    fig, animate,
    frames=50,
    interval=300,      # 300 ms = ~3.3 FPS
    blit=False,        # Colorbar ต้อง blit=False (ซับซ้อน)
    repeat=True
)

plt.show()

ผลลัพธ์

Animation แสดง Heatmap ที่ข้อมูลและ Colormap สลับเปลี่ยนไปเรื่อยๆ Colorbar ด้านขวาอัปเดตตาม Colormap ใหม่ทุกเฟรม

เทคนิคสำคัญ

  • cax.cla(): Clear Colorbar Axes ก่อนสร้างใหม่ (จำเป็น)
  • make_axes_locatable: สร้าง cax แยกต่างหาก ไม่ให้ Colorbar บีบ Axes หลัก
  • blit=False: การอัปเดต Colorbar ซับซ้อน ไม่รองรับ Blitting ได้ดี
  • im.set_clim(): คง Color Range ไว้ เพื่อเปรียบเทียบระหว่างเฟรมได้

วิธีอัปเดต Colorbar เดิม (ไม่สร้างใหม่) - เร็วกว่า

# สร้าง Colorbar ครั้งเดียว
cbar = fig.colorbar(im, cax=cax)

def animate(frame):
    new_data = np.random.rand(10, 10)
    im.set_data(new_data)
    im.set_cmap(colormaps[frame % len(colormaps)])
    
    # อัปเดต Colorbar เดิม (ไม่ต้อง cla + สร้างใหม่)
    cbar.update_normal(im)  # หรือ cbar.update_bruteforce(im)
    
    title.set_text(f'Frame {frame}')
    return im, title

# ต้องใช้ blit=False ยังคง
ani = animation.FuncAnimation(fig, animate, frames=50, interval=200, blit=False)

คำแนะนำ

  • ใช้ cbar.update_normal(im) เร็วกว่าสร้าง Colorbar ใหม่
  • กำหนด vmin, vmax คงที่ เพื่อให้สีสอดคล้องระหว่างเฟรม
  • สำหรับ Export: ani.save('colorbar_anim.gif', writer='pillow', fps=5)