Exporting and printing matlab figure [duplicate] - matlab

This question already has answers here:
Saving MATLAB figures as PDF with quality 300 DPI, centered
(2 answers)
Closed 2 years ago.
I have a Matlab figure. I need to use it as a picture so I can insert it in Word, then save that new Word document as a PDF file and then print that PDF file. I have tried saving Matlab figure as .JPG and . PNG file but the picture gets "smaller" when inserted in Word and converted to PDF and when printed, you can hardly distinguish anything. What can I do so that the quality of the figure dosen't change?

You have a couple of options here.
Specify the Resolution
When saving the figure, by default 72 dpi is used (your screen resolution) which may causeyour images to appear small when being inserted into a Word document. Rather than using saveas, you can use print to specify the resolution of the resulting image. For a PNG
print(hfig, 'filename.png', '-dpng', '-r300') % Resolution = 300 DPI
Note that if you're using print, you will also need to specify a few other properties of the figure to get it to look similar to the on-screen appearance.
set(hfig, 'Units', 'inches');
pos = get(hfig, 'Position');
set(hfig, 'PaperPositionMode', 'manual', ...
'PaperPosition', [0 0 pos(3:4)], ...
'InvertHardCopy', 'off');
Use an EPS
If you're ultimately exporting to a PDF and your image is line art, consider exporting to an EPS (a vector-graphic). Again, this can be done using print.
print(hfig, 'filename.eps', '-depsc2')
Use export_fig
The FEX submission export_fig is a widely-recommended utility for creating figures from your MATLAB figures in a way that preserves the way that they appear within MATLAB.

You don't need to save it as a file, just copy it to the clipboard and then paste it, it will be copied as a metafile (vector graphics) that looks good when resized. It is best to resize by dragging the corners to maintain the original aspect ratio.
After you make a figure, select from the figure menu: Edit / Copy Figure and then paste into Word or PowerPoint. You can change some of the options for copying by selecting Edit / Copy Options... from the figure menu

Related

Problems saving figure in Matlab with right proportions in pdf file

I have a figure with 2x3 subplots in Matlab where each subplot contains 2 histograms. I typically save Matlab figures in eps but because doing so removes the transparency between the histograms in each subplot, I resorted to saving as pdf.
Currently, this is how I'm saving the file:
figure;
set(gcf,'Position',[100 100 1400 500])
set(gcf,'PaperPositionMode','auto')
print(gcf, 'filename.pdf', '-dpdf','-r0');
However, it produces a pdf file in portrait layout which means some subplots get cut out.
Now, I've been scouring for answers online and the recommended approach to fix my problem is given in this link.
Following the approach, I don't have any subplots cut out but the problem is that this forces the figure to fill-in the space of my pdf. In otherwords, my histograms are stretched out to fill the space of the pdf file in landscape format. I'd simply prefer a pdf file that has exactly the same proportions as my figure size above which is set(gcf,'Position',[100 100 1400 500]). This is how it works with eps so I'd like to have the same behavior with pdf.
Can anyone help me to fix it?
To make sure the output is landscape:
set(gcf,'PaperOrientation','landscape')
Then use the "bestfit" option. That will scale it as large as possible but maintain the aspect ratio.
print(gcf, 'filename.pdf', '-dpdf','-r0','-bestfit')
There some more good info on Matlab's website
MATLAB’s PDF output is always on a full A4 or Letter-sized page by default. With 'PaperPositionMode' set to 'auto', this does not change. For other output file formats (e.g. EPS) that setting causes the page size to be adjusted to the figure size. Not so for PDF. You need to manually set the 'PaperPosition' and 'PageSize' properties.
This File Exchange submission handles this for you (I’m the author).

White lines in figure after exporting to PDF

