Tự Học Data Science · 15/02/2024 0

04.07 Customizing Colorbars

Tùy chỉnh thanh màu

Bảng màu có thể được chỉ định bằng cách sử dụng đối số cmap của chức năng vẽ đang tạo ra biểu đồ:

plt.imshow(I, cmap='gray');
ảnh ví dụ - data science lại blog của lưu

Tất cả các bản đồ màu hiện có đều có sẵn trong không gian tên plt.cm; sử dụng tính năng hoàn thành bằng tab của IPython sẽ cung cấp cho bạn một danh sách đầy đủ các tùy chọn tích hợp sẵn:

plt.cm.<TAB>

Nhưng việc có thể lựa chọn bảng màu chỉ là bước đầu tiên: quan trọng hơn là cách quyết định giữa các khả năng!Lựa chọn này thực sự tinh vi hơn rất nhiều so với những gì bạn có thể mong đợi ban đầu.

Chọn bản đồ màu

Một cách xử lý màu sắc đầy đủ trong trực quan hóa vượt quá phạm vi cuốn sách này, nhưng để đọc thú vị về chủ đề này và những chủ đề khác, hãy xem bài viết “Mười quy tắc đơn giản để có hình ảnh tốt hơn”.Tài liệu trực tuyến của Matplotlib cũng có một cuộc thảo luận thú vị về việc lựa chọn sơ đồ màu.

Chung quy, bạn nên nhận biết ba danh mục colormap khác nhau:

  • Sequential colormaps: Đây là các bản đồ màu được tạo thành từ một dãy màu liên tiếp (ví dụ: binary hoặc viridis).
  • Divergent colormaps: Thường chứa hai màu khác nhau, biểu thị sự chênh lệch dương và âm từ một giá trị trung bình (ví dụ: RdBu or PuOr).
  • Qualitative colormaps: Kết hợp các màu mà không có trình tự cụ thể (ví dụ: rainbow hoặc jet).

Cmap jet, tên ngắn của “jet colormap” được sử dụng mặc định trong Matplotlib trước phiên bản 2.0, là một ví dụ về colormaps cuả chất lượng.Việc sử dụng cmap này mặc định đã là một lựa chọn không may mắn, vì colormap chất lượng thường không phù hợp để biểu diễn dữ liệu định lượng.Một số vấn đề trong sử dụng colormap chất lượng là colormap này thường không hiển thị sự tiến trình đồn đều trong độ sáng khi giá trị tăng.

Ta có thể nhìn thấy điều này bằng cách chuyển đổi thanh màu jet thành đen trắng:

from matplotlib.colors import LinearSegmentedColormapdef grayscale_cmap(cmap):    """Return a grayscale version of the given colormap"""    cmap = plt.cm.get_cmap(cmap)    colors = cmap(np.arange(cmap.N))        # convert RGBA to perceived grayscale luminance    # cf. http://alienryderflex.com/hsp.html    RGB_weight = [0.299, 0.587, 0.114]    luminance = np.sqrt(np.dot(colors[:, :3] ** 2, RGB_weight))    colors[:, :3] = luminance[:, np.newaxis]            return LinearSegmentedColormap.from_list(cmap.name + "_gray", colors, cmap.N)    def view_colormap(cmap):    """Plot a colormap with its grayscale equivalent"""    cmap = plt.cm.get_cmap(cmap)    colors = cmap(np.arange(cmap.N))        cmap = grayscale_cmap(cmap)    grayscale = cmap(np.arange(cmap.N))        fig, ax = plt.subplots(2, figsize=(6, 2),                           subplot_kw=dict(xticks=[], yticks=[]))    ax[0].imshow([colors], extent=[0, 10, 0, 1])    ax[1].imshow([grayscale], extent=[0, 10, 0, 1])
view_colormap('jet')
ảnh ví dụ - data science lại blog của lưu

