Data Visualization, Web Application
3 Ways to Embed a Matplotlib Chart into an HTML Page
A tutorial on how to import a Matplotlib chart into an HTML file

Python provides many libraries to perform different operations, including data visualization. However, you may find integrating a chart built using Matplotlib into an HTML page complex. The simplest solution is to export the chart as a static image, such as a PNG or JPEG, and then integrate it into your HTML page. However, if you use a static image, you lose any possible interactivity from the original chart.
Another solution could be using external frameworks such as Streamlit or Flask, but in both cases, you must set up a standalone web server to serve your image. This solution could be too expensive. In my town, we say we shoot a fly with a cannon!
This blog post shows three strategies to embed a Matplotlib chart into an HTML page. The three solutions are:
- Using the mpld3 library
- Encoding the image as base64
- Using
py-script.
Before describing each solution, let’s describe the scenario we’ll use to demonstrate the three cases.
The scenario
Let’s suppose we want to draw a sinusoid using Matplotlib. Here is the code to generate the chart:
import numpy as np
import matplotlib.pyplot as plt
# Generate x from 0 to 2*pi with a step size of 0.1
x = np.arange(0, 2*np.pi, 0.1)
y = np.sin(x)
fig, ax = plt.subplots()
ax.plot(x, y)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_title('Sinusoid')
plt.show()The following figure shows the resulting chart:

Using the mpld3 library
The mpld3 library combines Matplotlib and D3.js, a popular Javascript library for data visualization. Mpld3 provides an API to export the Matplotlib charts in D3.js.
First, install the mpld3 library:
pip install mpld3
To save your Matplotlib chart as an HTML page, use the save_html() function provided by mtpld3, as follows:
import mpld3
import numpy as np
import matplotlib.pyplot as plt
# Generate x from 0 to 2*pi with a step size of 0.1
x = np.arange(0, 2*np.pi, 0.1)
y = np.sin(x)
# Create a figure and axis
fig, ax = plt.subplots()
# Plot the sinusoid
ax.plot(x, y)
# Set labels and title
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_title('Sinusoid')
# Display the plot
mpld3.save_html(fig,'fig.html')The save_html() function receives a Matplotlib figure as an input and the figure name. The script generates the fig.html. If you open it in your browser, you’ll see the following chart:

The chart is slightly different from the original one because it is the D3.js version of the original chart. This means that the mpld3 library transforms the original graph into D3.js. If you inspect the HTML file from your browser, you’ll see that the chart is an SVG image, as shown in the following figure:

To embed the generated chart into another HTML page, copy the content of the generated file precisely in the position where you want to include the image. For more details on how to proceed, follow my previous tutorial.
Encoding the image as base64
Another solution is encoding the Matplotlib figure as a base64 image, as described in this Stack Overflow thread. Here is the code to generate the HTML page containing the Matplotlib image:
import base64
from io import BytesIO
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(0, 2*np.pi, 0.1)
y = np.sin(x)
fig, ax = plt.subplots()
ax.plot(x, y)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_title('Sinusoid')
tmpfile = BytesIO()
fig.savefig(tmpfile, format='png')
encoded = base64.b64encode(tmpfile.getvalue()).decode('utf-8')
html = '<html>' + '<img src=\'data:image/png;base64,{}\'>'.format(encoded) + '</html>'
with open('fig2.html','w') as f:
f.write(html)In practice you generate a BytesIO() object and save the figure using the PNG format. Then use b64encode() function to encode the image and the decode() function to decode it. Finally, add the decoded image to an HTML string and save it. As a result, you have precisely the original Matplotlib figure.
Using py-script
Py-script is a Javascript library enabling you to include Python code directly into an HTML page. To use Py-script, you must include the following py-script library in the HTML heading:
<head>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>Then, use the py-config tag to install the required Python libraries:
<py-config>
packages = ["matplotlib", "numpy"]
</py-config>Finally, use the py-script tag to include your Python code:
<py-script>
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(0, 2*np.pi, 0.1)
y = np.sin(x)
fig, ax = plt.subplots()
ax.plot(x, y)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_title('Sinusoid')
display(fig, target="graph-area", append=False)
</py-script>
<div id="graph-area"></div>To show the figure, use the display() function, which receives the Matplotlib figure, the HTML div where to include the plot and if to use the append modality.
As a final result, you have precisely the same figure as the original one.
Summary
Congratulations! You have just learned three ways to include a Matplotlib chart into an HTML page! The three strategies are:
- Using the mpld3 library converts your Matplotlib chart into a D3.js chart
- Encoding the image as base64 generates a PNG image of the Matplotlib chart as a base64 encoded image and then includes it into an HTML page
- Using
py-scriptenables you to have your Python code directly in HTML.
Extra Bonus: How to add a Matplotlib animation to your HTML file
It may happen that you want to add an energy produced with Matplotlib to your HTML chart. Here is the code:
from IPython.display import HTML
from matplotlib.animation import FuncAnimation
import matplotlib.pyplot as plt
import numpy as np
# Create figure and axis objects
fig, ax = plt.subplots()
# Create x data
x = np.arange(0, 2 * np.pi, 0.01)
# Define the initial state of the line
line, = ax.plot(x, np.sin(x))
# Define the update function for the animation
def update(frame):
# Shift the x data by one step
line.set_xdata(x + frame * 0.1)
return line
# Create the animation object
ani = FuncAnimation(fig, update, frames=100, interval=50);
#Then the next code line will generate an #html file:
with open("matplotlib_to_video.html", "w") as f:
print(ani.to_html5_video(), file=f)Use the last two statements to save the animation as an HTML file. You can find the code in this Colab Notebook. To download the HTML file, access the Colab temporary filesystem, and download it.
I want to thank Pgeorges, who wrote the previous code.






