การสร้างกราฟที่มีข้อมูลภาษาไทยด้วย Matplotlib
ผมใช้ Python Notebook ในการแสดงและวิเคราะห์ข้อมูลเบื้องต้นอย่างเป็นประจำ จนกระทั้งวันนี้ต้องการสร้างกราฟฮิสโตแกรม (Histogram) เพื่อหาความถี่ของคำภาษาไทย และพบว่าการสร้างกราฟด้วย Matplotlib กับข้อมูลภาษาไทยนั้นมีปัญหาการแสดงผลข้อความภาษาไทยไม่ถูกต้อง 1 โดยแสดงอักษรไทยเป็นรูปกล่องตามภาพด้านล่าง จึงลองหาวิธีแก้ไขปัญหานี้
ตั้งสมมติฐาน
- ผมคิดว่าค่าเริ่มต้นของ Mathplotlib ไม่มีแบบอักษร (font) ภาษาไทย สังเกตจาก error message ด้านล่าง
UserWarning: Glyph 3586 (\N{THAI CHARACTER KHO KHAI}) missing from font(s) DejaVu Sans.fig.canvas.print_figure(bytes_io, **kw)
ทดสอบสมมติฐาน
- ลองหาวิธีการเพิ่ม font ภาษาไทยเข้าไปในระบบ
1. ดาวน์โหลด font ภาษาไทย ผมเลือกใช้ “Sarabun” จากที่นี่ 2
wget https://go.wiphoo.dev/PKcHva -O Sarabun-Regular.ttf
2. หาคำสั่งในการเลือกใช้ font ให้กับ Matplotlib
2.1 คำสั่งสำหรับการโหลด font Sarabun ให้กับ Matplotlib รู้จักและสามารใช้งานได้จากคำสั่งด้านล่าง
import matplotlib.font_manager as fm
font_path = "./Sarabun-Regular.ttf"
fm.fontManager.addfont(font_path)
2.2 คำสั่งในสำหรับการใช้การวาดกราฟใช้ font “Sarabun”
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = 'Sarabun'
3. ลองสร้างกราฟอีกครั้ง พบว่าการแสดงข้อความภาษาไทยถูกต้องแล้ว ดังรูปที่ 2
TLDR;
วิธีการด้านบนเป็นวิธีการเบื้องต้นที่ทำให้ Matplotlib แสดงอักษรภาษาแต่ไม่สามารถแสดงอักษรตัวหนา หรือตัวเอียงได้ เพราะเลือกที่จะเพิ่ม font ธรรมดาให้ Matplotlib ใช้ได้ภาษาไทยได้เท่านั้น
ขั้นตอนต่อไปนี้จะทำให้ Matplotlib สามารถแสดงอักษรตัวหนา ตัวเอียงได้
4. ดาวน์โหลดและติดตั้ง font ทั้งหมดเพื่อให้สามารถใช้งานตัวอักษรตัวหนาและตัวเอียงได้
เปลี่ยนจาก font Sarabun เป็น font Noto Sans เนื่องจาก Sarabun มีปัญหากับการแสดงอักษรตัวหนาและตัวเอียงกับ Matplotlib
หมายเหตุ: Noto Sans แยกไฟล์ font ออกเป็นของภาษาไทยและภาษาอังกฤษ ดังนั้นจึงต้องดาวน์โหลดและติดตั้งทั้งสอง font ตามขั้นตอนด้านล่าง
4.1 ดาวน์โหลด font ทั้งหมดใน GIT repository จากที่นี่ 3 4
wget https://go.wiphoo.dev/f6OtGJ -O 'NotoSans[wdth,wght].ttf'
wget https://go.wiphoo.dev/vHsbYE -O 'NotoSans-Italic[wdth,wght].ttf'
wget https://go.wiphoo.dev/D8Xrn2 -O 'NotoSansThai[wdth,wght].ttf'
4.2 ติดตั้ง font ทั้งหมดลงใน font directory ตามระบบปฏิบัติการของเครื่อง
# Ubuntu
mkdir -p ~/.fonts
cp ./NotoSans*.ttf ~/.fonts/
# MacOS
cp ./NotoSans*.ttf ~/Library/Fonts/
4.3 โหลด font “Noto Sans” ทั้งหมด ให้กับ Matplotlib รู้จักและสามารใช้งานได้จากคำสั่งด้านล่าง
import matplotlib.font_manager as fm
# Ubuntu
font_dir = '~/.fonts'
# MacOS
font_dir = '~/Library/Fonts'
font_files = fm.findSystemFonts(fontpaths=[font_dir])
for font_file in font_files:
fm.fontManager.addfont(font_file)
4.4 กำหนด font “Noto Sans” เป็นค่าเริ่มต้นสำหรับ Matplotlib
สามารถเพิ่มได้หลาย font ตามตัวอย่างด้านล่างเพิ่มทั้งภาษาไทยและภาษาอังกฤษ
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = ['Noto Sans Thai', 'Noto Sans']