Chú ý những vạch sáng trong hình ảnh đã được chuyển sang dạng xám.Ngay cả trong màu sắc đầy đủ, độ sáng không đồng đều này có nghĩa là mắt sẽ được hướng tới một số phần trong dải màu, điều này có thể làm nổi bật các phần không quan trọng của dữ liệu.Nên tốt hơn là sử dụng một colormap như viridis (mặc định từ Matplotlib 2.0), nó được xây dựng một cách cụ thể để có độ biến đổi độ sáng nhất quán trong dải màu.Do đó, nó không chỉ phù hợp với sự nhận thức về màu sắc của chúng ta, mà còn sẽ được dịch sang in đen trắng một cách tốt:

view_colormap('viridis')
ảnh ví dụ - data science lại blog của lưu

Nếu bạn thích những sắc màu cầu vồng, một lựa chọn tốt khác cho dữ liệu liên tục là bản đồ màu cubehelix:

view_colormap('cubehelix')
ảnh ví dụ - data science lại blog của lưu

Đối với những tình huống khác, chẳng hạn như hiển thị sự chênh lệch tích cực và tiêu cực từ một giá trị trung bình nào đó, các thanh màu kép như RdBu (Đỏ-Xanh lam) có thể hữu ích. Tuy nhiên, như bạn có thể thấy trong hình ảnh dưới đây, quan trọng nhất là lưu ý rằng thông tin tích cực-tiêu cực sẽ bị mất đi khi chuyển đổi sang màu xám!

view_colormap('RdBu')
ảnh ví dụ - data science lại blog của lưu

Chúng ta sẽ xem các ví dụ về việc sử dụng một số bản đồ màu này khi chúng ta tiếp tục.

Có một số lượng lớn colormaps có sẵn trong Matplotlib; để xem danh sách chúng, bạn có thể sử dụng IPython để khám phá phụ mục plt.cm. Để có cách tiếp cận chính thức hơn với màu sắc trong Python, bạn có thể tham khảo các công cụ và tài liệu trong thư viện Seaborn (xem Visualization With Seaborn).

Màu giới hạn và mở rộng

Matplotlib cho phép tùy chỉnh đa dạng cho thanh màu.Thanh mà lại chỉ đơn giản là một thể hiện của plt.Axes, vì vậy tất cả các chiêu trò định dạng trục và điểm đánh dấu mà chúng ta đã học đều có thể áp dụng được.Thanh màu có một sự linh hoạt thú vị: ví dụ, chúng ta có thể hạn chế giới hạn màu và chỉ ra các giá trị vượt ra ngoài với một mũi tên tam giác ở trên và dưới bằng cách đặt thuộc tính extend.Điều này có thể hữu ích, ví dụ như khi hiển thị một hình ảnh bị ảnh hướng bởi nhiễu:

# make noise in 1% of the image pixelsspeckles = (np.random.random(I.shape) < 0.01)I[speckles] = np.random.normal(0, 3, np.count_nonzero(speckles))plt.figure(figsize=(10, 3.5))plt.subplot(1, 2, 1)plt.imshow(I, cmap='RdBu')plt.colorbar()plt.subplot(1, 2, 2)plt.imshow(I, cmap='RdBu')plt.colorbar(extend='both')plt.clim(-1, 1);
ảnh ví dụ - data science lại blog của lưu

Lưu ý rằng trong bảng điều khiển bên trái, giới hạn màu mặc định phản ứng với các điểm ảnh nhiễu, và độ nhiễu hoàn toàn khiến mô hình chúng ta quan tâm bị mờ mờ mờ.Trong bảng điều khiển bên phải, chúng ta thủ công đặt giới hạn màu, và thêm các mở rộng để chỉ ra các giá trị vượt quá hoặc dưới giới hạn đó.Kết quả là một cách hiển thị dữ liệu hữu ích hơn nhiều.

Thanh màu rời rạc

