Tự Học Data Science · 01/03/2024 0

04.10 Customizing Ticks

Major và Minor Ticks

Trong mỗi trục, có khái niệm về đánh dấu chínhđánh dấu phụ. Như tên gợi ý, đánh dấu chính thường lớn hơn hoặc nổi bật hơn, trong khi đánh dấu phụ thường nhỏ hơn. Mặc định, Matplotlib hiếm khi sử dụng đánh dấu phụ, nhưng bạn có thể thấy chúng trong các đồ thị logarit:

import matplotlib.pyplot as pltplt.style.use('classic')%matplotlib inlineimport numpy as np
ax = plt.axes(xscale='log', yscale='log')ax.grid();
ảnh ví dụ - data science lại blog của lưu

Ta thấy ở đây rằng mỗi dấu chấm lớn thể hiện một đường kẻ gạch dọc lớn và một nhãn, trong khi mỗi dấu chấm nhỏ chỉ thể hiện một đường kẻ gạch dọc nhỏ mà không có nhãn.

Các thuộc tính dấu check này — vị trí và nhãn, nghĩa là, có thể được tùy chỉnh bằng cách thiết lập các đối tượng formatterlocator cho mỗi trục. Hãy xem xét chúng cho trục x của đồ thị vừa được hiển thị:

print(ax.xaxis.get_major_locator())print(ax.xaxis.get_minor_locator())
<matplotlib.ticker.LogLocator object at 0x10dbaf630><matplotlib.ticker.LogLocator object at 0x10dba6e80>
print(ax.xaxis.get_major_formatter())print(ax.xaxis.get_minor_formatter())
<matplotlib.ticker.LogFormatterMathtext object at 0x10db8dbe0><matplotlib.ticker.NullFormatter object at 0x10db9af60>

Chúng ta thấy rằng cả nhãn điểm chính và nhãn điểm phụ đều có vị trí được chỉ định bởi một LogLocator (điều này hợp lý cho một biểu đồ logarithmic). Tuy nhiên, nhãn điểm phụ lại được định dạng bởi một NullFormatter: điều này có nghĩa là không có nhãn nào sẽ được hiển thị.

Bây giờ chúng tôi sẽ thể hiện một số ví dụ về cách thiết lập các bộ chỉ định và định dạng cho các đồ thị khác nhau.

Ẩn các nhãn hoặc điểm đánh dấu

Có lẽ thao tác định dạng nhãn/tick phổ biến nhất là việc ẩn những dấu tick hoặc nhãn.Điều này có thể được thực hiện bằng cách sử dụng plt.NullLocator()plt.NullFormatter(), như được thể hiện ở đây:

ax = plt.axes()ax.plot(np.random.rand(50))ax.yaxis.set_major_locator(plt.NullLocator())ax.xaxis.set_major_formatter(plt.NullFormatter())
ảnh ví dụ - data science lại blog của lưu

Lưu ý rằng chúng tôi đã loại bỏ nhãn (nhưng giữ nguyên dấu tick/gridlines) trên trục x và loại bỏ những dấu tick (và nhãn theo đó) trên trục y.Không có dấu tick hoàn toàn có thể hữu ích trong nhiều tình huống – ví dụ, khi bạn muốn hiển thị một lưới hình ảnh.Ví dụ, xem xét hình vẽ sau đây, bao gồm các hình ảnh của các khuôn mặt khác nhau, một ví dụ thường được sử dụng trong các bài toán học máy có giám sát (xem, ví dụ, Sâu: Máy Vector Hỗ Trợ):

fig, ax = plt.subplots(5, 5, figsize=(5, 5))fig.subplots_adjust(hspace=0, wspace=0)# Get some face data from scikit-learnfrom sklearn.datasets import fetch_olivetti_facesfaces = fetch_olivetti_faces().imagesfor i in range(5):    for j in range(5):        ax[i, j].xaxis.set_major_locator(plt.NullLocator())        ax[i, j].yaxis.set_major_locator(plt.NullLocator())        ax[i, j].imshow(faces[10 * i + j], cmap="bone")
ảnh ví dụ - data science lại blog của lưu

Chú ý rằng mỗi hình ảnh có trục riêng của nó, và chúng tôi đã đặt trình tìm tuyến truyền dẫn thành null vì các giá trị đánh dấu (số điểm ảnh trong trường hợp này) không truyền tải thông tin liên quan cho việc hiển thị này cụ thể.

Giảm hoặc Tăng số lượng Cạnh

Một vấn đề phổ biến với các thiết lập mặc định là các subplots nhỏ có thể mắc kẹt với các nhãn quá đông.Chúng ta có thể thấy điều này trong lưới plot được hiển thị ở đây:

fig, ax = plt.subplots(4, 4, sharex=True, sharey=True)
ảnh ví dụ - data science lại blog của lưu

