4.45

4.5 | 23 ratings Rate this file 219 downloads (last 30 days) File Size: 4 KB File ID: #22018

print_pdf

by Oliver Woodford

 

06 Nov 2008 (Updated 14 Apr 2009)

Code covered by BSD License  

Save figures to high quality pdfs with cropped borders and embedded fonts.

Download Now | Watch this File

File Information
Description

PLEASE NOTE - This function has now been superseded by EXPORT_FIG, which encompasses all its functionality plus some further functionality. This function will therefore no longer receive any support. EXPORT_FIG can be downloaded from:
http://www.mathworks.com/matlabcentral/fileexchange/23629

PRINT_PDF saves a figure to a pdf file, with:
   - Figure borders cropped
   - Fonts embedded (as subsets)
   - Accurate vector graphics, compressed losslessly
   - High quality bitmap graphics, compressed lossily
   - Line dash lengths vary with line width (as on screen)
   - Grid lines given their own dot style, instead of dashed
   - No options to be set

The screenshot demonstrates the benefit of PRINT_PDF over MATLAB's pdf saving functions. It shows a figure (top right) saved to pdf using MATLAB's gui "File->Save as..." option (bottom right) and PRINT_PDF (left). MATLAB's default options provide no cropping, inaccurate vector graphics (including nasty dashed lines which don't resemble those in the original figure) and highly compressed, blocky bitmap graphics. PRINT_PDF overcomes these issues (albeit generating a larger file), and additionally embeds all fonts - perfect for using the pdf in scientific papers which require this.

PRINT_PDF requires only a target filename and an optional figure handle - there are no other options to be set. The output pdf is exactly the size and layout of the figure on the screen.

PRINT_PDF uses ghostscript, so this must be installed on your system and the executable must be on your system's path. Get ghostscript from:
http://www.ghostscript.com

Acknowledgements

The author wishes to acknowledge the following in the creation of this submission:
savefig
This submission has inspired the following:
export_fig

MATLAB release MATLAB 7.5 (R2007b)
Other requirements Ghostscript
Tags for This File  
Everyone's Tags
Tags I've Applied
Add New Tags Please login to tag files.
Comments and Ratings (45)
07 Nov 2008 Dave Ciochetto

Nice file. Almost perfect for what I was seeking. I have 2 problems.

The minor one - the path is not set properly for Linux, Mac and Unix machines. I moved the name = line into the if statement that determines if the machine is a pc and replace the \ (PC) with the / (UNIX). i.e.

