Guardar gráficos de matplotlib en un archivo pdf

Hay varios gráficos de matplotlib. Es necesario guardarlos en un solo archivo pdf. ¿Qué hacer?






Método I.Guardar un gráfico en una página usando PdfPages

Este método se puede implementar usando dos opciones.





Usando matplotlib magic:





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 acceso directo a 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()
      
      



Obtenemos:





Archivo pdf final
Archivo pdf final

Método II. Guardar varios gráficos en una 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()
      
      



Obtenemos:





Archivo pdf final
Archivo pdf final

Esto no funcionará si tenemos una serie de formas ya concretas. Por esta sencilla razón, ya se ha dibujado la figura de lo que se necesita, y como debe ser. Además, cada forma tiene su propio tamaño y ppp, lo que afecta al renderizado. Por supuesto, todo esto se puede tener en cuenta complicando el algoritmo, pero es mucho más fácil pasar al método 3.





Método III. Usando reportlab

La forma más 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()
      
      



Obtenemos:





Archivo pdf final
Archivo pdf final

Gracias por leer el articulo. ¡Buena suerte!








All Articles