MATLAB: latex interpreter font spacing - matlab

The font spacing in TeX-typeset equations in MATLAB defaults to being highly compressed. Is there a way to increase the amount of spacing, so that, for example, the numerator and denominator of a fraction do not make contact with the line separating the two?
plot(1:10,rand(1,10));
set(gca,'FontSize',18);
legend('$\frac{xy}{\exp\left(\frac{x}{y}\right)}$');
set(legend(),'interpreter','latex');

I think the easiest way is to use some LaTeX trickery.
Long story short, in LaTeX $ ... $ is used for inline math, but for display math, you should either use \[ ... \] or the legacy way of doing the same $$ ... $$. For LaTeX documents, don't use the latter, but for MATLAB it should be enough.
The difference between inline math and display math, is like the difference between using backticks (``) and indentation in StackOverflow. The first will show your code in-between text, the latter in-between paragraphs. With math, only display mode math will have decent lay-out for larger formulas.
So the following code should fix your problem:
plot(1:10,rand(1,10));
set(gca,'FontSize',18);
legend('$$\frac{xy}{\exp\left(\frac{x}{y}\right)}$$');
set(legend(),'interpreter','latex');
If you want even more, you might want to consult the Not So Short Introduction To LaTeX2e which gets you started with a lot of the tricks of the LaTeX trade.
edit:
What I tend to use as a trick to improve spacing in formulae is using phantoms (\phantom, \vphantom, \hphantom), but \vspace or \vskip might be a little cleaner to use.

Looking through the list of properties for the legend, there doesn't seem to be any way of specifying a line spacing that is consistent with automatic positioning. You can fudge the line spacing by enlarging the box, however, by changing the final entry (height) in the OuterPosition property. It seems the placement of the box is based on its bottom-left corner, so if your legend box is in a North position then you will also need to reduce the second entry (y-position) by an equal amount.
In this example I increase the height of a North-positioned legend box by 25% (which I have found that gives nice results), which increases the line spacing.
h = legend(s1,s2,s3, 'location', 'northeast');
set(h, 'fontsize', 16, 'interpreter', 'latex')
outerposition = get(h, 'OuterPosition');
delta_h = 0.25*outerposition(4);
outerposition(2) = outerposition(2) - delta_h;
outerposition(4) = outerposition(4) + delta_h;
set(h, 'OuterPosition', outerposition)
You have to be wary about resizing the figure after running this code fragment, since changing the OuterPosition property clears the automatic placement of the box with respect to the plot axes. If you resize the figure the legend box will go walkabouts.

Related

Adjusting graphical LaTeX text size in Matlab

