xlabel/ylabel 'HorizontalAlignment' issue

22 views (last 30 days)
Bruno Luong
Bruno Luong on 24 Nov 2023
Edited: Benjamin Kraus on 27 Nov 2023
I don't understand the 'HorizontalAlignment' of the text labels. It is not centered (when the figure has different size than the default?) in 3D.
Demo code:
I would expect the label is centered around xtick/ytick of 0. Obviously it is way off.
[X,Y,Z] = peaks(25);
fig = figure(1);
clf(fig);
set(fig, 'Units', 'pixel', 'Position', [1 41 1700 940]);
ax = axes(fig);
surf(ax, X, Y, Z);
view(ax, 3); % it works fine for view(ax, 2)
drawnow
xlabel(ax, 'here is the x-label', 'HorizontalAlignment', 'center');
ylabel(ax, 'here is the y-label', 'HorizontalAlignment', 'center');
Is it a bug or something I don't understand?

Answers (1)

Benjamin Kraus
Benjamin Kraus on 27 Nov 2023
Edited: Benjamin Kraus on 27 Nov 2023
The object used for the X-label and Y-label is the same text object that is created by the text command, and is a general purpose object that can be used for text anywhere in your axes.
The HorizonalAlignment and VerticalAlignment properties dictate two things:
  • How the text object is placed relative to its Position
  • How multiple lines of text are aligned with one another.
Consider this example, in which I create three text objects, with two lines of text in each text object, and different values of HorizontalAlignment and VerticalAlignment. I'm also adding a marker that shows the Position of each text object.
plot([0.25, 0.5 0.75],[0.25 0.5 0.75],'xr')
text(0.25, 0.25, ["T1: Long Word";"Short"],HorizontalAlignment='left',VerticalAlignment='bottom');
text(0.5, 0.5, ["T2: Long Word";"Short"],HorizontalAlignment='center',VerticalAlignment='middle');
text(0.75, 0.75, ["T3: Long Word";"Short"],HorizontalAlignment='right',VerticalAlignment='top');
xlim([0 1])
ylim([0 1])
You can see from the picture above the impact of HorizontalAlignment and VerticalAlignment. This behavior is true even for x-label, y-label, and title. In this next example, I'm querying the Position of the text objects, and drawing a marker at the Position assigned for each text object.
figure
t = title(["Long Word"; "Short"]);
xl = xlabel(["Long Word"; "Short"]);
yl = ylabel(["Long Word"; "Short"]);
hold on
xlim manual
ylim manual
x = [t.Position(1) xl.Position(1) yl.Position(1)];
y = [t.Position(2) xl.Position(2) yl.Position(2)];
plot(x,y,'rx', Clipping=false)
Now I'll draw the same picture, but change the HorizontalAlignment and VerticalAlignment of the text objects. You can see that:
  • The location of the red Xs have not moved.
  • But the alignment of the text relative to those red markers has changed.
figure
t = title(["Long Word"; "Short"],HorizontalAlignment='left',VerticalAlignment='top');
xl = xlabel(["Long Word"; "Short"],HorizontalAlignment='right',VerticalAlignment='bottom');
yl = ylabel(["Long Word"; "Short"],HorizontalAlignment='left',VerticalAlignment='middle');
hold on
xlim manual
ylim manual
x = [t.Position(1) xl.Position(1) yl.Position(1)];
y = [t.Position(2) xl.Position(2) yl.Position(2)];
plot(x,y,'rx', Clipping=false)
To summarize:
  • The axes automatically calculates the Position, HorizontalAlignment, and VerticalAlignment of the text objects used for the title, x-label, and y-label.
  • If you manually set either the Position, HorizontalAlignment, or VerticalAlignment of those text objects, the axes will still automatically calculate the remaining values, but it won't change the values you've set manually.
  • The axes does not change how it calculates the Position, even the HorizontalAlignment or VerticalAlignment have been modified.
  • The HorizontalAlignment and VerticalAlignment impact the alignment relative to the Position (in this case automatically calculated by the axes) not the alignment relative to the axes.
Things get a bit more complicated in 3D. The axes is calculating a position for the x-label and y-label that it thinks is a good location, both in terms of using space efficiently, and in terms of making the labels clearly assigned to specific axles. In this case, it has chosen to use space below and to the right of center (for the x-label) and left of center (for the y-label).
figure
view(3)
xl = xlabel(["Long Word"; "Short"]);
xl.HorizontalAlignment
ans = 'left'
xl.VerticalAlignment
ans = 'top'
yl = ylabel(["Long Word"; "Short"]);
yl.HorizontalAlignment
ans = 'right'
yl.VerticalAlignment
ans = 'top'
You can see from above that the default HorizontalAlignment of the x-label and y-label (respectively) is 'left' and 'right', and both have VerticalAlignment set to 'top'.
By changing the HorizonalAlignment to 'center', you are not assigning a different Position, you are simply moving the alignment of the text relative to the automatically chosen Position.
There is no automatic way to get the x-label and the y-label to be aligned with respect to a specific location on the x-axis or y-axis in 3D. Your only option is to manually position the text objects where you want them.

Categories

Find more on Measurements and Spatial Audio in Help Center and File Exchange

Products


Release

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!