2012-03-23 33 views
72

Tôi đang vẽ âm mưu cùng một loại thông tin, nhưng đối với các quốc gia khác nhau, với nhiều subplots với matplotlib. Đó là, tôi có 9 ô trên lưới 3x3, tất cả đều giống nhau cho các dòng (tất nhiên, các giá trị khác nhau trên mỗi dòng).làm cách nào để tạo một chú giải đơn lẻ cho nhiều trang con bằng matplotlib?

Tuy nhiên, tôi chưa tìm ra cách đặt một chú giải đơn (vì tất cả 9 ô con đều có cùng dòng) trên hình một lần.

Tôi làm như thế nào?

Trả lời

68

figlegend có thể là những gì bạn đang tìm kiếm: http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.figlegend

Ví dụ ở đây: http://matplotlib.org/examples/pylab_examples/figlegend_demo.html

Một ví dụ khác:

plt.figlegend(lines, labels, loc = 'lower center', ncol=5, labelspacing=0.) 

hay:

fig.legend(lines, labels, loc = (0.5, 0), ncol=5) 
+1

Tôi biết các dòng mà tôi muốn đặt trong chú giải, nhưng làm thế nào để tôi nhận biến 'dòng' để đặt trong đối số cho' chú giải'? –

+1

@patapouf_ai 'dòng' là danh sách các kết quả được trả về từ' axes.plot() '(tức là, mỗi' trục.plot' hoặc thường trình tương tự trả về một "dòng"). Xem thêm ví dụ được liên kết. – Evert

13

Bạn chỉ cần yêu cầu truyền thuyết một lần, bên ngoài vòng lặp của bạn.

Ví dụ: trong trường hợp này, tôi có 4 ô con, có cùng dòng và một chú giải.

from matplotlib.pyplot import * 

ficheiros = ['120318.nc', '120319.nc', '120320.nc', '120321.nc'] 

fig = figure() 
fig.suptitle('concentration profile analysis') 

for a in range(len(ficheiros)): 
    # dados is here defined 
    level = dados.variables['level'][:] 

    ax = fig.add_subplot(2,2,a+1) 
    xticks(range(8), ['0h','3h','6h','9h','12h','15h','18h','21h']) 
    ax.set_xlabel('time (hours)') 
    ax.set_ylabel('CONC ($\mu g. m^{-3}$)') 

    for index in range(len(level)): 
     conc = dados.variables['CONC'][4:12,index] * 1e9 
     ax.plot(conc,label=str(level[index])+'m') 

    dados.close() 

ax.legend(bbox_to_anchor=(1.05, 0), loc='lower left', borderaxespad=0.) 
     # it will place the legend on the outer right-hand side of the last axes 

show() 
+3

'figlegend', như sugested bởi Evert, có vẻ là một giải pháp tốt hơn nhiều;) – carla

+10

vấn đề của' fig.legend() 'là nó yêu cầu nhận dạng cho tất cả các dòng (lô) ... như, cho mỗi subplot , Tôi đang sử dụng một vòng lặp để tạo ra các dòng, giải pháp duy nhất tôi đã tìm ra để khắc phục điều này là tạo một danh sách trống trước vòng lặp thứ hai và sau đó nối thêm các dòng khi chúng được tạo ... một đối số cho hàm 'fig.legend()'. – carla

+0

Một câu hỏi tương tự [tại đây] (https://stackoverflow.com/questions/22001756/one-legend-for-all-subplots-in-pyplot) –

12

Đối với vị trí tự động của một huyền thoại duy nhất trong một figure với nhiều trục, giống như những người thu được với subplots(), giải pháp sau đây hoạt động thực sự tốt:

plt.legend(lines, labels, loc = 'lower center', bbox_to_anchor = (0,-0.1,1,1), 
      bbox_transform = plt.gcf().transFigure) 

Với bbox_to_anchorbbox_transform=plt.gcf().transFigure bạn đang xác định một hộp giới hạn mới có kích thước của figure của bạn là tham chiếu cho loc. Sử dụng (0,-0.1,1,1) di chuyển hộp xếp chồng này xuống dưới một chút để ngăn chú giải được đặt trên các nghệ sĩ khác.

OBS: sử dụng giải pháp này sau khi bạn sử dụng fig.set_size_inches() và trước khi bạn sử dụng fig.tight_layout()

+1

Hoặc simpy 'loc = 'upper center', bbox_to_anchor = (0.5, 0), bbox_transform = plt.gcf(). TransFigure' và nó sẽ không trùng lặp chắc chắn. –

+1

Tôi vẫn không chắc tại sao, nhưng giải pháp của Evert không hiệu quả đối với tôi - huyền thoại cứ bị cắt đứt. Giải pháp này (cùng với bình luận của davor) đã làm việc rất sạch sẽ - huyền thoại được đặt như mong đợi và có thể nhìn thấy rõ ràng. Cảm ơn! –

7

Ngoài ra còn có một chức năng đẹp get_legend_handles_labels() bạn có thể gọi trên trục cuối cùng (nếu bạn lặp qua chúng) mà sẽ thu thập tất cả mọi thứ bạn cần từ label= đối số:

handles, labels = ax.get_legend_handles_labels() 
fig.legend(handles, labels, loc='upper center') 
+1

Đây phải là câu trả lời hàng đầu. – naught101

0

Câu trả lời này bổ sung cho @ Evert ở vị trí huyền thoại.

Thử đầu tiên của tôi trên giải pháp @ Evert không thành công do trùng lặp của chú giải và tiêu đề của phụ đề.

Thực tế, các chồng chéo được gây ra bởi fig.tight_layout(), thay đổi bố cục của các vị trí phụ mà không xem xét chú giải hình. Tuy nhiên, fig.tight_layout() là cần thiết.

Để tránh trùng lặp, chúng tôi có thể yêu cầu fig.tight_layout() để lại dấu cách cho chú thích của hình bằng cách fig.tight_layout(rect=(0,0,1,0.9)).

Description of tight_layout() parameters.

Các vấn đề liên quan