A 2D data matrix was plotted in MATLAB 2016a using contour (the first Figure below), and then I saved as the figure in the *.emf format. Next, I inserted the figure (emf) into a MS word document. And finally, the word document was converted to a pdf file.
I found that there are many white lines in the figure (when in a pdf format) as shown in the second figure below. My question is how can I remove those white lines?
The code is attached here:
path = 'C:\Users\Administrator\Desktop\';
data = importdata([path, 'lsa2.txt'], ' ', 6);
cdata = data.data;
n = 25;
contourf(cdata,n, 'LineStyle', 'none');
colormap(jet);
axis equal;
The data can be accessed here: https://www.dropbox.com/s/hzf75qiju6zsy9i/lsa2.txt?dl=0
As I mentioned in my comment, this is a bug with the way MATLAB exports graphics, as explained by Yair Altman and Dene Farrell:
I discovered that these white line artifacts happen when the painters renderer is used ... [which] is the default rendering [format engine] for vectorized (EPS/PDF) formats.
There are two separate issues with the Matlab export:
1. The main thing that everyone notices is that patches are broken up into triangles, each of which is a separate path object if inspected in illustrator.
2. Matlab sometimes adds extraneous 'cropping paths' that create an apparent white line even when there is no issue with fractured paths.
One workaround suggested there by ambramson is the following:
1. Save the figure as an .eps file (using the print command).
2. Using a text editor, change the line in the eps header from:
/f/fill ld
to:
/f{GS 1 LW S GR fill}bd
and move the line down several lines, to right below the /LW/setlinewidth ld line.
From here, your eps file should display fine on all pdf viewers.

Convert just the content of a figure to an image in MATLAB

I am currently using getframe() and frame2im in MATLAB to convert a figure of a plot to an image.
I just realized that this is working almost like a screenshot of the figure, with all the axes and labels taken into account as well.
How can I convert JUST the contents of the figure (aka the "plot") into an image?
I don't really want to save all of them to file first.
You can use the getframe / cdata idiom. What this will do is that if you call getframe on the current frame in focus without any parameters, it will return a structure to you that contains a structure element called cdata. This stores the RGB pixel array of just the figure contents themselves. The axes and labels are not captured - only what is painted onto the figure is captured.
Here's an example to get you started:
im = imread('cameraman.tif');
imshow(im);
h = getframe;
out = h.cdata;
figure;
imshow(out); %// Should give you the contents within the imshow frame.
FWIW, I also answered this same question here, though it was for a different situation: keep new image when drawing lines by dragging the mouse in matlab
As far as i know, cdata DOES NOT WORK. I had a major problem recently with the same thing - the only work around i could find is to crop each image after using getframe and cdata - this will work fine for images that are all the same size (ugly as it is - you just need to find the grey edges in the image), but if the images are all different, this wont work (well, it wont work well. there might be some way to automatically adjust the crop size)

Matlab figure -> Word -> PDF results in bad quality

I create some figures with matlab and export them by using the "Edit -> Copy Figure" with setting "Preserve information (metafile if possible)". I import this in Word 2010. However, if I convert the word document with "save as pdf" the figures have artifacts.
The following image gives you an impression. To the left is Word at 400% zoom, to the right is the pdf with 400% zoom. One can clearly see that dotted lines become straight lines etc. How can I avoid this?
Expanding a bit on the answer that am304 gave - I just tested the following:
figure
% create a plot with some fine detail:
plot(sin(1./linspace(0.02, 1, 1000)));
% set the "paper size" of the figure (not the size on screen) to 30x20 cm:
set(gcf, 'PaperUnits', 'centimeters', 'PaperPosition', [0 0 30 20]);
% "print" to png with a resolution of 300 dpi
print('-dpng', 'myplot.png', '-r300');
This results in the following picture being saved to disk (cropped to show just detail):
The full size picture is just 43 kB - but it is a very high resolution (300 dpi) rendering so you can see the fine details of the plot.
I can insert this picture into a Word document and save it as a pdf. When I then take a screen shot of the pdf, it looks like this:
As you can see - the detail is pretty much all there.
You can use the print function to export your figure to various formats. EPS or TIFF should give good results. I wouldn't use the "Edit -> Copy Figure" if you want high quality figures.
I used the comments here to create my own approach (also with help of: How to set the plot in matlab to a specific size?). So here is my function:
function figureprint(hFig, width, height, res, filename)
%# figure size printed on paper
set(hFig, 'PaperUnits','centimeters')
set(hFig, 'PaperSize',[width height])
set(hFig, 'PaperPosition',[0 0 width height])
set(hFig, 'PaperOrientation','portrait')
%# export
print(hFig, '-dpng', res, filename)
This function is printing a figure to a specific size in cm. E.g.
figureprint(hFig, 12, 10, '-r1500', 'testPng.png')
So "hFig" is saved as a *.png with a width of 12cm and a height of 10cm. I measured this and this works fine. Optimizations are of course possible.
If you use
set(gca,'LooseInset', get(gca,'TightInset'))
the exponent of the multiply factor for the y values is cutted (when big numbers are plotted) (see image). In this cases you have to modify the values, e.g. like this:
tight = get(gca,'TightInset');
tight(1,4) = 0.08;
set(gca,'LooseInset',tight)

