Forums

Trying to dynamically Generate and render PNG image in Flask app

I would like to generate a plot using "matplotlib" module and then render then same dynamically onto Flask App. Below code is not rendering the image on the webpage. Which changes do i need to make in the below code so that i can render images dynamically.

Flask APP Code:

from flask import Flask, render_template
import numpy
import matplotlib.pyplot as plt
from io import BytesIO
import base64


app = Flask(__name__)

@app.route('/')
def hello_world():
    ### Generating X,Y coordinaltes to be used in plot
    X = numpy.linspace(0,10,30)
    Y = X*X
    ### Generating The Plot
    plt.plot(X,Y)
    ### Saving plot to disk in png format
    plt.savefig('/home/AnandSatya/mysite/square_plot.png')

    ### Rendering Plot in Html
    figfile = BytesIO()
    plt.savefig(figfile, format='png')
    figfile.seek(0)
    figdata_png = base64.b64encode(figfile.getvalue())
    result = figdata_png
    return render_template('output.html', result=result)

Github path to in Output.html: https://github.com/AnandVetcha/Flask_App/blob/master/templates/output.html

That looks like it should work as far as I can tell. Have you checked the rendered html to ensure that it has the expected base64 encoding in the html. You could also try reading a known png from disk and base64 encoding it to see whether you're putting the image into the html correctly.

Something else just occurred to me: perhaps Flask is HTML-encoding your base64 string or something like that.

Thanks glenn for your inputs. After taking help of my friend along with your inputs we have resolved the issue. Previously "result" variable contained data in b'abcd123.....' format

### Remove b' from begining and ' in the end
### So that we can send the string within base64 noation
result = str(figdata_png)[2:-1]

After modifying the code now "result" contained data in abcd123..... format. Html template dose not understand b' prefix and ' suffix. We need to remove those prefix and suffix before sending the data to HTML.

Congrats on getting it working! If you want to make some tweaks, here's a suggestion.

b'abcd123'

is the python representation for a sequence of bytes. if you want to convert that to a string, the "proper" way to do it is to "decode" the bytes:

>>> b'abcd123'
b'abcd123'
>>> type(b'abcd123')
<class 'bytes'>
>>> b'abcd123'.decode('ascii')
'abcd123'
>>> type(b'abcd123'.decode('ascii'))
<class 'str'>

So you probably want something like this:

figdata_png = base64.b64encode(figfile.getvalue()).decode('ascii')
return render_template('output.html', result=figdata_png)

Thanks harry for the tip. I have incorporated your suggestion into my Web App.