สิ่งที่เรียกว่ากราฟนั้นไม่ควรจะมีแค่เส้นหรือตัวเลขเท่านั้น เพื่อที่จะให้มองแล้วเข้าใจอะไรมากขึ้นจำเป็นต้องมีข้อความด้วย ดังนั้นเราจะมาพูดถึงการใส่ข้อความลงกราฟ
การใส่ชื่อหัวข้อและชื่อแกน ก่อนอื่นมาเริ่มจากการใส่ข้อความที่หัวข้อและชื่อแกน x และ y ซึ่งสามารถทำได้ง่ายๆด้วยการเพิ่มคีย์เวิร์ดในฟังก์ชัน plt.axes นั่นคือ title, xlabel และ ylabel หรือเพิ่มทีหลังโดยใช้ฟังก์ชันหรือเมธอดได้
คีย์เวิร์ด |
ฟังก์ชัน |
เมธอด |
ความหมาย |
title |
plt.title |
set_title |
หัวข้อกราฟ |
xlabel |
plt.xlabel |
set_xlabel |
ชื่อแกน x |
ylabel |
plt.ylabel |
set_ylabel |
ชื่อแกน y |
ตัวอย่าง
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0,150,1500)
y = np.sin(x)+np.sin(x*1.1)
plt.axes(title='y = sin(x) + sin(1.1x)',xlabel='x',ylabel='y')
plt.plot(x,y)
plt.show()
จะเห็นว่ามีตัวหนังสือโผล่มา ๓ จุดคือแกน x แกน y และด้านบน
อีกวิธีหนึ่งในการใส่ก็คือใช้เมธอดที่มีชื่อขึ้นต้นด้วย set_ ดังนี้
ax = plt.gca()
ax.set_title('y = sin(x) + sin(1.1x)')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.plot(x,y)
plt.show()
หรือย่อกว่านั้นอาจเขียนโดยใช้ฟังก์ชัน plt.title, plt.xlabel และ plt.ylabel โดยไม่จำเป็นต้องใช้ plt.gca หรือ plt.axes เลย
plt.title('y = sin(x) + sin(1.1x)')
plt.xlabel('x')
plt.ylabel('y')
plt.plot(x,y)
plt.show()
การปรับขนาดอักษร ถ้ารู้สึกว่าตัวอักษรเล็กไปก็สามารถปรับให้ขนาดใหญ่ขึ้นได้ โดยเพิ่มคีย์เวิร์ด fontsize ใน plt.title, plt.xlabel และ plt.ylabel หรือตอนที่ตั้งค่าด้วย set_title, set_xlabel และ set_ylabel
ตัวอย่าง
x = np.linspace(0,100,500)
y = np.cos(x)+np.cos(x*1.2)
plt.title('y = cos(x) + cos(1.2x)',fontsize=26)
plt.xlabel('x',fontsize=20)
plt.ylabel('y',fontsize=20)
plt.plot(x,y,'m')
plt.show()
การใส่สมการและสัญลักษณ์พิเศษ อาจมีบ่อยครั้งที่เราจะต้องใส่สมการลงบนกราฟ ซึ่งจะประกอบด้วยอักษรตัวห้อยตัวยกและเศษส่วนเต็มไปหมด ซึ่งไม่สามารถจะเขียนแบบธรรมดาได้
matplotlib ใช้วิธีเดียวกับภาษา latex ในการเขียนอักษรแบบพิเศษต่างๆ วิธีการเขียนสามารถอ้างอิงได้จากเว็บ
https://en.wikibooks.org/wiki/LaTeX/Special_Characters เช่น เลขยกกำลังเขียนเป็น ^{} เศษส่วนเขียนเป็น \frac{ตัวเศษ}{ตัวส่วน} และอีกมากมาย สามารถดูในเว็บได้ ในที่นี้จะไม่พูดถึงละเอียด
ในการเขียนสัญลักษณ์พวกนี้จะต้องคร่อมด้วยสัญลักษณ์ $ สองข้าง นอกจากนี้ยังมีสิ่งที่ต้องระวังอีกอย่างก็คือ เนื่องจากภาษา latex มีการใช้แบ็กสแลช \ เป็นจำนวนมาก และแบ็กสแลชนี้ก็ยังใช้เป็นเอสเคปคาแร็กเตอร์ในภาษาไพธอนด้วย ดังนั้นหากจะเขียนภาษา latex ในนี้ทางที่ดีควรจะใส่ r นำหน้าเครื่องหมายคำพูด เพื่อเป็นการบอกว่าจะไม่สนเอสเคปคาแร็กเตอร์
ดังนั้นรูปแบบการเขียนก็คือ r'$ข้อความ$'
ตัวอย่าง
x = np.linspace(0,150,1500)
y = (np.sin(x)+np.sin(x*1.1))*np.exp(-x/100)
plt.axes(xlabel='x',ylabel='y')
plt.title(r'$y = (sin(x) + sin(1.1x))e^{\frac{-x}{100}}$',fontsize=18)
plt.plot(x,y,'c')
plt.show()
การปรับมุมการเอียงของตัวหนังสือ ค่าตั้งต้นมาเราจะเห็นว่าหัวข้อแกน x วางนอนตามปกติ แต่ของแกน y จะตะแคงอยู่ในแนวตั้ง แต่หากต้องการให้ y วางนอนหรือให้เอียงก็สามารถปรับได้ โดยเพิ่มคีย์เวิร์ด rotation ไปใน set_ylabel
โดยปกติเริ่มต้น rotation ของ xlabel จะเป็น 0 และ ylabel จะเป็น 90 เราสามารถปรับให้ต่างไปได้
ตัวอย่าง
x = np.linspace(0,150,1500)
y = (np.sin(x)+np.sin(x*1.1))*np.exp(-x/100)
ax = plt.gca()
ax.set_title(r'$y = (sin(x) + sin(1.1x))e^{\frac{-x}{100}}$',fontsize=18,rotation=5)
ax.set_xlabel('x',fontsize=14,rotation=25)
ax.set_ylabel('y',fontsize=14,rotation=0)
ax.plot(x,y,'m')
plt.show()
นอกจากนี้แล้วหากต้องการปรับความเอียงของตัวเลขบอกค่าก็ทำได้เช่นกัน โดยปรับได้ที่ set_yticklabels และ set_yticklabels โดยเพิ่มคีย์เวิร์ด rotation ลงไปเช่นกัน
การปรับตำแหน่งข้อความปกติแล้วชื่อแกน y จะอยู่ทางซ้ายตรงกลาง และชื่อแกน x อยู่ตรงกลางด้านล่าง ส่วนหัวข้ออยู่ด้านบน แต่เราสามารถปรับตำแหน่งได้
ตำแหน่งแกน x สามารถปรับซ้ายขวาโดยใส่คีย์เวิร์ด x และปรับขึ้นลงโดยใส่คีย์เวิร์ด labelpad ใน xlabel
ตำแหน่งแกน y สามารถปรับบนล่างโดยใส่คีย์เวิร์ด y และปรับซ้ายขวาโดยใส่คีย์เวิร์ด labelpad ใน ylabel
ส่วนตำแหน่งหัวข้อสามารถปรับซ้ายขวาบนล่างโดยใส่คีย์เวิร์ด x และ y และ loc ใน title
คีย์เวิร์ด labelpad ที่ใส่ลงใน xlabel และ ylabel เป็นตัวกำหนดว่าจะให้อยู่ห่างจากแกนเท่าไหร่ ยิ่งค่ามากก็ยิ่งอยู่ห่าง ถ้าใส่ค่าติดลบก็จะเข้าด้านในแกน
ส่วนคีย์เวิร์ด x และ y นั้นมีหน่วยเป็นจำนวนเท่าของขนาดกรอบกราฟ
x=0 อยู่ที่กรอบกราฟด้านซ้าย
x=1 อยู่ทีกรอบกราฟด้านขวา
y=0 อยู่ที่กรอบกราฟด้านล่าง
y=1 อยู่ที่กรอบกราฟด้านบน
คีย์เวิร์ด loc ใน title นั้นเป็นตัวกำหนดว่าจะจัดตัวหนังสืออยู่ทางซ้ายหรือกลางหรือขวา ค่าที่ใส่ได้คือ left, center และ right
ตัวอย่าง
x = np.linspace(0,40,2000)
y = (np.sin(x*20)+np.sin(x*21))*np.exp(-x/10)
plt.title(r'$y = (sin(20x) + sin(21x))e^{\frac{-x}{10}}$',fontsize=18,x=0.99,y=0.9,loc='right')
plt.xlabel('x',fontsize=14,x=0.95,labelpad=-40)
plt.ylabel('y',fontsize=14,y=1.02,rotation=0,labelpad=-50)
plt.plot(x,y,'#7755CC')
plt.show()
การเปลี่ยนฟอนต์ และการใส่อักษรไทย ฟอนต์มาตรฐานของ matplotlib ไม่สามารถอ่านภาษาไทยได้ ดังนั้นหากเขียนกราฟแล้วใส่ภาษาไทยลงไปก็จะออกมาเป็นตัวแปลกๆทันที
ตัวอย่าง จำนวนประชากรเมืองคุมาโมโตะในช่วง ๔๐ ปี ข้อมูลจาก
https://ja.wikipedia.org/wiki/熊本市
x = range(1970,2011,5)
kuma = [534228,574299,619236,654348,680765,708097,720816,727978,734294]
plt.axes(title=u'ประชากรเมืองคุมาโมโตะในช่วง ๔๐ ปี',xlabel=u'ปี',ylabel=u'จำนวน (คน)')
plt.plot(x,kuma)
plt.show()
***u ที่ใส่นำหน้าสายอักขระใส่เพื่อให้ใช้ได้ทั้งในไพธอน 2 และ 3 แต่ที่จริงในไพธอน 3 ไม่จำเป็นต้องมี u ก็ได้
จะเห็นว่าอักษรไทยไม่สามารถแสดงผลได้ ดังนั้นจึงจำเป็นต้องเปลี่ยนฟอนต์เป็นอันที่รองรับภาษาไทย เช่น Tahoma
การเปลี่ยนฟอนต์ทำได้หลายวิธี แต่ที่ง่ายที่สุดก็คือใส่คีย์เวิร์ด fontname เพิ่มลงไปใน set_title หรือ plt.title เช่นเดียวกับตอนเปลี่ยนขนาด
ตัวอย่าง
x = range(1970,2011,5)
kuma = [534228,574299,619236,654348,680765,708097,720816,727978,734294]
ax = plt.gca()
ax.set_title(u'ประชากรเมืองคุมาโมโตะในช่วง ๔๐ ปี',fontname='Tahoma',fontsize='13')
ax.set_xlabel(u'ปี',fontname='Tahoma',fontsize='13')
ax.set_ylabel(u'จำนวน (คน)',labelpad=-4,fontname='Tahoma',fontsize='13')
ax.plot(x,kuma,'-og')
plt.show()
จะได้กราฟที่แสดงภาษาไทยตามที่ต้องการ
ในที่นี้จะใช้ Tahoma ถ้าหากใครไม่มีในเครื่องก็อาจต้องเอามาลงถึงจะแสดงผลได้
การใช้ FontProperties อีกวิธีหนึ่งในการเปลี่ยนขนาดและฟอนต์ตัวอักษรแต่อาจเข้าใจยากกว่าหน่อยก็คือการใช้คีย์เวิร์ด fontproperties ลงใน title, xlabel, ylabel
การใส่ค่าในคีย์เวิร์ดนี้จะยุ่งยากหน่อยตรงที่ต้องใส่เป็นออบเจ็กต์ชนิด FontProperties
ออบเจ็กต์ชนิดนี้อยู่ในมอดูลย่อยของ matplotlib ที่ชื่อ font_manager ต้องทำการ import เข้ามาก่อน จากนั้นก็จะสามารถสร้างออบเจ็กต์ชนิดนี้ โดยใส่คีย์เวิร์ดเป็นฟอนต์และขนาดของอักษร
import matplotlib as mpl
fp = mpl.font_manager.FontProperties(family='Tahoma',size=13)
ในที่นี้ family แทน fontname และ size แทน fontsize
จากนั้นก็นำออบเจ็กต์ FontProperties ที่ได้มานี้มาใช้ตอน set_title แทน โดยใส่เป็นคีย์เวิร์ด fontproperties แทนที่จะใส่ fontname และ fontsize
x = range(1970,2011,5)
kuma = [534228,574299,619236,654348,680765,708097,720816,727978,734294]
plt.figure()
ax = plt.gca()
ax.set_title(u'ประชากรเมืองคุมาโมโตะในช่วง 40 ปี',fontproperties=fp)
ax.set_xlabel(u'ปี',fontproperties=fp)
ax.set_ylabel(u'จำนวน (คน)',labelpad=-4,fontproperties=fp)
ax.plot(x,kuma,'-og')
plt.show()
ผลที่ได้จะเหมือนตัวอย่างก่อนหน้า
ข้อดีคือสร้างออบเจ็กต์ที่เก็บคุณสมบัติของตัวอักษรมาแค่ครั้งเดียวแล้วก็นำไป ใช้ได้กับหลายๆส่วนได้โดยไม่ต้องมาใส่ทั้งขนาดอักษรและรูปแบบฟอนต์ใหม่
ด้วยการทำแบบนี้ก็จะทำให้เราสามารถเปลี่ยนตัวหนังสือที่ต่างๆได้ตามที่ต้องการ จะเปลี่ยนขนาดของตัวอักษรบนกราฟก็ทำได้
ลองอ่านได้ในเนื้อหาเสริม >>
การเปลี่ยนตัวเลขบอกค่าในกราฟเป็นเลขไทย ในตัวอย่างมีการตั้งแค่ชนิดฟอนต์และขนาด แต่ยังมีอย่างอื่นที่สามารถตั้งได้อีก ค่าที่ใส่ได้มีดังนี้
ชื่อ |
ความหมาย |
ค่าที่ใส่ได้ |
family |
ชนิดฟอนต์ |
ชื่อฟอนต์หรือลิสต์ของชื่อฟอนต์ โดยเรียงตามลำดับความสำคัญ |
style |
ความเอียง |
'normal', 'italic' หรือ 'oblique' |
variant |
|
'normal' หรือ 'small-caps' |
stretch |
ความยืดหยุ่น |
ตัวเลข 0-1000 หรือ 'ultra-condensed', 'extra-condensed', 'condensed', 'semi-condensed', 'normal', 'semi-expanded', 'expanded', 'extra-expanded', 'ultra-expanded' |
weight |
ความหนา |
ตัวเลข 0-1000 หรือ 'ultralight', 'light', 'normal', 'regular', 'book', 'medium', 'roman', 'semibold', 'demibold', 'demi', 'bold', 'heavy', 'extra bold', 'black' |
size |
ขนาดอักษร |
ตัวเลข หรือ 'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large' |
การใส่ข้อความอธิบายเส้นกราฟ เวลาที่มีกราฟอยู่หลายเส้นเราจำเป็นจะต้องมีคำอธิบายว่ากราฟเส้นไหนคืออะไร
การจะเพิ่มคำอธิบายแต่ละเส้นกราฟลงไปทำได้โดยใช้เมธอด legend
เช่น ลองดูกราฟที่หาจำนวนประชากรเหมือนอย่างเมื่อครู่ แต่คราวนี้มี ๓ เมืองอยู่ด้วยกัน
ข้อมูลจาก
https://ja.wikipedia.org/wiki/竹原市 https://ja.wikipedia.org/wiki/尾道市 https://ja.wikipedia.org/wiki/福山市
fp = mpl.font_manager.FontProperties(family='Tahoma',size=13)
x = range(1970,2011,5)
take = [35017,36273,36895,36286,34771,33451,31935,30657,28655]
ono = [183325,185503,180901,177532,166930,159890,155200,150225,145217]
fuku = [355264,405677,425675,441502,445403,453791,456908,459087,459087]
ax = plt.gca()
ax.set_title(u'ประชากรในช่วง 40 ปี',fontname='Tahoma',fontsize=13)
ax.set_xlabel(u'ปี (ค.ศ.)',fontname='Tahoma',fontsize=13)
ax.plot(x,take,'-om')
ax.plot(x,ono,'-oc')
ax.plot(x,fuku,'-oy')
ax.legend([u'ทาเกฮาระ',u'โอโนมิจิ',u'ฟุกุยามะ'],prop=fp,loc=7,fancybox=1,shadow=1)
plt.show()
ผลคือจะได้กรอบข้อความที่ระบุว่ากราฟเส้นไหนมีความหมายยังไง
ภายในเมธอด legend นั้นประกอบไปด้วยอาร์กิวเมนต์ตัวแรกคือข้อความที่จะมาคู่กับกราฟ โดยใส่เป็นลิสต์หรือทูเพิลของสายอักขระ
นอกจากนั้นยังมีตัวคีย์เวิร์ดมากมาย ในตัวอย่างนี้ได้มีการใส่ ๔ ตัวคือ
prop คือรูปแบบของตัวอักษรที่จะใช้ ต้องใช้ออบเจ็กต์ชนิด FontProperties ซึ่งในนี้ได้กำหนดไว้ตั้งแต่ตรงส่วนหัวแล้ว ใส่ในตัวแปร fp
prop ในที่นี้จริงๆแล้วอาจไม่ต้องใช้ออบเจ็กต์ชนิด FontProperties แต่ใส่เป็นดิกชันนารีแทนได้ เช่นลองแก้บรรทัด ax.legend เป็น
ax.legend([u'ทาเกฮาระ',u'โอโนมิจิ',u'ฟุกุยามะ'],prop={'family':'Tahoma','size':13},loc=7,fancybox=1,shadow=1)
ผลที่ได้จะเหมือนเดิม
แต่การใส่รูปแบบอักษรเป็นดิกชันนารีแบบนี้ทำได้แค่กับคีย์เวิร์ด prop ของ legend เท่านั้น ไม่สามารถใช้กับคีย์เวิร์ด fontproperties ใน xlabel, ylabel และ title ได้ สำหรับคีย์เวิร์ด fontproperties ยังคงต้องใช้ออบเจ็กต์ FontProperties
fancybox คือตัวกำหนดว่าจะให้ขอบโค้งมนหรือเปล่า ถ้า fancybox=1 ขอบจะโค้ง ถ้าไม่ใส่หรือใส่ fancybox=0 ขอบจะเหลี่ยม
shadow คือตัวกำหนดว่าจะมีเงาหรือไม่ ถ้า shadow=1 จะมีเงา ถ้าไม่ใส่หรือใส่ shadow=0 จะไม่มีเงา
loc คือตำแหน่ง
ค่าของคีย์เวิร์ด loc ที่ใส่ได้มีตามนี้ จะใส่เป็นตัวเลขหรือสายอักขระก็ได้ โดยมีอยู่ 10 แบบ
0 |
best |
หาตำแหน่งดีที่สุดโดยอัตโนมัติ |
1 |
upper right |
ขวาบน |
2 |
upper left |
ซ้ายบน |
3 |
lower left |
ซ้ายล่าง |
4 |
lower right |
ขวาล่าง |
5 |
right |
ขวา |
6 |
center left |
ซ้ายกลาง |
7 |
center right |
ขวากลาง |
8 |
lower center |
กลางล่าง |
9 |
upper center |
กลางบน |
10 |
center |
กลาง |
ในที่นี้ใส่เป็น loc=7 จึงอยู่ตำแหน่งขวากลาง
กรณีที่ไม่ใส่จะถูกตั้งให้เป็นแบบ 0 best คือจะถูกเลือกตำแหน่งให้เองตามความเหมาะสม ซึ่งบางทีก็ไม่ใช่ตำแหน่งที่ดีที่สุด ดังนั้นเลือกเองอาจจะดีกว่า
นอกจากนี้อาจกำหนดค่าเองได้โดยใส่เป็นคู่อันดับ (ทูเพิลหรือลิสต์) โดยตำแหน่งซ้ายล่างเป็น (0,0) ขวาบนเป็น (1,1) ตำแหน่งนับโดยอ้างอิงมุมซ้ายล่าง
อาร์กิวเมนต์ที่ใส่ในตัวแรกของ legend นั้นอาจจะไม่จำเป็นต้องเขียน ถ้าหากในกราฟแต่ละกราฟมีการใส่คีย์เวิร์ด label ในคำสั่ง plot ตอนวาดกราฟ
อย่างไรก็ตาม ถ้ามีการใส่อาร์กิวเมนต์ตัวแรกลงไปใน legend ก็จะยึดชื่อเอาตามตรงนี้โดยไม่สน คีย์เวิร์ด label ใน plot
ลองเขียนตัวอย่างเดิมใหม่โดยแก้ไขเล็กน้อยแค่ตรง ๕ บรรทัดล่างสุด (ที่เหลือเหมือนเดิม) โดยเพิ่มคีย์เวิร์ด label ลงใน plot แต่ละอัน และแก้คีย์เวิร์ดใน legend
ax.plot(x,take,'-om',label=u'ทาเกฮาระ')
ax.plot(x,ono,'-oc',label=u'โอโนมิจิ')
ax.plot(x,fuku,'-oy',label=u'ฟุกุยามะ')
ax.legend(prop=fp,loc=(0.02,1.01),mode='expand',ncol=3,fancybox=1)
plt.show()
ในที่นี้ได้เปลี่ยน loc ให้เป็นตัวเลขคู่อันดับ โดยพิกัดแกน y เป็น 1.01 ซึ่งมากกว่า 1 หมายความว่าอยู่สูงเลยขอบบนของกราฟขึ้นไป จึงออกมาอย่างที่เห็น
และที่เห็นเรียงกันเป็นแนวนอนก็เพราะใส่คีย์เวิร์ด ncol เพิ่มเข้าไป
ncol คือจำนวนที่จะเรียงสูงสุดในแนวนอน ถ้าไม่กำหนดจะเรียงตัวในแนวตั้งทั้งหมด ในที่นี้ใส่ 3 ก็คือให้วางเรียงต่อกันได้ ๓ ตัว
ส่วนคีย์เวิร์ดอีกตัวที่เพิ่มเข้ามาคือ mode ถ้าใส่เป็น mode='expand' ขอบเขตจะขยายกว้างขึ้น
นอกจากนี้หากต้องการลบกรอบล้อมข้อความออกก็สามารถทำได้โดยใส่คีย์เวิร์ด frameon เขียน frameon=0
สรุปคีย์เวิร์ดที่ใส่ได้ใน legend
prop |
รูปแบบของอักษร ใส่เป็นดิกชันนารีหรือออบเจ็กต์ FontProperties |
loc |
ตำแหน่งที่วาง |
ncol |
จำนวนสูงสุดที่เรียงในแนวนอน ค่าตั้งต้น 1 |
frameon |
ตั้งว่าจะให้มีกรอบหรือไม่: 1 มี 0 ไม่มี ค่าตั้งต้น 1 |
mode |
โหมด ถ้าใส่เป็น expand จะขยายกว้าง |
fancybox |
ขอบมีโค้งมนหรือไม่: 1 มี 0 ไม่มี ค่าตั้งต้นคือ 0 |
shadow |
มีเงาหรือไม่ :1 มี 0 ไม่มี ค่าตั้งต้นคือ 0 |
อ้างอิง