ฉันจะพล็อตค่า NaN เป็นสีพิเศษด้วย imshow ใน matplotlib ได้อย่างไร


85

ฉันพยายามใช้ imshow ใน matplotlib เพื่อพล็อตข้อมูลเป็นแผนที่ความร้อน แต่ค่าบางค่าเป็น NaN ฉันต้องการให้ NaN แสดงผลเป็นสีพิเศษที่ไม่พบใน colormap

ตัวอย่าง:

import numpy as np
import matplotlib.pyplot as plt
f = plt.figure()
ax = f.add_subplot(111)
a = np.arange(25).reshape((5,5)).astype(float)
a[3,:] = np.nan
ax.imshow(a, interpolation='nearest')
f.canvas.draw()

ภาพที่ได้จะเป็นสีฟ้าทั้งหมดโดยไม่คาดคิด (สีต่ำสุดในเจ็ท Colormap) อย่างไรก็ตามถ้าฉันวางแผนเช่นนี้:

ax.imshow(a, interpolation='nearest', vmin=0, vmax=24)

- แล้วฉันจะได้อะไรที่ดีขึ้น แต่ค่า NaN ถูกวาดเป็นสีเดียวกับ vmin ... มีวิธีที่สง่างามไหมที่ฉันสามารถตั้งค่า NaN ให้วาดด้วยสีพิเศษ (เช่นเทาหรือโปร่งใส)


ไม่กี่ปีต่อมา ( matplotlib.__version__=='1.2.1') ใช้งานได้โดยไม่มีปัญหา
Frédéric Grosshans

คำตอบ:


47

ด้วย Matplotlib เวอร์ชันใหม่กว่าคุณไม่จำเป็นต้องใช้อาร์เรย์มาสก์อีกต่อไป

ตัวอย่างเช่นให้สร้างอาร์เรย์โดยทุกค่าที่ 7 เป็น NaN:

arr = np.arange(100, dtype=float).reshape(10, 10)
arr[~(arr % 7).astype(bool)] = np.nan

เราสามารถแก้ไข colormap ปัจจุบันและพล็อตอาร์เรย์ด้วยบรรทัดต่อไปนี้:

current_cmap = matplotlib.cm.get_cmap()
current_cmap.set_bad(color='red')
plt.imshow(arr)

พล็อตผลลัพธ์


เป็นไปได้ไหมที่จะใช้ 0 แทน np.nan
yukashima huksay

2
@yukashimahuksay: ใช่ แต่คุณจะต้องปิดบังค่าเหล่านี้ เช่น. arr = np.ma.array(arr, mask=(arr == 0)).
Arcturus B

ฉันคิดว่า 'c' ใน 'cmap' ย่อมาจาก 'current' อยู่แล้วดังนั้นฉันจะไม่เรียกตัวแปร 'current_cmap'
T. Gwen

3
@TGwen: ฉันค่อนข้างมั่นใจว่า cmap ย่อมาจาก colormap ซึ่งเป็นคำที่ใช้ใน doc: matplotlib.org/api/cm_api.html#matplotlib.cm.get_cmap
Arcturus B

82

อืมดูเหมือนว่าฉันสามารถใช้อาร์เรย์มาสก์เพื่อทำสิ่งนี้:

masked_array = np.ma.array (a, mask=np.isnan(a))
cmap = matplotlib.cm.jet
cmap.set_bad('white',1.)
ax.imshow(masked_array, interpolation='nearest', cmap=cmap)

แค่นี้ก็เพียงพอแล้วแม้ว่าฉันจะยังเปิดรับข้อเสนอแนะ :]


แน่นอนมันไม่หลอกลวง เอกสารอย่างเป็นทางการไม่แสดงอะไรเพิ่มเติม
Agos

6
จุดด้าน - ผมคิดว่าการทำเช่นนี้จะแทนที่ค่าเริ่มต้นดังนั้นฉันมักจะทำสำเนา:matplotlib.cm.jet import copy; cmap=copy.copy(matplotlib.cm.jet)นอกจากนี้หากคุณต้องการตั้งค่า 0 เป็นสีอื่นสิ่งที่ต้องการcmap._init(); cm._lut[:,0] = (1,1,1,1)จะใช้ได้
keflavich

3
นอกจากนี้ยังมีset_overและset_underควบคุมการระบายสีของค่านอกช่วง ลักษณะการทำงานเริ่มต้นคือตรงกับด้านบน / ล่างของช่วงสี
tacaswell

2
เป็นmasked_arrayต้องได้ทั้งหมดหรือไม่ ถ้าaมีค่า NaN (ดูเหมือนว่าmask=np.isnan(a) ) ดังนั้นimshowการจัดเรียงอาร์เรย์aด้วยแผนที่ที่กำหนดเองcmapจะแสดงเซลล์ NaN พร้อมสีที่ต้องการ (สีขาว) มันใช้ได้กับฉัน มีข้อยกเว้นหรือไม่?
MaciekS

2
@MaciekS เมื่อใช้ colormap แบบแยกส่วนคุณไม่ต้องการให้nanค่าและค่ามัธยฐานของคุณถูกพล็อตเป็นสีเดียวกันเช่นสีขาว
AGS
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.