Small eps figure size in Matlab - matlab

How to create a small eps file from a Matlab figure? I use LaTeX and the eps that I'm getting with Matlab (R2010a) is of the order 6 MB. How to set the plot options to give an eps figure of smaller size?
Does the render options painters or zbuffer help?
Thanks a lot...
One additional info: I use Laprint to generate my eps figures. So, I end up with 2 files: 1 tex file with information about the labels etc and one eps file which is just for the drawing itself. I use Laprint as I can write mathematical expressions in my labels and with a simple command in LaTeX, I can change the size of the fonts easily. Also I can have the default LaTeX fonts in the labels.

Don't use eps. Use pdf format instead, and compile your LaTeX file with pdflatex.

Does the render options painters or zbuffer help?
Does that mean that you're using OpenGL? If so, then what you're getting is a Postscript file which contains an image. Postscript is a good choice for vector images, but OpenGL can't generate vector images. If you really need the OpenGL renderer for something, then you might as well use a bitmap image format. If you really want to take advantage of EPS (or any other Postscript flavor), then you'll want to use Painters.

Related

Are there any options that prevent anti-aliasing when saving png in Matlab?

I need to export figure from Matlab to PNG, but if the size of the matrix I display with imshow gets too "large", the output saved starts adding shades of color different from the original ones. Setting opengl hardware or painter as a renderer helps until for lower dimensions, but if the figure grows the problem is still there. I attached a sample code so you can check the output. It should have only magenta and white pixels, but when I check the resulting PNG I can see a lot of pink shades (anti-aliasing?). I don't know if it depends on the code or on the export setup.
I need 600x300 PNG.
DISCLAIMER: I'd really rather not have to use export_fig, thanks. I really appreciate your help.
brick=zeros(2300,2600,3,'uint8');
colonnebianche=randi(1550,[1000,1]);
righebianche=randi(1000,[400,1]);
brick(:,:,1)=165;
brick(righebianche,colonnebianche,1)=255;
brick(:,:,2)=35;
brick(righebianche,colonnebianche,2)=255;
brick(:,:,3)=99;
brick(righebianche,colonnebianche,3)=255;
loops=1;
for index=1:loops
filenamearray=["face",index];
loopfilename=strjoin(filenamearray,'_');
imshow(brick);
set(0, 'DefaultFigureGraphicsSmoothing', 'off')
fig=get(groot,'CurrentFigure');
fig.PaperUnits='points';
fig.PaperPosition=[0 0 288 144];
fig.GraphicsSmoothing = 'off';
axis off;
print(loopfilename,"-dpng","-painters");
%saveas(fig,loopfilename,"png")
end
You can use the Interpolation="bilinear" Name/Value as part of image display with imshow, that includes anti-aliasing as part of the rendering pipeline.
imshow(brick,Interpolation="bilinear")
Alternatively, you could consider using imresize and downsampling with whatever interpolant you want. By default, imresize uses anti-aliasing when you downsample for the "bilinear" and "bicubic" cases. If what you want is to export your image data at a particular grid size, imresize + imwrite is what I would do instead of relying on the graphics system to downsample if I understand your workflow correctly.
B = imresize(brick,[600 300]); % Bicubic + anti-aliasing on by default
imwrite(B,"yourOutputPNG.png");

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

Matlab, high quality plot, two legends

I would like to produce a plot with two y-axis and two legends, looking something like this:
I have modified a code I found online to produce a high-quality plot to use in reports/papers. I was wondering how you add a second y-axis in such a code? I have attached the matrix and code to produce the high-quality plot: https://drive.google.com/file/d/1aKZLFeoO1wmQ1P2tEiiucvOFI7PehkGL/view?usp=sharing
https://drive.google.com/file/d/1aKZLFeoO1wmQ1P2tEiiucvOFI7PehkGL/view?usp=sharing
NOTE: This is basically a comment, however, it grew too long, and I felt it was too important not to mention properly.
Reporting plots from Matlab should always, unless you have some very good excuse, be done using vector graphics, i.e. pdf, ps, eps or similar format. The reason for this is the quality, e.g. here I have taken your high-quality and the similar pdf-version and zoomed in.
The png version has artifacts. The reason for this is that the png (similar for jpg and more) is that the picture is saved using pixels, thus when you zoom the quality deteriorate.
The pdf version, which is made with vector graphics, save the vectors, thus when I zoom the pdf viewer can regenerate the pixels and maintain the same quality. As an added bonus, the vector-graphic version is typically smaller in size.
This is made in Matlab using
saveas(gcf,'myfigure.pdf')
Use yyaxis to add another plot with an axis. Take a look at the following modified portion of your code.
yyaxis left
plot(N(:,1),N(:,3)/(27.5*2),'b-','DisplayName','Location','LineWidth',lw); %<- Specify plot properites
yyaxis right
plot(N(:,1),N(:,4)/(27.5*2),'r-', 'DisplayName','NorthEast','LineWidth',lw); %<- Specify plot properites
legend('Location', 'NorthEast');