Các đa dạng màu sắc mặc định là liên tục, nhưng đôi khi bạn muốn biểu diễn các giá trị rời rạc.Cách đơn giản nhất để làm điều này là sử dụng hàm plt.cm.get_cmap() và truyền tên của một bảng màu phù hợp cùng với số lượng bin mong muốn:

plt.imshow(I, cmap=plt.cm.get_cmap('Blues', 6))plt.colorbar()plt.clim(-1, 1);
ảnh ví dụ - data science lại blog của lưu

Phiên bản rời rạc của một bảng màu có thể được sử dụng giống như bất kỳ bảng màu nào khác.

Ví dụ: Chữ số viết tay

Ví dụ để minh họa cho việc này có thể được thấy trong một biểu đồ thú vị của dữ liệu về các chữ số được viết tay.Dữ liệu này được bao gồm trong Scikit-Learn và bao gồm gần 2,000 hình nhỏ $8 \times 8$ hiển thị các chữ số viết tay khác nhau.

Hiện tại, chúng ta hãy bắt đầu bằng cách tải xuống dữ liệu chữ số và trực quan hóa một số hình ảnh minh họa bằng cách sử dụng plt.imshow():

# load images of the digits 0 through 5 and visualize several of themfrom sklearn.datasets import load_digitsdigits = load_digits(n_class=6)fig, ax = plt.subplots(8, 8, figsize=(6, 6))for i, axi in enumerate(ax.flat):    axi.imshow(digits.images[i], cmap='binary')    axi.set(xticks=[], yticks=[])
ảnh ví dụ - data science lại blog của lưu

Vì mỗi chữ số được xác định bởi sắc thái của 64 pixel của nó, chúng ta có thể coi mỗi chữ số là một điểm nằm trong không gian 64 chiều: mỗi chiều đại diện cho độ sáng của một pixel.Nhưng việc hình dung mối quan hệ trong các không gian có số chiều cao như vậy có thể rất khó khăn.Một cách tiếp cận để giải quyết vấn đề này là sử dụng một kỹ thuật giảm số chiều như manifold learning để giảm số chiều dữ liệu trong khi vẫn giữ được mối quan hệ quan tâm.Giảm số chiều là một ví dụ về unsupervised machine learning, và chúng ta sẽ thảo luận về nó chi tiết hơn trong What Is Machine Learning?.

Trì hoãn thảo luận về các chi tiết này, hãy xem một hình chiếu học manifold hai chiều của dữ liệu chữ số này (xem Sâu: Học Manifold để biết chi tiết):

# project the digits into 2 dimensions using IsoMapfrom sklearn.manifold import Isomapiso = Isomap(n_components=2)projection = iso.fit_transform(digits.data)

Chúng ta sẽ sử dụng bản đồ màu độc lập của chúng tôi để xem kết quả, đặt ticksclim để cải thiện mỹ thuật của colorbar kết quả:

# plot the resultsplt.scatter(projection[:, 0], projection[:, 1], lw=0.1,            c=digits.target, cmap=plt.cm.get_cmap('cubehelix', 6))plt.colorbar(ticks=range(6), label='digit value')plt.clim(-0.5, 5.5)
ảnh ví dụ - data science lại blog của lưu

Phép chiếu đồng thời cung cấp cho chúng ta một số cái nhìn thú vị về các mối quan hệ trong tập dữ liệu: ví dụ, các phạm vi của 5 và 3 gần như trùng nhau trong phép chiếu này, cho thấy một số số năm và ba viết bằng tay khó phân biệt và do đó có khả năng bị nhầm lẫn hơn bởi một thuật toán phân loại tự động.Các giá trị khác, như 0 và 1, cách nhau xa hơn, và do đó khó bị nhầm lẫn hơn nhiều.Quan sát này tương đồng với trực giác của chúng ta, bởi vì số 5 và 3 trông giống nhau hơn so với số 0 và 1.

Chúng ta sẽ quay trở lại với thao tác học đa dạng và phân loại chữ số trong Chương 5.