φυβλαςのβλογ
บล็อกของ 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
ภาษา mongol
ภาษาศาสตร์
maya
ความน่าจะเป็น
บันทึกในญี่ปุ่น
บันทึกในจีน
-- บันทึกในปักกิ่ง
-- บันทึกในฮ่องกง
-- บันทึกในมาเก๊า
บันทึกในไต้หวัน
บันทึกในยุโรปเหนือ
บันทึกในประเทศอื่นๆ
qiita
บทความอื่นๆ

บทความแบ่งตามหมวด



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

  ค้นหาบทความ

  บทความแนะนำ

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

บทความแต่ละเดือน

2024年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2023年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2022年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2021年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2020年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

ค้นบทความเก่ากว่านั้น

ไทย

日本語

中文