avatarAngelica Lo Duca

Summary

The article provides three methods for embedding a Matplotlib chart into an HTML page: using the mpld3 library, encoding the image as base64, and utilizing py-script.

Abstract

The article outlines a tutorial on integrating Matplotlib charts into HTML pages, offering three distinct approaches. The first method involves the mpld3 library, which combines Matplotlib with D3.js to convert Python charts into interactive web graphics. The second approach demonstrates how to encode a Matplotlib figure as a base64 image and embed it into an HTML document. Lastly, the article introduces py-script, a Javascript library that allows embedding Python code, including Matplotlib chart generation, directly into HTML. Additionally, the article provides a bonus section on adding Matplotlib animations to HTML files, with a nod to Pgeorges for contributing code.

Opinions

  • The author suggests that using a static image export of a Matplotlib chart in an HTML page sacrifices interactivity.
  • The mpld3 library is presented as a straightforward solution for integrating Matplotlib charts into HTML, though it may alter the chart's appearance slightly.
  • The base64 encoding method is highlighted as a way to preserve the original Matplotlib figure's appearance in an HTML page.
  • Py-script is recommended for its ability to run Python code, including Matplotlib chart generation, directly in the browser, potentially simplifying the deployment of Python-based data visualizations on the web.
  • The author humorously notes that using external frameworks like Streamlit or Flask to serve a Matplotlib chart might be overkill, likening it to using a cannon to shoot a fly.
  • The author expresses gratitude to Pgeorges for providing code that demonstrates how to add a Matplotlib animation to an HTML file.

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

Image by Author

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:

Image by Author

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:

Image by Author

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:

Image by Author

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-script enables 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.

Related Articles

Stay connected!

Data Visualization
Python
Web
HTML
Matplotlib
Recommended from ReadMedium