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

40

Я хотел бы использовать PDF-версии моих графиков Matlab в документе LaTeX. Я сохраняю цифры, используя команду "saveas" с опцией PDF, но я получаю огромное количество пробелов вокруг моих участков в pdf файлах. Это нормально? Как я могу избавиться от него? Автоматически, конечно, так как у меня "много" сюжетов.

  • 1
    Тот же вопрос: stackoverflow.com/questions/5150802/…
  • 1
    У меня есть pdfcrop в моем рабочем процессе, чтобы избавиться от пробелов после факта. Помогает и многим другим программам, которые выводят PDF-файлы в виде полных листов бумаги.
Показать ещё 1 комментарий
Теги:
pdf

16 ответов

15

Экспорт фигур для публикации является хорошей отправной точкой. Вместо -deps используйте -dpdf для вывода в формате pdf.

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

set(gcf, 'PaperSize', [6.25 7.5]);
set(gcf, 'PaperPositionMode', 'manual');
set(gcf, 'PaperPosition', [0 0 6.25 7.5]);

set(gcf, 'PaperUnits', 'inches');
set(gcf, 'PaperSize', [6.25 7.5]);
set(gcf, 'PaperPositionMode', 'manual');
set(gcf, 'PaperPosition', [0 0 6.25 7.5]);

set(gcf, 'renderer', 'painters');
print(gcf, '-dpdf', 'my-figure.pdf');
print(gcf, '-dpng', 'my-figure.png');
print(gcf, '-depsc2', 'my-figure.eps');

Подробнее об этом можно прочитать в статье Тобина.

8

Ответы выше кажутся слишком сложными. Эта функция использует дескриптор фигуры и строку для печати материала в pdf файле без огромных полей.

function printpdf(h,outfilename)

set(h, 'PaperUnits','centimeters');
set(h, 'Units','centimeters');
pos=get(h,'Position');
set(h, 'PaperSize', [pos(3) pos(4)]);
set(h, 'PaperPositionMode', 'manual');
set(h, 'PaperPosition',[0 0 pos(3) pos(4)]);
print('-dpdf',outfilename);

Например, чтобы напечатать текущую цифру, вы можете вызвать ее с помощью:

printpdf(gcf,'trash')

Однако, если вам действительно нужна цифра в формате pdf, например, генерируемый Matlab eps, то есть только прямоугольная выпуклая оболочка сюжета (или набор подзаголовков), здесь более сложная версия:

function printpdf(h,outfilename)

% first use the same non-relative unit system for paper and screen (see
% below)
set(h,'PaperUnits','centimeters');

% now get all existing plots/subplots
a=get(h,'Children');
nfigs=length(a);

% bounds will contain lower-left and upper-right corners of plots plus one
% line to make sure single plots work
bounds=zeros(nfigs+1,4);
bounds(end,1:2)=inf;
bounds(end,3:4)=-inf;

% generate all coordinates of corners of graphs and store them in
% bounds as [lower-left-x lower-left-y upper-right-x upper-right-y] in
% the same unit system as paper (centimeters here)
for i=1:nfigs
    set(a(i),'Unit','centimeters');
    pos=get(a(i),'Position');
    inset=get(a(i),'TightInset');
    bounds(i,:)=[pos(1)-inset(1) pos(2)-inset(2) ...
        pos(1)+pos(3)+inset(3) pos(2)+pos(4)+inset(4)];
end

% compute the rectangular convex hull of all plots and store that info
% in mypos as [lower-left-x lower-left-y width height] in centimeters
auxmin=min(bounds(:,1:2));
auxmax=max(bounds(:,3:4));
mypos=[auxmin auxmax-auxmin];

% set the paper to the exact size of the on-screen figure using
% figure property PaperSize [width height]
set(h,'PaperSize',[mypos(3) mypos(4)]);

