φυβλαςのβλογ
บล็อกของ phyblas



numpy & matplotlib เบื้องต้น บทที่ ๒๔: คัลเลอร์แม็ปและแผนภาพไล่สี
เขียนเมื่อ 2016/06/12 02:52
ในบทที่ผ่านๆมาเราพูดถึงแต่ข้อมูลที่เป็นสองมิติเป็นหลัก แต่ต่อจากนี้ไปจะพูดถึงข้อมูลที่มีมิติเพิ่มขึ้นมาอีกมิติ



แนวความคิดเรื่องการแสดงข้อมูลสามมิติในสองมิติ
ปกติ แล้วการวาดกราฟเส้นคือการแสดงความสัมพันธ์ระหว่างปริมาณ ๒ ค่าว่า เช่นตำแหน่งเทียบกับเวลา (กราฟ t-x) หรือตำแหน่งบนพื้นสองมิติ (กราฟ x-y)

ปัญหาที่มีตัวแปรอยู่แค่สองตัวแบบนี้สามารถเขียนด้วยกราฟเส้นในสองมิติเพื่อให้เห็นภาพชัดได้ง่าย

แต่ในกรณีที่ต้องการแสดงความสัมพันธ์ระห่างปริมาณ ๓ ค่านั้น ปัญหาจะเพิ่มขึ้นมาอีกมิตินึง

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

ตัวอย่าง สร้างอาเรย์ที่เก็บความสูงตามแนวแกน x และ y โดยสุ่มค่าเอา
import numpy as np
khwamsung = np.random.randint(0,100,(10,10))

ได้
[[96 36 88 85 64 91  0 60 92 11]
 [47 92 76 85 66 16 44 19 62 27]
 [41 40 61 23 63 38 23 38 48 96]
 [65  8 68 62 47 82 76 76 78 17]
 [68 18 21 65 61 58 42 14 99 89]
 [81 59 38 84 60 56 44 91 16 50]
 [29 85 24 52 47  3 14  6 12 88]
 [ 9 87 59 41 53 13 48 58 37 16]
 [80 11  1 30 43 35 55 41 31 28]
 [48 92 18 24 12  2 79 84 73 38]]

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

วิธีที่ดีที่สุดก็คือนำค่าความสูงนี้มาวาดเป็นความสูงของพื้นจริงๆในสามมิติ แบบนั้นจะเห็นภาพได้ชัดที่สุด

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

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

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

วิธีหนึ่งที่ดีก็คือ การใช้สีแทนตัวค่าความสูง

การทำให้สีเปลี่ยนไปตามค่านั้นทำได้โดยให้ค่าเป็นตัวกำหนดความเข้มสีของแม่สีต่างๆ

ลองใช้แผนภาพการกระจายที่ได้พูดถึงไปในบทที่ ๑๖ ทำจุดไล่เรียงสี
import random
import matplotlib.pyplot as plt

x = range(10) # ให้ x ไล่ตั้งแต่ 0 ถึง 9
y = [0]*10 # ให้ y เป็น 0 ตลอด เพื่อจะให้จุดอยู่แนวเดียวกัน
c = [(1,random.random(),1) for i in range(10)] # ให้สัดส่วนของสีเขียวเปลี่ยนไปแบบสุ่ม
plt.figure(figsize=(8,2))
plt.scatter(x,y,c=c,s=1500)
plt.show()



จะได้จุดที่มีสีต่างไปตั้งแต่ขาวจนถึงม่วง ถ้าคิดซะว่าความม่วงของจุดแทนส่วนสูงก็จะได้ว่าแผนภาพนี้แสดงความสูงของแต่ละจุด

อย่างไรก็ตาม การต้องมาสร้างลิสต์ของแม่สีทั้งสามแบบนี้ตลอดเพื่อมาใช้นั้นดูแล้วยุ่งยาก

