Inserting generated Matplotlib plots into Flask with python3
<p>I am using Python 3 and Flask with Matplotlib and numpy.</p>

<p>I wish to load pages that generate many plots which are embedded into the page.</p>

<p>I have tried following suggestions made in other places, such as this <a href="http://stackoverflow.com/questions/20107414/passing-a-matplotlib-figure-to-html-flask">stackoverflow question</a> and this <a href="https://gist.github.com/wilsaj/862153" rel="nofollow">github post</a>.</p>

<p>However, when I try to implement anything of the kind I get all kinds of IO related errors. Usually of the form:</p>

<pre><code>TypeError: string argument expected, got 'bytes'
</code></pre>

<p>and is generated inside of:</p>

<pre><code>site-packages/matplotlib/backends/backend_agg.py
</code></pre>

<p>specifically the <code>print_png</code> function</p>

<p>I understand python3 no longer has a <code>StringIO import</code>, which is what is producing the error, and instead we are to <code>import io</code> and call it with <code>io.StringIO()</code> - at least that is what I understand we are to do, however, I can't seem to get any of the examples I have found to work. </p>

<p>The structure of my example is almost identical to that of the stackoverflow question listed above. The page generates as does the image route. It is only the image generation itself that fails. </p>

<p>I am happy to try a different strategy if someone has a better idea. To be clear, I need to generate plots - some times many (100+ on any single page and hundreds of pages) - from data in a database and display them on a webpage. I was hoping to avoid generating files that I then have to clean up given the large number of files I will probably generate and the fact they may change as data in the DB changes.</p>

<p>The code taken from this <a href="http://stackoverflow.com/questions/20107414/passing-a-matplotlib-figure-to-html-flask?rq=1">stackoverflow question</a> which is used in the above question contains the following:</p>

<pre><code>    import StringIO
    ...
    fig = draw_polygons(cropzonekey)
    img = StringIO()
    fig.savefig(img)
</code></pre>

<p>As poitned out by @furas, Python3 treats bytes and strings differently to Python2. In many Python 2 examples StringIO is used for cases like the above but in Python3 it will not work. Therefore, we need modify the above like this:</p>

<pre><code>    import io
    ...
    fig = draw_polygons(cropzonekey)
    img = BytesIO()
    fig.savefig(img)
</code></pre>

<p>Which appears to work.</p>

python python-3.x numpy matplotlib flask