% ensure that paper position mode is in manual in order for the
% printer driver to honor the figure properties
set(h,'PaperPositionMode', 'manual');

% use the PaperPosition four-element vector [left, bottom, width, height]
% to control the location on printed page; place it using horizontal and
% vertical negative offsets equal to the lower-left coordinates of the
% rectangular convex hull of the plot, and increase the size of the figure
% accordingly
set(h,'PaperPosition',[-mypos(1) -mypos(2) ...
    mypos(3)+mypos(1) mypos(4)+mypos(2)]);

% print stuff
print('-dpdf',outfilename);
  • 0
    Для примера того, как визуализированный PDF отличается между этими двумя функциями, смотрите эти два скриншота. Первый кодовый блок , Второй кодовый блок (только прямоугольный выпуклый корпус). Обратите внимание, что на втором изображении график расположен прямо напротив левого нижнего угла. Заметьте также, что они выглядят как настоящие векторные изображения (а не растровые), что для меня является тем, что мне нужно, хотя мне бы хотелось еще меньше пробелов. В любом случае спасибо Антонио!
6

Я немного побеспокоился относительно этого b4, найдя легкий ответ. Сохраните как .eps, а затем преобразуйте .eps в .pdf. В Mac OS это можно сделать в режиме предварительного просмотра.

5

В дополнение к другим предложениям здесь вы также можете попытаться использовать свойство LooseInset, как описано в http://UndocumentedMatlab.com/blog/axes-looseinset-property/, чтобы удалить лишнее пространство вокруг ваши сюжетные оси.

4

Для выходов растровых изображений (например, png) в моем файле Makefile находится следующее:

convert -trim input.png input-trimmed.png

Для этого требуется imagemagick.

Обновление:. Во всех моих последних публикациях я использовал https://github.com/altmany/export_fig, и это лучшее решение, которое я нашел так далеко (наряду со многими другими решениями для других задач в одном пакете). Я чувствую инструмент, который, по крайней мере, столь же мощный, как это уже должно быть официальной частью Matlab. Я использую его как:

export_fig -transparent fig.pdf

Которая экспортирует текущий рисунок, обрезая вывод по умолчанию.

Требовать ghostcript

4

Я просто потратил некоторое время на выполнение большинства этих параметров, но мой друг Эспен указал на самое простое: если вы используете пакет graphicsx в LaTeX, пойдите со стандартным выходом Matlab pdf и используйте опцию trim в \includegraphics. Пример в слайде Beamer:

\ includegraphics [trim = 0.1in 2.5in 0.1in 2.5in, clip, scale = 0.5] {matlabgraphic.pdf}

Порядок параметров обрезки здесь слева, снизу, справа, сверху. Ключ должен обрезать верх и низ много, чтобы избавиться от лишнего пространства. Подробнее в Wikibooks.

2

Мне понравился метод @Antonio, но он все еще оставил слишком много пробелов, и я искал одно графическое решение, которое экспортировалось в векторные pdf файлы для использования в LaTeX.

  • Я сделал что-то, основанное на его script, и добавил возможность экспортировать только поле графика (опускание осей).

  • Обратите внимание, что в отличие от Antonio script, это работает только с цифрами без подзаголовков.

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


