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

04.08 Multiple Subplots

plt.axes: Sử dụng subplot bằng cách tạo thủ công

Phương pháp cơ bản nhất để tạo một trục là sử dụng hàm plt.axes.Như chúng ta đã thấy trước đây, mặc định hàm này tạo ra một đối tượng trục chuẩn lấp đầy toàn bộ hình.plt.axes cũng có thể nhận một đối số tùy chọn là một danh sách gồm bốn số trong hệ tọa độ của hình.Các số này đại diện cho [left, bottom, width, height] trong hệ tọa độ của hình, với giá trị từ 0 ở góc dưới bên trái của hình đến 1 ở góc trên bên phải của hình.

Ví dụ, chúng ta có thể tạo ra một trục nội tại ở góc trên bên phải của một trục khác bằng cách đặt giá trị xy là 0.65 (tức là bắt đầu từ 65% chiều rộng và 65% chiều cao của hình) và giá trị mở rộng xy là 0.2 (tức là khổ của trục là 20% chiều rộng và 20% chiều cao của hình):

ax1 = plt.axes()  # standard axesax2 = plt.axes([0.65, 0.65, 0.2, 0.2])
ảnh ví dụ - data science lại blog của lưu

Đối tượng tương đương của lệnh này trong giao diện hướng đối tượng là fig.add_axes(). Hãy sử dụng nó để tạo hai trục được xếp chồng theo chiều dọc:

fig = plt.figure()ax1 = fig.add_axes([0.1, 0.5, 0.8, 0.4],                   xticklabels=[], ylim=(-1.2, 1.2))ax2 = fig.add_axes([0.1, 0.1, 0.8, 0.4],                   ylim=(-1.2, 1.2))x = np.linspace(0, 10)ax1.plot(np.sin(x))ax2.plot(np.cos(x));
ảnh ví dụ - data science lại blog của lưu

Bây giờ chúng ta có hai trục (trục trên không có nhãn dấu) chỉ cần chạm nhau: phần dưới của bảng trên (tại vị trí 0.5) khớp với phía trên của bảng dưới (tại vị trí 0.1 + 0.4).

plt.subplot: Sử dụng lưới đơn giản các bố cục con

Các cột hoặc hàng được căn chỉnh của các subplot là một nhu cầu phổ biến đủ mức mà Matplotlib có một số tiện ích giúp tạo chúng dễ dàng hơn. Mức thấp nhất trong số này là plt.subplot(), tạo một subplot duy nhất trong lưới. Như bạn có thể thấy, lệnh này có ba đối số nguyên – số hàng, số cột và chỉ số của plot được tạo ra trong kế hoạch này, chạy từ trên cùng bên trái đến góc dưới bên phải:

for i in range(1, 7):    plt.subplot(2, 3, i)    plt.text(0.5, 0.5, str((2, 3, i)),             fontsize=18, ha='center')
ảnh ví dụ - data science lại blog của lưu

Lệnh plt.subplots_adjust có thể được sử dụng để điều chỉnh khoảng cách giữa các đồ thị này.Đoạn mã dưới đây sử dụng lệnh hướng đối tượng tương đương, fig.add_subplot():

fig = plt.figure()fig.subplots_adjust(hspace=0.4, wspace=0.4)for i in range(1, 7):    ax = fig.add_subplot(2, 3, i)    ax.text(0.5, 0.5, str((2, 3, i)),           fontsize=18, ha='center')
ảnh ví dụ - data science lại blog của lưu

Chúng ta đã sử dụng các đối số hspacewspace của hàm plt.subplots_adjust, nhằm chỉ định khoảng cách theo chiều cao và chiều rộng của hình, tính bằng đơn vị của kích thước subplot (trong trường hợp này, khoảng cách là 40% chiều rộng và chiều cao của subplot).

plt.subplots: Toàn bộ lưới trong một lần

Cách tiếp cận vừa được mô tả có thể trở nên rất tẻ nhạt khi tạo một lưới lớn các subplot, đặc biệt là nếu bạn muốn ẩn nhãn trục x và y trên các subplot bên trong.Vì mục đích này, plt.subplots() là công cụ dễ sử dụng hơn (lưu ý s ở cuối của subplots). Thay vì tạo một subplot duy nhất, hàm này tạo một lưới đầy đủ các subplot trong một dòng duy nhất, trả về chúng dưới dạng một mảng NumPy.Các đối số là số hàng và số cột, cùng với các từ khóa tùy chọn sharexsharey, cho phép bạn chỉ định mối quan hệ giữa các trục khác nhau.

Ở đây chúng ta sẽ tạo ra một lưới chứa $2 \times 3$ subplot, trong đó tất cả các trục trong cùng một hàng chia sẻ cùng một thang đo trục y, và tất cả các trục trong cùng một cột chia sẻ cùng một thang đo trục x:

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

Lưu ý rằng bằng cách chỉ định sharexsharey, chúng ta đã tự động loại bỏ các nhãn bên trong trục lưới để làm cho biểu đồ trở nên sạch sẽ hơn.Kết quả của lưới các trục được trả lại dưới dạng một mảng NumPy, cho phép chỉ định thuận tiện các trục mong muốn bằng cách sử dụng ký hiệu chỉ mục mảng tiêu chuẩn:

# axes are in a two-dimensional array, indexed by [row, col]for i in range(2):    for j in range(3):        ax[i, j].text(0.5, 0.5, str((i, j)),                      fontsize=18, ha='center')fig
ảnh ví dụ - data science lại blog của lưu

So sánh với plt.subplot(), plt.subplots() được thực hiện nghiêm chỉnh hơn với cách đánh chỉ mục bắt đầu từ 0 trong Python.

plt.GridSpec: Sắp xếp phức tạp hơn

Để vượt qua lưới thông thường để có các subplot trải dài qua nhiều hàng và cột, plt.GridSpec() là công cụ tốt nhất.Đối tượng plt.GridSpec() không tạo ra một plot một mình; nó chỉ là một giao diện tiện lợi được nhận dạng bởi lệnh plt.subplot().Ví dụ, một gridspec cho một lưới hai hàng và ba cột với một số không gian chiều rộng và chiều cao cụ thể nhìn như thế này:

grid = plt.GridSpec(2, 3, wspace=0.4, hspace=0.3)

Từ đây, chúng ta có thể chỉ định vị trí và phạm vi của các subplot bằng cú pháp cắt Python quen thuộc:

plt.subplot(grid[0, 0])plt.subplot(grid[0, 1:])plt.subplot(grid[1, :2])plt.subplot(grid[1, 2]);
ảnh ví dụ - data science lại blog của lưu

Loại căn chỉnh lưới linh hoạt này có nhiều ứng dụng rộng rãi.Tôi thường sử dụng nó khi tạo đồ thị histogram đa trục như những đồ thị được hiển thị ở đây:

# Create some normally distributed datamean = [0, 0]cov = [[1, 1], [1, 2]]x, y = np.random.multivariate_normal(mean, cov, 3000).T# Set up the axes with gridspecfig = plt.figure(figsize=(6, 6))grid = plt.GridSpec(4, 4, hspace=0.2, wspace=0.2)main_ax = fig.add_subplot(grid[:-1, 1:])y_hist = fig.add_subplot(grid[:-1, 0], xticklabels=[], sharey=main_ax)x_hist = fig.add_subplot(grid[-1, 1:], yticklabels=[], sharex=main_ax)# scatter points on the main axesmain_ax.plot(x, y, 'ok', markersize=3, alpha=0.2)# histogram on the attached axesx_hist.hist(x, 40, histtype='stepfilled',            orientation='vertical', color='gray')x_hist.invert_yaxis()y_hist.hist(y, 40, histtype='stepfilled',            orientation='horizontal', color='gray')y_hist.invert_xaxis()
ảnh ví dụ - data science lại blog của lưu

Loại phân bố này được vẽ cùng các viền của nó là khá phổ biến, nó có một API vẽ riêng trong gói Seaborn; xem Visualization With Seaborn để biết thêm chi tiết.