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

การใช้ Matplotlib Pyplot โดยไม่ต้องมี Display (Headless Mode)

ในสภาพแวดล้อมที่ไม่มีหน้าจอ (Headless Server, Docker, CI/CD, SSH ไม่มี X11 Forwarding) ใช้ Matplotlib ได้โดยตั้งค่า Backend เป็น Agg (Non-interactive Backend) และบันทึกไฟล์ด้วย savefig()

วิธีการตั้งค่า Backend

วิธีที่ 1: ตั้งค่าก่อน Import pyplot (แนะนำ)

import matplotlib
matplotlib.use('Agg')  # ต้องเรียกก่อน import pyplot!

import matplotlib.pyplot as plt
import numpy as np

# สร้างกราฟ
x = np.linspace(-np.pi, np.pi, 200)
y = np.sin(x) * x

plt.figure(figsize=(10, 6))
plt.plot(x, y, 'r-', linewidth=2, label='y = x·sin(x)')
plt.xlabel('x')
plt.ylabel('y')
plt.title('Plot without Display (Headless)')
plt.legend()
plt.grid(True, alpha=0.3)

# บันทึกไฟล์แทนการแสดง
plt.savefig("plot_output.png", dpi=300, bbox_inches='tight')
print("Saved plot_output.png")

วิธีที่ 2: ตั้งค่าผ่าน Environment Variable

# ใน Terminal/Shell ก่อนรัน Python
export MPLBACKEND=Agg

# หรือใน Python (ต้องทำก่อน import matplotlib)
import os
os.environ['MPLBACKEND'] = 'Agg'
import matplotlib.pyplot as plt

Backend อื่นๆ ที่ใช้ได้ใน Headless

Backendคำอธิบายรองรับ
AggAnti-Grain Geometry - Raster (PNG, JPG, TIFF)ทุก Platform, ไม่ต้องมี Display
CairoVector/Raster (PDF, SVG, PNG)ต้องติดตั้ง pycairo
SVGScalable Vector GraphicsVector Output เท่านั้น
PDFPortable Document FormatVector Output เท่านั้น
PSPostScriptVector Output เท่านั้น

ตัวอย่างบันทึกหลาย Format พร้อมกัน

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y = np.sin(x)

fig, ax = plt.subplots(figsize=(8, 5))
ax.plot(x, y, 'b-', linewidth=2)
ax.set_title('Headless Plotting Demo')
ax.grid(True, alpha=0.3)

# บันทึกหลาย Format
formats = ['png', 'pdf', 'svg', 'jpg']
for fmt in formats:
    filename = f"plot_output.{fmt}"
    dpi = 300 if fmt in ['png', 'jpg'] else None
    fig.savefig(filename, dpi=dpi, bbox_inches='tight', format=fmt)
    print(f"Saved: {filename}")

plt.close(fig)  # ปิด Figure เพื่อปล่อย Memory

⚠️ ข้อควรระวัง

  • matplotlib.use() ต้องเรียกก่อน import pyplot - หากเรียกหลัง import จะไม่มีผล
  • ไม่สามารถใช้ plt.show() ได้ใน Headless Mode (จะ Error)
  • ใช้ plt.close() หรือ plt.close(fig) หลัง savefig เพื่อป้องกัน Memory Leak
  • สำหรับ Animation ใช้ ani.save() กับ Writer (ffmpeg, pillow)

การตรวจสอบ Backend ปัจจุบัน

import matplotlib
print(f"Current backend: {matplotlib.get_backend()}")
print(f"Available backends: {matplotlib.rcsetup.all_backends}")