How to show Matplotlib in Flask?

Matplotlib plots can be displayed in Flask web applications by converting them to PNG images and serving them as HTTP responses. This approach uses BytesIO to handle the image data in memory without saving files to disk.

Basic Flask Setup

First, create a Flask application that serves a Matplotlib plot as a PNG image ?

import io
from flask import Flask, Response
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure
import numpy as np

app = Flask(__name__)

@app.route('/print-plot')
def plot_png():
    fig = Figure(figsize=(7.5, 3.5))
    axis = fig.add_subplot(1, 1, 1)
    
    # Generate random data points
    xs = np.random.rand(100)
    ys = np.random.rand(100)
    
    # Plot the data
    axis.plot(xs, ys)
    axis.set_title('Random Data Plot')
    
    # Save plot to BytesIO object
    output = io.BytesIO()
    FigureCanvas(fig).print_png(output)
    
    return Response(output.getvalue(), mimetype='image/png')

if __name__ == '__main__':
    app.run(debug=True)

How It Works

The process involves several key steps ?

  • Figure Creation: Create a Matplotlib Figure object instead of using plt
  • Plot Generation: Add subplots and plot data using the figure's axis
  • BytesIO Buffer: Use io.BytesIO() to create an in-memory buffer for the PNG data
  • Canvas Rendering: Convert the figure to PNG format using FigureCanvas
  • Flask Response: Return the PNG data as an HTTP response with correct MIME type

Advanced Example with HTML Template

For a complete web page that displays the plot, create separate routes for HTML and image ?

import io
from flask import Flask, Response, render_template_string
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure
import numpy as np

app = Flask(__name__)

@app.route('/')
def index():
    html_template = '''
    <html>
    <head><title>Matplotlib in Flask</title></head>
    <body>
        <h1>Random Data Visualization</h1>
        <img src="/plot.png" alt="Random plot">
        <p><a href="/">Refresh for new data</a></p>
    </body>
    </html>
    '''
    return render_template_string(html_template)

@app.route('/plot.png')
def plot_png():
    fig = Figure(figsize=(10, 6))
    axis = fig.add_subplot(1, 1, 1)
    
    # Create more interesting data
    x = np.linspace(0, 2*np.pi, 100)
    y = np.sin(x) + np.random.normal(0, 0.1, 100)
    
    axis.plot(x, y, 'b-', linewidth=2)
    axis.set_xlabel('X values')
    axis.set_ylabel('Y values')
    axis.set_title('Sine Wave with Noise')
    axis.grid(True)
    
    output = io.BytesIO()
    FigureCanvas(fig).print_png(output)
    
    return Response(output.getvalue(), mimetype='image/png')

if __name__ == '__main__':
    app.run(debug=True)

Running the Application

To run your Flask application ?

  • Save the code as app.py
  • Set the Flask app: export FLASK_APP=app.py
  • Run: flask run
  • Visit: http://127.0.0.1:5000/
Flask + Matplotlib Flow Browser Request Flask Route /plot.png Matplotlib Generate PNG BytesIO In Memory PNG Response Display Plot

Key Points

  • Memory Efficiency: Using BytesIO avoids creating temporary files on disk
  • Backend Selection: Use FigureCanvasAgg for web applications as it doesn't require a display
  • MIME Type: Always specify mimetype='image/png' in the Response
  • Figure vs Pyplot: Use Figure objects instead of plt for better control in web contexts

Conclusion

Displaying Matplotlib plots in Flask requires converting figures to PNG format using BytesIO and serving them as HTTP responses. This approach provides dynamic, real-time plot generation without file system overhead.

Updated on: 2026-03-25T20:14:34+05:30

7K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements