MATLAB and high quality EPS figures - matlab

I am looking to export my MATLAB plot as a high quality figure. Specifically, I would like to save it as a vector based file format such as EPS or SVG.
I have tried print and saveas commands:
saveas(h,'myFileName','epsc2');
print('-r150','-depsc2', 'myFilename');
On all occasions this produces poor quality parts of the graph, although the axis-labels are indeed vector. Why does MatLab do some horrible rendering before putting it into an EPS?
Example of poor quality plot here:
http://users.ox.ac.uk/~pemb2372/myFileName.eps
Edit:
It is also worth noting that if you use a Mac viewing an EPS file from Matlab, 'Preview' app may render inner graph content rasterized and poor quality, while leaving the axis and labels vectorized and high quality. This is very misleading but when you open said EPS file in, for example, Inkscape, the quality is actually vector and quite high.
Edit 2:
My university hosting account has expired, so you can no longer view the figure. Suffice it to say that it showed a poor quality raster-style plot within high quality beautiful axis lines, ticks and labels.

I thought I would share the issue I had, and how I overcame it...
I was getting terrible results because I had the wrong renderer set to default. In my startup.m, I had the zbuffer renderer enabled. This is an example eps output.
I made that eps output with: print(gcf,'-depsc2','filename.eps'). This eps is so OBVIOUSLY rasterised. It makes me angry at matlab. Then, I had a brainwave - perhaps my default renderer zbuffer is interfering with the image save process. So, adding the line:
set(gcf,'renderer','painters')
and running the print command as before, here is the output:
Note that I just took screenshots of the eps output files at 100%. And I can confirm the second image is actually vector. Here is a good question/explanation on choosing Renderers in MATLAB.

Matlab can export to pdf with better quality than EPS, but with its own caveats of setting decent margins and font sizes.
edit:
Examples are similar to the EPS case as explained in the help of e.g. print:
saveas(gcf,'filename.pdf')
or
print('-dpdf','filename.pdf')
You might also want to take a look at the PaperSize, PaperPosition and PaperUnits properties of your figure (by means of the set and get functions).
edit: Another option is to use one of the functions available on FileExchange such as the ones mentioned by #user664303 below. My personal favorite for use with LaTeX is matlab2tikz for which the latest version can be gotten from GitHub. Together with the external library of TikZ, I think this delivers some of the most nicest graphs around.
Probably it's also best to mention that I have been actively involved in the matlab2tikz project since 2012.

The export_fig function on the MATLAB file exchange is a reasonably reliable way of accurately exporting figures to eps and pdf (as well as bitmap formats) in MATLAB.
The plot2svg function, also from the file exchange, allows you to export in svg format. It provides some additional benefits, such as being able to export translucent patch objects in vector format.
A comparison of exporting methods is given in this blog post.

I always acquire the final plots (those which are supposed to be inserted into papers and publications) by matplotlib library of python.
You can bet on the amazing quality of the generated plots, both .pdf and .eps formats.

Related

Change size of figure in MATLAB to use them in LaTeX

I have generated several plots in MATLAB and I haven't set the ( width or height) to any of them. I save them as pdf to place them in LaTeX but each figure appear with different size. I can change each figure size in LaTeX but I wonder if there is an easy way in MATLAB to get same size for all figures.
Can I reset the figure size after generating in MATLAB or I have to regenerate each figure with specific size?
What is the best way to export figures in MATLAB to use them in LaTeX?
Exporting figures from MATLAB to LaTeX is best done via .eps or directly to PDF. MATLAB's saveas() functionality supports both. The benefit of these file-types is that thy are vector files, meaning, loosely, that coordinates of corners in the lines are saved, as opposed to a bunch of fixed pixels such as with PNG or JPG figures. Using then these figures in LaTeX gives infinite scalability (theoretically, usefulness of highly-zoomed figures may vary).
If you need different aspect ratios, i.e. one figure taller than broad, the other broader than tall, You'd have to set the proper aspect ratio for each figure independently, then save using one of the aforementioned vector file types.
One of the best ways to export pretty figures is the export_fig() functionality written by Oliver Woodford and currently maintained by Yair Altman and freely available on the FileExchange.
Answering your first question: yes you can resize figures after generating them. Either by hand (change the window size), or programatically: you can make a figure handle (h=figure();, where h is your handle), which has several options to control figure size; h.position being the most prominent: [upper-left, lower-left, upper-right, lower-right] being its content in terms of corner coordinates. Changing those changes the figure size.

exporting svg image from matlab surface plot