ดังนั้นอาจเป็นการสะดวกที่จะใช้สิ่งที่เรียกว่า คัลเลอร์แม็ป (color map)



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

ใน matplotlib ได้เตรียมฟังก์ชันคัลเลอร์แม็ปเอาไว้หลายตัว สามารถหาได้ด้วยฟังก์ชัน plt.get_cmap

ตัวอย่าง
print(plt.get_cmap('spring')(1.)) # ได้ (1.0, 1.0, 0.0, 1.0)
print(plt.get_cmap('spring')(0.75)) # ได้ (1.0, 0.75294117647058822, 0.24705882352941178, 1.0)
print(plt.get_cmap('spring')(0.5)) # ได้ (1.0, 0.50196078431372548, 0.49803921568627452, 1.0)
print(plt.get_cmap('spring')(0.25)) # ได้ (1.0, 0.25098039215686274, 0.74901960784313726, 1.0)
print(plt.get_cmap('spring')(0.)) # ได้ (1.0, 0.0, 1.0, 1.0)
print(plt.get_cmap('hot')(0.)) # ได้ (0.041599999999999998, 0.0, 0.0, 1.0)

ใน ที่นี้ plt.get_cmap('spring')() คือฟังก์ชันอันหนึ่ง ซึ่งรับค่าตัวเลขเป็นอาร์กิวเมนต์แล้วคืนค่าสีออกมา เลข ๔ ค่าคือ (แดง,เขียว,น้ำเงิน,ความทึบแสง)

ส่วน plt.get_cmap('hot')() ก็เป็นฟังก์ชันคัลเลอร์แม็ปอีกตัวหนึ่ง ใส่ค่าตัวเลขลงไปตัวนึงแล้วก็จะได้เลข ๔ ค่าออกมาเช่นกัน แต่จะต่างจาก spring

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

รายการคัลเลอร์แม็ปทั้งหมด เข้าไปดูแล้วเลือกสีตามที่ต้องการกันได้ http://matplotlib.org/examples/color/colormaps_reference.html

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

ขอบเขตของค่าที่ใส่ ลงในฟังก์ชันคือจำนวนจริงตั้งแต่ 0 ถึง 1 หากลองไล่ค่าในช่วงนี้มาใส่ในฟังก์ชันจะได้ค่าสีที่เปลี่ยนไปเรื่อยๆ แต่ถ้าเกินจาก 1 ไปแล้วค่าจะไม่เปลี่ยนแปลงอีกแล้ว
for c in np.arange(0,1.6,0.1):
    print('%s: %s'%(c,plt.get_cmap('winter')(c)))

ผลลัพธ์
0.0: (0.0, 0.0, 1.0, 1.0)
0.1: (0.0, 0.098039215686274508, 0.9509803921568627, 1.0)
0.2: (0.0, 0.20000000000000001, 0.90000000000000002, 1.0)
0.3: (0.0, 0.29803921568627451, 0.85098039215686272, 1.0)
0.4: (0.0, 0.40000000000000002, 0.80000000000000004, 1.0)
0.5: (0.0, 0.50196078431372548, 0.74901960784313726, 1.0)
0.6: (0.0, 0.59999999999999998, 0.69999999999999996, 1.0)
0.7: (0.0, 0.70196078431372544, 0.64901960784313728, 1.0)
0.8: (0.0, 0.80000000000000004, 0.59999999999999998, 1.0)
0.9: (0.0, 0.90196078431372551, 0.5490196078431373, 1.0)
1.0: (0.0, 1.0, 0.5, 1.0)
1.1: (0.0, 1.0, 0.5, 1.0)
1.2: (0.0, 1.0, 0.5, 1.0)
1.3: (0.0, 1.0, 0.5, 1.0)
1.4: (0.0, 1.0, 0.5, 1.0)
1.5: (0.0, 1.0, 0.5, 1.0)



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

