Есть несколько сюжетов matplotlib. Необходимо сохранить их в единый pdf файл. Что делать?
Способ I. Сохранение одного сюжета на одной странице с помощью PdfPages.
Этот способ можно реализовать с помощью двух вариантов.
Использование магии 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()
Использование непосредственного доступа к фигурам:
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()
Получим:
Способ II. Сохранение несколько сюжетов на одной странице с помощью 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()
Получим:
Так сделать не получится, если у нас есть массив уже конкретных построенных фигур. По той простой причине, на фигуре уже отрисовано то, что нужно, и так, как нужно. Да и к тому же, каждая фигура имеет свое значение dpi и size, которые влияют на отрисовку. Конечно, все это можно учесть, усложнив алгоритм, но намного проще перейти к 3 способу.
Способ III. Использование reportlab.
Наиболее универсальный способ.
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()
Получим:
Спасибо за прочтение статьи. Удачи!
ссылка на оригинал статьи https://habr.com/ru/post/544132/
Добавить комментарий