Existem vários gráficos de matplotlib. É necessário salvá-los em um único arquivo pdf. O que fazer?
Método I. Salvando um gráfico em uma página usando PdfPages
Este método pode ser implementado usando duas opções.
Usando a magia matplotlib:
from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.pyplot as plt
import numpy as np
# .
pdf = PdfPages("Figures.pdf")
# .
FUNCTIONS = [np.sin, np.cos, np.sqrt, lambda x: x**2]
X = np.linspace(-5, 5, 100)
for function in FUNCTIONS:
plt.plot(X, function(X))
pdf.savefig()
plt.close()
#
pdf.close()
Usando acesso direto às formas:
from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.pyplot as plt
import numpy as np
# .
FUNCTIONS = [np.sin, np.cos, np.sqrt, lambda x: x**2]
X = np.linspace(-5, 5, 100)
figures = []
for function in FUNCTIONS:
figure = plt.figure()
axes = figure.subplots()
axes.plot(X, function(X))
figures.append(figure)
# .
# figures = []
# .
pdf = PdfPages("Figures.pdf")
for figure in figures:
pdf.savefig(figure)
#
pdf.close()
Nós temos:
Método II. Salvar vários gráficos em uma página usando PdfPages
from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.pyplot as plt
import numpy as np
#
FUNCTIONS = [np.sin, np.cos, np.sqrt, lambda x: x**2, np.tan]
X = np.linspace(-5, 5, 100)
#
ROWS = 2
COLUMNS = 2
# .
pdf = PdfPages("Figures.pdf")
#
index = 0
for page in range(len(FUNCTIONS)//(ROWS*COLUMNS)+1):
# .
figure = plt.figure(figsize=(12, 12))
axes = figure.subplots(ROWS, COLUMNS)
#
for row in range(ROWS):
for column in range(COLUMNS):
if index < len(FUNCTIONS):
axes[row, column].plot(X, FUNCTIONS[index](X))
index += 1
#
pdf.savefig(figure)
#
pdf.close()
Nós temos:
Isso não funcionará se tivermos uma série de formas já concretas. Por esta simples razão, a figura já foi desenhada o que é necessário e como deve ser. Além disso, cada forma tem seu próprio dpi e tamanho, que afetam a renderização. Claro, tudo isso pode ser levado em consideração ao complicar o algoritmo, mas é muito mais fácil ir para o método 3.
Método III. Usando reportlab
A forma mais versátil.
import matplotlib.pyplot as plt
import numpy as np
from io import BytesIO
from reportlab.pdfgen import canvas
from reportlab.lib.units import cm
from reportlab.lib.utils import ImageReader
# .
FUNCTIONS = [np.sin, np.cos, np.sqrt, lambda x: x**2]
X = np.linspace(-5, 5, 100)
figures = []
for function in FUNCTIONS:
figure = plt.figure()
axes = figure.subplots()
axes.plot(X, function(X))
figures.append(figure)
# .
# figures = []
#
indent = 1.5
# canvas
c = canvas.Canvas("Figures.pdf")
c.setTitle("Figures")
height = indent
# .
for figure in figures:
# dpi ( )
dpi = figure.get_dpi()
figureSize = figure.get_size_inches()
# .
# , .
figure.patches.extend(
[plt.Rectangle((0, 1/(dpi*figureSize[1])), width=1-2/(dpi*figureSize[0]),
height=1-2/(dpi*figureSize[1]),
transform=figure.transFigure, figure=figure, clip_on=False,
edgecolor="black",
facecolor="none", linewidth=1)])
# .
image = BytesIO()
figure.savefig(image, format="png")
image.seek(0)
image = ImageReader(image)
# .
figureSize = figure.get_size_inches()*2.54
# A4 210×297
# ,
if height + figureSize[1] + indent > 29.7:
height = indent
c.showPage()
# image pdf
c.drawImage(image, (10.5-figureSize[0]/2)*cm, height*cm,
figureSize[0]*cm, figureSize[1]*cm)
height += figureSize[1]
# .
c.save()
Nós temos:
Obrigado por ler o artigo. Boa sorte!