ในสองบทที่ผ่านมาเราได้มีการใส่แถบสีเข้าไปด้านข้างเพื่อเป็นตัวอธิบายประกอบแผนภาพไล่สี
โดยทั่วไปแล้วแถบสีจะถูกสร้างขึ้นมาโดยกินพื้นที่แคบๆทางด้านขวาถ้าหากเราไม่ได้ระบุค่าอะไรต่างๆไว้
แต่จริงๆแล้วแถบสีสามารถปรับแต่งอะไรได้อีกมากมายเพื่อให้ได้รูปแบบตามที่ต้องการ
การตั้งค่าต่างๆใน plt.colorbar แถบสีสามารถปรับแต่งอะไรต่างๆได้ด้วยการเติมคีย์เวิร์ดเข้าไปตอนที่ใช้ plt.colorbar เพื่อสร้าง เช่น
orientation |
ระบุว่าจะให้อยู่แนวไหน แนวตั้ง vertical แนวนอน horizontal ค่าตั้งต้นคือแนวตั้ง |
fraction |
ขนาดของแถบสีเป็นสัดส่วนกับพื้นที่กราฟทั้งหมด หน่วยเป็นสัดส่วนเต็ม 1 ค่าตั้งต้นคือ 0.15 |
pad |
ระยะห่างระหว่างแถบสีกับกราฟ หน่วยเป็นสัดส่วนเต็ม 1 ถ้าหากไม่ใส่จะเป็น 0.05 สำหรับแนวตั้ง 0.15 สำหรับแนวนอน |
aspect |
สัดส่วนระหว่างด้านยาวกับด้านกว้าง |
shrink |
ขนาดของแถบสี ว่าจะให้ย่อลงแค่ไหน หน่วยเป็นสัดส่วนเต็ม 1 ใส่ค่าที่ต่ำกว่า 1 ยิ่งน้อยก็ยิ่งเล็ก |
label |
ข้อความอธิบาย |
ticks |
ค่าที่จะให้มีขีดและตัวเลขบอก |
extend |
ทำแถบสีให้มีปลายแหลม ถ้าต้องการให้ฝั่งค่ามากเป็นแหลมก็ใส่ว่า max ถ้าฝั่งค่าน้อยเป็น min ถ้าต้องการให้แหลมสองฝั่งใส่ both |
ตัวอย่าง ลองสร้างแถบสีแนวนอน
import numpy as np
import matplotlib.pyplot as plt
x,y = np.meshgrid(np.linspace(-20,20,101),np.linspace(-10,10,101))
z = np.cos(x/5)**2+np.cos(y/5)**2
plt.pcolor(x,y,z,cmap='terrain')
plt.colorbar(orientation='horizontal')
plt.show()
สามารถปรับให้แถบสีมาอยู่ติดกับตัวกราฟได้โดยใส่ pad=0
x,y = np.meshgrid(np.linspace(-10,10,101),np.linspace(-10,10,101))
z = np.cos(x)+np.cos(y)
plt.pcolor(x,y,z,cmap='terrain')
plt.colorbar(pad=0)
plt.show()
ค่าบางอย่างไม่สามารถปรับได้โดยใส่คีย์เวิร์ดตอนสร้าง แต่สามารถเอาตัวแปรมารับค่าเพื่อใช้เมธอดมาตั้งปรับค่า เช่นตั้งข้อความที่ขีดบอกค่า ใช้ set_ticklabels
สามารถเปลี่ยนข้อความที่เส้นขีดได้ เช่นใช้ตัวอักษรเป็นขีดบอก
x,y = np.meshgrid(np.linspace(-10,10,101),np.linspace(-10,10,101))
z = (np.cos(x)**2+np.cos(y)**2)*(x**2+y**2)
plt.pcolor(x,y,z,cmap='terrain')
cb = plt.colorbar(ticks=[50,150,250,350])
cb.set_ticklabels(['a','b','c','d'])
plt.show()
ลองทำให้แถบสีเป็นหัวแหลมชี้ด้านบน แล้วก็ปรับขนาดให้กว้างดู
x,y = np.meshgrid(np.linspace(10,20,101),np.linspace(10,20,101))
z = 1/x+1/y
plt.pcolor(x,y,z,cmap='terrain')
cb = plt.colorbar(aspect=3,fraction=0.3,extend='min')
plt.show()
นอกจากนี้ก็ยังปรับอะไรได้อีกมาก ลองไปปรับแต่งกันดูได้
สร้าง axes ขึ้นมาเพื่อใส่แถบสีโดยเฉพาะ จากตัวอย่างที่ผ่านๆมาจะเห็นว่าพอสร้างแถบสีขึ้นด้วย plt.colorbar มันจะถูกวางโดยไปเบียดเข้ากับแกนเดิมที่มีอยู่ จัดสันปันส่วนตามค่าที่เรากำหนด
แต่มีอีกวิธีหนึ่งในการจัดวางแถบสีคือการสร้าง axes เฉพาะขึ้นมาเพื่อจัดวางแถบสีลงไป
เราสามารถทำได้โดยการใส่คีย์เวิร์ด cax ลงใน plt.colorbar ค่าที่ใส่ก็คือออบเจ็กต์แทน axes ที่ต้องการใช้เป็นแถบสี
วิธีที่อาจทำได้ง่ายๆก็คืออาจใช้ subplot เพื่อสร้างกราฟย่อยมาสองอัน แล้วให้อันนึงเป็นแถบสีไปเลย เช่น
x,y = np.meshgrid(np.linspace(-20,20,101),np.linspace(-10,10,101))
z = np.cos(x/5)**2+np.cos(y/5)**2
plt.subplot(2,1,1)
plt.pcolor(x,y,z,cmap='rainbow')
ax_cb = plt.subplot(2,1,2)
plt.colorbar(cax=ax_cb,orientation='horizontal')
plt.show()
พอทำแบบนี้แล้ว subplot ด้านล่างก็จะกลายเป็นสีไป
หรืออาจใช้ฟังก์ชัน plt.axes เพื่อกำหนดขนาดปันส่วนอย่างอิสระ เช่น
x,y = np.meshgrid(np.linspace(-20,20,101),np.linspace(-10,10,101))
z = np.cos(x**2/5)**2+np.cos(y**2/5)**2
plt.axes([0.05,0.05,0.8,0.9])
plt.pcolor(x,y,z,cmap='cubehelix')
ax_cb = plt.axes([0.86,0.05,0.07,0.9])
plt.colorbar(cax=ax_cb)
plt.show()
การสร้างให้กราฟย่อยหลายอันใช้แถบสีร่วมกัน บางครั้งเราอาจต้องการวาดแผนภาพไล่สีหลายๆอันแล้วเอามารวมกัน แต่ว่าแถบสีจะจำเพาะต่อกราฟอันเดียวเท่านั้น เพราะแถบสีจะถูกสร้างขึ้นคู่กับกราฟที่เพิ่งสร้างมาตัวล่าสุด
หากเราสร้างกราฟย่อยและต้องการให้แต่ละอันมีแถบสีก็ทำได้โดย
x,y = np.meshgrid(np.linspace(-10,10,201),np.linspace(-4,4,201))
z1 = np.sin(x**2+y**2)
z2 = np.sin(x**2+y**2)**2
plt.subplot(2,1,1)
plt.pcolor(x,y,z1,cmap='CMRmap')
plt.colorbar()
plt.subplot(2,1,2)
plt.pcolor(x,y,z2,cmap='CMRmap')
plt.colorbar()
plt.show()
ทำแบบนี้จะได้แถบสีมาสองอัน ซึ่งมีมาตราส่วนต่างกัน หากเราต้องการเปรียบเทียบแผนภาพทั้งสองนี้ก็คงจะทำได้ยาก
ตรงนี้เราก็อาจแก้ปัญหาด้วยการแค่ใส่ vmin vmax ลงไปให้แผนภาพทั้งสองเท่ากัน แบบนี้แผนภาพไล่สีทั้งสองก็จะเป็นมาตราส่วนเดียวกัน และแถบสีก็จะออกมาเหมือนกันด้วย
ซึ่งพอทำแบบนี้แล้วเราก็คงไม่จำเป็นจะต้องอุตส่าห์สร้างแถบสีขึ้นมาถึงสองอันแล้ว เพราะยังไงก็เหมือนกัน
แต่หากเราตัด plt.colorbar() ออกไปอันนึงดื้อๆเลย ผลที่ได้ก็จะออกมาประหลาด เช่นแบบนี้
x,y = np.meshgrid(np.linspace(-10,10,201),np.linspace(-4,4,201))
z1 = np.sin(x**2+y**2)
z2 = np.sin(x**2+y**2)**2
plt.subplot(2,1,1)
plt.pcolor(x,y,z1,cmap='CMRmap',vmin=-1,vmax=1)
plt.subplot(2,1,2)
plt.pcolor(x,y,z2,cmap='CMRmap',vmin=-1,vmax=1)
plt.colorbar()
plt.show()
นั่นเพราะแถบสีจะไปผูกติดกับแผนภาพอันที่สองซึ่งสร้างมาทีหลัง
ดังนั้นกรณีเช่นนี้จำเป็นจะต้องสร้าง axes สำหรับวางแถบสี โดยจัดสรรปันส่วนพื้นที่เอาเอง วิธีการก็มีหลากหลาย ในที่นี้จะลองใช้ plt.subplot2grid
x,y = np.meshgrid(np.linspace(-10,10,201),np.linspace(-4,4,201))
z1 = np.sin(x**2+y**2)
z2 = np.sin(x**2+y**2)**2
plt.subplot2grid((6,11),(0,0),rowspan=3,colspan=10)
plt.pcolor(x,y,z1,cmap='CMRmap',vmin=-1,vmax=1)
plt.subplot2grid((6,11),(3,0),rowspan=3,colspan=10)
plt.pcolor(x,y,z2,cmap='CMRmap',vmin=-1,vmax=1)
ax_cb = plt.subplot2grid((6,11),(0,10),rowspan=6,colspan=1)
plt.colorbar(cax=ax_cb)
plt.subplots_adjust(0.05,0.05,0.92,0.95,0.4,0.4)
plt.show()
เกี่ยวกับ plt.subplot2grid และ plt.axes หากใครยังไม่ค่อยเข้าใจอาจต้องลองไปอ่าน
บทที่ ๑๐ อ้างอิง