how to make an image large enough to avoid tick label overlapping?

Assume that the data X has size 1000 *1000. X is displayed using the command:
imagesc(X);
and all the rows are labeld using:
set(gca, 'YTickLabel', somelabels);
Although the data X are properly polotted and the Ytick labels are also shown, the labels are highly overlapped because of the large number of rows. Is there any way to solve the problem? Any help will be highly appreciated.
Edit 1
I realize my question was not stated well to represent my problem. I am going to wrap up my understanding based on the answers and re-ask a question:
To show as many rows/labels in a Figure Window, the following helps:
set(gca,'FontSize',6),
or, alternate the distance (suggested by yuk),
or, set(gca,'YTick',1:10:1000,'YTickLabel',somelabels(1:10:1000));
The code
set(gca,'Units','pixels','Position',[20 20 10000 10000]);
will display a zoomed-in image by default. But if the zoomed-in image is too large to fit in the Figure Window, only part of the image will be displayed. However, neither zoom out nor the pan tool can reach to the rest part of that image.
The default behavior of the code
imagesc(X);
set(gca, 'ytick', 1:1000, 'yticklabe', ylabel);
displays the whole image fitting to the Figure Window with overlapping labels. Nevertheless, it does allow one to zoom into part of the image and to see the un-overlapped labels.
If I save the image into a pdf file:
imagesc(X);
set(gca, 'ytick', 1:1000, 'yticklabe', ylabel);
saveas(gcf, 'fig.pdf');
Then the saved pdf is only the image fit to the Figure Window with overlapping labels. However, unlike zoom in within Matlab figure window, zoom in within a pdf reader won't change the relative position/distance of labels. As a result, the zoomed-in image in pdf is still label-overlaped.
So my question is:
How to save the image into a pdf file or png such that it has a similar behavior as of point 3 above when opened in Adobe reader, rather than that of point 4?
You can also play with axes label font to make it smaller.
set(gca,'FontSize',6)
See also other axes properties to change font - FontName, FontWidth, FontUnits, etc.
Another solution: If your labels are short, you can alternate there distance from the axes, so the labels will not overlap. Check this example:
lbl = cellstr(reshape(sprintf('%3d',1:100),3,100)');
lbl(1:2:100) = strcat(lbl(1:2:100),{' '});
imagesc(rand(100))
set(gca,'ytick',1:100)
set(gca,'yticklabel',lbl)
Part of the resulted image:
UPDATE
To answer your updated question.
PDF document can contain only static images. Once you saved the figure to PDF (or any other graphic file), you cannot zoom in/out as with MATLAB figure tools.
You can zoom first on the MATLAB figure, then save PDF file. In this case the figure will be saved as is. But this way assumes user interactivity with the figure.
If you know your region of interest in advance, you can set axes limits with XLim/YLim properties, then save the figure.
Example:
imagesc(X);
set(gca, 'ytick', 1:1000, 'yticklabe', ylabel);
set(gca, 'XLim',[1 20], 'YLim', [20 40])
saveas(gcf, 'fig.pdf');
By the way, you can also save figure to file with PRINT function. More flexible. SAVEAS is just wrapper around it.
print('-dpdf','fig.pdf')
Another option is to rotate the tick labels which is discussed in this technical solution. You can find a number of easy-to-use implementations on the MATLAB File Exchange.