Cải thiện kích thước / khoảng cách của subplot với nhiều subplot trong matplotlib


313

Rất giống với câu hỏi này nhưng với sự khác biệt mà con số của tôi có thể lớn như nó cần phải có.

Tôi cần phải tạo ra một loạt các lô được xếp theo chiều dọc trong matplotlib. Kết quả sẽ được lưu bằng cách sử dụng figsave và được xem trên một trang web, vì vậy tôi không quan tâm hình ảnh cuối cùng cao bao nhiêu miễn là các ô con được đặt cách nhau để chúng không trùng nhau.

Cho dù tôi cho phép con số lớn đến mức nào, các ô con dường như luôn chồng chéo.

Mã của tôi hiện tại trông giống như

import matplotlib.pyplot as plt
import my_other_module

titles, x_lists, y_lists = my_other_module.get_data()

fig = plt.figure(figsize=(10,60))
for i, y_list in enumerate(y_lists):
    plt.subplot(len(titles), 1, i)
    plt.xlabel("Some X label")
    plt.ylabel("Some Y label")
    plt.title(titles[i])
    plt.plot(x_lists[i],y_list)
fig.savefig('out.png', dpi=100)

Câu trả lời:


413

Hãy thử sử dụng plt.tight_layout

Ví dụ nhanh:

import matplotlib.pyplot as plt

fig, axes = plt.subplots(nrows=4, ncols=4)
fig.tight_layout() # Or equivalently,  "plt.tight_layout()"

plt.show()

Không có bố cục chặt chẽ

nhập mô tả hình ảnh ở đây


Với bố cục chặt chẽ nhập mô tả hình ảnh ở đây


21
Sẽ rõ ràng hơn một chút nếu bạn cho thấy bạn nên thực hiện điều này sau mã cốt truyện của mình, nhưng ngay trước khi hiển thị ()
pyj

5
tight_layout()là trúng và bỏ lỡ. Tôi đã cố gắng hiểu điều gì khác biệt khi nó không có tác dụng (vẫn còn nhiều lợi nhuận giữa các lô lớn) - thường là
javadba

3
Điều này làm việc khá tốt đối với tôi, ngoại trừ nó phủ lên tiêu đề hình của tôi ( suptitle) với tiêu đề phụ của tôi. Trong trường hợp bất kỳ ai gặp phải một vấn đề tương tự, đây là những gì đã giúp trong trường hợp của tôi stackoverflow.com/a/45161551/11740420 . Cụ thể, rectthông số củatight_layout()
Siyana Pavlova

284

Bạn có thể sử dụng plt.subplots_adjustđể thay đổi khoảng cách giữa các ô con (nguồn)

chữ ký gọi:

subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=None)

Ý nghĩa tham số (và mặc định được đề xuất) là:

left  = 0.125  # the left side of the subplots of the figure
right = 0.9    # the right side of the subplots of the figure
bottom = 0.1   # the bottom of the subplots of the figure
top = 0.9      # the top of the subplots of the figure
wspace = 0.2   # the amount of width reserved for blank space between subplots
hspace = 0.2   # the amount of height reserved for white space between subplots

Mặc định thực tế được kiểm soát bởi tệp RC


3
Tôi đã thử gây rối với hspace, nhưng việc tăng nó dường như chỉ làm cho tất cả các biểu đồ nhỏ hơn mà không giải quyết được vấn đề chồng chéo. Tôi cũng đã thử chơi với các thông số khác, nhưng tôi không biết những gì bên trái, bên phải, dưới cùng và trên cùng đang thực sự chỉ định ở đó.
mcstr

52
@mcstrother bạn có thể thay đổi tương tác tất cả 6 tham số đó nếu bạn nhấp vào nút 'điều chỉnh' sau khi hiển thị một âm mưu, sau đó sao chép chúng vào mã khi bạn tìm thấy những gì hoạt động.
Nick T

1
Tôi không thấy nút điều chỉnh. Mặc dù tôi đang ở trong một cuốn sổ tay Jupyter. Tôi đã thử% matplotlib nội tuyến và% matplotlib.
Matt Kleinsmith

1
@MattKleinsmith: Nút điều chỉnh có dòng chữ "Cấu hình các ô con" và xuất hiện trong các ứng dụng không phải là máy tính xách tay thông thường của Matplotlib. Đây là nút bên trái của nút lưu "đĩa mềm" ở đây: pythonspot-9329.kxcdn.com/wp-content/uploads/2016/07/ - - lưu ý nút này trông khác nhau tùy thuộc vào hệ thống cửa sổ nào của bạn sử dụng, nhưng nó luôn ở bên trái nút lưu.
John Zwinck

@JohnZwinck, liên kết trong bình luận của bạn đã chết ngay bây giờ.
user4015990

