MatLab: set function arguments - matlab

I have found this line of MatLab code on the internet that displays a figure window in fullscreen:
set(figure(1),'Units','Normalized','OuterPosition',[0 0 1 1])
It works perfectly, and my question isn't regarding any problems here; it is instead regarding some explanation of it. You see, I don't understand the code line. Can anybody explain to me the arguments in this?
figure(1) is my figure handler - the current figure window - I understand that. But the rest of the arguments are confusing me. What does Units, Normalized and OuterPosition do, and what is the vector [0 0 1 1] specifying?
I have found the code line here: source (see the latest answer).
I'm having big trouble decrypting the help info provided by the help set command in MatLab. The MathWorks website weren't better and had no exampls of this that I could find.
Does anyone have some explanation or do you know where to find some understandable info?
Note
Alternatively, does anyone know of a better method for displaying a plot window or figure window in fullscreen? I need to be able to understand the method, or else I can't use it.

The arguments are considered "property-value pairs".
The first pair, 'Units', 'Normalized', tells the figure that you'll be giving it normalized values (between 0 and 1) rather than other options - pixels or inches, for example.
The second pair, 'OuterPosition', [0 0 1 1], tells it that you want to position the figure with the lower left (outside) corner at (0,0) with a width and height of (1,1). Since you indicated that units are normalized, (0,0) means the lower left corner of the screen, and (1,1) means the full height and width of the screen.
Property-value pairs allows you to pass in some relevant information but not other stuff for which the default is fine, and makes the order in which you do so flexible. It is a widely-used system in MATLAB.

Related

Irregular scaling of MATLAB figure axes

During my work, I got the figure shown below
It is clear that it turns out to be a mess below 5 on the y-axis. What I want to do, is to "expand" the y-axis only in the range from 3 to 5 such that the lines are separated and can be clearly distinguished.
I tried using set(gca, 'Xtick', [0 1 2 3:.5:5 5:25]) but this didn't help at all.
Any hint is appreciated.
What I got is as shown in the figure below:
Since I am getting my data through iterative loops and even sub-loops, I couldn't manage to get the desired figure using "inset plot", it got so complicated. However, what I did is simply that I had two MATLAB figures, the original one and another copy of it with a zoom-in of the y-axis from 3.5 to 5, then I copied the zoomed one to the original one and that's it.
This practice is better than using power point or paint to get the figure since doing so in MATLAB gives MUCH more flexibility in terms of editing the two figures, resizing them, axes labeling and so on.
Hope this would help someone else.

Matlab: create lines with equal physical length along each axis

I want to make scale bars with ticks, and I want the ticks on the X and Y bars to have the same physical length, regardless of the relative lengths, dimensions, or "modes" of the axes (at least at the time the ticks are created). I was hoping that daspect() would give me the information I need for this, but daspect() seems to be mostly useless for interrogating aspect ratio. For instance, if I generate a plot that Matlab gives an XLim of [0 3.5] and a YLim of [0 1], then daspect() gives [3.5 1 ...] regardless of how I have the figure sized on the screen. That's obviously not accurate or helpful. Is there another function, or maybe a way to make daspect() give useful information without manipulating the plot?
daspect() returns garbage on a typical plot. It's because of the stretch-to-fill feature, which distorts the plot to fill up the figure space, rendering the values in DataAspectRatio inaccurate. Instructions for turning off stretch-to-fill can be found here.
I also found a workaround if you want to leave stretch-to-fit on, which is to temporarily set PlotBoxAspectRatioMode to 'manual,' which has the effect of changing the value of DataAspectRatio to match what is on screen.
figure;plot(0.1:0.1:pi,sin(0.1:0.1:pi))
pbaspect manual
val = daspect
pbaspect auto
Or a safer way to do it if you want a generally useful script (e.g. in case PlotBoxAspectRatioMode is already manual and you don't want to change that) would be:
pbaspectMode = get(gca,'PlotBoxAspectRatioMode');
pbaspect manual;
val = daspect;
set(gca,'PlotBoxAspectRatioMode',pbaspectMode);
I'm not sure whether this will have any intermittent or pernicious side effects, however.
According to The Mathworks support:
The technique of setting bpaspect to manual and then back may be "safe" (although I wouldn't be surprised if there are side effects), but a better way is to divide:
real_daspect = daspect./pbaspect;

Why is errorbar whisker length dependent on X

I am running a simulation in Matlab 2015 which creates data each round, so I am plotting a number of single errorbar series individually. Here's a sample code and the output plot:
figure
xlim([0 30])
hold on
errorbar(1,2.0,1.9,16.5,'x')
errorbar(15,2.0,1.9,16.5,'x')
errorbar(25,2.0,1.9,16.5,'x')
errorbar(10,2.0,1.9,16.5,'x')
errorbar(30,2.0,1.9,16.5,'x')
errorbar(5,2.0,1.9,16.5,'x')
errorbar(20,2.0,1.9,16.5,'x')
The weirdness is that the whisker length appears to be dependent on my X value. As you can see it increases from left to right, even though I did not plot them from left to right. The single-sided width of each whisker is 0.01*x.
Why is this happening, and how can I fix it? This doesn't seem like intended functionality. Ideally I would just manually set the width of each whisker, but I can't find a way to do that. There was a function posted on the MFX a while back, but that was made for R2007b and no longer works. The errorbar series properties do not give any indication that the whiskers can even be affected at all. Any help here would be greatly appreciated!

How do I make a Matlab plot fill the whole page?

I want to make a plot in Matlab which is twice as tall as it is long. I tried following the advice of this question using Position and PaperPositionMode, like so:
figure
set(gcf,'PaperPositionMode','auto');
set(gcf, 'Position', [0 0 100 200]);
barh(1:20);
print('test', '-dpng');
Annoyingly, this resizes the paper size but not the plot, as below.
Is there any way to make a graph with specified width and height? I'm running this on a headless server so clicking and dragging, or any other GUI-specific solutions, aren't an option. Obviously I don't actually want a 100x200 plot, I just wanted to make the figure small enough to fit nicely into the question.
You might try setting the paper size and units. There's a similar question on Mathworks. Relevant content:
set(0,'defaultfigurepaperunits','inches');
set(0,'defaultfigurepaperorientation','landscape');
set(0,'defaultfigurepapersize',[8.5 11]);
set(0,'defaultfigurepaperposition',[.25 .25 [8.5 11]-0.5]);
where set(0, ...) sets the root graphics system values. You could also use your figure instead. Hope this helps.
Alternative approach reference the documentation for figure(). Uses the units & outerposition properties.
figure('units','normalized','outerposition',[0 0 1 1])
See also the position property for another approach.

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: