摆脱matlab图的pdf输出周围的空白区域

时间:2010-09-27 07:07:19

标签: pdf matlab

我想在LaTeX文档中使用我的matlab图的PDF版本。我使用带有PDF选项的“saveas”命令保存数字,但是我在pdf文件中的图表周围留下了巨大的空白区域。这是正常的吗?我怎么能摆脱它?当然,因为我有很多情节,所以自动进行。

17 个答案:

答案 0 :(得分:15)

Exporting Figures for Publication是一个很好的起点。而不是-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');

您可以在Tobin's文章中详细了解此信息。

答案 1 :(得分: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')

但是,如果你真的想要一个像Matlab生成的eps的pdf图形,也就是说,只有图的矩形凸包(或一组子图),这里是更复杂的版本:

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);

答案 2 :(得分:6)

我对这个b4有点担心找到一个简单的答案。保存为.eps,然后将.eps转换为.pdf。在Mac OS中,这可以在预览中完成。

答案 3 :(得分:5)

除了此处的其他建议外,您还可以尝试使用http://UndocumentedMatlab.com/blog/axes-looseinset-property/中所述的LooseInset属性来移除绘图轴周围的额外空间。

答案 4 :(得分:4)

我只是花了一些时间尝试这些选项,但我的朋友Espen指出最简单:如果您在LaTeX中使用了graphicx包,请使用标准的Matlab pdf输出并使用\中的trim选项includegraphics。 Beamer幻灯片中的一个例子:

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

这里的修剪参数顺序是左,下,右,上。关键是要修剪顶部和底部以消除额外的空间。更多Wikibooks

答案 5 :(得分:4)

对于光栅图像输出(例如png),我的Makefile中有以下内容:

convert -trim input.png input-trimmed.png

这需要imagemagick。

更新:对于我最近的所有出版物,我都使用了https://github.com/altmany/export_fig,这是我到目前为止找到的最佳解决方案(以及单个包中其他问题的许多其他解决方案)。我觉得一个至少和它一样强大的工具应该已经是Matlab的官方部分了。我用它作为:

export_fig -transparent fig.pdf

导出当前图形,默认情况下裁剪输出。

  

需要代笔

答案 6 :(得分:2)

在MATLAB上file exchange我找到了JürgSchwizer提供的非常有用的功能:

plot2svg( filename, figHandle );

将图形输出为矢量图形(.svg),将各个图形组件输出为像素图形(默认为.png)。这使您可以对图形执行各种操作(删除标签,移动颜色栏等),但如果您对删除白色背景感兴趣,只需打开.svg文件即可。 inkscape,取消组合项目并将您感兴趣的项目导出为新数字。

答案 7 :(得分:2)

对于那些使用linux的人来说,一个非常简单的解决方案是在shell中编写: ps2pdf14 -dPDFSETTINGS=/prepress -dEPSCrop image.eps

答案 8 :(得分: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');

希望它有所帮助。

答案 9 :(得分:2)

我最喜欢@Antonio的方法,但它仍然留下太多的空白,我正在寻找一个单独的绘图解决方案,导出到矢量pdf用于LaTeX。

  • 我根据他的脚本制作了一些东西,并添加了仅导出绘图框的选项(省略了轴)。

  • 请注意,与安东尼奥的剧本不同,这仅适用于没有子图的数字。

  • 下面的代码会将任何单个绘图图形句柄导出为矢量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's 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

示例图片:

使用轴:

Sample PDF screenshot with axes

没有轴:

Sample PDF screenshot without axes

测试代码:

%% 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);

答案 10 :(得分:1)

您也可以使用乳胶本身。

  1. 使用notpad打开eps文件
  2. 转到第一行(%!PS-Adobe-3.1 EPSF- 3.0
  3. 如果最后一个数字是3, 搜索“rf”,然后在该行的开头注释该行%

    否则如果最后一个数字是2, 搜索“pr”,然后在该行的开头注释该行%

答案 11 :(得分:1)

对于Linux用户,以下命令可能有帮助

ps2epsi <input.eps> <output.eps>

建议here

如果您打算在乳胶中使用,请使用Latex命令\includegraphics*代替\includegraphics

答案 12 :(得分:1)

这适用于显示目的:

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

也适用于打印。

答案 13 :(得分: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"`

答案 14 :(得分:0)

在Matlab中将绘图保存为.eps格式,然后在Linux下执行esptopdf命令。这不需要任何额外的编码。只需要一台Linux机器。

答案 15 :(得分:0)

使用 pdfcrop 是另一种解决方案。只需cd到保存所有pdf的文件夹并运行

for i in *;do pdfcrop "$i";done

唯一的问题是 pdfcrop 不适用于 Windows。所以我从 Windows Subsystem for Linux (WSL) 运行它。

答案 16 :(得分:-2)

如果您的现有pdfs具有额外的空格,则可以将此命令与Inkscape一起使用。

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

虽然注意到这个方法仍然留下一些空白,因为导出图形的“绘图区域”本身包含一些空格。

使用Inkscape的效果如下所示:

之前:(使用文件保存图 - &gt;另存为)

PDF saved using File -> Save As

之后:(使用Inkscape)

PDF Cropped using the inkscape command shown above