Đặc biệt là với các điểm chấm x, các số gần nhau và làm cho chúng khó để đọc.Chúng ta có thể chỉnh sửa điều này bằng cách sử dụng plt.MaxNLocator(), cho phép chúng ta xác định số lượng tối đa của các điểm chấm sẽ được hiển thị.Dựa trên số lượng tối đa này, Matplotlib sẽ sử dụng logic nội bộ để chọn các vị trí cụ thể của các điểm chấm:

# For every axis, set the x and y major locatorfor axi in ax.flat:    axi.xaxis.set_major_locator(plt.MaxNLocator(3))    axi.yaxis.set_major_locator(plt.MaxNLocator(3))fig
ảnh ví dụ - data science lại blog của lưu

Việc này làm cho mọi thứ trở nên sạch sẽ hơn. Nếu bạn muốn có thêm kiểm soát về vị trí của các ticks được cách đều nhau, bạn cũng có thể sử dụng plt.MultipleLocator, mà chúng ta sẽ thảo luận trong phần tiếp theo.

Các Định dạng Tick Phong cách

Định dạng đánh dấu mặc định của Matplotlib có thể không đáp ứng được yêu cầu: nó hoạt động tốt như một định dạng mặc định rộng, nhưng đôi khi bạn muốn làm điều gì đó hơn.Xem xét đồ thị được vẽ của một hàm sin và một hàm cos:

# Plot a sine and cosine curvefig, ax = plt.subplots()x = np.linspace(0, 3 * np.pi, 1000)ax.plot(x, np.sin(x), lw=3, label='Sine')ax.plot(x, np.cos(x), lw=3, label='Cosine')# Set up grid, legend, and limitsax.grid(True)ax.legend(frameon=False)ax.axis('equal')ax.set_xlim(0, 3 * np.pi);
ảnh ví dụ - data science lại blog của lưu

Có một số thay đổi chúng ta có thể muốn thực hiện. Trước tiên, việc căn đều các đường đánh dấu và đường lưới theo bội số của $\pi$ sẽ tự nhiên hơn. Chúng ta có thể thực hiện điều này bằng cách thiết lập một MultipleLocator, mà sẽ định vị các đường đánh dấu tại các bội số của số bạn cung cấp. Nhằm đảm bảo, chúng ta sẽ thêm cả đường đánh dấu chính và đường đánh dấu phụ tại các bội số của $\pi/4$:

ax.xaxis.set_major_locator(plt.MultipleLocator(np.pi / 2))ax.xaxis.set_minor_locator(plt.MultipleLocator(np.pi / 4))fig
ảnh ví dụ - data science lại blog của lưu

Nhưng bây giờ các nhãn tick này trông hơi lố: chúng ta có thể thấy rằng chúng là bội số của $\pi$, nhưng biểu diễn thập phân không ngay lập tức truyền tải điều này.

def format_func(value, tick_number):    # find number of multiples of pi/2    N = int(np.round(2 * value / np.pi))    if N == 0:        return "0"    elif N == 1:        return r"$\pi/2$"    elif N == 2:        return r"$\pi$"    elif N % 2 > 0:        return r"${0}\pi/2$".format(N)    else:        return r"${0}\pi$".format(N // 2)ax.xaxis.set_major_formatter(plt.FuncFormatter(format_func))fig
ảnh ví dụ - data science lại blog của lưu

Điều này tốt hơn nhiều! Lưu ý rằng chúng tôi đã sử dụng hỗ trợ LaTeX của Matplotlib, được chỉ định bằng cách bao quanh chuỗi bằng dấu đô la. Điều này rất thuận tiện cho việc hiển thị các biểu tượng và công thức toán học: trong trường hợp này, "$\pi$" được hiển thị dưới dạng ký tự Hy Lạp $\pi$.

Thẻ plt.FuncFormatter() cung cấp kiểm soát cực kỳ tinh tế về diện mạo của các điểm chấm trên đồ thị của bạn, và rất hữu ích khi chuẩn bị đồ thị cho việc thuyết trình hoặc xuất bản.

Tóm tắt các Formatters và Locators

Chúng ta đã đề cập đến một vài định dạng và trình tìm vị trí có sẵn.Chúng ta sẽ kết thúc phần này bằng việc liệt kê tóm tắt tất cả các tùy chọn trình tìm vị trí và định dạng tích hợp sẵn. Để biết thêm thông tin về bất kỳ cái nào trong số này, hãy tham khảo docstrings hoặc tài liệu trực tuyến của Matplotlib.Mỗi phần sau đây đều có sẵn trong không gian tên plt:

Chúng ta sẽ xem những ví dụ cụ thể hơn về những điều này trong phần còn lại của cuốn sách.