Matlab: How to avoid artefacts in filled contour plots

I am trying to export filled contour plots from Matlab as vector graphics to include in a Latex file. My current methodology is:
contourf(x,y,v_mag,20), axis([0,width,0,height]),daspect('manual') ;
grid off
colormap jet
h = colorbar;
caxis([0 v_lid])
h.Label.String = 'Velocity Magnitude (m/s)';
set(gcf,'renderer','painters')
export_fig('-painters', '-transparent', 'pdf', 'filename.pdf');
The problem with this method is that it produces artefacts (the white lines) which look like the following:
I understand that these white lines are the polygons defining the shaded areas which have invisible edges, and don't quite overlap (according to here). The problem is caused by the pdf viewer itself which tries to smooth the lines displayed on the screen (according to here). My problem is that most people viewing the document will not know this and will not know how to prevent the viewer doing this. So my questions is:
Is it possible to create a vector graphic of a filled contour plot from Matlab without these artefacts?
Eps produces the same problems. I have tried to use the SVG function but have not had any luck. I am trying to avoid using raster graphics due to the pixelation caused by zooming in. Any advice would be much appreciated.
EDIT - Additional info - Using Matlab v.2014b and Ghostscript v.9.15
This is an extremely frustrating issue for which there seems to be no solution (or even, few attempts at a solution), and it has been many years now. In summary, Matlab cannot cope with outputting artefact-free contour or surface plots (anything with complicated meshes or transparencies).
I can suggest a simple workaround that will work in most cases, where the colours or details of the underlying contour plot do not need to be preserved perfectly.
Output a version of the figure without lines in png format with high enough resolution.
Output a version of the figure without colours in pdf format. This should be free of any artefacts. If your figure it complicated and has many transparencies, you may need to output multiple versions building up the 'levels'.
Use Adobe Illustrator (or some equivalent) to perform a vectorized trace of the raster image. You may lose some detail here, but for simple contour plots with limited details, it will be converted easily to vectorized form.
Overlay the two images within Illustrator. Output in vector format.
This also allows you to use things like Illustrator's ability to compress pdfs.
If you don't want to toy with vectorizing the raster output, you can also simply replace steps 3-4 and combine a raster colour image with a vectorized line image. This would work well for complicated contour plots giving you crisp lines, but the ability to compress the underlying colours.
Eventually, MatLab 2013b doesn't have this problem. Furthermore the files it produces has much less volume. That is because MatLab 2013b composes vectorized image of big overlapping figures, while MatLab 2014b makes that awful meshing.
Here the first file was got with 2013b and the second with MatLab 2014b (I highlighted one of the polygons with red stroke to show the difference). The volumes differ in approximately 22 times (38 Kb vs. 844 Kb).
So it is not the viewer problem, it's how the image is exported from MatLab.
The issue is also discussed here Triangular split patches with painters renderer in MATLAB 2014b and above, but still no direct solution.

Printing a transparent figure in MATLAB's terminal emulation mode

Is it possible? The code below illustrates what I want to do:
xdata = [0 1 2];
ydata = [0 1 0];
h = patch(xdata,ydata,'w');
set(h, 'FaceAlpha', 0.2);
print -dpng myfig
If I start MATLAB using option -nodisplay and run the code above, MATLAB simply gives me a core dump. I think that MATLAB should behave a bit better than crashing without further explanations, but I understand that this is due to the fact that neither the opengl nor the zbuffer renderers are available in terminal emulation mode.
I am getting around this problem by plotting the transparent figures in .svg format but this is not an ideal solution for me. My MATLAB scripts are generating HTML reports with many embedded figures and most browsers perform very poorly when rendering pages that contain several (relatively complex) .svg images. So, does anyone know of a better solution?
An indirect solution to this problem is to print the transparent figures to a .svg file using plot2svg(), and then use Inkscape to convert the .svg file to .png, .pdf or any other format supported by Inkscape. Inkscape offers quite good command line support so you can easily script the whole process from MATLAB. Inkscape is available in Windows, Linux and Mac OS X.