How can I make my plots look prettier (including fonts, label, etc )? - matlab

I am trying to obtain very nice plots for my presentation below is a code that I used to plot
clear all
clc
close all
syms v
omegat= -2:0.000001:2;
Nt=32;
gainfuc = (1/Nt)*exp(1i*pi*omegat*(Nt-1)/2).*sin(pi*Nt*omegat/2)./sin(pi*omegat/2);
gainfuc(omegat == 0) = 1;
G = (omegat < 2/Nt).*(omegat > -2/Nt);
plot(omegat,abs(gainfuc))
syms t
hold on
grid on
plot(omegat,G,'r')
ylabel('G_t(y)','FontSize',16,'FontWeight','bold')
xlabel('y','FontSize',16,'FontWeight','bold')
My question is quite simple, any ideas to make this plot nicer (font, grids, etc...) so that it would look nice in presentations?
Update
I have obtained the following figure after the changes recommended in the answer below

In Matlab 2014b a new graphic engine got introduced, it immediately looks more pretty.
New default colormap presents data more accurately, making it easier to interpret. New default line colors, fonts, and styles with anti-aliased graphics and fonts improve the clarity and aesthetics of MATLAB visualizations.
In Matlab 2014a you can also activate the new graphics engine by following these instructions.
In earlier versions the hack is may also possible, but I haven't tested it. It is most likely quite buggy. For 2014a I use it for almost a year now and it works like a charm. I couldn't find any differences to the final release of HG2 in 2014b.
Make sure that smoothing is set to 'on'
h = gcf;
h.GraphicsSmoothing = 'on'
I also used the standard LateX font CMU Serif Roman to spice everything up. Enter this lines at the beginning of your code after installing the fonts (open source).
set(0,'defaultAxesFontName', 'CMU Serif Roman')
set(0,'defaultAxesFontSize', 12)
General recommendations:
Use vector graphic renders: set(gcf, 'renderer', 'painters')
Specify the resolution when saving your plots, especially for pixel graphics: print('-dpng','-r600','PeaksSurface') (still use the vector renderer!)
The vector format for MS Office is .emf and is also supported by Matlab
May use: set(gcf,'InvertHardcopy','off')

Related

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.

Colorbar not appearing in (surface) plot - LaTeX interpreter issue