ขอยกตัวอย่างโดยเอาตัวอย่างที่แล้วมาแก้เล็กน้อยโดยเปลี่ยนค่า c ให้เป็นเลขสุ่มตัวเดียวแทนที่จะเป็นทูเพิลของเลขสีทั้ง ๓ แล้วก็ใส่
x = range(10)
y = [0]*10
c = [random.random() for i in range(10)] # เลขสุ่มในช่วง 0 ถึง 1
plt.figure(figsize=(8,2))
plt.scatter(x,y,c=c,s=1500,cmap=plt.get_cmap('PuRd')) # เพิ่ม cmap เข้าไป
plt.show()



จะพบว่าได้ผลออกมาคล้ายเมื่อกี้ เพราะ PuRd เป็นคัลเลอร์แม็ปที่ไล่สีในโทนขาวแดงชมพู

และจะเห็นว่าง่ายกว่าเดิมเพราะไม่ต้องใส่ค่าตัวเลขแม่สีทั้ง ๓ ตัว แค่ใส่เลขตัวเดียวแล้วมันก็จะเข้าสู่ฟังก์ชันคัลเลอร์แม็ปเพื่อเปลี่ยนเป็น ค่าสีทั้ง ๓ (และค่าความโปร่งใส) ให้โดยอัตโนมัติ

นอกจากนี้จริงๆ แล้ว cmap=plt.get_cmap('PuRd') สามารถย่อเหลือแค่ cmap='PuRd' ได้เลย ถ้าค่าที่ใส่เป็นสายอักขระโปรแกรมจะทำการค้นคัลเลอร์แม็ปที่มีชื่อนี้มาใช้ อยู่แล้ว

ในตัวอย่างนี้เราใส่ค่าสี (c) เป็นเลขในช่วง 0 ถึง 1 แต่ความจริงแล้วค่าสีไม่จำเป็นต้องอยู่ในช่วง 0 ถึง 1 ก็ได้ แม้ว่าค่าของฟังก์ชันคัลเลอร์แม็ปจะมีการเปลี่ยนแปลงเฉพาะในช่วง 0 ถึง 1 ก็ตาม

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

การปรับค่าทั้งหมดให้อยู่ในช่วง 0 ถึง 1 แบบนี้เรียกว่าการนอร์มาไลซ์ (normalize)

ค่านอร์มาไลซ์ = (ค่าเดิม - ค่าต่ำสุด)/(ค่าสูงสุด - ค่าต่ำสุด)

ดังนั้นเราจึงได้ค่าสีที่ไล่จากต่ำสุดจนสูงสุดเสมอ ไม่ต้องมาแปลงเอง

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



การใส่แท่งแถบสี
จากตัวอย่างที่แล้ว เพื่อให้เห็นการไล่เรียงสีชัด คราวนี้ลองเพิ่มแท่งที่มีการไล่เรียงสีตามลำดับเข้าไป
x = range(10)
y = [0]*10
c = [random.random() for i in range(10)]
plt.figure(figsize=(8,2))
plt.gca(ylim=[-4.5,1.5])
plt.scatter(x,y,c=c,s=1500,cmap='PuRd')
plt.scatter(x,[-3]*10,c=x,s=1500,marker='s',cmap='PuRd')
plt.show()

ทำแบบนี้ด้านล่างก็จะได้แท่งที่มีการจัดเรียงสีตามแบบของ PuRd



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

ที่จริงแล้ว matplotlib มีคำสั่งที่สร้างแท่งไล่เรียงสีที่ใช้อธิบายสีในคัลเลอร์แม็ป นั่นคือ plt.colorbar()

ลองพิมพ์ตามนี้เพิ่มเข้าไป
plt.colorbar()

จากนั้นก็จะมีแถบสีปรากฏทางขวา



แถบสีนี้เป็นสิ่งที่ควรใส่ไว้ทุกครั้ง มีความสำคัญเพราะทำให้เข้าใจว่าสีอะไรแทนค่าเท่าไหร่

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

