# Charts & graphs¶

## Charts¶

### Using Matplotlib¶

Before running this example, please install the required dependencies using the command below:

pip install fpdf2 matplotlib

Example taken from Matplotlib artist tutorial:

from fpdf import FPDF
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure
import numpy as np
from PIL import Image

fig = Figure(figsize=(6, 4), dpi=300)
ax1.set_ylabel("volts")
ax1.set_title("a sine wave")

t = np.arange(0.0, 1.0, 0.01)
s = np.sin(2 * np.pi * t)
(line,) = ax1.plot(t, s, color="blue", lw=2)

# Fixing random state for reproducibility
np.random.seed(19680801)

ax2 = fig.add_axes([0.15, 0.1, 0.7, 0.3])
n, bins, patches = ax2.hist(
np.random.randn(1000), 50, facecolor="yellow", edgecolor="yellow"
)
ax2.set_xlabel("time (s)")

# Converting Figure to an image:
canvas = FigureCanvas(fig)
canvas.draw()
img = Image.fromarray(np.asarray(canvas.buffer_rgba()))

pdf = FPDF()
pdf.image(img, w=pdf.epw)  # Make the image full width
pdf.output("matplotlib.pdf")


Result:

You can also embed a figure as SVG:

from fpdf import FPDF
import matplotlib.pyplot as plt
import numpy as np

plt.figure(figsize=[2, 2])
x = np.arange(0, 10, 0.00001)
y = x*np.sin(2* np.pi * x)
plt.plot(y)
plt.savefig("figure.svg", format="svg")

pdf = FPDF()
pdf.image("figure.svg")
pdf.output("doc-with-figure.pdf")


### Using Pandas¶

The dependencies required for the following examples can be installed using this command:

pip install fpdf2 matplotlib pandas


Create a plot using pandas.DataFrame.plot:

from io import BytesIO
from fpdf import FPDF
import pandas as pd
import matplotlib.pyplot as plt
import io

data = {
"Unemployment_Rate": [6.1, 5.8, 5.7, 5.7, 5.8, 5.6, 5.5, 5.3, 5.2, 5.2],
"Stock_Index_Price": [1500, 1520, 1525, 1523, 1515, 1540, 1545, 1560, 1555, 1565],
}

plt.figure()  # Create a new figure object
df = pd.DataFrame(data, columns=["Unemployment_Rate", "Stock_Index_Price"])
df.plot(x="Unemployment_Rate", y="Stock_Index_Price", kind="scatter")

# Converting Figure to an image:
img_buf = BytesIO()  # Create image object
plt.savefig(img_buf, dpi=200)  # Save the image

pdf = FPDF()
pdf.image(img_buf, w=pdf.epw) # Make the image full width
pdf.output("pandas.pdf")
img_buf.close()

Result:

Create a table with pandas DataFrame:

from fpdf import FPDF
import pandas as pd

df = pd.DataFrame(
{
"First name": ["Jules", "Mary", "Carlson", "Lucas"],
"Last name": ["Smith", "Ramos", "Banks", "Cimon"],
"Age": [34, 45, 19, 31],
"City": ["San Juan", "Orlando", "Los Angeles", "Saint-Mahturin-sur-Loire"],
}
)

df = df.applymap(str)  # Convert all data inside dataframe into string type

columns = [list(df)]  # Get list of dataframe columns
rows = df.values.tolist()  # Get list of dataframe rows
data = columns + rows  # Combine columns and rows in one list

# Start pdf creating
pdf = FPDF()
pdf.set_font("Times", size=10)
line_height = pdf.font_size * 2.5
col_width = pdf.epw / 4  # distribute content evenly

for row in data:
for datum in row:
pdf.multi_cell(
col_width,
line_height,
datum,
border=1,
new_y="TOP",
max_line_height=pdf.font_size,
)
pdf.ln(line_height)
pdf.output("table_with_cells.pdf")


Result:

## Mathematical formulas¶

fpdf2 can only insert mathematical formula in the form of images. The following sections will explaing how to generate and embed such images.

Official documentation: Google Charts Infographics - Mathematical Formulas.

Example:

from io import BytesIO
from urllib.parse import quote
from urllib.request import urlopen
from fpdf import FPDF

formula = "x^n + y^n = a/b"
height = 170
with urlopen(url) as img_file:

pdf = FPDF()
pdf.image(img, w=30)
pdf.output("equation-with-gcharts.pdf")


Result:

### Using LaTeX & Matplotlib¶

Matplotlib can render LaTeX: Text rendering With LaTeX.

Example:

from io import BytesIO
from fpdf import FPDF
from matplotlib.figure import Figure

fig = Figure(figsize=(6, 2))
gca = fig.gca()
gca.text(0, 0.5, r"$x^n + y^n = \frac{a}{b}$", fontsize=60)
gca.axis("off")

# Converting Figure to a SVG image:
img = BytesIO()
fig.savefig(img, format="svg")

pdf = FPDF()
pdf.image(img, w=100)
pdf.output("equation-with-matplotlib.pdf")


Result:

If you have trouble with the SVG export, you can also render the matplotlib figure as pixels:

from fpdf import FPDF
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure
import numpy as np
from PIL import Image

fig = Figure(figsize=(6, 2), dpi=300)
gca = fig.gca()
gca.text(0, 0.5, r"$x^n + y^n = \frac{a}{b}$", fontsize=60)
gca.axis("off")

canvas = FigureCanvas(fig)
canvas.draw()
img = Image.fromarray(np.asarray(canvas.buffer_rgba()))

...


### Using Plotly¶

Before running this example, please install the required dependencies using the command below:

pip install fpdf2 plotly kaleido numpy


kaleido is a cross-platform library for generating static images that is used by plotly.

Example taken from Plotly static image export tutorial:

import io
import plotly.graph_objects as go
import numpy as np
from fpdf import FPDF

np.random.seed(1)

N = 100
x = np.random.rand(N)
y = np.random.rand(N)
colors = np.random.rand(N)
sz = np.random.rand(N) * 30

fig = go.Figure()
x=x,
y=y,
mode="markers",
marker=go.scatter.Marker(
size=sz,
color=colors,
opacity=0.6,
colorscale="Viridis"
)
))
# Convert the figure to png using kaleido
image_data=fig.to_image(format="png", engine="kaleido")
# Create an io.BytesIO object which can be used by FPDF2
image = io.BytesIO(image_data)
pdf = FPDF()
pdf.image(image,w=pdf.epw)  # Width of the image is equal to the width of the page
pdf.output("plotly.pdf")


Result:

You can also embed a figure as SVG but this is not recommended because the text data such as the x and y axis bars might not show as illustrated in the result image because plotly places this data in a svg text tag which is currently not supported by FPDF2.

Before running this example, please install the required dependencies:

pip install fpdf2 plotly kaleido pandas

from fpdf import FPDF
import plotly.express as px

fig = px.bar(x=["a", "b", "c"], y=[1, 3, 2])
fig.write_image("figure.svg")

pdf = FPDF()