I am trying this example:
http://www.mathworks.com/help/symbolic/latex.html
Let's say I wanted to resize those labels. How? I can't figure out any LaTeX code, and 'fontsize' does not do the trick.
This hits a sore spot when it comes to Matlab's support for (or use of) Latex. The normal font-size commands from Latex aren't available. (In Latex normally you'd just say \Large{Text ... $x$} or even \normalsize ....)
To do this in a Matlab plot you can add fontsize spec at the end
title(['For $x$ and ...'], 'Interpreter', 'latex', 'fontsize', 14)
For more discussion and how to change font type as well see this post. Note that there are not so many fonts readily available in Matlab. To preserve sanity I'd keep this kind of tweaking to the minimum.
There is another method that will work anywhere in Matlab where you can use Latex -- in any text, in the middle of a string, etc: You can drop to Latex's lower level font specification.
title(['\fontsize{15}{0}\selectfont For $x$ and ...'], 'Interpreter', 'latex')
The first command \fontsize{}{} specifies the font, the second one \selectfont actually changes it for the rest of the text. When you want to switch to a different font, even mid-string, you again issue \fontsize{12}{0}\selectfont and you have that font size after that point. The only thing you need to change is the size (I used 15 and 12 as examples), the rest is boilerplate (for this purpose).
See what these things mean and more discussion in this post. For far more detail on fonts in Matlab see this article. For how to change fonts across the whole document see this post.
There are yet other ways but it gets progressively trickier and this should be enough. Probably the best advice is to set it once for the whole document. That also makes sense typesetting-wise.
Note. The font command of the second example must be given outside of math mode. Latex has two major modes, text and math. To make it go to 'math mode', where it processes everything as it were math symbols, you put a $, or $$. (There are yet many other ways, but in Matlab's strings this is all you'll ever use.) When you want it to go back to typesetting text normally, you end math mode with another $, or $$. All math is in between $...$, everything else is normal text.
This is some text, now typeset some math: $y = x^2$ ... back to text.
The font commands do not work in math mode but need be given outside the $...$. They will apply to any following math as well. In a plot command we'd say
ylabel(['\fontsize{16}{0}\selectfont $\dot{x}$'], 'interpreter','latex');
Here is the line that worked:
ylabel('$x_e, x_c$', 'interpreter','latex', 'fontsize', 32);
Obviously, between the dollar signs can be whatever appropriate LaTeX expression desired.

Scale text to fit in a box

I'm working on a matlab GUI and I am trying to make the text font size resize to boxes. Currently I have a few solutions, but they aren't optimal. The fastest one is scaling the text by a goal/Extent factor:
goal = [0 0 .9 .9].*b.Position
fs = b.FontSize*min(goal./b.Extent)
b.FontSize = fs;
b is the uicontrol element. This works, but if the text is too long and needs to wrap it won't, and it will rather shrink the height until it fits on one line in the box.
I also have a while loop approach that * or /s by .99 until extent and goal are close enough.
What I've been looking for is an approach that will wrap the text so that I display the whole string but also take advantage of the whole space. I also had a recursive backtracking attempt that would try to find the best ratio the words would have to the ratio of the sides of the box, but that takes O(2^n) which is good to avoid.
Online I found the textwrap function, but I think that depends on font size, so it doesn't help me. Any ideas on how to do this?
maybe you can load your text as an image, instead of using labels use an axis and load the image o your desired text. Next time you wanted to resize your figure you won't be worry about it.

Change legend line style

I am playing with the visual effect of plots, and a question came up while changing the style of a legend.
To be able to save the figure with legends big enough that can be seen usually one needs to change the FontSize property to e.g. 24. When you do that, the size of the font changes, however, the small line next to it has the same size than when it was small. The proportion between line/text seem quite appropriate to me with a FontSize of around 10, while I believe that with big font sizes bigger "eat" visually the line, which is the important part.
Example with fontsize 30 and 10 (please ignore how much I suck in mspaint and the low resolution of the zoomed legend). The proportion between line/text is nicer in the small one.
I was wondering if there is a way to modify that line. I have been checking the properties but I haven't found any relevant one.
NOTE: The LineWidth property does not change the width of the colour lines, but the width of the bounding box.
You could play with the outputs arguments of legend, especially the icons variable (check here).
According to the docs, they correspond to
Objects used to create the legend icons and descriptions, returned as
text, patch, and line object.
Therefore you might use something like this to modify the LineWidth property of any of your plot, or both of course:
clear
clc
close all
x = 1:10;
plot(x,rand(1,10));
hold on;
plot(x,x,'k');
[h,icons,plots,str] = legend('First plot','Second plot','Location','NorthWest');
set(h,'FontSize',30);
set(icons(:),'LineWidth',2); %// Or whatever
Which outputs:
Note that I used R2014a so it might be a bit different for R2014b.

Matlab: Scale figures for publishing - exact dimensions and font sizes

I am currently writing up a scientific thesis and am very desparate about creating figures that have the exact dimensions I want them to have. Especially the font sizes do not match.
I already googled alot and there are a bunch of guides and scripts about this topic but nothing really helped - I have not yet figured out (sorry) why my approach does not work:
FS=8; %font size in points (the same as in my document)
width=12; %width of figure in cm
height=4; %height of figure in cm
scatter(1:20,rand(20,1));
xlabel('X','fontsize',FS),ylabel('Y','fontsize',FS),title('X vs. Y','fontsize',FS)
%now I scale the figure and place it in the bottom left corner. The white margins around it are cropped automatically
set(gca,'units','centimeters','outerposition',[0 0 width height])
%export as .eps
print(gcf,'-depsc','test')
When I load test.eps into Inkscape, the figure is 10.16 x 3.529 cm large and the font sizes (of title and axis labels) are 10.
How do I get a figure with the exact scaling, especially regarding the font size?
I did the following:
FS=8; %font size in points (the same as in my document)
width=12; %width of figure in cm
height=4; %height of figure in cm
scatter(1:20,rand(20,1));
set(gca, 'fontsize', FS);
xlabel('X','fontsize',FS),ylabel('Y','fontsize',FS),title('X vs. Y','fontsize',FS)
set(gcf,'units','centimeters','position',[0 0 width height])
export_fig(gcf, 'test.pdf', '-transparent', '-nocrop')
The output figure is 12cm x 4cm. The font size still claims to be 10 in Inkscape, however, but it looks the same size as that in the figure. Export_fig can be downloaded from the MATLAB file exchange.
Here is how I solve it as of now - it is not exactly elegant but it works...
I plot my figure and arrange and scale it in the figure window the way I want it to be scaled:
set(gcf,'units','centimeters','position',[0 0 width height])
Due to the white margins around the axes, I increase the width/height by approximate (trial and error...) values that the margins use up. I then export it:
export_fig(gcf,'test','-eps','-transparent')
And load it into Inkscape. Now I set the document properties so that the document has the exact size I want my figure to have - the figure is partly out of this frame because I increased the width/height earlier.
Then I arrange the axes to have as much white space between them as I want them to have; hopefully, everything is inside the document borders after that.
Probably the drawing is smaller than the document borders now - to ensure that it will not get expanded, messing up the scaling, when I put it in my actual document (my thesis, not the Inkscape document...), I simply create a white background that matches the document borders. Aaand done.
Except for the fontsize and fontname properties in Matlab - I have not figured out why they are not properly exported...but this is not hard to manually fix in Inkscape.
Thanks for your help, everyone.

Save Matlab Simulink Model as PDF with tight bounding box

Given a Simulink block diagram (model), I would like to produce a 'Screenshot' to be used later in a LaTeX document. I want this screenshot to be PDF (vector graphic, -> pdflatex) with a tight bounding box, by that I mean no unneccessary white space around the diagram.
I have searched the net, searched stackexchange, searched the matlab doc. But no success so far. Some notes:
For figures, there are solutions to this question. I have a Simulink block diagram, it's different (see below).
I am aware of solutions using additional software like pdfcrop.
PDF seems to be the only driver that really produces vector graphics (R2013b on Win7 here). The EPS and PS output seems to have bitmaps inside. You zoom, you see it.
What I have tried:
1.
The default behaviour of print
modelName = 'vdp'; % example system
load_system(modelName); % load in background
% print to file as pdf and as jpeg
print(['-s',modelName],'-dpdf','pdfOutput1')
print(['-s',modelName],'-djpeg','jpegOutput1')
The JPEG looks good, tight bounding box. The PDF is centered on a page that looks like A4 or usletter. Not what I want.
2.
There are several parameters for printing block diagrams. See the Simulink reference page http://www.mathworks.com/help/simulink/slref/model-parameters.html. Let's extract some:
modelName = 'vdp'; % example system
load_system(modelName); % load in background
PaperPositionMode = get_param(modelName,'PaperPositionMode');
PaperUnits = get_param(modelName,'PaperUnits');
PaperPosition = get_param(modelName,'PaperPosition');
PaperSize = get_param(modelName,'PaperSize');
According to the documentation, PaperPosition contains a four element vector [left, bottom, width, height]. The last two elements specify the bounding box, the first two specify the distance of the lower left corner of the bounding box from the lower left corner of the paper.
Now when I print the PDF output and measure using a ruler, I find the values of both the bounding box and the position of its lower left corner are totally wrong (Yes, I have measured in PaperUnits). That's a real bummer. I could have calculated the margins to trim off the paper to be used later in \includegraphics[clip=true,trim=...]{pdfpage}.
3.
Of course what I initially wanted is a PDF that is already cropped. There is a solution for figures, it goes like this: You move the bounding box to the lower left corner of the paper and than change the paper size to the size of the bounding box.
oldPaperPosition = get_param(modelName,'PaperPosition');
set_param(modelName,'PaperPositionMode','manual');
set_param(modelName,'PaperPosition',[0 0 oldPaperPosition(3:4)]);
set_param(modelName,'PaperSize',oldPaperPosition(3:4));
For simulink models, there are two problems with this. PaperSize is a read-only parameter for models. And changing the PaperPosition has no effect at all on the output.
I'm running out of ideas, really.
EDIT ----------------------------------
Allright, to keep you updated: I talked to the Matlab support about this.
In R2013b, there are bugs causing wrong behaviour of PaperPositionMode and the bounding box from PaperPostion to be wrong.
There is no known way to extract the scale factor from print.
They suggested to go this way: Simulink --(print)--> SVG --(Inkscape)--> PDF. It works really good this way. The (correct) bounding box is an attribute of the svg node and the scale factor when exporting to SVG is always the same. Furthermore, Inkscape produces an already cropped PDF. So this approach solves all my problems, just you need Inkscape.
You can try export_fig to export your figures. WYSIWYG! This function is especially suited to exporting figures for use in publications and presentations, because of the high quality and portability of media produced.
Why you don't like to use pdfcrop?
My code works perfectly, and everything is inside Matlab:
function prints(name)
%%Prints Print current simulink model screen and save as eps and pdf
print('-s', '-depsc','-tiff', name)
print('-s', '-dpdf','-tiff', name)
dos(['pdfcrop ' name '.pdf ' name '.pdf &']);
end
You just have to invoke pdfcrop using "dos" command, and it's works fine!
on 2021a you have exportgraphics.
beatiful pdf images.
figure(3);
plot(Time.Data,wSOHO_KpKi.Data,'-',Time.Data,Demanded_Speed.Data,'--');
grid;
xlh = xlabel('$\mathrm{t\left [ s \right ]}$','interpreter','latex',"FontSize",15);
ylh = ylabel('$\mathrm{\omega _{m}\left [ rads/s \right ]}$','interpreter','latex',"FontSize",15);
xlh.Position(2) = xlh.Position(2) - abs(xlh.Position(2) * 0.05);
ylh.Position(1) = ylh.Position(1) - abs(ylh.Position(1) * 0.01);
exportgraphics(figure(3),'Grafico de Escalon Inicial velocidad estimada por algoritmo SOHO-KpKi.pdf');