ลองดูตัวอย่างเพิ่มเติม เอาตัวอย่างที่แล้วมาแก้ต่อโดยใช้ numpy แล้วก็เพิ่มเป็นร้อยจุด
import numpy as np
import matplotlib.pyplot as plt

x = np.arange(100)
y = np.zeros(100)
c = np.random.randint(0,100,100)
plt.figure(figsize=(8,2))
sc = plt.scatter(x,y,c=c,s=50,marker='d',cmap='hot')
plt.colorbar()
plt.show()



แถบสีนั้นสามารถปรับแต่งอะไรต่างๆได้มากมายโดยการเติมคีย์เวิร์ดเข้าไป เราจะกลับมาพูดถึงการปรับแต่งแถบสีเพิ่มเติมอีกในบทที่ ๒๖



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

แต่ว่าการทำสองมิตินั้นมีความซับซ้อน เราจำเป็นจะต้องเตรียมอาเรย์ที่เก็บไล่เรียงตำแหน่งในแกน x และ y ไว้ควบคู่กัน ซึ่งวิธีการสร้างก็มีอยู่หลายวิธี

วิธีหนึ่งอาจใช้ tile repeat reshape
x = np.tile(np.arange(10),(10,1))
y = np.repeat(np.arange(10),10).reshape(10,10)
print(x)
print(y)

ได้
[[0 1 2 3 4 5 6 7 8 9]
 [0 1 2 3 4 5 6 7 8 9]
 [0 1 2 3 4 5 6 7 8 9]
 [0 1 2 3 4 5 6 7 8 9]
 [0 1 2 3 4 5 6 7 8 9]
 [0 1 2 3 4 5 6 7 8 9]
 [0 1 2 3 4 5 6 7 8 9]
 [0 1 2 3 4 5 6 7 8 9]
 [0 1 2 3 4 5 6 7 8 9]
 [0 1 2 3 4 5 6 7 8 9]]
[[0 0 0 0 0 0 0 0 0 0]
 [1 1 1 1 1 1 1 1 1 1]
 [2 2 2 2 2 2 2 2 2 2]
 [3 3 3 3 3 3 3 3 3 3]
 [4 4 4 4 4 4 4 4 4 4]
 [5 5 5 5 5 5 5 5 5 5]
 [6 6 6 6 6 6 6 6 6 6]
 [7 7 7 7 7 7 7 7 7 7]
 [8 8 8 8 8 8 8 8 8 8]
 [9 9 9 9 9 9 9 9 9 9]]

จะเห็นว่า x เปลี่ยนค่าไปตามแนวนอน ส่วน y เปลี่ยนค่าไปตามแนวตั้ง แต่จะเหมือนเดิมตลอดในอีกแนว

นี่คืออาเรย์ที่เราต้องการ มีไว้ใช้แทนพิกัดในแกน x และ y สำหรับในแต่ละจุด



ที่จริงในมอดูลมาตรฐานของไพธอนก็มีฟังก์ชันที่ช่วยให้ทำอะไรในลักษณะนี้ออกมา ได้ นั่นคือฟังก์ชัน product ในมอดูล itertools ซึ่งอธิบายไว้ในบทความภาษาไพธอนเบื้องต้นบทที่ ๒๘

เพียงแต่ว่าผลที่ได้จะอยู่ในรูปหนึ่งมิติ ต้องมาแปลงเป็นอาเรย์แล้ว reshape อีกที
import itertools
xy = list(itertools.product(range(10),range(10)))
print(xy) # ได้ [(0, 0), (0, 1), (0, 2), (0, 3),...
x,y = np.array(xy).T.reshape(2,10,10)

ทำแบบนี้ก็จะได้ x กับ y เหมือนกันกับตัวอย่างที่แล้ว

แต่มีวิธีที่ทำได้ง่ายกว่าและนิยมมากกว่า นั่นคือการใช้ฟังก์ชัน np.meshgrid

