- Undocumented Matlab - https://undocumentedmatlab.com -

Customizing axes part 5 – origin crossover and labels

Posted By Yair Altman On July 27, 2016 | 13 Comments

When HG2 graphics was finally released in R2014b, I posted a series of articles about various undocumented ways by which we can customize Matlab’s new graphic axes: rulers (axles) [1], baseline, box-frame, grid [2], back-drop [3], and other aspects [4]. Today I extend this series by showing how we can customize the axes rulers’ crossover location.

Non-default axes crossover location
Non-default axes crossover location

The documented/supported stuff

Until R2015b, we could only specify the axes’ YAxisLocation as 'left' (default) or 'right', and XAxisLocation as 'bottom' (default) or 'top'. For example:

x = -2*pi : .01 : 2*pi;
plot(x, sin(x));
hAxis = gca;
hAxis.YAxisLocation = 'left';    % 'left' (default) or 'right'
hAxis.XAxisLocation = 'bottom';  % 'bottom' (default) or 'top'

Default axis locations: axes crossover is non-fixed
Default axis locations: axes crossover is non-fixed

The crossover location is non-fixed in the sense that if we zoom or pan the plot, the axes crossover will remain at the bottom-left corner, which changes its coordinates depending on the X and Y axes limits.
Since R2016a [5], we can also specify 'origin' for either of these properties, such that the X and/or Y axes pass through the chart origin (0,0) location. For example, move the YAxisLocation to the origin:

hAxis.YAxisLocation = 'origin';

Y-axis location at origin: axes crossover at 0 (fixed), -1 (non-fixed)
Y-axis location at origin: axes crossover at 0 (fixed), -1 (non-fixed)

And similarly also for XAxisLocation:

hAxis.XAxisLocation = 'origin';

X and Y-axis location at origin: axes crossover fixed at (0,0)
X and Y-axis location at origin: axes crossover fixed at (0,0)

The axes crossover location is now fixed at the origin (0,0), so as we move or pan the plot, the crossover location changes its position in the chart area, without changing its coordinates. This functionality has existed in other graphic packages (outside Matlab) for a long time and until now required quite a bit of coding to emulate in Matlab, so I’m glad that we now have it in Matlab by simply updating a single property value. MathWorks did a very nice job here of dynamically updating the axles, ticks and labels as we pan (drag) the plot towards the edges – try it out!

The undocumented juicy stuff

So far for the documented stuff. The undocumented aspect is that we are not limited to using the (0,0) origin point as the fixed axes crossover location. We can use any x,y crossover location, using the FirstCrossoverValue property of the axes’ hidden XRuler and YRuler properties. In fact, we could do this since R2014b, when the new HG2 graphics engine was released, not just starting in R2016a!

% Set a fixed crossover location of (pi/2,-0.4)
hAxis.YRuler.FirstCrossoverValue = pi/2;
hAxis.XRuler.FirstCrossoverValue = -0.4;

Custom fixed axes crossover location at (π/2,-0.4)
Custom fixed axes crossover location at (π/2,-0.4)

For some reason (bug?), setting XAxisLocation/YAxisLocation to ‘origin’ has no visible effect in 3D plots, nor is there any corresponding ZAxisLocation property. Luckily, we can set the axes crossover location(s) in 3D plots using FirstCrossoverValue just as easily as for 2D plots. The rulers also have a SecondCrossoverValue property (default = -inf) that controls the Z-axis crossover, as Yaroslav pointed out [6] in a comment below. For example:

N = 49;
x = linspace(-10,10,N);
M = peaks(N);
mesh(x,x,M);

Default crossover locations at (-10,±10,-10)
Default crossover locations at (-10,±10,-10)

hAxis.XRuler.FirstCrossoverValue  = 0; % X crossover with Y axis
hAxis.YRuler.FirstCrossoverValue  = 0; % Y crossover with X axis
hAxis.ZRuler.FirstCrossoverValue  = 0; % Z crossover with X axis
hAxis.ZRuler.SecondCrossoverValue = 0; % Z crossover with Y axis