function SaveFigureAsVectorPDF(InputFigureHandle, OutFileName, ShouldPrintAxes)
    %% Check input parameters
    [NumberOfFigures, ~] = size(InputFigureHandle);    

    if(NumberOfFigures ~= 1)
        error('This function only supports one figure handle.');

    end

    if(isempty(OutFileName))
        error('No file path provided to save the figure to.');

    end

    cUnit = 'centimeters';

    %% Copy the input figure so we can mess with it    
    %Make a copy of the figure so we don't modify the properties of the
    %original.
    FigureHandleCopy = copy(InputFigureHandle);

    %NOTE:  Do not set this figure to be invisible, for some bizarre reason
    %       it must be visible otherwise Matlab will just ignore attempts 
    %       to set its properties.
    % 
    %       I would prefer it if the figure did not briefly flicker into
    %       view but I am not sure how to prevent that.

    %% Find the axis handle
    ChildAxisHandles     = get(FigureHandleCopy, 'Children');
    NumberOfChildFigures = length(ChildAxisHandles);

    if(NumberOfChildFigures ~= 1)
       %note that every plot has at least one child figure
       error('This function currently only supports plots with one child figure.');

    end

    AxisHandle = ChildAxisHandles(1);

    %% Set Units
    % It doesn't matter what unit you choose as long as it the same for
    % the figure, axis, and paper. Note that 'PaperUnits' unfortunately
    % does not support 'pixels' units.

    set(FigureHandleCopy,   'PaperUnits',   cUnit);
    set(FigureHandleCopy,   'Unit',         cUnit);
    set(AxisHandle,         'Unit',         cUnit); 

    %% Get old axis position and inset offsets 
    %Note that the axes and title are contained in the inset
    OldAxisPosition = get(AxisHandle,   'Position');
    OldAxisInset    = get(AxisHandle,   'TightInset');

    OldAxisWidth    = OldAxisPosition(3);
    OldAxisHeight   = OldAxisPosition(4);

    OldAxisInsetLeft    = OldAxisInset(1);
    OldAxisInsetBottom  = OldAxisInset(2);
    OldAxisInsetRight   = OldAxisInset(3);
    OldAxisInsetTop     = OldAxisInset(4);

    %% Set positions and size of the figure and the Axis 
    if(~ShouldPrintAxes)

        FigurePosition = [0.0, 0.0, OldAxisWidth, OldAxisHeight];

        PaperSize = [OldAxisWidth, OldAxisHeight];

        AxisPosition = FigurePosition;      

    else
        WidthWithInset  = OldAxisWidth   + OldAxisInsetLeft + OldAxisInsetRight;
        HeightWithInset = OldAxisHeight  + OldAxisInsetTop  + OldAxisInsetBottom;

        FigurePosition = [0.0, 0.0, WidthWithInset,  HeightWithInset];

        PaperSize = [WidthWithInset, HeightWithInset];

        AxisPosition = [OldAxisInsetLeft, OldAxisInsetBottom, OldAxisWidth, OldAxisHeight];

    end

    set(FigureHandleCopy,   'Position', FigurePosition);
    set(AxisHandle,         'Position', AxisPosition);

    %Note:  these properties do not effect the preview but they are
    %       absolutely necessary for the pdf!!
    set(FigureHandleCopy,   'PaperSize',        PaperSize);
    set(FigureHandleCopy,   'PaperPosition',    FigurePosition);

    %% Write the figure to the PDF file
    print('-dpdf', OutFileName);

    set(FigureHandleCopy, 'name', 'PDF Figure Preview', 'numbertitle', 'off');

    %If you want to see the figure (e.g., for debugging purposes), comment
    %the line below out.
    close(FigureHandleCopy);

end

Образцы изображений:

С осями:

Изображение 6321

Без осей:

Изображение 6322

Код тестирования:

%% Generates a graph and saves it to pdf

FigureHandle = figure;

plot(1:100);

title('testing');

%with axes
SaveFigureAsVectorPDF(FigureHandle, 'withaxes.pdf', true);

%without axes
SaveFigureAsVectorPDF(FigureHandle, 'withoutaxes.pdf', false);
  • 0
    Обратите внимание, что легенды фигуры считаются «дочерними» фигуры.
2

Я также столкнулся с этой проблемой. Наконец, я использовал следующий метод, который разрешил его, что может автоматически сохранить фигуру в формате MATLAB как правильный формат PDF.

вы можете сделать это в MATLAB через:

h = figure; % For example, h = openfig('sub_fig.fig'); Or you just ploted one figure: plot(1:10);
set(h,'Units','Inches');
pos = get(h,'Position');
set(h,'PaperPositionMode','Auto','PaperUnits','Inches','PaperSize',[pos(3),pos(4)]);
print(h,'your_filename','-dpdf','-r0');

Надеюсь, что это поможет.

2

Для тех, кто использует linux, очень простое решение - написать в оболочке: ps2pdf14 -dPDFSETTINGS=/prepress -dEPSCrop image.eps

2

В MATLAB обмен файлами я нашел чрезвычайно полезную функцию, предоставленную Jürg Schwizer:

plot2svg( filename, figHandle );

Выводит фигуру в виде векторной графики (.svg) и отдельных фигурных компонентов в качестве пиксельной графики (по умолчанию -.png). Это позволяет делать всевозможные вещи на вашем рисунке (удалять ярлыки, перемещать цветные панели и т.д.), Но если вы хотите удалить белый фон, просто откройте файл .svg, например. inkscape, разгруппируйте элементы и экспортируйте интересующие вас предметы в качестве новой фигуры.

1

Для пользователей Linux следующая команда может помочь

ps2epsi <input.eps> <output.eps>

как предложено здесь

и если вы собираетесь использовать в латексе, используйте команду Latex \includegraphics* вместо \includegraphics

  • 0
    Как это помогает с PDF?
1

Вы также можете сделать это в латекс.

  • откройте файл eps с помощью notpad
  • перейти к первой строке (%! PS-Adobe-3.1 EPSF- 3.0)

Если последнее число равно 3, выполните поиск "rf", а затем прокомментируйте эту строку, набрав % в начале строки

else, если последнее число равно 2, найдите "pr", а затем прокомментируйте эту строку, набрав % в начале строки

  • 0
    это похоже на редактирование необработанного файла изображения, а не на что-нибудь, связанное с латексом? Вы также можете указать, что % является комментарием в PS (AFAIR)
1

Это работает для отображения целей:

set(gca, 'LooseInset', get(gca, 'TightInset'));

Должен работать и для печати. ​​

  • 0
    Нет, не повезло: >> set (gca, 'LooseInset', get (gca, 'TightInset')); >> print (gcf, '-dpdf', 'my-figure.pdf'); >> print (gcf, '-dpng', 'my-figure.png'); не работает
0

сохранить график в формате .eps в Matlab, затем выполнить команду esptopdf под Linux. Это не требует дополнительного кодирования. Требуется только машина Linux.

0

Для меня был использован следующий двухэтапный подход (с использованием pdfcrop). Предполагая, что у вас установлены все pdf-инструменты и PDFcrop (http://pdfcrop.sourceforge.net/)

В MATLAB введите

print -deps -r600 figure.eps

И затем в командной строке

./cropEpsFigure.sh figure

Используя следующий файл: cropEpsFigure.sh

#!/bin/bash
/usr/texbin/epstopdf "$1.eps"
/usr/texbin/pdfcrop "$1.pdf"
/usr/local/bin/pdftops -eps "$1-crop.pdf"`
-3

Вы можете использовать эту команду с Inkscape, если у вас есть существующие PDF файлы с дополнительными пробелами.

Inkscape.exe --file SomePDFWithWhitespace.pdf --export-pdf=SomePDFWithWhitespaceRemoved.pdf --export-area-drawing

Обратите внимание, что этот метод все еще оставляет некоторые пробелы, потому что "область рисования" экспортируемой фигуры сама содержит некоторые пробелы.

Эффекты использования Inkscape показаны ниже:

До: (фигура сохранена с использованием файла → Сохранить как)

Изображение 6323

После: (используя Inkscape)

Изображение 6324

  • 7
    Возможно, вы захотите включить фактическую команду, необходимую при ответе на вопрос.
  • 1
    Я был бы очень признателен за это решение, но не смог его найти. Если кто-нибудь знает об этом, пожалуйста, опубликуйте его.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню