Làm cách nào để vẽ các giá trị NaN dưới dạng màu đặc biệt với imshow trong matplotlib?


85

Tôi đang cố gắng sử dụng imshow trong matplotlib để vẽ dữ liệu dưới dạng bản đồ nhiệt, nhưng một số giá trị là NaN. Tôi muốn NaN được hiển thị dưới dạng màu đặc biệt không có trong bản đồ màu.

thí dụ:

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()

Hình ảnh kết quả bất ngờ toàn màu xanh lam (màu thấp nhất trong biểu đồ màu máy bay phản lực). Tuy nhiên, nếu tôi thực hiện âm mưu như thế này:

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

--Sau đó, tôi nhận được thứ gì đó tốt hơn, nhưng các giá trị NaN được vẽ cùng màu với vmin ... Có cách nào duyên dáng để tôi có thể đặt các NaN được vẽ bằng màu đặc biệt (ví dụ: xám hoặc trong suốt) không?


Một vài năm sau ( matplotlib.__version__=='1.2.1'), điều này hoạt động mà không có vấn đề gì.
Frédéric Grosshans

Câu trả lời:


46

Với các phiên bản mới hơn của Matplotlib, không cần thiết phải sử dụng mảng che nữa.

Ví dụ: hãy tạo một mảng trong đó mọi giá trị thứ 7 là một NaN:

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

Chúng ta có thể sửa đổi bản đồ màu hiện tại và vẽ mảng bằng các dòng sau:

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

kết quả âm mưu


có thể sử dụng 0 thay vì np.nan không?
yukashima huksay

2
@yukashimahuksay: có, nhưng bạn sẽ cần che những giá trị này. Ví dụ. arr = np.ma.array(arr, mask=(arr == 0)).
Arcturus B

Tôi nghĩ rằng 'c' trong 'CMAP' đã là viết tắt của 'hiện tại', vì vậy tôi sẽ không gọi biến 'current_cmap'
T. Gwen

3
@TGwen: Tôi khá chắc rằng cmap là viết tắt của colormap, là thuật ngữ được sử dụng trong tài liệu: matplotlib.org/api/cm_api.html#matplotlib.cm.get_cmap
Arcturus B

82

Hrm, có vẻ như tôi có thể sử dụng một mảng được che để làm điều này:

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)

Điều này là đủ, mặc dù tôi vẫn mở các đề xuất. :]


Nó chắc chắn làm được thủ thuật. Tài liệu chính thức không hiển thị gì thêm.
Agos

6
Một điểm bên - Tôi nghĩ rằng việc này sẽ ghi đè mặc định matplotlib.cm.jet, vì vậy tôi thường tạo một bản sao: import copy; cmap=copy.copy(matplotlib.cm.jet). Ngoài ra, nếu bạn muốn đặt các giá trị 0 thành một màu khác, một cái gì đó tương tự cmap._init(); cm._lut[:,0] = (1,1,1,1)sẽ hoạt động.
keflavich

3
Ngoài ra còn có set_overset_underđể kiểm soát màu của các giá trị ngoài phạm vi. Hành vi mặc định là khớp với phần trên / dưới của dải màu.
tacaswell

2
masked_arrayyêu cầu ở tất cả? Nếu achứa các giá trị NaN (có vẻ như mask=np.isnan(a)), thì chỉ cần imshow-ing mảng avới bản đồ tùy chỉnh cmapsẽ hiển thị các ô NaN với màu bắt buộc (trắng). Vì vậy, nó làm việc cho tôi. Có ngoại lệ nào không?
MaciekS

2
@MaciekS, khi sử dụng bản đồ màu phân kỳ, bạn không muốn các nangiá trị và giá trị trung vị của mình được vẽ cùng một màu, ví dụ như màu trắng.
AGS
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.