Matlab setting print size of figure - matlab

I know there are lots of questions on matlab printing questions, but I can't seem to figure this out.
I want to print/save my figure at 17x23cm printed. With a resolution of 600dpi.
I've tried this
set(gcf, 'Units', 'centimeters', 'Position', [0 0 17 23], 'PaperUnits', 'centimeters', 'PaperSize', [17 23]);
I'm then using the export_fig script and do either of the following
export_fig Test.pdf -pdf -transparent;
export_fig Test.pdf -pdf -transparent -r600;
Either way, I get a figure that is ~14x19 cm. And the resolution is only 100dpi.
So I thought, okay 600dpi for a 17cm figure is ~4,000 pixels. So lets just set the figure on screen to be that many pixels
set(gcf, 'Units', 'pixels', 'Position', [0 0 4000 5500]);
But that doesn't work. I assume because my monitor isn't big enough to support that many pixels, so it won't display. And I can't then save it because the figure doesn't even show up.
I know I can resize after in gimp or illustrator or whatever. But I don't really want to.
How do I export/save a pdf/eps graph at a specific print size (17cm) with a specific resolution (600dpi)?

Printing using export_fig is going to crop the resulting figure to remove any white space (places where your figure has no content). Because of this, the output is going to be smaller than the Position that you specify.
To prevent this, you can use the -nocrop option.
export_fig('Test.pdf', '-pdf', '-nocrop', '-transparent', '-r600')
Specifying a resolution is really only intended to have an effect for raster images, for vector graphic formats such as PDF this shouldn't really have an effect. How are you determining the "resolution" of the PDF?
Another option is to just use the built-in print function to create your image
print('myimage.pdf', '-dpdf', '-loose', '-r600')
The -loose option here will ensure that it uses a loose bounding box and won't crop the empty regions of your figure, resulting in an image of the dimensions you're prescribing.

Related

Strange behaviour when changing xlim [duplicate]

When I display a bitmap image using image in a Matlab figure window, I'm experiencing strange artifacts:
What I'm referring to are the cross-shaped structures which are particularly visible at the edges of the brain slice, but present throughout.
These structures are not in the underlying image data, which are exactly identical to those in this image:
I assume the artifacts have to do with the slight rescaling that is necessary to match the image to the given axes size.
Does someone have an idea how to avoid these artifacts? I tried changing the figure 'Renderer', which does indeed affect the artifact, but does not let it vanish.
How to reproduce the effect:
save the second image as "image.png"
execute:
im = imread('image.png');
image(im)
set(gca, 'Units', 'pixels')
set(gca, 'Position', [76.1094204520027 576.387782501678 343.969568136048 357.502797046319])
maximize the figure window, so that the axes with the image becomes visible
Native image dimensions are 306 x 318, but it is displayed at about 344 x 358 pixels.
I did some further experiments and found that the effect is not specific to this image, the particular positioning, or the colormap:
[x, y] = meshgrid(-1:0.01:1);
imagesc(cos(10*sqrt(x.^2 + y.^2)))
giving
for a specific size of the figure window shows the same kind of artifacts.
It would be interesting to know whether the artefact is specific to my Matlab version (2013a) or platform (Debian Linux, kernel 3.14 with NVidia graphics).
It looks to me as if the artifacts are caused by Matlab interpolating to translate picture pixels into screen pixels.
It would be nice to be able to change the interpolation method used by Matlab when displaying the image, but that doesn't seem to be possible (changing 'renderer' doesn't help). So you could manually interpolate the image to match the display size, and then display that interpolated image, for which one image pixel now corresponds to one screen pixel. That way Matlab doesn't have to interpolate.
To do the interpolation I've used the imresize function. I find all available interpolation methods give more or less the same results, except 'box', which is even worse than Matlab's automatic screen interpolation. I attach some results:
First picture is obtained with your approach. You can see artifacts in its left and right edges, and in the lower inner diagonal edges. Code:
m = 344;
n = 358;
image(im)
set(gca, 'units', 'pixels', 'Position', [40 40 m n])
Second picture applies manual interpolation with imresize using 'box' option. The artifacts are similar, or even more pronounced.
imr = imresize(double(im)/255, [m n], 'box'); %// convert to double and
%// interpolate to size [m, n]
image(imr/max(imr(:))) %// display with image size matching display size.
%// Normalization is required because the interpolation may give values
%// out of the interval [0 1]
set(gca, 'units', 'pixels', 'Position', [40 40 m n])
Third figure is as the second but with 'bilinear' option. The artifacts are very attenuated, although still visible in some parts. Other interpolation methods give similar results.
As has been mentioned, MATLAB uses a nearest-neighbor interpolation for both upsampling and downsampling images for display. Because the image window is user-resizeable, the artifacts due to this can change just by moving the window around.
One solution is to write a wrapper class for image display that monitors window events and resizes using imresize to more accurately display the data to the screen. I've written such a class, and it's publicly available. I do image processing work all the time, and MATLAB's inbuilt display system is very irritating. I use this one:
http://www.mathworks.com/matlabcentral/fileexchange/46051-rviewer
It's designed to be a drop-in replacement for image, and will properly resample the images.

`imagesc` in MATLAB: paper size and `colorbar`

