2013-04-17 26 views
12

Tôi muốn Matplotlib/Pyplot tạo ra các ô có kích thước vải phù hợp. Tức là, các con số cũng có thể có các kích thước khác nhau để chứa các mô tả trục, nhưng khu vực vẽ (hình chữ nhật trong đó các đường cong được vẽ) phải luôn có cùng kích thước.Đặt kích cỡ của ô vẽ đồ thị trong Matplotlib

Có cách nào đơn giản để đạt được điều đó không? Tùy chọn figsize của pyplot.figure() dường như thiết lập kích thước tổng thể của hình, không phải là của canvas, vì vậy tôi nhận được kích thước canvas khác nhau bất cứ khi nào mô tả trục chiếm nhiều hoặc ít không gian hơn.

+0

Có thể là 'gridspec' cho phép bạn kiểm soát những gì bạn muốn (xem 3 [ví dụ ở đây] cuối cùng (http://matplotlib.org/examples/pylab_examples/demo_tight_layout.html)). Bạn có thể thêm một số ví dụ hiển thị các mô tả trục khác nhau gây ra sự cố không? – Bonlenfum

+0

Đây là chi phí của cách mà MPL ​​tách cặp mô tả về những gì cần vẽ và _how_ để vẽ nó. Khá chắc chắn làm điều này bằng tay, và thận trọng tránh 'tight_layout,' là cách tốt nhất để đi với điều này. – tacaswell

Trả lời

12

Đây là một trong những sự thất vọng lớn nhất của tôi với Matplotlib. Tôi thường làm việc với dữ liệu raster, ví dụ tôi muốn thêm một bản đồ màu, chú giải và một số tiêu đề. Bất kỳ ví dụ đơn giản nào từ thư viện matplotlib làm như vậy sẽ dẫn đến một độ phân giải khác và do đó dữ liệu được lấy mẫu lại. Đặc biệt khi thực hiện phân tích hình ảnh, bạn không muốn bất kỳ việc lấy mẫu lại (không mong muốn) nào.

Đây là những gì tôi thường làm, mặc dù tôi rất muốn biết nếu có những cách đơn giản hoặc tốt hơn.

Hãy bắt đầu với tải một hình ảnh và xuất nó chỉ vì nó là với cùng độ phân giải:

import matplotlib.pyplot as plt 
import urllib2 

# load the image 
img = plt.imread(urllib2.urlopen('http://upload.wikimedia.org/wikipedia/en/thumb/5/56/Matplotlib_logo.svg/500px-Matplotlib_logo.svg.png')) 

# get the dimensions 
ypixels, xpixels, bands = img.shape 

# get the size in inches 
dpi = 72. 
xinch = xpixels/dpi 
yinch = ypixels/dpi 

# plot and save in the same size as the original 
fig = plt.figure(figsize=(xinch,yinch)) 

ax = plt.axes([0., 0., 1., 1.], frameon=False, xticks=[],yticks=[]) 
ax.imshow(img, interpolation='none') 

plt.savefig('D:\\mpl_logo.png', dpi=dpi, transparent=True) 

Lưu ý rằng tôi tự xác định vị trí các trục để kéo dài toàn bộ hình.

Trong một cách tương tự như trên bạn có thể thêm một số biên độ xung quanh hình ảnh để cho phép nhãn hoặc colorbars, vv

Ví dụ này cho biết thêm một biên độ 20% so với hình ảnh, sau đó được sử dụng cho âm mưu tiêu đề:

fig = plt.figure(figsize=(xinch,yinch/.8)) 

ax = plt.axes([0., 0., 1., .8], frameon=False, xticks=[],yticks=[]) 
ax.imshow(img, interpolation='none') 
ax.set_title('Matplotlib is fun!', size=16, weight='bold') 

plt.savefig('D:\\mpl_logo_with_title.png', dpi=dpi) 

Vì vậy, kích thước y (chiều cao) được tăng lên và kích cỡ y của các trục bị giảm bằng nhau. Điều này cho một hình ảnh đầu ra (tổng thể) lớn hơn, nhưng khu vực trục sẽ vẫn có cùng kích thước.

Nó có thể là tốt đẹp có một hình hoặc trục tài sản như .set_scale() để buộc một đầu ra đúng 1-on-x.

+0

Thay vào đó, bạn có thể sử dụng một số định dạng véc tơ không? Nó _should_ (tôi nghĩ) vẽ từng pixel dưới dạng hình chữ nhật. Hoặc chỉ _way_ trên mẫu. – tacaswell

+2

Cảm ơn bạn, đề xuất của bạn đã hoạt động! Bằng cách này, tôi nghĩ rằng tôi đã tìm thấy một cách thanh lịch hơn một chút bằng cách sử dụng subplot_adjust (0,0,1,1) ngay lập tức sau khi gọi con số(). Sau đó, bạn không cần phải xác định vị trí trục vì chúng đã lớn như hình. Cuối cùng, bạn có thể gọi savefig() với đối số bbox_inches = 'tight' nếu bạn không muốn chỉ định thủ công các lề. Trong trường hợp này, diện tích âm mưu sẽ chính xác như được xác định bởi (xinch, yinch) và hình sẽ đủ lớn để chứa các mô tả trục. (Như được chỉ ra bởi tcaswell, không sử dụng tight_layout!) – Dario

+0

Điều đó nghe có vẻ dễ dàng hơn, nhờ những lời khuyên. Tôi sẽ thử đề xuất của bạn sau. @tcaswell, cảm ơn, điều đó có thể làm việc trong một số trường hợp, tôi nghĩ rằng pcolor sẽ có thể làm điều đó khá dễ dàng. Bất kỳ quá trình hậu xử lý nào khác sẽ khó khăn hơn. –