หากเขียนเป็น
x,y = np.meshgrid(np.arange(10),np.arange(10))

ก็จะได้ x,y ในลักษณะแบบเดียวกับตัวอย่างข้างต้น

ฟังก์ชัน np.meshgrid มีไว้สำหรับสร้างลิสต์ของอาเรย์ที่แจกแจงค่า โดยออกมาในรูปของอาเรย์ที่มีมิติตามจำนวนอาร์กิวเมนต์ที่ใส่เข้าไป

ในที่นี้ใส่อาร์กิวเมนต์เป็น np.arange(10) ไป ๒ ตัว ซึ่ง ๒ ตัวนี้แทนแกน x และ y ผลที่ได้คือฟังก์ชันนี้จะคืนค่าอาเรย์ 10x10 มา ๒ ตัว ตัวแรกคือค่าของแกน x ตัวหลังคือของแกน y จากนั้นเราก็ใช้ตัวแปร x กับ y มารับค่าทั้งสองนี้

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

ทีนี้เมื่อได้โครงข่าย x และ y ตามที่ต้องการมาแล้วเราก็สร้างอาเรย์แทนความสูงซึ่งมีจำนวนแถวและหลักเท่ากันมา
z = np.random.randint(0,100,(10,10))
print(z)

ได้
[[93 43 63 56 68 71 15 16 40 16]
 [25 42 64  5 14 61 49 77 81 34]
 [77  1 78 96 93 81 11 33 45 26]
 [84 61 95 61  6 86 74 31 45 67]
 [10 28 73  4  9 34  2 34 37 70]
 [33  8 99 20 78 50 24  7 81 57]
 [56 62 16 69 64 44 14 49 78 92]
 [31 87 25 29 97 12 69 78 65 68]
 [12 67 23 82 32 37 25 23 13 83]
 [94 93 79 10  5  3 15 10 42 74]]

ลองนำมาเรียงต่อกันดูจะทำให้เห็นภาพขึ้น ในที่นี้อันบนสุดคืออาเรย์แทนความสูง และสองอันล่างคือพิกัดในแกน x และ y



เท่านี้ส่วนประกอบที่เราต้องการนำมาใช้วาดแผนภาพไล่สีก็พร้อมแล้ว

ต่อมาลองนำมาใช้วาดกราฟการแจกแจงเพื่อแสดงความสูงของพื้นที่ในสองมิติกันดูเลย
x,y = np.meshgrid(np.arange(10),np.arange(10)) # สร้างโครงข่ายแกน x และ y
khwamsung = np.random.randint(0,100,(10,10)) # สุ่มความสูงในช่วง 0 ถึง 99
plt.gca(aspect=1,xlim=[-1,10],ylim=[-1,10])
plt.scatter(x,y,c=khwamsung,s=600,marker='s',cmap='BuGn') # ใช้สีโทนเขียว
plt.colorbar() # ใส่แถบสีทางขวา
plt.show()





ต่อมาขอลองยกตัวอย่างใหม่ คราวนี้ลองเพิ่มความละเอียดเป็นร้อยแล้วให้ค่าความสูงเป็นค่าที่ได้จากการคำนวณ โดยใช้เป็นฟังก์ชันพาราโบลาซึ่งมีค่าต่ำสุดที่จุด 0,0 ที่ใจกลาง
x,y = np.meshgrid(np.linspace(-4,4,100),np.linspace(-4,4,100))
z = x**2+y**2 # ค่าความสูงเป็นพาราโบลา
plt.gca(xlim=[-4,4],ylim=[-4,4]) # กำหนดขอบเขตให้อยู่ในช่วง -4 ถึง 4
plt.scatter(x,y,c=z,s=15,marker='s',cmap='jet',lw=0) # วางจุด
plt.colorbar()
plt.show()





