File Exchange

image thumbnail

phymhan/matlab-axis-label-alignment

version 1.7.0.0 (144 KB) by Ligong Han
Align axis labels nicely in parallel with axes in MATLAB (3-D) plots.

37 Downloads

Updated 23 Dec 2017

GitHub view license on GitHub

Editor's Note: This file was selected as MATLAB Central Pick of the Week

This is a simple MATLAB function for axis label alignment. It still works when Projection mode is Perspective or when DataAspectRatio is not [1 1 1].
## Functions
- `align_axislabel`: it rotates $x$, $y$ and $z$ labels to the direction of their corresponding axes and moves the labels to a proper distance from the axes;
- `align_axislabel_log`: supports log-scale in $z$ axis;
- `axislabel_rotation`: it performs rotation only;
- `axislabel_rotation_angle`: it computes the angles of $x$, $y$ and $z$ labels to be rotated properly (without performing the actual rotation);
- `axislabel_translation`: it moves axis labels to a proper distance from the axes;
- `axislabel_translation_slider`: a GUI slider for setting parameters `AXISALIGN_TRANS_A` and `AXISALIGN_TRANS_B`.
## Common usage
Label alignment plus GUI slider:
```
z = peaks;
figure('color', [1 1 1])
surf(z);
set(gca, 'dataaspectratio', [1 1 0.5], 'projection', 'perspective', 'box', 'on')
xlabel('This is an x label', 'fontsize', 16, 'fontweight', 'bold', 'color', [1 0 0])
ylabel('This is a y label', 'fontsize', 16, 'fontweight', 'bold', 'color', [0 0 0])
zlabel('This is a z label', 'fontsize', 16, 'fontweight', 'bold', 'color', [0 0 1])

% Add the following after you plot your figures
h = rotate3d;
set(h, 'ActionPreCallback', 'set(gcf,''windowbuttonmotionfcn'',@align_axislabel)')
set(h, 'ActionPostCallback', 'set(gcf,''windowbuttonmotionfcn'','''')')
set(gcf, 'ResizeFcn', @align_axislabel)
align_axislabel([], gca)
axislabel_translation_slider;

```

See `demo.m` for more information.

Cite As

Ligong Han (2020). phymhan/matlab-axis-label-alignment (https://github.com/phymhan/matlab-axis-label-alignment), GitHub. Retrieved .

Comments and Ratings (32)

Ashutosh Kumar Gupta

Tingrui Liu

hi @Ligong Han, it has some mistake when it is used in the function "bar3" in the matlab, i need you help

Tao Yang

Thank you for sharing. The function works well on Matlab_2018b.

Hao Huang

Chris L'Esperance

Can use something simple like the following, adjust dx and dy as necessary.

dx = 0.5;
dy = 0.5;
x_axis_label_pos = get(xlh, 'Position');
x_axis_label_pos(1,1) = x_axis_label_pos(1,1) + dx;
x_axis_label_pos(1,2) = x_axis_label_pos(1,2) + dy;
set(xlh, 'Position', x_axis_label_pos);

Ligong Han

Hi @mukund, you can follow the second example by add the following:

h = rotate3d;
set(h, 'ActionPreCallback', 'set(gcf,''windowbuttonmotionfcn'',@align_axislabel)')
set(h, 'ActionPostCallback', 'set(gcf,''windowbuttonmotionfcn'','''')')
set(gcf, 'ResizeFcn', @align_axislabel)
align_axislabel([], gca)
axislabel_translation_slider;

then you should be able to move labels by adjusting the sliders.

Mukund

Thanks for sharing. The code works fine. I want labels to be slightly closer to axis. How this can be achieved.

Works fantastic on 2017a, thanks!

Allan Albuquerque

hi @Ligong Han. Thank you for you help. I tried the demo code below but xlabel and ylabel has not rotated to align. How can I solve this?

%% Demo of setting text properties
% Perspective, DataAspectRatio = [1 1 0.5]
z = peaks;
figure('color',[1 1 1])
surf(z);
set(gca,'dataaspectratio',[1 1 0.5],'projection','perspective','box','on')
xlabel('This is an x label','fontsize',16,'fontweight','bold','color',[1 0 0])
ylabel('This is a y label','fontsize',16,'fontweight','bold','color',[0 0 0])
zlabel('This is a z label','fontsize',16,'fontweight','bold','color',[0 0 1])
get(gca,'dataaspectratio')
set(gca,'dataaspectratio',ans)
h = rotate3d;
set(h,'ActionPostCallback',@align_axislabel)

Ligong Han

Hi @Simon L, thanks for catching that. The code doesn't work because in your example the `YDir` property of the axes becomes 'reverse', and I haven't thought about this situation. A quick fix would be set `YDir` back to 'normal':
>> set(gca, 'ydir', 'normal');
This is of course not an elegant solution. I might update the code sometime.

Simon L

Hi @Ligong Han ! This tool does not work correctly with the function "bar3" (I have Matlab R2016b in Win64).

The xlabel, ylabel and zlabel are rotated correctly, but they are close to the wrong axis.
To better understand what I mean please check your example by using "bar3(z)" instead of "surf(z)".

Here following the code. What do you think ?

Limo

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
z = peaks;
figure('color', [1 1 1])
% surf(z);
bar3(z);
set(gca, 'dataaspectratio', [1 1 0.5], 'projection', 'perspective', 'box', 'on')
xlabel('This is an x label', 'fontsize', 16, 'fontweight', 'bold', 'color', [1 0 0])
ylabel('This is a y label', 'fontsize', 16, 'fontweight', 'bold', 'color', [0 0 0])
zlabel('This is a z label', 'fontsize', 16, 'fontweight', 'bold', 'color', [0 0 1])

% Add the following after you plot your figures
h = rotate3d;
set(h, 'ActionPreCallback', 'set(gcf,''windowbuttonmotionfcn'',@align_axislabel)')
set(h, 'ActionPostCallback', 'set(gcf,''windowbuttonmotionfcn'','''')')
set(gcf, 'ResizeFcn', @align_axislabel)
align_axislabel([], gca)
axislabel_translation_slider;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

hypmfrcl

Still do not work if axis are not equal....

Ligong Han

Hi @Caster Troy, thanks for comments. If only z axis is log scale, there's a quick fix. I added align_axislabel_log.m (please see the 4th example above).

Ligong Han

Hi @Leo Simon, thanks for comments. Please see the latest example for subplots.

Leo Simon

Thanks very much for this contribution, I've been wanting something like this for a *long* time. It's seems to be having trouble with subplots, as the following example code illustrates. Alignment for the full plot is perfect, but is off for the subplot. Do you have a fix for this? Thanks! Leo

Z = peaks;
surf(Z);
xlabel('x label');
ylabel('y label');
zlabel('z label');
ax = struct('Axes', gca);
align_axislabels([],ax)


figure
subplot(2,1,1);
surf(Z);
xlabel('x label');
ylabel('y label');
zlabel('z label');
ax = struct('Axes', gca);
align_axislabels([],ax)

Caster Troy

Function doesn't work correct, when axes are log :-(

Nicholas Fette

Ligong Han

Hi @Oscar, sorry I don't have MATLAB 2016a available for testing, but your code works on my 2015a (Win64).

Oscar

Thanks for your quick response.
Well, I tried that but then the labels disappear. I am using Matlab 2016a on Win64 if it matters.

--- code
figure
axes;
xlabel('x')
ylabel('y')
zlabel('z')
n = 90;
el = 30*ones(1, n);
az = linspace(0, 180, n);
ax = struct('Axes', gca);
for k = 1:n
view([az(k) el(k)]);
align_axislabels([], ax)
drawnow
pause(0.1)
end
---/code

Thanks
/Oscar

Ligong Han

Hi @Oscar, sorry for the confusion of the function naming. You can just call align_axislabels instead of axislabel_rotation. Then labels would be rotated and translated.

For example,

n = 100;
el = 30*ones(1, n);
az = linspace(0, 180, n);
ax = struct('Axes', gca);
for k = 1:n
view([az(k) el(k)]);
align_axislabels([], ax)
pause(0.1)
end

Oscar

Hi

I want to use this code to automatically align the labels from the code. I have a loop that changes the view for every iteration and I want the labels to change with the angle.

I tried to call
'axislabel_rotation([],gca)'
and in the function set
'h_a=gca;'
on row 16.

It kind of works, but the zlabel gets really close to the z-axis and the fix you mentioned below does not work since the function 'axislabel_translation.m' is not called at all.

Also, the letters in the labels seem to jump a bit so that they are not relly aligned to eachother. But maybe this is how it is?

Regards
Oscar

Ligong Han

Hi @Jianwei Tu, thank you for the feedback. For your question, a quick fix is to reset the DataAspectRatio of your plot (or axes to be precise). For example, you can add the following line in your code:

>> set(gca,'DataAspectRatio', get(gca,'DataAspectRatio'))

The problem seems to be caused by some strange behavior when MATLAB renders a picture. You can do a quick experiment here:

Plot a surface, and add x y labels:
>> surf(peaks); xlabel('this is an x label'); ylabel('this is a y label');
Get the data aspect ratio of the axes:
>> get(gca,'dataaspectratio')
Now if you set 'dataaspectratio' as the same value as what it is previously, your plot will change:
>> set(gca,'dataaspectratio',ans)

I think this is the reason why axis labels are misaligned in your case, but I don't know why it happens. A common practice is to always set the 'DataAspectRatio' to some value explicitly, so that the labels should be aligned nicely. Thanks!

Jianwei Tu

@Ligong Han, Thank you for your answer. Your first suggestion works well to solve the z axis label problem that I had. But the x and y axis label alignment issue still exists. I am not an expert at all in Matlab. When I run the example you gave here, the x and y axis labels were fine, but when I run the following codes:

figure
X = linspace(0,1,10);
Y = X./2;
Z = sin(X) + cos(Y);
stem3(X,Y,Z,'fill')
xlabel('This Is Going to Be a Long Title!');
ylabel('This Is Going to Be a Long Title!');
zlabel('This Is Going to Be a Long Title!');
h = rotate3d;
set(h,'ActionPostCallback',@align_axislabels)

and rotated the 3D plot to (Az:45 El:45) position, both x and y axis labels formed a 10-20 degree angle with x and y axes, instead of being parallel with them, which is really strange. I don't see too much difference in the example codes here and my given codes.

Ligong Han

Hi @Jianwei Tu, thanks for your feedback! For your first question, you can comment out the code from line 259 to 261 in align_axislabels.m or always add 180 degrees to theta_z, if you wish; for the second question, how off are label and axis misaligned? I'm not sure why this happens but theoretically the calculation should be correct. If you have any questions please let me know. Thanks.

Jianwei Tu

Jianwei Tu

Hi @Ligong Han, This is great work you have done!! Exactly what I am looking for!
I had the same issue as Anthony did with larger font size label coinciding with label ticks, but I fixed it using your suggestion, i.e., increasing the A and B values.
However, I also found that after I rotate the 3D figures, (1.) z axis label got turned 180 degrees around its center, and (2) the x and y labels were not exactly aligned with x and y axes. What would you suggest to fix these two problems?
Thank you so much again for your great work!!!

Ligong Han

Hi, @jasongrig, thanks for your comment. What do you mean by "all over the place"? I haven't tested it on 2013a.

jasongrig

hi, i am afraid your function does not work on matlab R2013a. I copy-pasted your example in the description and the labels are all over the place. Any ideas?

Ligong Han

Thanks @Anthony There are two parameters you can change to avoid this problem: you can adjust (increase) the value of A and B in line 42 and 43 in axislabel_translation.m (the latest version), for example, A = 1.25, B = 3. The definition of A and B is in line 41.

Anthony

Very nice job, thanks a lot for sharing this :-)
There is only a minor problem (I am using R2015a): when I increase the font size, the labels cover the axes TickLabels. I guess it is very hard to take into account all the possibilities. Is there a way to manually control the spacing between the label and the ticklabels (or is there a parameter I could change in your code)?

