Matlab : Plot options with "set" fail when saving to eps and jpg - matlab

I am using a script to get an automated data treatment (polynomial interpolation, tangent, ...), but when I use the function set to change my plot options before saving, I don't always get the right result : only the font option (see code) seem to work, while the image is really small and the background color doesn't change as it should.
What I would like is to have both eps and jpg files with the plot options I used. Writing this script, I kept adding/moving plot options, and I really don't understand why sometimes some options appear on the plot but seem to be ignored while saving.
Here is the part of my code that has all the plot options, I added those three first line instead of all my treatment.
t=linspace(0,10,10);
front=rand(1,10);
fit=front+rand(1,10)/2;
degre=1;
plot(t,fit,'-b','LineWidth',2);
hold on
grid on
plot(t,front,'.r','LineWidth',2);
hold off
l=legend({['Interpolation polynomiale de degre ',num2str(degre)],'Resultats experimentaux'});
set(l,'Color',[0.8 0.8 0.8])
set(gca,'FontSize',12,'FontWeight','bold','Color',[0.8 0.8 0.8]);
set(gcf, 'Units', 'pixels', 'Position', [0, 0, 1200, 1000])
xlabel('\fontsize{14}Temps de maintien (en s)')
ylabel('\fontsize{14}Distance parcourue (en mm)');
str='essai';
title(str)
filename='essai1';
saveas(gcf,filename,'jpg')
saveas(gcf,filename,'epsc2')
Trying to fix the resolution issue, I tried to change the default resolution using set(0, 'DefaultFigurePosition', [0 0 1200 1000]); but this line of code does not change anything
Thank you in advance

The background of the saved image will be white unless you set InvertHardcopy to off and for the size try 'PaperPositionMode'
set(gcf,'InvertHardcopy','off');
set(gcf,'PaperPositionMode','auto');
set(gcf,'Position', [0, 0, 2400, 2000]); %the resoultion you want

I managed to solve both issues on my example script, using
hFig = figure(1);
set(hFig, 'Position', [0 0 1200 1000])
before "plot", and
l=legend({['Interpolation polynomiale de degre ',num2str(degre)],'Resultats experimentaux'});
set(l,'Color',[0.8 0.8 0.8])
set(gca,'FontSize',12,'FontWeight','bold','Color',[0.8 0.8 0.8]);
set(gcf,'InvertHardcopy','off');
between plot and plot options.
However, this does not work with my main code, I am trying to put in comment most of my non-vital plot options and see what happens.
It would be great if someone could provide me with a better understanding of how those options work, I am mostly coding by try-and-error, but this is not the most efficient approach.
Edit I solved my problem, I had 4 plots on the same figure and I just wrote hold all instead of hold on
Looking at Matlab help, this shouldn't work, but it did.
hold all is the same as hold on.
Note: This syntax will be removed in a future release. Use hold on instead.
If anyone has an explanation as to why it worked, I would like to understand what happened.
Thank you

Related

Matlab saves figure to a very large eps file for seemingly no reason

