Lưu cốt truyện vào tệp hình ảnh thay vì hiển thị nó bằng Matplotlib


1150

Tôi đang viết một kịch bản nhanh và bẩn để tạo ra các âm mưu một cách nhanh chóng. Tôi đang sử dụng mã dưới đây (từ tài liệu Matplotlib ) làm điểm bắt đầu:

from pylab import figure, axes, pie, title, show

# Make a square figure and axes
figure(1, figsize=(6, 6))
ax = axes([0.1, 0.1, 0.8, 0.8])

labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
fracs = [15, 30, 45, 10]

explode = (0, 0.05, 0, 0)
pie(fracs, explode=explode, labels=labels, autopct='%1.1f%%', shadow=True)
title('Raining Hogs and Dogs', bbox={'facecolor': '0.8', 'pad': 5})

show()  # Actually, don't show, just save to foo.png

Tôi không muốn hiển thị cốt truyện trên GUI, thay vào đó, tôi muốn lưu cốt truyện vào một tệp (giả sử foo.png), ví dụ, để nó có thể được sử dụng trong các tập lệnh bó. Làm thế nào để làm điều đó?


85
Có vẻ như tôi đã tìm thấy câu trả lời: pylab.savefig ('foo.png')
Homunculus Reticulli

2
Liên kết có lẽ nên liên kết đến một nơi nào đó trong matplotlib.org?
A.Wan

40
Ngoài ra nếu không sử dụng pylab, đối tượng hình cũng có một savefigphương thức. Vậy bạn có thể gọi fig = plt.figure()rồi fig.savefig(...).
A.Wan

27
Nhiều câu trả lời thấp hơn trang đề cập plt.close(fig)đặc biệt quan trọng trong các vòng lặp lớn. Mặt khác, các số liệu vẫn mở và chờ trong bộ nhớ và tất cả các số liệu mở sẽ được hiển thị khi thực hiệnplt.show()
timctran

nb: matplotlib.pyplot được ưa thích: stackoverflow.com/questions/11469336/
Khăn

Câu trả lời:


1440

Trong khi câu hỏi đã được trả lời, tôi muốn thêm một số mẹo hữu ích khi sử dụng matplotlib.pyplot.savefig . Định dạng tệp có thể được chỉ định bởi tiện ích mở rộng:

from matplotlib import pyplot as plt

plt.savefig('foo.png')
plt.savefig('foo.pdf')

Sẽ cung cấp một đầu ra rasterized hoặc vectorized tương ứng, cả hai đều có thể hữu ích. Ngoài ra, bạn sẽ thấy rằng pylabđể lại một khoảng trắng hào phóng, thường không mong muốn xung quanh hình ảnh. Xóa nó bằng:

savefig('foo.png', bbox_inches='tight')

9
Có thể thay đổi kích thước của hình ảnh kết quả?
Llamageddon

43
@Asmageddon Trong plt.savefigbạn có thể thay đổi dpi, xem liên kết trong câu trả lời. Kích thước có thể được kiểm soát khi tạo hình, xem figsizetrong matplotlib.org/api/figure_api.html#matplotlib.figure.Figure
Hooked

5
@MoTSCHIGGE bạn có thể gọi plt.ioff()nên tắt tính tương tác trong matplotlib.pyplotcác lệnh.
rubenvb

5
@STMohammed foo.png con đường. Bạn có thể, ví dụ, đặt nó trong một thư mục như thế này savefig("mydir/foo.png").
Móc vào

3
bbox_inches = 'chặt chẽ' hoạt động như một bùa mê. Bạn đã thực hiện một ngày của tôi
Catbuilts

205

Như những người khác đã nói, plt.savefig()hoặc fig1.savefig()thực sự là cách để lưu một hình ảnh.

Tuy nhiên tôi đã thấy rằng trong một số trường hợp , con số này luôn được hiển thị . (ví dụ: với Spyder có plt.ion(): chế độ tương tác = Bật.) Tôi xử lý vấn đề này bằng cách buộc đóng cửa sổ hình trong vòng lặp khổng lồ của tôi với plt.close(figure_object)(xem tài liệu ), vì vậy tôi không có một triệu số liệu mở trong vòng lặp:

import matplotlib.pyplot as plt
fig, ax = plt.subplots( nrows=1, ncols=1 )  # create figure & 1 axis
ax.plot([0,1,2], [10,20,3])
fig.savefig('path/to/save/image/to.png')   # save the figure to file
plt.close(fig)    # close the figure window

Bạn sẽ có thể mở lại hình sau nếu cần fig.show()(không tự kiểm tra).


9
Bạn cũng có thể thiết lập plt.ioff() # turn of interactive plotting mode, nhưng điều đó có thể vô hiệu hóa hành vi bạn muốn sử dụng nếu mã của bạn thoát khi có lỗi.
Demis

2
Bạn sẽ thấy vấn đề tương tự trong máy tính xách tay Jupyter. plt.close(fig)đã giải quyết nó
intsco


89

Chỉ cần tìm thấy liên kết này trên tài liệu MatPlotLib giải quyết chính xác vấn đề này: http://matplotlib.org/faq/howto_faq.html#generate-images-without-having-a-window-appear

Họ nói rằng cách dễ nhất để ngăn hình ảnh bật lên là sử dụng phụ trợ không tương tác (ví dụ: Agg), thông qua matplotib.use(<backend>), ví dụ:

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
plt.plot([1,2,3])
plt.savefig('myfig')

Cá nhân tôi vẫn thích sử dụng plt.close( fig ), từ đó bạn có tùy chọn ẩn các số liệu nhất định (trong một vòng lặp), nhưng vẫn hiển thị các số liệu để xử lý dữ liệu sau vòng lặp. Có lẽ chậm hơn so với việc chọn một phụ trợ không tương tác - sẽ rất thú vị nếu ai đó thử nghiệm điều đó.

CẬP NHẬT : đối với Spyder, bạn thường không thể thiết lập phụ trợ theo cách này (Vì Spyder thường tải matplotlib sớm, ngăn bạn sử dụng matplotlib.use()).

Thay vào đó, hãy sử dụng plt.switch_backend('Agg')hoặc Tắt " bật hỗ trợ " trong các prefs Spyder và tự chạy matplotlib.use('Agg')lệnh.

Từ hai gợi ý này: một , hai


1
Điều này hoạt động thực sự tốt cho các tình huống mà bạn không có màn hình hiển thị. Sử dụng một phụ trợ khác .plot()sẽ gây ra lỗi nếu os.environ['DISPLAY']không được đặt chính xác.
nền kinh tế

1
cảm ơn. điều này hoạt động và rất hữu ích cho các máy chủ sản xuất khi không có kết nối internet và cần quản trị hệ thống để cài đặt bất kỳ gói nào.
Leon

Tôi thích hướng dẫn mà trang matplotlib đưa ra để mô tả / định nghĩa về "phụ trợ": matplotlib.org/tutorials/int sinhtory / giả
Tanner Strunk

47

Nếu bạn không thích khái niệm về con số "hiện tại", hãy làm:

import matplotlib.image as mpimg

img = mpimg.imread("src.png")
mpimg.imsave("out.png", img)

2
Điều này không chỉ sao chép src.pngvào out.png?
gerrit

Đó chỉ là một ví dụ, cho thấy nếu bạn có một đối tượng hình ảnh ( img), thì bạn có thể lưu nó vào tệp bằng .imsave()phương thức.
wonder.mice

4
@ wonder.mice sẽ giúp hiển thị cách tạo hình ảnh mà không cần sử dụng hình hiện tại.
scry

@ wonder.mice Cảm ơn ví dụ này, đây là ví dụ đầu tiên chỉ cho tôi cách lưu đối tượng hình ảnh vào .png.
Arthur Dent

@scry Bạn không phải lúc nào cũng cần tạo một hình ảnh, đôi khi bạn thử một số mã và muốn có một đầu ra trực quan, nó rất tiện dụng trong những dịp như vậy.
Schütze

29

Các câu trả lời khác là chính xác. Tuy nhiên, đôi khi tôi thấy rằng tôi muốn mở đối tượng hình sau. Ví dụ: tôi có thể muốn thay đổi kích thước nhãn, thêm lưới hoặc xử lý khác. Trong một thế giới hoàn hảo, tôi chỉ cần chạy lại mã tạo ra cốt truyện và điều chỉnh các cài đặt. Than ôi, thế giới không hoàn hảo. Do đó, ngoài việc lưu vào PDF hoặc PNG, tôi thêm:

with open('some_file.pkl', "wb") as fp:
    pickle.dump(fig, fp, protocol=4)

Như thế này, sau này tôi có thể tải đối tượng hình và thao tác cài đặt theo ý muốn.

Tôi cũng viết ra ngăn xếp với mã nguồn và locals()từ điển cho từng hàm / phương thức trong ngăn xếp, để sau này tôi có thể nói chính xác những gì đã tạo ra hình.

Lưu ý: Hãy cẩn thận, vì đôi khi phương pháp này tạo ra các tệp lớn.


nó sẽ không dễ dàng hơn để làm phát triển trong một máy tính xách tay jupyter, với các số liệu nội tuyến? Bằng cách này bạn có thể theo dõi chính xác lịch sử và thậm chí chạy lại nó.
Ciprian Tomoiagă

3
@CiprianTomoiaga Tôi không bao giờ tạo các lô sản xuất từ ​​trình bao Python tương tác (Jupyter hoặc cách khác). Tôi âm mưu tất cả từ các kịch bản.
gerrit

28
import datetime
import numpy as np
from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.pyplot as plt

# Create the PdfPages object to which we will save the pages:
# The with statement makes sure that the PdfPages object is closed properly at
# the end of the block, even if an Exception occurs.
with PdfPages('multipage_pdf.pdf') as pdf:
    plt.figure(figsize=(3, 3))
    plt.plot(range(7), [3, 1, 4, 1, 5, 9, 2], 'r-o')
    plt.title('Page One')
    pdf.savefig()  # saves the current figure into a pdf page
    plt.close()

    plt.rc('text', usetex=True)
    plt.figure(figsize=(8, 6))
    x = np.arange(0, 5, 0.1)
    plt.plot(x, np.sin(x), 'b-')
    plt.title('Page Two')
    pdf.savefig()
    plt.close()

    plt.rc('text', usetex=False)
    fig = plt.figure(figsize=(4, 5))
    plt.plot(x, x*x, 'ko')
    plt.title('Page Three')
    pdf.savefig(fig)  # or you can pass a Figure object to pdf.savefig
    plt.close()

    # We can also set the file's metadata via the PdfPages object:
    d = pdf.infodict()
    d['Title'] = 'Multipage PDF Example'
    d['Author'] = u'Jouni K. Sepp\xe4nen'
    d['Subject'] = 'How to create a multipage pdf file and set its metadata'
    d['Keywords'] = 'PdfPages multipage keywords author title subject'
    d['CreationDate'] = datetime.datetime(2009, 11, 13)
    d['ModDate'] = datetime.datetime.today()

28

Sau khi sử dụng cốt truyện () và các hàm khác để tạo nội dung bạn muốn, bạn có thể sử dụng mệnh đề như thế này để chọn giữa âm mưu trên màn hình hoặc để tệp:

import matplotlib.pyplot as plt

fig = plt.figure(figsize=(4, 5))       # size in inches
# use plot(), etc. to create your plot.

# Pick one of the following lines to uncomment
# save_file = None
# save_file = os.path.join(your_directory, your_file_name)  

if save_file:
    plt.savefig(save_file)
    plt.close(fig)
else:
    plt.show()

Một số người nói fig = plt.figure(figuresize=4, 5)có thể làfig = plt.figure(figsize=(4, 5)) #figure sizes in inches
người dùng

24

Tôi đã sử dụng như sau:

import matplotlib.pyplot as plt

p1 = plt.plot(dates, temp, 'r-', label="Temperature (celsius)")  
p2 = plt.plot(dates, psal, 'b-', label="Salinity (psu)")  
plt.legend(loc='upper center', numpoints=1, bbox_to_anchor=(0.5, -0.05),        ncol=2, fancybox=True, shadow=True)

plt.savefig('data.png')  
plt.show()  
f.close()
plt.close()

Tôi thấy rất quan trọng để sử dụng plt.show sau khi lưu con số, nếu không nó sẽ không hoạt động. con số xuất khẩu trong png


2
xin lỗi, những gì f trong này? vẽ hình ảnh tập tin? f= plt.savefig('data.png')
Morse

14

Bạn có thể làm:

plt.show(hold=False)
plt.savefig('name.pdf')

và nhớ để cho savefig kết thúc trước khi đóng biểu đồ GUI. Bằng cách này bạn có thể nhìn thấy hình ảnh trước.

Ngoài ra, bạn có thể xem nó với plt.show() Sau đó đóng GUI và chạy lại tập lệnh, nhưng lần này thay thế plt.show()bằng plt.savefig().

Ngoài ra, bạn có thể sử dụng

fig, ax = plt.figure(nrows=1, ncols=1)
plt.plot(...)
plt.show()
fig.savefig('out.pdf')

2
có một đối số từ khóa bất ngờ 'giữ'
amitdatta

13

Nếu, giống như tôi, bạn sử dụng Spyder IDE, bạn phải tắt chế độ tương tác với:

plt.ioff()

(lệnh này được tự động khởi chạy cùng với khởi động khoa học)

Nếu bạn muốn kích hoạt lại, hãy sử dụng:

plt.ion()


12

Giải pháp :

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
matplotlib.style.use('ggplot')
ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))
ts = ts.cumsum()
plt.figure()
ts.plot()
plt.savefig("foo.png", bbox_inches='tight')

Nếu bạn muốn hiển thị hình ảnh cũng như lưu hình ảnh, hãy sử dụng:

%matplotlib inline

sau import matplotlib


9

Theo câu hỏi Matplotlib (pyplot) savefig xuất hình ảnh trống .

Một điều cần lưu ý: nếu bạn sử dụng plt.showvà sau đó plt.savefig, hoặc bạn sẽ đưa ra một hình ảnh trống.

Một ví dụ chi tiết:

import numpy as np
import matplotlib.pyplot as plt


def draw_result(lst_iter, lst_loss, lst_acc, title):
    plt.plot(lst_iter, lst_loss, '-b', label='loss')
    plt.plot(lst_iter, lst_acc, '-r', label='accuracy')

    plt.xlabel("n iteration")
    plt.legend(loc='upper left')
    plt.title(title)
    plt.savefig(title+".png")  # should before plt.show method

    plt.show()


def test_draw():
    lst_iter = range(100)
    lst_loss = [0.01 * i + 0.01 * i ** 2 for i in xrange(100)]
    # lst_loss = np.random.randn(1, 100).reshape((100, ))
    lst_acc = [0.01 * i - 0.01 * i ** 2 for i in xrange(100)]
    # lst_acc = np.random.randn(1, 100).reshape((100, ))
    draw_result(lst_iter, lst_loss, lst_acc, "sgd_method")


if __name__ == '__main__':
    test_draw()

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


6
import matplotlib.pyplot as plt
plt.savefig("image.png")

Trong Jupyter Notebook, bạn phải xóa plt.show()và thêm plt.savefig(), cùng với phần còn lại của mã plt trong một ô. Hình ảnh sẽ vẫn hiển thị trong máy tính xách tay của bạn.


1
"xóa plt.show ()" .. điều này đã cứu ngày của tôi ...

4

Cho rằng ngày hôm nay (không có sẵn khi câu hỏi này đã được thực hiện) rất nhiều người sử dụng Jupyter Máy tính xách tay như trăn console, có một cách rất dễ dàng để lưu các lô như .png, chỉ cần gọi matplotlib's pylablớp từ Jupyter Máy tính xách tay, vẽ con số' inline 'jupyter ô, và sau đó kéo hình / hình đó vào một thư mục cục bộ. Đừng quên %matplotlib inlinetrong dòng đầu tiên!


1
đó là một ý tưởng tốt, chỉ cần lưu ý về tác động lên kích thước tệp nếu hình ảnh được nhúng vào sổ ghi chép ..
prusswan

3

Ngoài ra với những người ở trên, tôi đã thêm __file__tên để ảnh và tệp Python có cùng tên. Tôi cũng đã thêm một vài đối số để làm cho nó trông tốt hơn:

# Saves a PNG file of the current graph to the folder and updates it every time
# (nameOfimage, dpi=(sizeOfimage),Keeps_Labels_From_Disappearing)
plt.savefig(__file__+".png",dpi=(250), bbox_inches='tight')
# Hard coded name: './test.png'

2

Khi sử dụng matplotlib.pyplot, trước tiên bạn phải lưu cốt truyện của mình và sau đó đóng nó bằng 2 dòng sau:

fig.savefig('plot.png') # save the plot, place the path you want to save the figure in quotation
plt.close(fig) # close the figure window

1

Như đã đề xuất trước đây, bạn có thể sử dụng:

import matplotlib.pyplot as plt
plt.savefig("myfig.png")

Để lưu bất cứ hình ảnh IPhython nào mà bạn đang hiển thị. Hoặc trên một ghi chú khác (nhìn từ một góc độ khác), nếu bạn đã từng làm việc với cv mở hoặc nếu bạn đã mở cv đã nhập, bạn có thể đi:

nhập cv2

cv2.imwrite ("myfig.png", hình ảnh)

Nhưng đây chỉ là trong trường hợp nếu bạn cần làm việc với Open CV. Nếu không thì plt.savefig () là đủ.


0

Bạn có thể lưu hình ảnh của mình với bất kỳ tiện ích mở rộng nào (png, jpg, v.v.) và với độ phân giải bạn muốn. Đây là một chức năng để lưu con số của bạn.

import os

def save_fig(fig_id, tight_layout=True, fig_extension="png", resolution=300):
    path = os.path.join(IMAGES_PATH, fig_id + "." + fig_extension)
    print("Saving figure", fig_id)
    if tight_layout:
        plt.tight_layout()
    plt.savefig(path, format=fig_extension, dpi=resolution)

'fig_id' là tên mà bạn muốn lưu hình của mình. Hy vọng nó giúp:)


0

Bạn có thể làm như thế này:

def plotAFig():
  plt.figure()
  plt.plot(x,y,'b-')
  plt.savefig("figurename.png")
  plt.close()
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.