I need some to produce some publication-quality figures. I first export the figures from matlab in .svg format, and then I do some post-processing in inkscape. I am no problem with figures generated using plot or scatter, but when I export figures generated using surf (in view(2)), I run into problems. If I use plot or scatter, I am able to ungroup and process various parts like the title, axes, scattered points, lines, etc. in inkscape. For surf, however, matlab just exports one single figures with all various parts grouped into one single unit. I can't separate individual part, and when I zoom very close I can actually see the bitmap resolution for the axes and titles (if I use plot, the titles and axes have 'infinite' resolution when I zoom very close). I am fine with the surface plot having finite resolution, but I need to at least be able to process the axes and titles (which I currently cannot do). What should I do so that I can 'separate' the title and axes from the main plot, just like figures generated from plot and scatter?
I stumbled across this question, since I encountered the same problem.
As mentioned by #vindarmagnus, it is possible to use tikz and get rather nice results. However, tikz experiences problems with large data sets in my experience as present when using surf etc..
Solution, that worked for me:
Change the renderer to painters and the exported .svg file will retain its vectorgraphic properties when opened e.g. in inkscape:
figure('Renderer','Painters');
I used to use Inkscape for my scientific publications as well, but I found that a lot of the time you can get better results with pgfplots in latex, together with the matlab2tikz matlabscript. There’s a ton of resources about this online, but here’s how my workflow would look adopted to your surf situation. I have macOSX with latex, matlab and matlab2tikz installed. Will work with little to no modifications on linux.
In Matlab:
surf(peaks(25))
matlab2tikz('plot.tikz’)
Then I have the following bash-script (just a script in the same folder as the image, which is executed by mere double-click). (Needs to be chmod-ed as an executable for that).
#!/bin/bash
cd ~/Desktop
rm *.eps
cat > plot.tex << EOF
\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{max space between ticks=50}
\pgfplotsset{scaled ticks = false}
\pgfplotsset{compat=1.6}
\pgfplotsset{xticklabel style={/pgf/number format/fixed}}
\pgfplotsset{yticklabel style={/pgf/number format/fixed}}
\begin{document}
\input{plot.tikz}
\end{document}
EOF
pdflatex plot.tex
pdf2ps plot.pdf
ps2eps plot.ps
Note that the row cd ~/Desktop above should be changed as to reflect which folder the script is supposed to be run from (a bit crappy, but needed since Finder doesn’t properly pass along the folder from a program is executed, afaik).
This yields high-quality images in eps or pdf or what you like, with a ton of settings for axes and ticks etc. And it all uses native latex fonts.
Edit:
Recently I’ve begun to use patch() in matlab and then export it to tikz in the same manner as above, with great results. That’s another suggestion!
You can use also:
set(gcf,'Renderer','Painters')

exporting figure to eps file

I am trying to export a figure which includes highlighting of regions - something like this: Highlight parts of matlab plot. Unfortunately, when I export the figures to .eps files the size is of the order of ~10 MB... Thus, when I include them in a tex file, the quality is severely degraded. As expected this problem seems to occur due to the use of the area function for the highlighting. Is there any workaround on this?
You have transparency in your plot which requires the renderer to be OpenGL which causes any EPS to not really be vector graphics but rather bitmaps coerced in some strange way. This is why the file size is much larger than what you would expect for vector graphics. If you open the resulting EPS file with an external editor (Illustrator, Inkscape, etc.) you will see what I am talking about. As a side-note, transparency isn't technically supported in EPS files.
Your options are really to
Save your figures as something else such as TIFF or PNG
You could try saving the figure as an EPS using export_fig from the file exchange but you will likely still have the same issue.
Turn off transparency, save to an EPS, and use Illustrator or an external program to change the transparency and try to save as an EPS file and see if you get better results.

How to visualize correlation matrix as a schemaball in Matlab

I have 42 variables and I have calculated the correlation matrix for them in Matlab. Now I would like to visualize it with a schemaball. Does anyone have any suggestions / experiences how this could be done in Matlab? The following pictures will explain my point better:
In the pictures each parabola between variables would mean the strength of correlation between them. The thicker the line is, the more correlation. I prefer the style of picture 1 more than the style in picture 2 where I have used different colors to highlight the strength of correlation.
Kinda finished I guess.. code can be found here at github.
Documentation is included in the file.
The yellow/magenta color (for positive/negative correlation) is configurable, as well as the fontsize of the labels and the angles at which the labels are plotted, so you can get fancy if you want and not distribute them evenly along the perimeter/group some/...
If you want to actually print these graphs or use them outside matlab, I suggest using vector formats (eg eps). It's also annoying that the text resizes when you zoom in/out, but I don't know of any way to fix that without hacking the zoom function :/
schemaball % demo
schemaball(arrayfun(#num2str,1:10,'uni',false), rand(10).^8,11,[0.1587 0.8750],[0.8333 1],2*pi*sin(linspace(0,pi/2-pi/20,10)))
schemaball(arrayfun(#num2str,1:50,'uni',false), rand(50).^50,9)
I finished and submitted my version to the FEX: schemaball and will update the link asap.
There are a some differences with Gunther Struyf's contribution:
You can return the handles to the graphic object for full manual customization
Labels are oriented to allow maximum left-to-rigth readability
The figure stretches to fit labels in, leaving the axes unchanged
Syntax requires only correlations matrix (but allows optional inputs)
Optimized for performance.
Follow examples of demo, custom labels and creative customization.
Note: the first figure was exported with saveas(), all others with export_fig.
schemaball
x = rand(10).^3;
x(:,3) = 1.3*mean(x,2);
schemaball(x, {'Hi','how','is','your','day?', 'Do','you','like','schemaballs?','NO!!'})
h = schemaball;
set(h.l(~isnan(h.l)), 'LineWidth',1.2)
set(h.s, 'MarkerEdgeColor','red','LineWidth',2,'SizeData',100)
set(h.t, 'EdgeColor','white','LineWidth',1)
The default colormap:
To improve on screen rendering you can launch MATLAB with the experimental -hgVersion 2 switch which produces anti/aliased graphics by default now (source: HG2 update | Undocumented Matlab). However, if you try to save the figure, the file will have the usual old anti-aliased rendering, so here's a printscreen image of Gunther's schemaball:
Important update:
You can do this in Matlab now with the FileExchange submission:
http://www.mathworks.com/matlabcentral/fileexchange/48576-circulargraph
There is an exmample by Matlab in here:
http://uk.mathworks.com/examples/matlab/3859-circular-graph-examples
Which gives this kind of beautiful plots:
Coincidentally, Cleve Moler (MathWorks Chief Mathematician) showed an example of just this sort of plot on his most recent blog post (not nearly as beautiful as the ones in your example, and the connecting lines are straight rather than parabolic, but it looks functional). Unfortunately he didn't include the code directly, but if you leave him a comment on the post he's usually very willing to share things.
What might be even nicer for you is that he also applies (and this time includes) code to permute the rows/columns of the array in order to maximize the spatial proximity of highly connected nodes, rather than randomly ordering them around the circumference. You end up with a 'crescent'-shaped envelope of connecting lines, with the thick bit of the crescent representing the most highly connected nodes.
Unfortunately however, I suspect that if you need to enhance his code to get the very narrow, high-resolution lines in your example plots, then MATLAB's currently non-anti-aliased graphics aren't quite up to it yet.
I've recently been experimenting with MATLAB data and the D3 visualization library for similar graphs - there are several related types of circular visualizations you may be interested in and many of them are interactive. Another helpful, well-baked, and freely available option is Circos which is probably responsible for most of the prettier versions of these graphs you've seen in popular press.

Getting rid of interpolation/aliasing in EPS export of matlab?

I have a 2D color-map plot created with imagesc and want to export it as a .eps file using
print -depsc.
The problem is that the "original" image data is from a rather small matrix (131 x 131). When I view the image in the matlab figure window, I can see all the individual pixels if I zoom a bit closer.
When I export to eps, however, there seems to be some interpolation or anti-aliasing going on, in that neighboring pixels get blurred/blended into each other. I don't get the problem if I export a high-resolution tiff, but that format is not an option (as demanded by a publisher).
How can I obtain an eps that preserves the pixely structure of my image without applying interpolation or anti-aliasing?
The blurring actually depends on the rendering software your viewer application or printer uses. To get good results all the time, make each pixel in your image an 8x8 block of pixels of the same color. The blurring then only affects the pixels at the edge of each block. 8x8 blocks are best as they compress without nasty artifacts using DCT compression (sometimes used in eps files).
Old question, but highly ranked in Google, so here is my answer:
Open the .eps-file with a text editor, search for "Interpolate" and change the following "true" to "false". Repeat that step for all Interpolate-statements.
It might also depend on the viewer you're using, but probably just because some viewers ignore the "Interpolate"s...
Had the same problem using plot2svg in Matlab and exporting from Inkscape to eps.