2011-11-21 23 views
39

Ở dạng gọn gàng/scipy Tôi có một hình ảnh được lưu trữ trong một mảng. Tôi có thể hiển thị nó, tôi muốn lưu nó bằng cách sử dụng savefigmà không cần bất kỳ đường viền, rìu, nhãn, tiêu đề, ... Chỉ là hình ảnh thuần túy, không có gì khác.scipy: savefig không có khung, rìu, chỉ nội dung

Tôi muốn tránh gói như PyPNG hoặc scipy.misc.imsave, họ đôi khi có vấn đề (họ không phải lúc nào cài đặt tốt, chỉ cơ bản savefig() cho tôi

Trả lời

56

Giả sử:

import matplotlib.pyplot as plt 

Để thực hiện một con số không có khung:

fig = plt.figure(frameon=False) 
fig.set_size_inches(w,h) 

Để làm cho c ontent lấp đầy toàn bộ hình

ax = plt.Axes(fig, [0., 0., 1., 1.]) 
ax.set_axis_off() 
fig.add_axes(ax) 

Sau đó vẽ hình ảnh của bạn trên đó:

ax.imshow(your_image, aspect='normal') 
fig.savefig(fname, dpi) 

Tham số aspect thay đổi kích thước pixel để đảm bảo họ điền vào kích thước con số quy định tại fig.set_size_inches(…). Để có được cảm giác về cách chơi với những thứ như thế này, hãy đọc qua matplotlib's documentation, đặc biệt là về chủ đề của Trục, Trục và Nghệ sĩ.

+3

nope, tôi vẫn có một số biên giới nhỏ trong suốt, và những gì tôi muốn là _no biên giới tại ALL_, hình ảnh tinh khiết –

+0

Có lẽ, đó là vì tôi quên về trường hợp hình ảnh không vuông: P. Chỉ cần chỉnh sửa để thêm tham số 'aspect'. Làm thế nào là nó bây giờ? – matehat

+1

grrr, không, vẫn như cũ. Có một đường viền nhỏ, trong suốt xung quanh hình ảnh, một vài điểm ảnh trên mặt _each_ –

19

Bạn có thể tìm bbox của hình ảnh bên trong trục (sử dụng get_window_extent), và sử dụng các tham số bbox_inches để lưu chỉ phần đó của hình ảnh:

import numpy as np 
import matplotlib.pyplot as plt 

data=np.arange(9).reshape((3,3)) 
fig=plt.figure() 
ax=fig.add_subplot(1,1,1) 
plt.axis('off') 
plt.imshow(data) 

extent = ax.get_window_extent().transformed(fig.dpi_scale_trans.inverted()) 
plt.savefig('/tmp/test.png', bbox_inches=extent) 

Tôi đã học được thủ thuật này từ Joe Kington here.

+0

chỉ 'plt.axis ('off')' đã giúp. Các câu trả lời khác không giúp được gì nhiều. – imsrgadich

39

Một giải pháp dễ dàng hơn có vẻ là:

fig.savefig('out.png', bbox_inches='tight', pad_inches=0) 
+1

Điều này làm việc tuyệt vời cho tôi. Ngoài ra, pad_inches có thể được thay đổi thành kích thước mong muốn dễ dàng. Cảm ơn! – Curious2learn

+0

+1 cũng rất tuyệt vời cho tôi :) Và đây thực sự là cách đơn giản hơn câu trả lời được chấp nhận –

+8

Tôi vẫn có lề trắng với điều này. –

4

Tôi đã thử một vài lựa chọn trong trường hợp của tôi, và giải pháp tốt nhất là thế này:

fig.subplots_adjust(bottom = 0) 
fig.subplots_adjust(top = 1) 
fig.subplots_adjust(right = 1) 
fig.subplots_adjust(left = 0) 

sau đó lưu hình của bạn với savefig

4

Tôi sẽ đề xuất câu trả lời heron13 với một khoản bổ sung nhỏ được vay từ here để xóa phần đệm bên trái sau khi đặt bbox thành chế độ chặt chẽ, do đó:

fig.axes.get_xaxis().set_visible(False) 
fig.axes.get_yaxis().set_visible(False) 
fig.savefig('out.png', bbox_inches='tight', pad_inches=0) 
+0

Tôi gặp lỗi khi nói get_xaxis() và get_yaxis() không tồn tại. Bất kỳ ý tưởng tại sao điều đó sẽ xảy ra? –

+0

Thực hiện một đối tượng trục(), sau đó sử dụng ax.xaxis và ax.yaxis – perigon

3

tôi đã cùng một vấn đề trong khi làm một số hình dung sử dụng librosa nơi tôi muốn trích xuất nội dung của cốt truyện mà không cần bất kỳ thông tin khác. Đây là cách tiếp cận của tôi. unutbu câu trả lời cũng giúp tôi thực hiện để làm việc.

figure = plt.figure(figsize=(500, 600), dpi=1) 
    axis = plt.subplot(1, 1, 1) 
    plt.axis('off') 
    plt.tick_params(axis='both', left='off', top='off', right='off', bottom='off', labelleft='off', labeltop='off', 
        labelright='off', labelbottom='off') 

    # your code goes here. e.g: I used librosa function to draw a image 
    result = np.array(clip.feature_list['fft'].get_logamplitude()[0:2]) 
    librosa.display.specshow(result, sr=api.Clip.RATE, x_axis='time', y_axis='mel', cmap='RdBu_r') 


    extent = axis.get_window_extent().transformed(figure.dpi_scale_trans.inverted()) 
    plt.savefig((clip.filename + str("_.jpg")), format='jpg', bbox_inches=extent, pad_inches=0) 
    plt.close() 
+0

Điều này giúp tôi đi đúng hướng, nhưng tôi có hai vấn đề: 1) Tôi phải đặt dpi thành một số lớn hơn 1 để tránh phông chữ lỗi trong sổ ghi chép jupyter của tôi; và 2) vẫn còn một đường viền nhỏ nên tôi phải thay đổi mức độ Bbox thành 'extent.get_points() * np.array ([[1.1], [. 9]])'. –

+0

cảm ơn bạn đã hoàn thành câu trả lời có thể giúp người khác. – GPrathap

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