ในสภาพแวดล้อมที่ไม่มีหน้าจอ (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 | คำอธิบาย | รองรับ |
|---|---|---|
| Agg | Anti-Grain Geometry - Raster (PNG, JPG, TIFF) | ทุก Platform, ไม่ต้องมี Display |
| Cairo | Vector/Raster (PDF, SVG, PNG) | ต้องติดตั้ง pycairo |
| SVG | Scalable Vector Graphics | Vector Output เท่านั้น |
| Portable Document Format | Vector Output เท่านั้น | |
| PS | PostScript | Vector 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}")