Trước hết, có nhiều cách để thực hiện việc này.
- Sử dụng
colors
kwarg để contourf
và tự xác định màu sắc
- Sử dụng một lớp tùy chỉnh
Normalize
và vượt qua một ví dụ trong khi norm
kwarg.
- Sử dụng bản đồ rời rạc được tạo bằng
matplotlib.colors.from_levels_and_colors
.
Cách đơn giản nhất là chuyển màu cụ thể bằng colors=sequence_of_colors
. Tuy nhiên, nếu bạn không tự thiết lập số lượng đường nét, điều này có thể bất tiện.
Cách linh hoạt nhất là tùy chọn thứ hai: sử dụng số norm
kwarg để chỉ định tùy chỉnh chuẩn hóa. Đối với những gì bạn muốn, bạn sẽ cần phải phân lớp Normalize
, nhưng điều này không quá khó để làm. Đây là tùy chọn duy nhất cho phép bạn sử dụng bản đồ màu liên tục.
Lý do sử dụng tùy chọn thứ hai hoặc thứ ba là chúng sẽ hoạt động với bất kỳ loại âm mưu matplotlib nào sử dụng bản đồ màu (ví dụ: imshow
, scatter
, v.v ...).
Tùy chọn thứ ba xây dựng một đối tượng chuẩn hóa và đối tượng chuẩn hóa rời rạc từ các màu cụ thể. Về cơ bản nó giống với tùy chọn đầu tiên, nhưng nó sẽ a) làm việc với các loại ô khác so với các ô đường viền, và b) tránh phải chỉ định số lượng đường bao theo cách thủ công.
Như một ví dụ về sự lựa chọn thứ hai (Tôi sẽ sử dụng imshow
ở đây vì nó có ý nghĩa hơn contourf
cho dữ liệu ngẫu nhiên, nhưng contourf
sẽ phải sử dụng giống hệt nhau khác hơn là tùy chọn interpolation
.):
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import Normalize
class MidpointNormalize(Normalize):
def __init__(self, vmin=None, vmax=None, midpoint=None, clip=False):
self.midpoint = midpoint
Normalize.__init__(self, vmin, vmax, clip)
def __call__(self, value, clip=None):
# I'm ignoring masked values and all kinds of edge cases to make a
# simple example...
x, y = [self.vmin, self.midpoint, self.vmax], [0, 0.5, 1]
return np.ma.masked_array(np.interp(value, x, y))
data = np.random.random((10,10))
data = 10 * (data - 0.8)
fig, ax = plt.subplots()
norm = MidpointNormalize(midpoint=0)
im = ax.imshow(data, norm=norm, cmap=plt.cm.seismic, interpolation='none')
fig.colorbar(im)
plt.show()
Như một ví dụ về sự lựa chọn thứ ba (lưu ý rằng điều này mang lại một bản đồ màu rời rạc thay vì một bản đồ màu liên tục):
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import from_levels_and_colors
data = np.random.random((10,10))
data = 10 * (data - 0.8)
num_levels = 20
vmin, vmax = data.min(), data.max()
midpoint = 0
levels = np.linspace(vmin, vmax, num_levels)
midp = np.mean(np.c_[levels[:-1], levels[1:]], axis=1)
vals = np.interp(midp, [vmin, midpoint, vmax], [0, 0.5, 1])
colors = plt.cm.seismic(vals)
cmap, norm = from_levels_and_colors(levels, colors)
fig, ax = plt.subplots()
im = ax.imshow(data, cmap=cmap, norm=norm, interpolation='none')
fig.colorbar(im)
plt.show()
Tuyệt vời, đây chỉ là những gì tôi đang tìm kiếm, cảm ơn! – pgierz
Nên được thêm vào Matplotlib – Moritz
@Joe Kington, điều đó thực sự tuyệt vời! Tôi đang sao chép định nghĩa lớp học của bạn cho một dự án nguồn mở và đặt tên của bạn là tác giả. Hy vọng bạn sẽ ổn với nó. –