Русский
Русский
English
Статистика
Реклама

Сохранение сюжетов matplotlib в pdf файл

Есть несколько сюжетов matplotlib. Необходимо сохранить их в единый pdf файл. Что делать?


Способ I. Сохранение одного сюжета на одной странице с помощью PdfPages.

Этот способ можно реализовать с помощью двух вариантов.

Использование магии matplotlib:

from matplotlib.backends.backend_pdf import PdfPagesimport matplotlib.pyplot as pltimport 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 PdfPagesimport matplotlib.pyplot as pltimport 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 файлКонечный pdf файл

Способ II. Сохранение несколько сюжетов на одной странице с помощью PdfPages.

from matplotlib.backends.backend_pdf import PdfPagesimport matplotlib.pyplot as pltimport numpy as np# КонстантыFUNCTIONS = [np.sin, np.cos, np.sqrt, lambda x: x**2, np.tan]X = np.linspace(-5, 5, 100)# Количество строк и столбоц на одной строкеROWS = 2COLUMNS = 2# Создание файла.pdf = PdfPages("Figures.pdf")# Цикл по страницамindex = 0for 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 файлКонечный pdf файл

Так сделать не получится, если у нас есть массив уже конкретных построенных фигур. По той простой причине, на фигуре уже отрисовано то, что нужно, и так, как нужно. Да и к тому же, каждая фигура имеет свое значение dpi и size, которые влияют на отрисовку. Конечно, все это можно учесть, усложнив алгоритм, но намного проще перейти к 3 способу.

Способ III. Использование reportlab.

Наиболее универсальный способ.

import matplotlib.pyplot as pltimport numpy as npfrom io import BytesIOfrom reportlab.pdfgen import canvasfrom reportlab.lib.units import cmfrom 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 210297 мм    # Если выходим за пределы листа, то добавляем новый лист    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 файлКонечный pdf файл

Спасибо за прочтение статьи. Удачи!

Источник: habr.com
К списку статей
Опубликовано: 25.02.2021 14:18:30
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Python

Программирование

Matplotlib

Pdf

Reportlab

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru