φυβλαςのβλογ
phyblas的博客



numpy & matplotlib เบื้องต้น บทที่ ๒๘: คอนทัวร์
เขียนเมื่อ 2016/06/12 11:28
แก้ไขล่าสุด 2021/09/28 16:42


ในบทก่อนๆได้พูดถึงการสร้างแผนภาพไล่สีไปแล้ว อย่างไรก็ตามในแง่ของการวิเคราะห์ข้อมูลแล้ว บางทีแค่เห็นความแตกต่างของสีก็อาจจะไม่เพียงพอ เราอาจเห็นภาพได้ชัดมากขึ้นกว่าเดิมหากทำเป็นคอนทัวร์

คอนทัวร์คือแผนภาพไล่สีแบบมีลำดับขั้นชัดเจน เห็นเส้นแบ่งแต่ละขั้นเป็นส่วนๆ

ที่จริงหากใช้ BoundaryNorm ดังที่กล่าวไปในบทที่ ๒๖ ก็สามารถสร้างคอนทัวร์ได้ แต่ว่ามีวิธียืดหยุ่นกว่านั้น matplotlib ได้เตรียมฟังก์ชันสำหรับสร้างคอนทัวร์โดยเฉพาะไว้อยู่แล้ว

ฟังก์ชันที่ใช้สร้างคอนทัวร์มี ๒ ตัวคือ plt.contour เป็นคอนทัวร์แบบไม่ใส่พื้นสี กับ plt.contourf เป็นคอนทัวร์แบบใส่พื้นสี



คอนทัวร์แบบเส้นแบ่ง
การสร้างคอนทัวร์ที่มีแต่เส้นไม่มีพื้นทำได้โดยใช้ฟังก์ชัน plt.contour โดยอาร์กิวเมนต์และคีย์เวิร์ดโดยหลักๆที่ใช้ก็จะคล้ายกับ plt.pcolor

ตัวอย่าง
import numpy as np
import matplotlib.pyplot as plt
x,y = np.meshgrid(np.linspace(-10,10,100),np.linspace(-10,10,100))
z = np.sin(x)+np.sin(y)
plt.contour(x,y,z,cmap='jet')
plt.colorbar(pad=0.01)
plt.subplots_adjust(0.05,0.05,1.05,0.95)
plt.show()


จะเห็นว่าผลที่ได้คล้ายกับแผนภาพสี เพียงแต่แทนที่จะปรากฏเป็นพื้นสีก็ปรากฏเป็นเส้นที่แบ่งเขตค่าแทน และสีของเส้นก็กำหนดโดยคัลเลอร์แม็ปที่กำหนดใน cmap

จำนวนเขตที่แบ่งสามารถทำได้โดยใส่อาร์กิวเมนต์ตัวที่สี่ต่อจากค่าสีลงไป จะได้คอนทัวร์ที่แบ่งส่วนโดยเว้นค่าห่างเท่าๆกันโดยมีเส้นแบ่งตามจำนวนนั้น เช่นลองแก้เป็น
plt.contour(x,y,z,22,cmap='jet')



จำได้ว่าแบ่งเป็น 21 ส่วนแทนที่จะเป็น 6 ส่วนซึ่งเป็นค่าตั้งต้น

ส่วนแบ่งจะใช้ลิสต์หรืออาเรย์ก็ได้ ซึ่งในกรณีนี้จะทำให้สามารถกำหนดขีดแบ่งได้ตามที่ต้องการ ไม่จำเป็นจำต้องแบ่งเท่าๆกัน
plt.contour(x,y,z,[-2,-1.9,-1.5,-1,1,1.5,1.9,2],cmap='jet')



รูปแบบของเส้นและความหนาของเส้นสามารถกำหนดได้ด้วยคีย์เวิร์ด linewidths และ linestyles

หากใส่เลขเดี่ยวจะเป็นการกำหนดรูปแบบให้กับทุกเส้นพร้อมกัน

ลอง
plt.contour(x,y,z,9,linewidths=4,linestyles='-.',cmap='jet')



หากใส่เป็นลิสต์จะเป็นการกำหนดความหนาและรูปแบบให้กับเส้นทีละเส้น
plt.contour(x,y,z,7,linewidths=[1,4,1,4,1,4,1],linestyles=['-',':','-',':','-',':','-'],cmap='jet')



สีสามารถกำหนดด้วยคีย์เวิร์ด colors แทนที่จะกำหนดด้วย cmap ได้ ทั้งสองคีย์เวิร์ดนี้จะใช้คู่กันไม่ได้

ลอง
plt.contour(x,y,z,7,colors=['m','g','y','r','c','b','#000000'])





การใส่ตัวเลขบอกค่าลงบนเส้น
บางทีแค่มีแถบสีด้านข้างคอยบอกค่าก็อาจไม่ชัดพอ ถ้าใส่ค่าตัวเลขลงไปบนเส้นคอนทัวร์ได้เลยอาจทำให้เห็นภาพอะไรง่ายกว่า

การใส่ตัวเลขลงบนเส้นสามารถทำได้โดยฟังก์ชัน plt.clabel