การสร้างแผนภาพไล่สี
แม้ว่า scatter จะใช้ทำแผนภาพไล่สีได้ แต่จริงๆแล้วมันไม่ได้ถูกออกแบบมาเพื่อการนี้โดยเฉพาะ มีอีกวิธีที่เหมาะกว่า นั่นคือใช้ฟังก์ชัน pcolor

ฟังก์ชันนี้มีไว้ระบายสีพื้นตามสีที่กำหนดในตำแหน่งต่างๆ การใช้ก็คล้ายๆกับ scatter ใส่อาร์กิวเมนต์สองตัวแรกเป็นแกน x และ y และตัวที่ ๓ ใส่ค่าสี

ลองแทนโค้ดตัวอย่างที่แล้ว บรรทัด plt.scatter ด้วย pcolor
plt.pcolor(x,y,z,cmap='jet')

ผลที่ได้จะแทบไม่ต่างจากเดิม

แต่ pcolor นั้นเมื่อใช้แล้วพื้นสีจะกระจายทั่วฉากเสมอ จะวางตำแหน่งจุดห่างแค่ไหนก็ได้

ถ้าวางจำนวนจุดน้อยก็จะเห็นเป็นเหมือนภาพที่ความละเอียดต่ำ

จะให้แนวตั้งและนอนมีความละเอียดไม่เท่ากันก็ได้ ตัวอย่างเช่น
x,y = np.meshgrid(np.linspace(-40,40,13),np.linspace(-40,40,50))

z = x**2+y**2

plt.pcolor(x,y,z,cmap='rainbow')
plt.colorbar()
plt.show()



หากต้องการจะแบ่งให้ไม่เท่ากันก็สามารถทำได้เช่นกัน

ตัวอย่างเช่น ลองให้ความกว้างช่องเพิ่มขึ้นเรื่อยๆเมื่อไกลจากตรงกลาง
x,y = np.meshgrid(np.linspace(-2,2,50)**3,np.linspace(-2,2,50)**3)

z = x**2+y**2

plt.pcolor(x,y,z,cmap='rainbow')
plt.colorbar()
plt.show()



ซึ่งตรงจุดนี้จะเห็นข้อแตกต่างระหว่าง pcolor กับ scatter ได้ชัดเมื่อลองดูข้อมูลที่มีความไม่ต่อเนื่อง เช่น
x,y = np.meshgrid(np.linspace(0,20,100),np.hstack((np.linspace(-20,5,100),np.linspace(15,20,50))))
z = x**2+y**2
plt.subplot(121,xlim=[0,20],ylim=[-20,20])
plt.scatter(x,y,c=z,marker='s',lw=0,cmap='gnuplot2')
plt.subplot(122,xlim=[0,20],ylim=[-20,20])
plt.pcolor(x,y,z,cmap='gnuplot2')
plt.show()



จะเห็นว่า scatter นั้นจะไม่มีการระบายในส่วนที่ข้อมูลขาด แต่ pcolor จะมีการเติมสีเชื่อมทำให้อาจดูแล้วแปลกๆหากสีที่เติมนั้นไม่ตรงกับที่ควรจะเป็นจริงๆ ดังนั้นในกรณีที่ต้องการให้แสดงเฉพาะข้อมูลส่วนที่มีแบบนี้อาจควรใช้ scatter มากกว่า



ในกรณีที่ต้องการให้สีแบ่งสม่ำเสมอนั้น pcolor ยังสามารถละ x,y ได้ด้วย โดยใส่อาร์กิวเมนต์เป็นสี (ความสูง) อย่างเดียวได้เลย แล้วพิกัดที่ได้จะถูกคิดตามตำแหน่งภายในอาเรย์ของอาเรย์ที่เก็บสี

ตัวอย่าง
x,y = np.meshgrid(np.linspace(-4,4,100),np.linspace(-4,4,100))
z = x**2+y**2
plt.pcolor(z,cmap='rainbow')
plt.colorbar()
plt.show()



นอกจากนี้ยังเพิ่มเส้นกั้นแต่ละช่องลงไปได้ด้วยคีย์เวิร์ด edgecolor โดยใส่ค่าสีลงไป และกำหนดความหนาของเส้นด้วยคีย์เวิร์ด linewidths

ลองแก้เป็น
plt.pcolor(z,cmap='rainbow',edgecolors='#222222',linewidths=0.5)

จะออกมาแบบนี้





นอกจากฟังก์ชัน pcolor แล้วก็ยังมี pcolormesh อีกตัวที่ทำงานคล้ายกันมาก แต่ก็มีความต่างกันเล็กน้อย โดยหลักๆแล้วก็คือ pcolormesh ทำงานเร็วกว่ามาก ดังนั้นโดยทั่วไปหากแผนภาพที่จะวาดมีความละเอียดมากต้องใช้เวลาวาดนานก็อาจควรเลือกใช้ pcolormesh แทน pcolor

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



อ้างอิง


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


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

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

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

หมวดหมู่

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

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

สารบัญ

รวมคำแปลวลีเด็ดจากญี่ปุ่น
python
-- numpy
-- matplotlib

-- pandas
-- pytorch
maya
การเรียนรู้ของเครื่อง
-- โครงข่าย
     ประสาทเทียม
บันทึกในญี่ปุ่น
บันทึกในจีน
-- บันทึกในปักกิ่ง
บันทึกในไต้หวัน
บันทึกในยุโรปเหนือ
บันทึกในประเทศอื่นๆ
เรียนภาษาจีน
qiita
บทความอื่นๆ

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



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

  ค้นหาบทความ

  บทความแนะนำ

หลักการเขียนทับศัพท์ภาษาจีนกลาง
g ในภาษาญี่ปุ่นออกเสียง "ก" หรือ "ง" กันแน่
ค้นพบระบบดาวเคราะห์ ๘ ดวง เบื้องหลังความสำเร็จคือปัญญาประดิษฐ์ (AI)
หอดูดาวโบราณปักกิ่ง ตอนที่ ๑: แท่นสังเกตการณ์และสวนดอกไม้
พิพิธภัณฑ์สถาปัตยกรรมโบราณปักกิ่ง
บ้านเก่าของจางเสวียเหลียงในเทียนจิน
เที่ยวจิ่นโจว ๓ วัน ๒ คืน 23 - 25 พ.ค. 2015
เที่ยวเมืองตานตง ล่องเรือในน่านน้ำเกาหลีเหนือ
บันทึกการเที่ยวสวีเดน 1-12 พ.ค. 2014
แนะนำองค์การวิจัยและพัฒนาการสำรวจอวกาศญี่ปุ่น (JAXA)
เที่ยวฮ่องกงในคืนคริสต์มาสอีฟ เดินทางไกลจากสนามบินมาทานติ่มซำอร่อยโต้รุ่ง
เล่าประสบการณ์ค่ายอบรมวิชาการทางดาราศาสตร์โดยโซวเคนได 10 - 16 พ.ย. 2013
ตระเวนเที่ยวตามรอยฉากของอนิเมะในญี่ปุ่น
เที่ยวชมหอดูดาวที่ฐานสังเกตการณ์ซิงหลง
บันทึกการเที่ยวญี่ปุ่นครั้งแรกในชีวิต - ทุกอย่างเริ่มต้นที่สนามบินนานาชาติคันไซ
หลักการเขียนคำทับศัพท์ภาษาญี่ปุ่น
ทำไมจึงไม่ควรเขียนวรรณยุกต์เวลาทับศัพท์ภาษาต่างประเทศ
ทำไมถึงอยากมาเรียนต่อนอก
เหตุผลอะไรที่ต้องใช้ภาษาวิบัติ?

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

2019年

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

2018年

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

2017年

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

2016年

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

2015年

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

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

ไทย

日本語

中文