[Python, Программирование] Сохранение сюжетов matplotlib в pdf файл

Автор Сообщение
news_bot ®

Стаж: 6 лет 3 месяца
Сообщений: 27286

Создавать темы news_bot ® написал(а)
25-Фев-2021 17:31

Есть несколько сюжетов 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()
Получим:
Конечный pdf файлСпособ 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()
Получим:
Конечный pdf файлТак сделать не получится, если у нас есть массив уже конкретных построенных фигур. По той простой причине, на фигуре уже отрисовано то, что нужно, и так, как нужно. Да и к тому же, каждая фигура имеет свое значение 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()
Получим:
Конечный pdf файлСпасибо за прочтение статьи. Удачи!
===========
Источник:
habr.com
===========

Похожие новости: Теги для поиска: #_python, #_programmirovanie (Программирование), #_matplotlib, #_pdf, #_reportlab, #_python, #_python, #_programmirovanie (
Программирование
)
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 17-Май 12:44
Часовой пояс: UTC + 5