อาร์กิวเมนต์ที่ต้องใส่ในฟังก์ชันนี้คือออบเจ็กต์แทนตัวกราฟคอนทัวร์ที่ต้องการใส่ตัวเลข ดังนั้นเราต้องเอาตัวแปรมารับค่าคืนกลับจากฟังก์ชัน plt.contour แล้วจึงใช้ตัวแปรนั้นไปใส่ในฟังก์ชัน plt.clabel

ตัวอย่าง
x,y = np.meshgrid(np.linspace(-5,5,100),np.linspace(-5,5,100))
z = np.cos(x)+np.cos(y)
pct = plt.contour(x,y,z,9,cmap='jet')
plt.clabel(pct)
plt.colorbar(pad=0.01)
plt.subplots_adjust(0.05,0.05,1.05,0.95)
plt.show()



จะเห็นว่ามีตัวเลขบอกค่าเข้าแทรกบนเส้น ทำให้เส้นแหว่งไป

ถ้าไม่อยากให้เส้นแหว่งไปก็ทำได้โดยใส่คีย์เวิร์ด inline=0 ลองแก้เป็น
plt.clabel(pct,inline=0)



รูปแบบของตัวเลขที่แสดงสามารถปรับได้ด้วยคีย์เวิร์ด fmt และขนาดอักษรก็เปลี่ยนได้ด้วยคีย์เวิร์ด fontsize

ลอง
plt.clabel(pct,fontsize=17,fmt='%+.3f')



ตำแหน่งของตัวเลขที่ปรากฏนี้ถูกจัดวางตามความเหมาะสมให้โดยอัตโนมัติ



คอนทัวร์บนแผนภาพแจกแจงความหนาแน่น
เวลาวาดแผนภาพไล่สีเพื่อแสดงการแจกแจงความหนาแน่นเราสามารถใช้ฟังก์ชัน plt.hist2d ได้ แต่ว่าสำหรับคอนทัวร์แล้วไม่มีฟังก์ชันเฉพาะสำหรับทำแบบนั้น

ดังนั้นจึงอาจต้องใช้ np.histogram2d หรืออาจใช้ค่าที่ได้จาก plt.hist2d มาวาดเป็นคอนทัวร์อีกทีก็ได้ (รายละเอียดเกี่ยวกับแผนภาพแจกแจงความหนาแน่นอ่านในบทที่แล้ว)

เราอาจวาดคอนทัวร์ทับลงบนแผนภาพไล่สีที่ได้จาก plt.hist2d ไปเลยก็ได้

ตัวอย่าง ลองวาดแผนภาพไล่สีแสดงการแจกแจงแบบปกติที่มีจุดศูนย์กลางอยู่สองจุดซึ่งมีขนาดไม่เท่ากัน
px1 = np.random.randn(700000) # ตำแน่งกลุ่มก้อนใหญ่
px2 = np.random.randn(300000)+4 # ตำแน่งกลุ่มก้อนเล็ก
px = np.hstack((px1,px2)) # นำกลุ่มก้อนทั้งสองมารวมกัน
py = np.random.randn(1000000)
lx = np.linspace(-3,6,151) # จุดขีดแบ่งของช่อง
ly = np.linspace(-3,3,101)
h = plt.hist2d(px,py,bins=[lx,ly],cmap='summer')
plt.colorbar(pad=0.01)
plt.subplots_adjust(0.05,0.05,1.05,0.95)
x,y = np.meshgrid((lx[1:]+lx[:-1])/2,(ly[1:]+ly[:-1])/2)
z = h[0].T
plt.contour(x,y,z,linewidths=2,cmap='winter')
plt.show()





คอนทัวร์แบบลงสี
หากใช้ฟังก์ชัน plt.contourf แทน plt.contour ก็จะเป็นการสร้างคอนทัวร์ที่พื้นมีสี ลักษณะโดยส่วนใหญ่ก็คล้ายๆกัน

ตัวอย่าง
x,y = np.meshgrid(np.linspace(-5,5,100),np.linspace(-5,5,100))
z = np.cos(x**2+y**2)
plt.contourf(x,y,z,9,cmap='nipy_spectral')
plt.colorbar(pad=0.01)
plt.subplots_adjust(0.05,0.05,1.05,0.95)
plt.show()



ลองวาดเปรียบเทียบความต่างระหว่าง plt.contour และ plt.contourf
x,y = np.meshgrid(np.linspace(-5,5,100),np.linspace(-5,5,100))
z = np.cos(x)+np.cos(y*0.5)
plt.subplot(2,1,1)
plt.contourf(x,y,z,np.linspace(-2,2,9),cmap='ocean')
plt.colorbar(pad=0.01)
plt.subplot(2,1,2)
plt.contour(x,y,z,np.linspace(-2,2,9),cmap='ocean')
plt.colorbar(pad=0.01)
plt.subplots_adjust(0.05,0.05,1.05,0.95)
plt.show()



ถ้าจะวาดทั้งเส้นทั้งระบายสีพื้นก็ใช้คู่กันซ้อนทับกันได้เลย
x,y = np.meshgrid(np.linspace(-5,5,100),np.linspace(-5,5,100))
z = np.cos(x)+np.cos(y)
plt.contour(x,y,z,np.linspace(-2,2,9),colors='m',linestyles='-',linewidths=3)
plt.contourf(x,y,z,np.linspace(-2,2,9),cmap='seismic')
plt.colorbar(pad=0.01)
plt.subplots_adjust(0.05,0.05,1.05,0.95)
plt.show()





คอนทัวร์แบบลงสีในแผนภาพแจกแจงความหนาแน่น
เนื่องจากใน matplotlib ไม่มีฟังก์ชันสำหรับสร้างคอนทัวร์แจกแจงความหนาแน่นโดยตรง ถ้าเราไม่ได้ใช้ plt.hist2d เพื่อสร้างแผนภาพไล่สีแจกแจงความหนาแน่นมาก่อนก็อาจใช้ np.histogram2d ของ numpy ช่วย
px = np.random.randn(1000000)+np.linspace(-8,8,1000000)
py = np.random.randn(1000000)+np.cos(np.linspace(-8,8,1000000))
lx = np.linspace(-10,10,101)
ly = np.linspace(-4,4,101)
h = np.histogram2d(px,py,bins=[lx,ly])
x,y = np.meshgrid((lx[1:]+lx[:-1])/2,(ly[1:]+ly[:-1])/2)
z = h[0].T
plt.contourf(x,y,z)
plt.colorbar(orientation='horizontal',pad=0.01)
plt.subplots_adjust(0.05,-0.03,0.95,0.97)
plt.show()





อ้างอิง


<< บทที่แล้ว     บทถัดไป >>
หน้าสารบัญ


-----------------------------------------

囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧

ดูสถิติของหน้านี้

หมวดหมู่

-- คอมพิวเตอร์ >> เขียนโปรแกรม >> python >> matplotlib

ไม่อนุญาตให้นำเนื้อหาของบทความไปลงที่อื่นโดยไม่ได้ขออนุญาตโดยเด็ดขาด หากต้องการนำบางส่วนไปลงสามารถทำได้โดยต้องไม่ใช่การก๊อปแปะแต่ให้เปลี่ยนคำพูดเป็นของตัวเอง หรือไม่ก็เขียนในลักษณะการยกข้อความอ้างอิง และไม่ว่ากรณีไหนก็ตาม ต้องให้เครดิตพร้อมใส่ลิงก์ของทุกบทความที่มีการใช้เนื้อหาเสมอ

目录

从日本来的名言
模块
-- numpy
-- matplotlib

-- pandas
-- manim
-- opencv
-- pyqt
-- pytorch
机器学习
-- 神经网络
javascript
蒙古语
语言学
maya
概率论
与日本相关的日记
与中国相关的日记
-- 与北京相关的日记
-- 与香港相关的日记
-- 与澳门相关的日记
与台湾相关的日记
与北欧相关的日记
与其他国家相关的日记
qiita
其他日志

按类别分日志



ติดตามอัปเดตของบล็อกได้ที่แฟนเพจ

  查看日志

  推荐日志

ตัวอักษรกรีกและเปรียบเทียบการใช้งานในภาษากรีกโบราณและกรีกสมัยใหม่
ที่มาของอักษรไทยและความเกี่ยวพันกับอักษรอื่นๆในตระกูลอักษรพราหมี
การสร้างแบบจำลองสามมิติเป็นไฟล์ .obj วิธีการอย่างง่ายที่ไม่ว่าใครก็ลองทำได้ทันที
รวมรายชื่อนักร้องเพลงกวางตุ้ง
ภาษาจีนแบ่งเป็นสำเนียงอะไรบ้าง มีความแตกต่างกันมากแค่ไหน
ทำความเข้าใจระบอบประชาธิปไตยจากประวัติศาสตร์ความเป็นมา
เรียนรู้วิธีการใช้ regular expression (regex)
การใช้ unix shell เบื้องต้น ใน linux และ mac
g ในภาษาญี่ปุ่นออกเสียง "ก" หรือ "ง" กันแน่
ทำความรู้จักกับปัญญาประดิษฐ์และการเรียนรู้ของเครื่อง
ค้นพบระบบดาวเคราะห์ ๘ ดวง เบื้องหลังความสำเร็จคือปัญญาประดิษฐ์ (AI)
หอดูดาวโบราณปักกิ่ง ตอนที่ ๑: แท่นสังเกตการณ์และสวนดอกไม้
พิพิธภัณฑ์สถาปัตยกรรมโบราณปักกิ่ง
เที่ยวเมืองตานตง ล่องเรือในน่านน้ำเกาหลีเหนือ
ตระเวนเที่ยวตามรอยฉากของอนิเมะในญี่ปุ่น
เที่ยวชมหอดูดาวที่ฐานสังเกตการณ์ซิงหลง
ทำไมจึงไม่ควรเขียนวรรณยุกต์เวลาทับศัพท์ภาษาต่างประเทศ