Ligong Han

Thanks @4st4rl04 It's true that axis labels appear only if you rotate the figure manually. But it is because you set 'projection' to 'perspective'. If you don't want to change the default view angle, you can click the 'Rotate 3D' button and click the figure rather than rotate it so that the callback function will be called without changing the azimuth and elevation of view.

4st4rl04

Hi, this doesn't seem to work on MATLAB 2014a on my Mac. The figure of the example only shows the labels once I rotate the figure manually, and it looks funny even then.

Updates

1.7.0.0

- updates examples

1.6.0.0

- Adds GUI slider for parameter setting (controlling translation behaviour)

1.5.0.0

- Log scale on z axis

1.5.0.0

- Adds example for subplots

1.5.0.0

- Changes align_axislabel.m back to align_axislabels.m, sorry for the confusion
- Fixes typos in examples

1.5.0.0

- Adds check for class of 'ax' in align_axislabel.m
- Adds a new example where axis labels are updated/aligned as you rotate the plot simultaneously

1.4.0.0

- Adds a trans_mode option

1.4.0.0

- Revised for R2014b

1.3.0.0

- Modified the method to move labels to avoid potential overlap;
- Modified parameters in axis_translation.

1.2.0.0

- Modified the direction of axis label translation

1.1.0.0

- Added a function for translation
- Updated descriptions

MATLAB Release Compatibility
Created with R2016a
Compatible with any release
Platform Compatibility
Windows macOS Linux
Acknowledgements

Inspired by: Align axes labels in 3D plot