As the title states, the colorbar in surface plots does not appear when the default interpreter is set to 'latex'. This occurs in MATLAB 2012b and 2013a and on two different machines.
Precisely, the colorbar object is created, can be clicked when editing the plot, can be edited using the interactive colorbar editor but is not visible at all.
It does not appear when saved as a figure and reopened, saved as a PNG, exported in .eps format or saved as a .pdf.
After searching around, I found the following post from 2011, concerning MATLAB 7:
http://mathforum.org/kb/message.jspa?messageID=7518470
Specifically, the interpreter appears to be at fault, when it is set to 'latex', the colorbar will not display. When set to the default, it does.
Here is the smallest demonstrating example.
set(0,'defaulttextinterpreter','none');
figure;
surf(peaks(100)); colorbar
set(0,'defaulttextinterpreter','latex');
figure
surf(peaks(100)); colorbar
The two figures are identical except that the colorbar is visible only in the first figure.
I use a lot of special characters and sub/superscripts in my plots so in startup.m I set the default interpreter to 'latex'. I could surround all calls to colorbar with:
set(0,'defaulttextinterpreter','none');
colorbar;
set(0,'defaulttextinterpreter','latex');
But this is probably the least elegant solution possible. Can anyone shed some light on this issue which appears to be extant for over 5 years and multiple editions of MATLAB?
This behaviour is gone in Matlab R2014b, which uses an entirely new graphics engine, hg2. The plots look different (most of the time in a better way), but instead of old, documented bugs, there are now new, undocumented bugs...
Earlier versions of Matlab support somewhat experimental stages of hg2. You can enable these by running Matlab with the switch "-hgVersion 2". You can do this, for example, by editing the Desktop shortcut to point to something like "C:\Program Files\MATLAB\R2013b\bin\matlab.exe" -hgVersion 2.
Unfortunately, with the new graphics engine being the default in Matlab2014b, the old bugs are less likely to be fixed in the future. I wish I could help you in a better way, but the workaround you posted seems like a good solution, especially if you wrap it in a function called robust_colorbar or so.
I can reproduce the problem on my system (R2010b, Windows Vista 32 bits) . It seems to be solved by changing the 'Renderer' property of the figure from the default 'OpenGL' to either 'painters' or 'zbuffer'. So, you can either change the renderer when creating the figure:
set(0, 'defaulttextinterpreter', 'latex');
figure('Renderer', 'zbuffer') %// this line changed
surf(peaks(100)); colorbar
or change the default renderer to be used for all figures (so you don't need to change it in every figure):
set(0, 'DefaultFigureRenderer', 'zbuffer'); %// this line added
set(0, 'defaulttextinterpreter', 'latex');
figure
surf(peaks(100)); colorbar
Using a renderer other than 'OpenGL' may affect features such as transparency or drawing speed. Here's some information about pros and cons of each renderer.

Jagged outline using Matlab 2014b

I am plotting some maps using Matlab that use mapshow to plot the country border from a shapefile. I then export them to both a PDF and EPS format using the export_fig package. This worked completely fine using Matlab 2014a, but I have just upgraded to Matlab 2014b to take advantage of something else that has improved, and now my country border is all jagged. The border only looks jagged on the saved versions of the file. If I zoom in on the figure window, the outline isn't like that.
Here are the snippets of code that are important. It is a custom shapefile, so I don't know how to put it on here so people can replicate it.
This bit reads in the shapefile and plots it. The display type is 'polygon' if that is relevent, hence getting rid of the 'FaceColor' so I can see what I am plotting underneath (the green bits in the background of the images, plotted using pcolor).
thaiborder=shaperead('Thailandborder');
mapshow(thaiborder,'FaceColor','none');
This bit is how I am exporting the figure.
export_fig test.eps -r600 -painters
export_fig test.pdf -r600 -painters
This is the version with a smooth border from Matlab 2014a:
This is roughly the same area of the image, with the jagged border from Matlab 2014b:
Does anyone know why these differences are occurring? I want the border to be like it is in the first image, but I need the "improved" functionality of Matlab 2014b for another thing in the same image. What do I need to change?
Edit to add: I have been in contact with the creator of export_fig and he thinks it is caused by Matlab now using mitred joins rather than round ones. Apparently I have to write to MathWorks to complain. I didn't put this as an answer because someone else may be able to provide a solution for me.
Matlab acknowledged that this is known bug. For me the first fix worked.
The issue of jagged lines on the figures while exporting in the vector format is a known bug in MATLAB R2014b. It is associated with the combination of linejoins and meterlimits used in vector format.
To work around this issue, use the attached function fixeps to post process the EPS file.
You can use one of the following ways to call this fixeps function.
fixeps('input.eps','output.eps','LJ') % Will change the linejoins to round
fixeps('input.eps','output.eps','ML') % Will correct the miterlimit
function fixeps(inname,outname,fixmode)
if nargin==2
fixmode = 'LJ';
end
fi = fopen(inname,'r');
fo = fopen(outname,'w');
tline = fgets(fi);
while ischar(tline)
if (strcmp(tline,['10.0 ML' 10])) % Replace 10.0 miterlimit
switch (fixmode)
case 'LJ'
fwrite(fo,['1 LJ' 10]); % With round linejoin
case 'ML'
fwrite(fo,['2.5 ML' 10]); % With smaller miterlimit
end
else
fwrite(fo,tline);
end
tline = fgets(fi);
end
fclose(fo);
fclose(fi);
I had a similar problem that I found to be caused by the 'MarkerSize' option. It seems that in version 2014b it inherits the units of the figure. For example, if I have a figure in centimeters and I ask for ('MarkerSize', 10), the 10 will not be interpreted as points (as in 2014a) but as cm. I fixed this by changing the figure units to pt.

How to draw good looking arrows in Matlab?

I have been trying to draw arrows in Matlab in my figure but they all look terrible.
Also, I want my arrowhead to be a solid triangle, not a V.
I tried using the packages available on the Matlab File Exchange: arrow, arrows, arrows3, and probably at least one other one.
I even tried manually creating an arrow in the Matlab figure editor, but when I adjust the line width, the arrow looks like this:
I used the annotation command to create the arrow above:
annotation(gcf,'arrow',[0.621875 0.457916666666667],...
[0.205421152030217 0.40755429650614],...
'HeadLength',4,'LineWidth',5);
Here's the result trying to use the arrow package available here: Arrow.m (notice how the bottom arrow head is not perpendicular to the line:
I even tried the following and here is the result below (notice the terrible looking arrowhead):
figure
plot(1:10, 1:10)
annotation(gcf,'arrow',[0.621875 0.457916666666667],...
[0.205421152030217 0.40755429650614],...
'HeadLength',4,'LineWidth',5);
Vector graphics is hard. Though Matlab's typography is just as bad, but here's a simplistic text-based solution (I refuse to do this sort of annotation in Matlab any more):
figure
plot(1:10, 1:10)
text(5,4,'\rightarrow','FontSize',54,'Rotation',135,...
'HorizontalAlignment','center');
which yields a figure like this
Note that I have used '\leftarrow' because it points in the direction of zero degrees, which makes doing math in my head easier. This is no canned solution, you'll still need to fiddle with position to overcome the fact that Matlab is aligning this as text (see the 'Extent' and 'Margin' properties). Not surprisingly, you may see small glitches. The LaTeX interpreter can be used to obtain a different style arrow head:
text(5,4,'$\rightarrow$','FontSize',54,'Rotation',135,...
'HorizontalAlignment','center','Interpreter','latex');
I don't get the small glitches with this option, but the arrows look different (there are likely other LaTeX arrow styles that could be substituted). Changing the font may also have an effect and there are certainly other text-based arrows that could be used. More details on adding arrows can be found in this article from The MathWorks.
Another solution is to use the open-source Waterloo graphics - a library that addresses this by providing a pure Java library of 2D graphics functions that can easily be integrated in Matlab. See some examples here...
For example, try this code (after properly installing waterloo)
f = GXFigure();
x = -5:0.1:5;
gr1 = gxgca();
a1 = line(gr1, x, cos(x), 'LineSpec','-ob');
b1 = line(gr1, x, sin(x), 'LineSpec','-sg');
annotation(gr1,'arrow',[0.1 0.1],[0.4 0.4],'HeadLength',0.2,'HeadWidth', 0.5, 'LineWidth',2);
gr1.getObject().getView().autoScale();
Having worked with Matlab for more than 10 years and seeing almost zero progress in the quality of the plots (anti-aliased output to bitmap, decent looking eps-files, ...), I decided that my long time solution will be here. Some examples of decent looking arrows here, more beautiful graphs here. Unfortunately, some of the toolboxes prevent me from going completely to numpy/scipy/matplotlib. I know this is more of a rant than an answer, but that is my solution ...
Using quiver or quiver3 for 3-D plots will certainly look better than the that last arrow you made using annotation. I'm not sure it will look much better than the ones you made using the Arrow.m package though. It's possible to change the stlyes on quiver as well if you want.
I resorted to installing InkScape and drawing arrows in there. Nothing beat the simplicity and quality.
InkScape Website
When line-based arrows fail, you can always try patch-based ones:
xArrow = [0 1 1 1.2 1 1 0]; % X-coords of arrow edge points
yArrow = [-0.1 -0.1 -0.2 0 0.2 0.1 0.1]; % Y-coords of arrow edge points
hArrow = fill(xArrow,yArrow, [1 0 0]); % Plot a red arrow
axis equal % Set axis tick marks to be equal
Although more work, you can potentially parameterize the above into a function that takes a number of arguments for adjusting the scaling, aspect ratio, rotation, and position of the arrow. You can even adjust the color, edge line color, and alpha transparency.
This sort of idea appears to have been implemented by François Beauducel in his File Exchange submission ARROWS: generalized 2-D arrows plot.
There is now the DaVinci Draw toolbox (full disclosure: I wrote/sell the toolbox), which uses low-level Matlab commands like plot() and patch() to draw mid-level shapes like arrows. Example syntax:
davinci( 'arrow', 'X', [0 10], ...
'Y', [0 2], ...
'Shaft.Width', 1, ...
'Head.Length', 2.5, ...
'Color', 'w', ...
'EdgeColor', 'k', ...
'LineWidth', 2.5 )
From the documentation:

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.