56

Tôi thấy rằng subplots_adjust (hspace = 0,001) là thứ cuối cùng làm việc cho tôi. Khi tôi sử dụng khoảng trắng = Không có, vẫn còn khoảng trắng giữa mỗi ô. Tuy nhiên, đặt nó thành một cái gì đó rất gần với số 0 dường như buộc họ phải xếp hàng. Những gì tôi đã tải lên ở đây không phải là đoạn mã thanh lịch nhất, nhưng bạn có thể thấy cách hspace hoạt động.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as tic

fig = plt.figure()

x = np.arange(100)
y = 3.*np.sin(x*2.*np.pi/100.)

for i in range(5):
    temp = 510 + i
    ax = plt.subplot(temp)
    plt.plot(x,y)
    plt.subplots_adjust(hspace = .001)
    temp = tic.MaxNLocator(3)
    ax.yaxis.set_major_locator(temp)
    ax.set_xticklabels(())
    ax.title.set_visible(False)

plt.show()

nhập mô tả hình ảnh ở đây


31
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(10,60))
plt.subplots_adjust( ... )

Các plt.subplots_adjust phương pháp:

def subplots_adjust(*args, **kwargs):
    """
    call signature::

      subplots_adjust(left=None, bottom=None, right=None, top=None,
                      wspace=None, hspace=None)

    Tune the subplot layout via the
    :class:`matplotlib.figure.SubplotParams` mechanism.  The parameter
    meanings (and suggested defaults) are::

      left  = 0.125  # the left side of the subplots of the figure
      right = 0.9    # the right side of the subplots of the figure
      bottom = 0.1   # the bottom of the subplots of the figure
      top = 0.9      # the top of the subplots of the figure
      wspace = 0.2   # the amount of width reserved for blank space between subplots
      hspace = 0.2   # the amount of height reserved for white space between subplots

    The actual defaults are controlled by the rc file
    """
    fig = gcf()
    fig.subplots_adjust(*args, **kwargs)
    draw_if_interactive()

hoặc là

fig = plt.figure(figsize=(10,60))
fig.subplots_adjust( ... )

Kích thước của hình ảnh quan trọng.

"Tôi đã thử gây rối với hspace, nhưng việc tăng nó dường như chỉ làm cho tất cả các biểu đồ nhỏ hơn mà không giải quyết được vấn đề chồng chéo."

Do đó, để tạo thêm khoảng trắng và giữ kích thước ô phụ, tổng hình ảnh cần phải lớn hơn.


2
Kích thước của vấn đề hình ảnh, kích thước hình ảnh lớn hơn có thể giải quyết vấn đề này! thiết lập plt.figure(figsize=(10, 7)), kích thước của hình ảnh sẽ là 2000 x 1400pix
Belter


20

Tương tự như tight_layoutmatplotlib bây giờ (kể từ phiên bản 2.2) cung cấp constrained_layout. Ngược lại tight_layout, có thể được gọi bất cứ lúc nào trong mã cho một bố cục được tối ưu hóa duy nhất, constrained_layoutlà một thuộc tính, có thể được kích hoạt và sẽ tối ưu hóa bố cục trước mỗi bước vẽ.

Do đó, nó cần phải được kích hoạt trước hoặc trong khi tạo subplot, chẳng hạn như figure(constrained_layout=True)hoặc subplots(constrained_layout=True).

Thí dụ:

import matplotlib.pyplot as plt

fig, axes = plt.subplots(4,4, constrained_layout=True)

plt.show()

nhập mô tả hình ảnh ở đây

ràng buộc_layout cũng có thể được thiết lập thông qua rcParams

plt.rcParams['figure.constrained_layout.use'] = True

Xem mục mớiHướng dẫn bố cục hạn chế


1
sẽ thử điều này: đã không thấy tùy chọn này - và tight_layoutkhông đáng tin cậy
javadba

điều này nghe có vẻ hứa hẹn nhưng không cho tôi đủ khoảng cách (nhãn trục và tiêu đề vẫn chồng chéo) và việc kết xuất mất nhiều thời gian hơn. tight_layout()làm việc tốt hơn
craq

2
@craq Đúng, nói chung contrained_layoutlà chậm hơn, vì như đã thấy trong câu trả lời này, nó tối ưu hóa bố cục trước mỗi bước vẽ .
ImportanceOfByingErnest

đối với tôi đây là câu trả lời hữu ích nhất - đối với tôi, luôn luôn cải thiện khoảng cách dọc để dành chỗ cho tiêu đề bảng điều khiển, nhưng với chi phí cắt nhãn trục y mỗi lần. Điều này, thay vào đó, hoạt động hoàn hảo, cảm ơn.
Adrian Tompkins
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.