35

Problem : Need to transform a graphic image of matplotlib to a base64 image

Current Solution : Save the matplot image in a cache folder and read it with read() method and then convert to base64

New Problem : Annoyance : Need a workaround so I dont need to save the graphic as image in any folder. I want to just use the image in the memory. Doing unnecessary I/O is a bad practice.

def save_single_graphic_data(data, y_label="Loss", x_label="Epochs", save_as="data.png"):
    total_epochs = len(data)
    plt.figure()
    plt.clf()

    plt.plot(total_epochs, data)

    ax = plt.gca()
    ax.ticklabel_format(useOffset=False)

    plt.ylabel(y_label)
    plt.xlabel(x_label)

    if save_as is not None:
        plt.savefig(save_as)

    plt.savefig("cache/cached1.png")

    cached_img = open("cache/cached1.png")

    cached_img_b64 = base64.b64encode(cached_img.read())

    os.remove("cache/cached1.png")

    return cached_img_b64

3 Answers 3

46
import cStringIO
my_stringIObytes = cStringIO.StringIO()
plt.savefig(my_stringIObytes, format='jpg')
my_stringIObytes.seek(0)
my_base64_jpgData = base64.b64encode(my_stringIObytes.read())

[edit] in python3 it should be

import io
my_stringIObytes = io.BytesIO()
plt.savefig(my_stringIObytes, format='jpg')
my_stringIObytes.seek(0)
my_base64_jpgData = base64.b64encode(my_stringIObytes.read()).decode()

I think at least ... based on the documentation http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.savefig

Sign up to request clarification or add additional context in comments.

7 Comments

If you are using Python 3 or greater, you need to use io.BytesIO as mentioned by @nobar at stackoverflow.com/a/18284900/1802726.
Or for Python 2/3 compatibility with fastest implementation: try: from cStringIO import StringIO; except ImportError: from six import StringIO (six ref)
Hi Joran, from your code, where is the figure variable? I only see my_stringIObytes, I don't see any variable related to original mtaplotlib plot object. Thanks for clarifying.
my_base64_jpgData has the base64 encoded data you could then do something like <img src="data:image/jpeg;base64,{my_base64_jpgData}" /> or use other methods to decode it back to the original image
my_base64_jpgData might have to be wrapped in an str(), as the data is in binary string format by default. ( b'sfsafs')
|
27

For python 3

import base64
import io 
pic_IObytes = io.BytesIO()
plt.savefig(pic_IObytes,  format='png')
pic_IObytes.seek(0)
pic_hash = base64.b64encode(pic_IObytes.read())

The reason is both cStringIO and cStringIO.StringIO() are deprecated

2 Comments

You might want to add a more detailed explanation
@YuliaV what I was saying is that in Python 3 the cStringIO module has been deprecated in place of io module. So that is why I used the io module in my answer.
20

I could not get answers above work, but this did:

    import io
    import base64
    s = io.BytesIO()
    plt.plot(list(range(100)))
    plt.savefig(s, format='png', bbox_inches="tight")
    plt.close()
    s = base64.b64encode(s.getvalue()).decode("utf-8").replace("\n", "")
    return '<img align="left" src="data:image/png;base64,%s">' % s

1 Comment

is it the fastest solution ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.