Custom fixed axes crossover location at (0,0,-10)
Custom fixed axes crossover location at (0,0,-10)

hAxis.XRuler.SecondCrossoverValue = 0; % X crossover with Z axis
hAxis.YRuler.SecondCrossoverValue = 0; % Y crossover with Z axis

Custom fixed axes crossover location at (0,0,0)
Custom fixed axes crossover location at (0,0,0)

Labels

Users will encounter the following unexpected behavior (bug?) when using either the documented *AxisLocation or the undocumented FirstCrossoverValue properties: when setting an x-label (using the xlabel function, or the internal axes properties), the label moves from the center of the axes (as happens when XAxisLocation=’top’ or ‘bottom’) to the right side of the axes, where the secondary label (e.g., exponent) usually appears, whereas the secondary label is moved to the left side of the axis:

Unexpected label positions
Unexpected label positions

In such cases, we would expect the labels locations to be reversed, with the main label on the left and the secondary label in its customary location on the right. The exact same situation occurs with the Y labels, where the main label unexpectedly appears at the top and the secondary at the bottom. Hopefully MathWorks will fix this in the next release (it is probably too late to make it into R2016b, but hopefully R2017a). Until then, we can simply switch the strings of the main and secondary label to make them appear at the expected locations:

% Switch the Y-axes labels:
ylabel(hAxis, '\times10^{3}');  % display secondary ylabel (x10^3) at top
set(hAxis.YRuler.SecondaryLabel, 'Visible','on', 'String','main y-label');  % main label at bottom
% Switch the X-axes labels:
xlabel(hAxis, '2^{nd} label');  % display secondary xlabel at right
set(hAxis.XRuler.SecondaryLabel, 'Visible','on', 'String','xlabel');  % main label at left

As can be seen from the screenshot, there’s an additional nuisance: the main label appears a bit larger than the axes font size (the secondary label uses the correct font size). This is because by default Matlab uses a 110% font-size for the main axes label, ostensibly to make them stand out. We can modify this default factor using the rulers’ hidden LabelFontSizeMultiplier property (default=1.1). For example:

hAxis.YRuler.LabelFontSizeMultiplier = 1;   % use 100% font-size (same as tick labels)
hAxis.XRuler.LabelFontSizeMultiplier = 0.8; % use 80% (smaller than standard) font-size

Note: I described the ruler objects [1] in my first article of the axes series. Feel free to read it for more ideas on customizing the axes rulers.

Categories: Handle graphics, Low risk of breaking in future versions, Stock Matlab function, Undocumented feature


13 Comments (Open | Close)

13 Comments To "Customizing axes part 5 – origin crossover and labels"

#1 Comment By Yaroslav On July 28, 2016 @ 00:36

Hi Yair,

Great post yet again. It is worth mentioning that your methods can be extended to 3 dimensional plots, which are currently unsupported. For example,

% Plot Peaks
N = 49;
x = linspace(-10,10,N);
M = peaks(N);
%
mesh(x,x,M);
%

% Set a fixed crossover location of (0,0,0)
hAxis = gca;
hAxis.XRuler.FirstCrossoverValue  = 0; % crossover with Y axis
hAxis.YRuler.FirstCrossoverValue  = 0; % crossover with X axis
%
hAxis.ZRuler.FirstCrossoverValue  = 0; % crossover with X axis
hAxis.ZRuler.SecondCrossoverValue = 0; % crossover with Y axis

#2 Comment By Yair Altman On July 28, 2016 @ 10:44

@Yaroslav – thanks! I updated the text accordingly.

#3 Comment By Guillaume De Lescluze On November 6, 2016 @ 10:08

Hi Yarasov/Yair,

Context: I am using R2015a to display a ternary three-dimensional plot, so I have a base equilateral triangle and a vertical axis on top of this.

My question: When copying the above code in Matlab, I get an error when using the “ZRuler” command.

Do you have an idea why it might not be working in my case?

Many thanks!

#4 Comment By Frank Brown On August 17, 2016 @ 17:34

Yair,

Great site!

I have been moving axes to cross at the origin as part of plotting for years and I’m glad to see MATLAB adopt this capability. One question though.

How could I make this the default behavior?

set(0,'defaultYAxisLocation','origin')  % does not work.
 

Does not work in 2015b, though the property exists and can be modified. Also similar syntax works for other axes properties (‘DefaultAxesLineWidth’).

Thanks for the help,
Frank

#5 Comment By Yair Altman On August 17, 2016 @ 21:25

@Frank –

set(0,'defaultAxesYAxisLocation','origin')

(you forgot the “Axes” part in ‘defaultAxesYAxisLocation’)

#6 Comment By Sarah On August 9, 2018 @ 19:54

Thank you!

#7 Comment By Reza On October 22, 2019 @ 17:08

Hi Yair,
Great post. i tried to rotate the axes in a 3d graph in Matlab. but i couldn’t do that. i have two Point Cloud, which i need to calculate the distance between them. As result want to represent it in a Heatmap with a coded Colormap. My project have Orientation according to the global cartesian coordinate system (measured with Totalstation scanner). I monitor facade of a Building (detect Moving in x,z plane). I want to change the Orientation of my Point cloud along x, y and z to have a good front view of the Project (not distorted). how can i rotate the Axes suitable to my project? Thanks for your help.

#8 Comment By Yair Altman On October 22, 2019 @ 17:43

Reza – try using the view function.

#9 Comment By Reza On October 27, 2019 @ 21:16

Thank you Yair!
In order to analyze the deformation of a surface, I would like to monitor this surface (facade of a building) every 2 hours, for example. so I get every 2 hours a point cloud I have to compare with a reference 3d-surface. How can I represent the distance between the surface and the point cloud as a colored figure?
I couldnt find any method or function in matlab to do that.
do you Any idea to do this?
I would be grateful for a answer, help, ideas or suggestions.

#10 Comment By Vinicius On March 21, 2021 @ 20:49

I would just like to thank you for your fantastic work. I was looking for ages for a SIMPLE way to do this!

#11 Comment By Nitin On August 2, 2021 @ 20:48

Thanks for the great help

#12 Comment By Sagar Chawla On April 3, 2022 @ 19:19

I want to know how to change the x-axis to the z-axis. I mean the position. Like if there is a 3d animated graph then how to change position of the axis. X-axis in place of Z-Axis & Y- axis in place of Z-axis and Z in place of Y.

#13 Comment By Yair Altman On April 3, 2022 @ 19:25

@Sagar – use the view(az,el) function to rotate the 3D axes.


Article printed from Undocumented Matlab: https://undocumentedmatlab.com

URL to article: https://undocumentedmatlab.com/articles/customizing-axes-part-5-origin-crossover-and-labels

URLs in this post:

[1] rulers (axles): http://undocumentedmatlab.com/blog/customizing-axes-rulers

[2] baseline, box-frame, grid: http://undocumentedmatlab.com/blog/customizing-axes-part-2

[3] back-drop: http://undocumentedmatlab.com/blog/customizing-axes-part-3-backdrop

[4] other aspects: http://undocumentedmatlab.com/blog/customizing-axes-part-4-additional-properties

[5] Since R2016a: http://www.mathworks.com/help/matlab/ref/axes-properties.html#property_xaxislocation

[6] pointed out: http://undocumentedmatlab.com/blog/customizing-axes-part-5-origin-crossover-and-labels#comment-384290

[7] Customizing axes tick labels : https://undocumentedmatlab.com/articles/customizing-axes-tick-labels

[8] Customizing axes rulers : https://undocumentedmatlab.com/articles/customizing-axes-rulers

[9] Customizing axes part 2 : https://undocumentedmatlab.com/articles/customizing-axes-part-2

[10] Customizing axes part 4 – additional properties : https://undocumentedmatlab.com/articles/customizing-axes-part-4-additional-properties

[11] Customizing axes part 3 – Backdrop : https://undocumentedmatlab.com/articles/customizing-axes-part-3-backdrop

[12] Setting axes tick labels format : https://undocumentedmatlab.com/articles/setting-axes-tick-labels-format

Copyright © Yair Altman - Undocumented Matlab. All rights reserved.