I use LaTeX for most of my writings and always uses eps files -- that Matlab can create. There wasn't any problem but, for a new case I started studying Matlab generated a 95MB file (and eps2pdf fails to produce a pdf with that)
This question would likely be difficult to answer. It seems like an unexpected Matlab behavior but I cannot share the original code unfortunately (plus the code is very long and depends of so many variables and functions...). I have tried to build a minimum working example using built-in functions but of course it doesn't reproduce the problem. Still, I can give the structure of the code and type of objects created (see end of post): curves, surfaces, transparency, no crazy things.
This code has been running without any problem for many different situations, and gives me files of a few MB. The number of points present in one of the surfac, the approximate shape, the number of points in the curves etc. nothing changes or the changes are minute. I cannot explain the file size difference.
I would welcome either an explanation of the behavior or an alternative for getting this picture to eps. Or both of course. For now I output it to png, but I'd like vector files very much. Has anyone encountered the issue of very large eps before?
colordef white;
figure('Color','White','Name','STUFF')
hold all
% Show a curve
lpot = plot3(//STUFF\\, '-',...
'Color', [0 0 1], 'LineWidth', 2);
% Show a curve
ph = plot3(//STUFF\\,'-',...
'Color', [1 0 0], 'LineWidth', 2);
% Show a curve
plot3(//STUFF\\, '-',...
'Color', [0 1 0], 'LineWidth', 2);
% Show a point
plot3(//STUFF\\, ...
'k', 'MarkerSize', 10, 'Marker', '^', ...
'MarkerFaceColor', [1 1 0]);
% Show a surface
surf(//STUFF\\);
colormap(jet);
shading interp;
% Show a surface in transparency
surf_1 = trisurf(//STUFF\\);
set(surf_1,'FaceColor', [1 1 1], 'EdgeAlpha', 0, 'FaceAlpha', 0.5);
% Axis adjustements
axis equal tight
xlabel('stuff');
ylabel('stuff');
zlabel('stuff');
view(2);
grid on;
h_cbar = colorbar;
ylabel(h_cbar, //STUFF\\);
legend(//STUFF\\,...
{//STUFF\\});
set(gcf,'units','normalized','outerposition',[0.10 0.10 0.80 0.80])
hold off
hgexport(gcf, ['mytoobigfigure.eps'],...
hgexport('factorystyle'), 'Format', 'eps');
The code runs on matlab r2014b, windows 7.
Thanks everyone!
Yay, thanks to Peter comment, I solved the problem! The fix:
myfig = gcf; % or define myfig when the figure is created
myfig.RendererMode = 'manual' % use a set with older versions of Matlab
Which does not mean I understand why this happens and this is most likely not a desired behavior of Matlab. I think that for some reason, the renderer would switch from OpenGL to painters while saving the figure. Examining the eps, it was clear the transparency was very wrong (off in most places) and the polygon offset (or the property that allows to draw line in front of their patches) was also very poor. Whether or not a bitmap was involved, it is beyond my skills to retrieve such an information. But clearly the saved figure was not the same as the displayed figure. It should also be noted that switching the renderer to manual does not affect the picture in any other way on the screen. I wonder if setting the renderer to manual by default would not be a good idea... would there be any drawbacks to forcing OpenGl all the time?
If somebody has a more detailed answer on the topic, I'd be happy to read it.
Go to File -> Export setup -> Rendering -> Custom rendering and change the painters (vector format) to OpenGL (bitmap format) and click on "Apply to figure". Now save the figure in whatever format. Even an eps file is not bigger than a few MB.
This works for me!

Rendering with painters and HG2 leads to black background of plot after printing

If I print a figure in MATLAB the background of the plot gets rendered black instead of white, like this:
(But in the figure window of MATLAB it is white as it is supposed to be)
This is the code similar to the one used to print the figure(but will run copy-paste):
figure;
set(0,'DefaultAxesFontSize',13)
set(0,'DefaultTextFontSize',13)
set(gcf, 'Renderer', 'painters');
y = 1:100;
plot(y)
xlabel('Some X', 'FontSize', 14)
ylabel('Some Y', 'FontSize', 14)
title('Example', 'FontSize', 15)
legend('some function')
print(gcf,'test1.pdf','-dpdf')
If I add the following line, however, it works (but there a slight grey background in the areas around the plot, of course)
set(gcf, 'color', [0.99 0.99 0.99])
My MATLAB version is R2013a (8.1.0.604)
edit:
set(gcf, 'InvertHardCopy', 'off'); does not resolve the issue.
edit2:
The problem seams to be caused by the HG2-Update.
I'm also using the HG2-Update hack for the sake of beauty. Returning to HG1 is no option for me. Well, I don't have any problems with it, except one: printing directly to .pdf. That's what you're trying to do also. This functionality is still totally screwed up.
The solution: Save with the plot with -dsvg as vector graphic, open the file in Inkscape and save again as pdf with the Export area is drawing checkmark set.
I actually hoped to find a way to script this procedure, without success. So you have to do it manually or wait for the final release of HG2.
The copy-paste code actually works fine on my version (R2013a as well), but to ensure the background color stays what it appears to be like after print, use this:
set(gcf, 'InvertHardCopy', 'off');
You can look at the example in the matlab docs here under Setting the Background Color.
Thus, to get a different background color for your plot, use:
set(gcf, 'color', 'blue');
set(gcf, 'InvertHardCopy', 'off');
print(gcf,'test1.pdf','-dpdf')

`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.

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.

Problem or bug in xticklabel_rotate while drawing heatmap and rotating xtick labels in Matlab

I have been drawing heatmaps with labels in Matlab, mainly using the functions imagesc to draw the heatmap and xticklabel_rotate to rotate the xtick labels.
(please see here for xticklabel_rotate).
It usually works well. But today I met some problem which appeared to be caused by xticklabel_rotate (or maybe the Matlab text handle used by xticklabel_rotate?)
To illustrate the problem, in the following I print my code and the results generated from the code (basically, what it does is to randomly generate a normally distributed data matrix, draw a heatmap for the data using imagesc, draw its labels on top and right of the axis, and then rotate xticklabels):
function debug_xticklabelRotate(numX, numY, axisFontsize)
data = randn(numY, numX);
imagesc(data);
colormap(jet);
box on
set(gca, 'ticklength', [0,0]);
set(gca, 'xminortick', 'off', 'yminortick', 'off');
set(gca, 'XAxisLocation', 'top');
set(gca, 'YAxisLocation', 'right');
set(gca,'FontSize', axisFontsize);
axis image
set(gca, 'Xtick', 1 : numX);
htext = xticklabel_rotate([],90, [], 'fontsize', axisFontsize);
set(gca, 'YTick', 1 : numY);
end
Problem 1: I called the above function with parameters as
debug_xticklabelRotate(40, 100, .5);
the output image is shown below (to save space here, I cut the image and only show the top few rows):
Please notice that the bug is that, as the result of calling xticklabel_rotate, neither the right side of the figure box nor the yticklabels are drawn.
Problem 2: When I call the above function with parameters as
debug_xticklabelRotate(40, 200, .5); % only numY is changed from 100 to 200
the output image is shown below (again to save space here, I cut the image and only show the top few rows):
http://i55.tinypic.com/317grdd.png
Compared to the call with numY=100, in this figure both the data image and the labels are shown. However, please notice two problems here. First, the fontsize of xticklabel is not the same as that of yticklabel (axisFontsize). Second, the xtick labels are not aligned well with the columns (xticks): some labels are closer and some are further away.
Please note if I remove the function call of xticklable_rotate in my function debug_xticklabelRotate, all these mentioned problems are gone (except that now the xticklabel are not rotated).
I wish my problem is stated clear above. Any suggestion on solving the problem will be highly appreciated. Thank you very much.
As the author of xticklabel_rotate, I have tried to reproduce the errors mentioned with only small success. I have found an issue with the axis position being changed when y-labels are on the right, which I will look into. I do not get such marked misalignements as you have shown when I run the same examples, so I am not sure how to respond. Please verify that these issues exist when you PRINT the figure, and it is not a simple display issue.
The text boxes are created at the tick positions, in data units. They are middle aligned, there is not much more that can be done, but I am open to suggestions.
PS. I agree it would be nice if this function was inherent in MatLab. If it was, I wouldn't have had to work on this.
If you comment out the line:
set(gca, 'YAxisLocation', 'right')
then it should work as expected. It seems that the XTICKLABEL_ROTATE function does not support right y-labels. You should contact the original author and let him know of the possible bug...