Я использую пользовательское преобразование, PNG в порядке, но PDF-файл пуст

Этот вопрос является продолжением Создание плаката: как разместить художников на рисунке, используя мм и начало координат в левом верхнем углу

Этот код:

import matplotlib.pyplot as plt
from matplotlib.transforms import Affine2D

mm, dpi = 1/25.4, dpi
w, h = 841, 1189
trans = Affine2D().scale(mm*dpi).scale(1,-1).translate(0,h*mm*dpi)

fig = plt.figure(figsize=(w*mm, h*mm), layout='none', dpi=dpi)
fig.patches.append(
    plt.Rectangle((230, 190), 40, 18, transform=trans))
fig.savefig('A0.pdf')
fig.savefig('A0.png')

создает пустой PDF-файл, а PNG-файл правильный.

К сожалению, типографии с широким струйным плоттером нужен PDF-файл. Хотя я мог бы преобразовать растровый файл в PDF, я бы предпочел напрямую создать правильный PDF-файл.

Что-то не так в моем коде или этого не должно произойти, и это ошибка, о которой я должен сообщить разработчикам Matplotlib?


Этот код, не использующий пользовательское преобразование, создает правильный PDF-файл с прямоугольником в правильном положении и нужных размерах.

import numpy as np
import matplotlib.pyplot as plt

mm, dpi = 1/25.4, 96
w, h = 841, 1189
fig = plt.figure(dpi=dpi, layout='none', figsize=(w*mm,h*mm))
fig.patches.append(plt.Rectangle((660/w, 1-1000/h), 40/w, -40/h,
                                 transform=fig.transFigure))
fig.savefig('A0.pdf')

ОБНОВЛЯТЬ

...
fig = plt.figure(figsize=(w*mm, h*mm), layout='none', dpi=dpi)
fig.patches.append(
    plt.Rectangle((230, 190), 40, 18, transform=trans))
fig.patches.append(
    plt.Rectangle((600/w, 1-190/h), 40/w, -18/h, transform=fig.transFigure))
fig.savefig('A0.pdf')

создает непустой PDF-файл, но виден только второй прямоугольник, нарисованный без использования пользовательского преобразования.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
53
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

В этой теме, посвященной воспоминаниям от июля 2010 года, они предлагают жестко запрограммировать dpi=72 в средство визуализации PDF для обеспечения обратной совместимости со старыми спецификациями PDF. И действительно, когда я установил его в savefig, прямоугольник (и любые другие художники, добавленные к фигуре с помощью пользовательской трансформации) отображаются нормально:

fig.savefig("A0.pdf", dpi=72)

В своих экспериментах я обнаружил, что fig.savefig("A0.pdf", dpi=72) недостаточно, нужно еще fig = plt.figure(…, dpi=72), иначе вывода в PDF не будет.

gboffi 17.07.2024 15:29

Чтобы решить эту проблему, вы можете более эффективно использовать параметр преобразования, применив

преобразования, которые более совместимы с серверной частью PDF. В частности, вы

можно попытаться избежать сложных пользовательских преобразований и больше полагаться на

преобразования, предоставляемые Matplotlib, например fig.transFigure, который работает


последовательно на разных бэкэндах.

Ответ принят как подходящий

Если вы когда-нибудь обнаружите, что чертите что-то и вам придется указывать разрешение вручную, у вас возникнут проблемы, если вы попытаетесь сохранить изображение с другим разрешением. Правильный способ сделать это, чтобы он был инвариантным по dpi, но все еще находился в физическом пространстве:

import matplotlib.pyplot as plt
from matplotlib.transforms import Affine2D

mm = 1.0/25.4
w, h = 841.0, 1182.0
fig = plt.figure(figsize=(w*mm, h*mm), layout='none')

trans = Affine2D().scale(mm).scale(1,-1).translate(0,h*mm) + fig.dpi_scale_trans
fig.patches.append(
    plt.Rectangle((230, 190), 40, 18, transform=trans))

Другие вопросы по теме