I am using imagesc in MATLAB to show an NxM matrix as an image, where the warmer is the color the higher is the value. By using the following command:
f = imagesc(points, [0 1]);
the matrix points is displayed. Nevertheless, a legend showing the coupling between colors and values is missing. I have found out that the command:
colorbar
can be used so as to display the requested legend. However, when printing the figure on PDF using the following lines of code:
set(gcf, 'PaperUnits', 'centimeters')
set(gcf,'PaperSize',[12 8]) % Set the paper size to the figure size
print('-dpdf',figurePath)
I encounter two problems:
The paper size is not set properly
The color bar is not showing on the PDF
How can I fix these problems?
Thanks in advance,
Eleanore.
I've found a solution in the state of the art, that uses the export_fig script (https://sites.google.com/site/oliverwoodford/software/export_fig).
The following code is needed:
set(gcf, 'Color', 'w'); % Change background color
set(gcf, 'Position', [100 100 700 500]) % Change figure dimensions
export_fig([figurePath '.pdf']) % Export the figure
I always export my figures to .eps and then use the epstopdf utility that comes with Ghostscript to convert for inclusion in a LaTeX document; this seems to solve the vast majority of issues.
Another way to do it is to use the export_fig script, but I see you've already discovered that.

Blurry label text in matlab plots

I'm having some matlab plots. when I save the plot and then put it in my word document and then save it as pdf file. I get the plot labels blurry and some letters is unclear ?!
plot(d1,S,'*');
title('Frequency','FontWeight','bold','FontSize',11);
xlabel('delta','FontWeight','bold','FontSize',11), ylabel('sigma','FontWeight','bold','FontSize',11);
why does that happened (got angry)?!
how can I fix it ?!
There are many discussions about this on the web, but non of the solutions actually satisfied me when I wanted to export a graph to an image.
Anyway here is what I've done:
MyFont = {'FontName', 'Times New Roman', 'FontSize', 25};
graph_size = [1200 800]; % in pixels
fig_h = figure('Units', 'pixels', 'Position', [10 50 graph_size]);
% Do your plot
x = 0:0.1:2*pi;
plot(x, sin(x))
set(gca, MyFont{:}); % Adjust all the font sizes in the axes
Now you can copy a vector-based version (which is nicest quality as #wakjah mentioned) to clipboard with print (as #Amro said):
print -dmeta
Or with hgexport which exports to metafile again:
hgexport(figH,'-clipboard')
However you need to adjust the graph_size and FontSize in MyFont manually to get your desired output. But the good thing is that if you want it for some publication you just need to do it once.
Please note that although you are exporting the graphs as a vector-based format but your graph lines would still seem fractured if you zoom on them but they are not blurry. This is why you might want to increase the size of your graph on screen (graph_size and consequently the FontSize) to have a more accurate graph.
Hope this helps.
Related posts:
MATLAB: print a figure to pdf as the figure shown in the MATLAB
In matlab, how do you save a figure as an image in the same way as using "Save As..." in the figure window?

Export Matlab figure as PNG?

I need to automatically export figures from Matlab to PNG. My figure has a size of 600x200 px:
hFig = figure(1);
set(hFig, 'Color', [1 1 1]); % backgroundcolor white
set(hFig, 'Position', [500 500 600 200]) % size 600x200
I tried e.g.
print -dpng image.png
but the image.png is larger than 600x200 px. Exporting the figure manually from the Figure Window GUI using the "save" button works great, I want to do exactly this automatically / from a script. Thanks for any hint!
I also know the problem that figures save never look the same as on screen.
There is the saveas command which might work for you - but does also some resolution changing for me.
Only way I know is to carefully set every aspect like this:
set(gcf,'PaperUnits','inches','PaperSize',[2,6],'PaperPosition',[0 0 2 6])
print('-dpng','-r100','test')
(so paper size is 2x6" and print with 100dpi, PaperPosition is important as you will have otherwise some extra border.)
My preferred approach for generating png plots from MATLAB is the export_fig utility available at the MATLAB file exchange.
Here's an example:
set(gcf, 'Position', [100 100 500 500], 'Color', 'w')
x=0:0.01:10;
plot(x, sin(x))
set(gca, 'FontSize', 20, 'FontName', 'Arial')
export_fig 'strip-diff-far-forward.png' -painters -nocrop
This will create a png that is 500 x 500 pixels, with 20 pixel fonts. I'm sure that internally it does the same kinds of things as in bdecaf's answer, but it is all ecapsulated in a function for you already, and has a bunch of other features too.
The drawback is that if you use the -painters renderer (which I think looks the best) you will need to have ghostscript installed. If you don't want to mess with that, you can change -painters to -opengl
Edit Now setting figure size correctly!
Based upon bdecaf's answer:
set(gcf,'PaperUnits','inches','PaperSize',[600/96,200/96],'PaperPosition',[0 0 600/96 200/96])
print('-dpng','-r96','test')
96 is the dpi of my system. This gives me EXACTLY the same output as the save function. For Windows the dpi is typically 96, sometimes 120. Simply adjust it accordingly to your system. Note that on a beamer the DPI might again be different from your system, especially if your system has 120 DPI! 96 DPI should in general be a quite safe choice for beamers I think. Google if you need help finding out the DPI setting of your system. This answer is 99,9% based on bdecaf and Florian, so I will leave bdecaf's answer selected as the right one.
edit: 600 = horizontal image size in px, 200 = vertical image size in px
Amro answer works perfectly, after you generate your figure, set PaperPositionMode to auto and the print size will be the same as screen size.
set(gcf, 'PaperPositionMode','auto')
print('-dpng','test.png')
Try:
set(hFig, 'PaperPositionMode','auto') %# WYSIWYG
print -dpng -r0 image.png %# at screen resolution
This tells it to produce an image the same size as it appears on screen.

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.