% Print to eps file
tmp_nam = [tempname '.eps'];
print('-depsc2', '-noui', '-painters', ['-f' num2str(fig)], '-r600', tmp_nam);
% Convert to pdf
% This assumes that the ghostscript binary is on your path - you can also
% give the complete path
if ispc
    cmd = 'gswin32c.exe';
    name = [cd '\' name];
else
    cmd = 'gs';
    name = [cd '/' name];
end

The second problem that I have is that it squashes my superscripts on the x-axis up into the axis numbers. I have not been able to trouble shoot that yet. It seems to be related to the ghostscript call which is yet unfamiliar to me. I am seeking a hack but would be interested to know if anyone else had this problem.

07 Nov 2008 Dave Ciochetto

In the previous submission I did not intend to give it a star rating. That was an error and two stars does not reflect my rating of this script.

07 Nov 2008 Dave Ciochetto

This is an excellent script solving a problem that I have been struggling with. Inserting PDF figures into a LaTeX document for processing with PDFaTeX. This script should give a much greater amount of control over the consistency rather than using

print -dpdf filename

which adds borders and resizes the figure from what you see on the screen.

Get your figure all set up the way you want it to look on the screen and then you will get a cropped PDF that will look just like the figure on the screen. If you don't size the figure in Matlab for the end size (printed version from your word processor) then realize that things will scale when you adjust the size in the word processor so be sure to make your text large enough to be seen in print form.

The script is excellent for me as this is the way I work. It will make your work much more repeatable with results that you desire and save time when it comes to figures.

10 Nov 2008 Jody Klymak

Nice job with this. I have something similar using epstopdf As a trick to force the cropping to be at the figure size (retaining white space) I added

axes('position',[0 0 1 1])

By the way, the Mathworks looked into the lack of PDF cropping as a bug for me at one point. We didn't know about the -DEpsCrop option, so it didn't get fixed.

24 Nov 2008 zhang jie

good work, thanks for sharing.

25 Nov 2008 Abdulwahab Abokhodair

Please tel me how to add ghostscript to my system path. When I add the full path in the print_pdf file as:
cmd = 'C:\Program Files\gs\gs8.63\bin\gswin32c.exe';
I get an error because of the space in <Program Files>
I also tried to add the path via the Environment Variables
but was not successful!
Thanks

26 Nov 2008 Oliver Woodford

You should edit the Path in the User Environment Variables. The way to do this varies between versions of windows. I suggest you search for the relevant instructions in google using:
windows XXXX set system path
where XXXX is your version of Windows, e.g. Vista, XP, 2000.
Add
;C:\Program Files\gs\gs8.63\bin\gswin32c.exe
(or the appropriate path to your Ghostscript installation) to end of the path, remembering the semicolon at the start to separate paths.

26 Nov 2008 Oliver Woodford

Alternatively you can set the path in print_pdf.m by changing the line
cmd = [cmd 'win32c.exe'];
to
cmd = '"C:\Program Files\gs\gs8.63\bin\gswin32c.exe"';
or the correct path for you. Note there are double quotes inside single quotes here.

26 Nov 2008 Oliver Woodford

The latest version now finds Ghostscript automatically on Windows, if it was installed in the default location.

01 Dec 2008 Cris Luengo

Works great for me! The only complaint is that it changes the units on the figure window, which is a tad annoying when you want to update and print the figure repeatedly. I changed the papersize/position setting thus:

set(fig, 'PaperPositionMode', 'auto') % sets paperposition equal to position (independent of units used)
sz = get(fig, 'PaperPosition');
sz(1:2) = 0;
set(fig, 'PaperSize', sz(3:4), 'PaperPosition', sz);

(the alternative is to set the figure units to inches and set them back to the initial value afterward, but this seemed simpler).

Thanks!

01 Dec 2008 Oliver Woodford

I wondered if that would cause problems. Duly fixed. Thanks, Cris.

12 Dec 2008 Oliver Woodford

Apologies for the recent flurry of updates to this file. I was too quick to upload functionality that turned out to be buggy and incomplete. The latest version is now stable, and also enables dash lengths to change with line width - super!

29 Dec 2008 Johannes

Thanks a lot, This was exactly what I wanted!

I only had to edit line 58, to correct the path where my ghostcript binary is located.

The find script did not work, and I think it is not necessarry.
More likely the user should be able to define the path once he starts working with the script.

Cheers and thank you so much!

Johannes

29 Dec 2008 Jian

it's very useful .......thanks a lot

17 Jan 2009 Koray S. Erer

Hi,
Nice work but originally italic Greek letters (TeX) turn out to be non-italic. Any ideas?

20 Jan 2009 David Gingras

Very useful code. Perfect for direct image integration in pdfLaTeX.

23 Jan 2009 Mohd Kharbat  
23 Jan 2009 Morvan

Nice job... I did my own equivalent file, but clearly not as much efficient as yours.
There is just one thing that could eventually be improved when the figure include patch objects, Matlab does not know how to export vectorial data in this case. This results in a "Warning: RGB color data not yet supported in Painter's mode". And changing Painter for another renderer implies lost of vectorial format... I know this is a Matlab limitation, but if anyone has an idea about it, it would be nice!

27 Jan 2009 James

Nice work, produces PDFs of my figures exactly how I want them.

However, when I include them in Latex using \includegraphics I get "Error: Cannot determine size of graphic in xxx.pdf (no BoundingBox)" - anyone any ideas how to fix this?

28 Jan 2009 Oliver Woodford

PDFs can be used in Latex to produce PDF files using pdflatex, but not PS files using latex & dvips. See:
http://amath.colorado.edu/documentation/LaTeX/reference/figures.html
James: perhaps you are trying to do the latter. If so you need to save your figures as EPS files - try using print_eps.

29 Jan 2009 Ben

I get a message after trying to execute the system() command on line 64 of

"gs -q -dNOPAUSE ..<snip> : Segmentation Fault" with a status of 139.

I think this might be a bug in Matlab or a setup issue because if I copy and paste the actual system command into a terminal window (CSH) it executes without any issues and the .PDF results are as expected.

Note: I am using 64-bit Linux RedHat 4

So, unfortunately this function did not work on my system but I gave it 5 stars anyway because the results when pasting to CSH window are very good. I will try the newsgroup for help on why a command works in a terminal window but not through a Matlab system() command.

05 Feb 2009 R

Great job! However, I don't get it to work on 3D-plots. On 2D-plots it works like a charm. I get the following error message:

>> t = 0:pi/50:10*pi;
        plot3(sin(t),cos(t),t);
>> print_pdf('test')
??? Error using ==> minus
Matrix dimensions must agree.

Error in ==> print_pdf>fix_lines at 162
ind2 = repmat(ind2', [1 numel(ind)]) - repmat(ind, [numel(ind2) 1]);

Error in ==> print_pdf at 49
fix_lines(tmp_nam);

Is it possible to fix this?

09 Feb 2009 Petter

The following code fails (MATLAB 7.5):

figure(1);
clf;
F = rgb2gray(imread('peppers.png'));
imagesc(F);
hold on;
contour(F,[128 128],'r-');
axis off;

print_pdf('test.pdf');

??? Error using ==> minus
Matrix dimensions must agree.

Error in ==> print_pdf>fix_lines at 162
ind2 = repmat(ind2', [1 numel(ind)]) - repmat(ind, [numel(ind2) 1]);

Error in ==> print_pdf at 50
fix_lines(tmp_nam);

Error in ==> print_pdf_fail at 9
print_pdf('test.pdf');

09 Feb 2009 Oliver Woodford

The bug reported in the last two comments has been fixed.

09 Feb 2009 Petter

Thanks for the update!

10 Feb 2009 Petter  
11 Feb 2009 Balaji Ganeshan

On the whole this is an excellent post.

But I am having a problem using this file for guide generated figures. I have a push button within my gui to generate a pdf - however I receive an error as follows:

??? Error using ==> print at 310
What follows -f is not a Figure handle.

Error in ==> print_pdf at 48
print('-depsc2', '-noui', '-painters', ['-f' num2str(fig)], '-r864', tmp_nam);

Any help will be much appreciated.

19 Feb 2009 Dazhi Jiang

Nice work!
However, I just found that all the pdf files generated by print_pdf have a white background, although I've already set the MATLAB figure background and axis background as 'none' with the commands
>> set(gca, 'Color', 'none');
>> set(gcf, 'Color', 'none');

I wondered whether it can produce a pdf file with transparent background?

By the way, I tried to change the original code to fix the problem. I added two options at the part where the gs command is constructed, that is, -dCompatibilityLevel=1.4 -dHaveTransparency=true. So I have the following code line:

options = [' -q -dNOPAUSE -dBATCH -dEPSCrop -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -dCompatibilityLevel=1.4 -dHaveTransparency=true -sOutputFile="' name '" -f "' tmp_nam '"'];

But it doesn't work! Am I on the right way? Any help is appreciated.

Thanks.

19 Feb 2009 Oliver Woodford

You can generate a pdf with a transparent (or other colored) background using the following command prior to calling print_pdf:
>> set(gcf, 'color', 'none', 'inverthardcopy', 'off');

19 Feb 2009 Dazhi Jiang  
19 Feb 2009 Dazhi Jiang

I found the solution to print a pdf file with transparent background. Add the following command before you use 'print_pdf',

set(gcf, 'InvertHardCopy', 'off');

19 Feb 2009 Dazhi Jiang

Oliver,

Thanks for your answer. I didn't see it when I posted the last comment. Sorry for the over-posting.

26 Feb 2009 Karim N'Diaye  
17 Mar 2009 Xu Wings

the programme was not properly working!

17 Mar 2009 Petter

Xu Wings: Very helpful! Maybe you should try harder to make it work, since everyone else seem to have made it work.

18 Mar 2009 Wolfgang Schwanghart

Excellent. Thanks!

23 Mar 2009 Wolfgang Schwanghart

I got an error message saying:

********************

??? Error using ==> fread
Out of memory. Type HELP MEMORY for your options.

Error in ==> print_pdf>fix_lines at 116
fstrm = char(fread(fh)');

Error in ==> print_pdf at 50
fix_lines(tmp_nam);

Error in ==> script_chexample at 24
print_pdf fig5.pdf

*******

The plot is a surface plot created by surf, shading interp and camlight. Any help will be appreciated.

23 Apr 2009 David Meller

Not compatible with R13 (6.5.0). Gives the following error in the file 'print_pdf.m' on line 128:

??? Error using ==> regexp
Invalid option for regexp: start.

Any ideas?

25 Apr 2009 Oliver Woodford

David Meller: remove the last two input arguments ('start', 'end') from regexp on line 128. Please email me (use the contact author link on my author page) if you get any more errors.

20 Jul 2009 Matthijs  
06 Nov 2009 Stefan

Hi,

not each font is exported correctly on my system.

Ex:
plot((0:10),sin(0:10));
set(gca,'FontName','Arial Black');
export_fig('test', '-pdf');

The font is not 'Arial Black' in this example, although beeing correctly displayed in Matlab.

I'm using winXP, Matlab 7.8.0 (R2009a), Ghostscript 8.70, Adobe Reader 9.2.0. I tried some other fonts, only 'Arial' seems to work properly.

Is this behavior reproducible on your systems or is a solution available?

Thanks for your help!
Stefan

08 Nov 2009 Oliver Woodford

Stefan: Two things might help. Firstly, you need to make Ghostscript knows about the fonts you want to include. You can tell it where to look by using the -sFONTPATH="C:\blah\blah" option (obviously using the right path). Secondly, you need to make sure the fonts are in a format that Ghostscript understands. For example, I don't think it understands the OpenType format.

10 Nov 2009 Stefan

Hi Oliver,

thanks for your reply.
I only use ttf fonts at the moment.

I tried your first suggestion, but nothing changed. I now use the options

options = [options '-q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -sOutputFile="' dest '" -sFONTPATH="C:/Windows/Fonts"'];

Obviously gs doesn't know the fonts except for the standard ones.

I also tried to set the path:

c:\> SET GS_LIB=c:\windows\fonts

And I tried to add fonts to gs/fonts/fontmap (using FontMap v1.7), e.g. the line

/Coronet (C:/WINDOWS/FONTS/coronet.ttf) ;

But all I can see in the pdf file is this Courier font.

Any other ideas? Did anyone successfully export other fonts to pdf?

Stefan

10 Nov 2009 Oliver Woodford

Stefan: For some reason the eps file generated by MATLAB's print function doesn't name the fonts correctly. I suggest you contact TMW's technical support. If and when print generates an eps file correctly but print_pdf/export_fig doesn't then generate the correct pdf, then I will investigate further.

16 Nov 2009 Stefan

Today the answer of TMW's support team arrived.
They admit that the font support of the print function is limited to a few fonts only up to now.
See http://www.mathworks.com/access/helpdesk/help/techdoc/creating_plots/f3-103191.html#f3-96545

It it not sure if or when this will change.

Thank you Oliver anyway!

I now use Matlab for formatting the figure and the page size. Subsequently I print pdfs using an external pdf printer.

Please login to add a comment or rating.
Updates
08 Apr 2009

Reduce memory footprint to allow conversion of larger files

14 Apr 2009

Superseded by EXPORT_FIG

Tag Activity for this File
Tag Applied By Date/Time
print Oliver Woodford 07 Nov 2008 10:11:56
pdf Oliver Woodford 07 Nov 2008 10:11:56
embed Oliver Woodford 07 Nov 2008 10:11:56
font Oliver Woodford 07 Nov 2008 10:11:56
save Oliver Woodford 07 Nov 2008 10:11:56
figure Oliver Woodford 07 Nov 2008 10:11:56
data export Oliver Woodford 07 Nov 2008 10:11:56
crop Oliver Woodford 07 Nov 2008 10:11:56
embed fonts Oliver Woodford 07 Nov 2008 10:36:31
publish Oliver Woodford 07 Nov 2008 10:36:37
export figure Oliver Woodford 07 Nov 2008 10:36:56
scientific paper Oliver Woodford 07 Nov 2008 10:37:07
crop border Oliver Woodford 07 Nov 2008 10:37:25
data import Cristina McIntire 07 Nov 2008 12:13:14
data export Cristina McIntire 10 Nov 2008 10:37:41
figure Cristina McIntire 10 Nov 2008 10:37:48
embed Cristina McIntire 10 Nov 2008 10:37:55
crop Ilya Rozenfeld 13 Nov 2008 13:15:48
line style Oliver Woodford 16 Dec 2008 16:43:21
dotted Oliver Woodford 16 Dec 2008 16:43:21
dashed Oliver Woodford 16 Dec 2008 16:43:21
pdf Chris Hahn 20 Dec 2008 01:36:46
export figure Omid Khanmohamadi 19 Feb 2009 10:29:31
crop gowtham soorya 24 Feb 2009 05:05:11
potw Shari Freedman 20 Apr 2009 12:52:10
 

MATLAB Central Terms of Use

NOTICE: Any content you submit to MATLAB Central, including personal information, is not subject to the protections which may be afforded information collected under other sections of The MathWorks, Inc. Web site. You are entirely responsible for all content that you upload, post, e-mail, transmit or otherwise make available via MATLAB Central. The MathWorks does not control the content posted by visitors to MATLAB Central and, does not guarantee the accuracy, integrity, or quality of such content. Under no circumstances will The MathWorks be liable in any way for any content not authored by The MathWorks, or any loss or damage of any kind incurred as a result of the use of any content posted, e-mailed, transmitted or otherwise made available via MATLAB Central. Read the complete Terms prior to use.

Contact us at files@mathworks.com