Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't use read-write files with matplotlib's savefig()?

I'm trying to save my figure in a tempfile. I want to do it in the most pythonic way possible. For that, I tried to use the tempfile, but I ran into a few problems. The savefig function is supposed to be able to take either a filename as a string, or a file-like object, which I don't see violated at all in the first two things I tried.

This is what I tried initially:

with tempfile.TemporaryFile(suffix=".png") as tmpfile:
    fig.savefig(tmpfile, format="png") #NO ERROR
    print b64encode(tmpfile.read()) #NOTHING IN HERE

What I then tried:

with open("test.png", "rwb") as tmpfile:
    fig.savefig(tmpfile, format="png")
    #"libpngerror", and a traceback to 
    # "backends_agg.py": "RuntimeError: Error building image"
    print b64encode(tmpfile.read()) 

What I then tried:

with open("test.png", "wb") as tmpfile:
    fig.savefig(tmpfile, format="png")

with open("test.png"), "rb") as tmpfile:
    print b64encode(tmpfile.read())

This works. But now the whole point of using the module tempfile is gone, since I have to handle naming and deleting the tempfile myself, since I have to open it twice. Is there any way I can use tempfile (without weird workarounds/hacks)?

like image 498
mueslo Avatar asked Nov 23 '13 13:11

mueslo


1 Answers

The file has current position at which read, write is performed. Initially the file position is at the beginning (unless you opened the file with append move (a) or you moved file position explicitly).

File position is advanced if you write/read accordingly. If you don't rewind the file, you will get empty string if you read from there. Using file.seek, you can move the file position.

with tempfile.TemporaryFile(suffix=".png") as tmpfile:
    fig.savefig(tmpfile, format="png") # File position is at the end of the file.
    tmpfile.seek(0) # Rewind the file. (0: the beginning of the file)
    print b64encode(tmpfile.read())
like image 182
falsetru Avatar answered Sep 29 '22 06:09

falsetru