How to label a plot in Matlab with combine label?
You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Show older comments
1 vote
Share a link to this question
It is hard to explaine here.
For example "peaks" is located second line and combine with "a" and "b".

Accepted Answer
0 votes
Option 1: use boxplotGroup()
See boxplotGroup() on the file exchange. If your boxplot data are matrices with the same number of columns, you can use this function to group them and provide primary and secondary labels.
Option 2: Use newline to create two rows of tick labels
Pro: Easy and clean
Con: Less control of the alignment between the upper and lower labels.
ax = axes();
xlim([0,12])
ticks = {'a_peaks','b','a_concat','b','a_F0','b','a_Fs','b'};
ticks = strrep(ticks,'_','\newline'); % replace underscore with \newline
ax.XTick = [1 2 4 5 7 8 10 11];
ax.XTickLabel = ticks;

This variation below controls the alignment between the upper and lower labels but adds an additional tick between the upper labels.
ax = axes();
xlim([0,12])
ticks = {'a','_peaks','b','a','_concat','b','a','_F0','b','a','_Fs','b'};
ticks = strrep(ticks,'_','\newline'); % replace underscore with \newline
ax.XTick = [1 1.5 2 4 4.5 5 7 7.5 8 10 10.5 11];
ax.XTickLabel = ticks;

Option 2.1: Use cell array with justified text
Added to answer 11-Feb-2021
Pro: Intuitive label arrangement & text justification
ax = axes();
xlim([0,12])
ticks = {'a','','b','a','','b','a','','b','a','','b'; ... % 1st row of labels
'','peaks','','','concat','','','F0','','','Fs',''}; % 2nd row of labels
ticksJust = strjust(pad(ticks),'center'); % Justify: 'left'(default)|'right'|'center
% ticksJust =
% 2×9 cell array
% {' a '} {' '} {' b '} {' a '} {' '} {' b '} {' a '} {' '} {' b '}
% {' '} {'peaks'} {' '} {' '} {'peaks'} {' '} {' '} {'peaks'} {' '}
tickLabels = strtrim(sprintf('%s\\newline%s\n', ticksJust{:}));
ax.XTick = [1 1.5 2 4 4.5 5 7 7.5 8 10 10.5 11];
ax.XTickLabel = tickLabels;

Option 3: Use text() to create a second row of tick lables
Pro: More control over the placement of the tick labels.
Con: Axis limits must be set and the lower tick labels will move if the pan feature is used.
ax = axes();
% Set axis limits before labeling
xlim([0,12])
ylim([0,1]);
% Shorten the height of the axes to 90% and shift
% upward to make room for the 2-layers of labels.
upperPosition = sum(ax.Position([2,4]));
ax.Position(4) = ax.Position(4) * .9;
ax.Position(2) = minus(upperPosition, ax.Position(4));
% label the upper row using xtick and xticklabel
ax.XTick = [1 2 4 5 7 8 10 11];
ax.XTickLabel = {'a' 'b'};
% use text() to creat the lower row of tick labels
% The 2nd layer will be 6% of the y axis range below the axis.
lowerLevel = min(ylim(ax))-range(ylim(ax))*.06;
lowerLabels = {'peaks','concat','F0','FS'};
text([1.5, 4.5, 7.5, 10.5], repmat(lowerLevel,1,numel(lowerLabels)), lowerLabels,...
'VerticalAlignment','Top','HorizontalAlignment','Center')

28 Comments
Matlaber
on 6 Mar 2020
Thanks. Can i ask if this applied to boxplot function?
I tried, but it not working well.
Adam Danz
on 6 Mar 2020
If you share the code you tried, I could help fix it.
Matlaber
on 6 Mar 2020
Thanks for your reply.
I not sure how to add in boxplot function
boxplot(rand(100,2),{'a','b'})
xlabel('Peaks','FontSize',12)
Adam Danz
on 6 Mar 2020
With this syntax, you only need to apply the 2nd row of labels since the first row is provided by the boxplot() function.
For example,
ax = gca();
lowerLevel = min(ylim(ax))-range(ylim(ax))*.06;
lowerLabels = {'peaks'}; % <--- define lower labels here
lowerLabelsX = [1.5]; % <--- define the x-position of each label
text(lowerLabelsX, repmat(lowerLevel,1,numel(lowerLabels)), lowerLabels,...
'VerticalAlignment','Top','HorizontalAlignment','Center')
Adam Danz
on 6 Mar 2020
Note that I've updated my answer with a new Option 1.
See the boxplotGroup() function on the file exchange
Matlaber
on 7 Mar 2020
Thanks. Your answer very good.
Can I ask how to lable 4 values like below:

boxplot(randn(4),{'a','b','c','d'})
xlabel('Peaks', 'Peaks2','FontSize',12)
To use the boxplotGroup() function, you just need to split the matrix up into a cell array which is demonstrated below.
data = randn(4);
splitData = {data(:,1:2), data(:,3:4)};
% or
% splitData = mat2cell(data, size(data,1), [2,2]);
boxplotGroup(splitData,'primaryLabels', {'a' 'b' 'c' 'd'}, 'SecondaryLabels', {'Peak', 'Peak1'})

If you're rather not have the horizontal space between groups, set "InterGroupSpace" to 0.
Matlaber
on 9 Mar 2020
Thanks, the function you created is brillant!
Between, if I add a y-axis, it seemed overlap with the y-axis label.
I didn't understand that last part about adding a y axis. Can you share a screen shot and a snippet of relevant code?
Matlaber
on 9 Mar 2020
Sorry for my bad English
data = randn(4);
splitData = {data(:,1:2), data(:,3:4)};
% or
% splitData = mat2cell(data, size(data,1), [2,2]);
boxplotGroup(splitData,'primaryLabels', {'a' 'b' 'c' 'd'}, 'SecondaryLabels', {'Peak11', 'Peak1'})
ylabel('Percentages')

Thanks for bringing that to my attention. I fixed that in the boxplotGroup() function and updated the file on the file exchange (version 1.2.0).
You can download the new version and the problem should be fixed.
Matlaber
on 9 Mar 2020
I should thanks you.
However, could you check again? I am not sure is my file loaded wrongly.
But the new code, y-axis does not show up.
data = randn(4);
splitData = {data(:,1:2), data(:,3:4)};
% or
% splitData = mat2cell(data, size(data,1), [2,2]);
boxplotGroup(splitData,'primaryLabels', {'a' 'b' 'c' 'd'}, 'SecondaryLabels', {'Peak11', 'Peak1'})
ylabel('Percentages')
It looks fine to me (screen shot below). What version of Matlab are you using? Are you sure you're using the newest version of boxplotGroup()?

Matlaber
on 9 Mar 2020
Hi, Thanks.
I am usng MATLAB R2017b and also I using the newest version of code.
Is below will give some hints why not working?
>> data = randn(4);
splitData = {data(:,1:2), data(:,3:4)};
% or
% splitData = mat2cell(data, size(data,1), [2,2]);
boxplotGroup(splitData,'primaryLabels', {'a' 'b' 'c' 'd'}, 'SecondaryLabels', {'Peak11', 'Peak1'})
ylabel('Percentages')
ans =
LinkProp with properties:
Enabled: 'on'
PropertyNames: {'Units' 'Position' 'ActivePositionProperty' 'Parent'}
Targets: [1×2 Axes]
No appropriate method, property, or field 'Toolbar' for class 'matlab.graphics.axis.Axes'.
Error in boxplotGroup (line 172)
h.axis2.Toolbar.Visible = 'off';
ah.... there is a version issue between r2017b and r2019b. Thanks again for bringing this to my attention.
I've update the file and you can download the most recent version 1.2.1. I've tested it on r2017b and r2016b.
Matlaber
on 9 Mar 2020
Thanks, it working very well.
Just one question. Regarding the range of boxplot between the function of "boxplot" and "boxplotGroup".
For example:
Using MALTAB function "boxplot", the y-axis start from 30 to 100.

Using "boxplotGroup" function, the y-axis start from 0 to 100.

%%
y = [33, 44, 67, 78, 80, 90, 99, 47];
boxplot(y,'Labels',{'1'})
%%
boxplotGroup(y)
Error using boxplotGroup
The value of 'x' is invalid. Expected input to be one of these types:
cell
Instead its type was double.
Error in boxplotGroup (line 95)
parse(p,varargin{:})
Error in Boxplot2 (line 129)
boxplotGroup(x)
Thanks.
If you execute
help('boxplotGroup')
you'll notice that the 'x' input should be a cell array.
% boxplotGroup(x) receives a 1xm cell array where each element is a matrix with
% n columns and produced n groups of boxplot boxes with m boxes per group.
Here's the correct way to set that up.
figure()
y = [33, 44, 67, 78, 80, 90, 99, 47];
ax1 = subplot(1,2,1);
boxplot(y);
ax2 = subplot(1,2,2);
boxplotGroup(ax2, {y(:)})
xlim(ax2, xlim(ax1)) % This just equates the scaling

Regarding the difference in the y-axis and x-axis limits between boxplot() and boxplotGroup(), that is expected. The limits are set within the boxplotGroup() function but you can change them as needed after the plots are produced.
Matlaber
on 9 Mar 2020
Thanks for your reply.
It is still a bit difficult for me. Not sure why still not working with the y-axis limit.
1. Using "boxplotGroup" function
a= [33.3333 100.0000 61.9048 95.2381;
57.1429 80.9524 66.6667 100.0000;
57.1429 85.7143 47.6190 95.2381;
42.8571 90.4762 52.3810 80.9524;
42.8571 95.2381 61.9048 85.7143;
57.1429 100.0000 71.4286 100.0000;
42.8571 100.0000 28.5714 85.7143;
61.9048 95.2381 76.1900 66.6667;
38.1000 100.0000 57.1429 76.1905;
71.4286 90.4762 52.3810 100.0000]
splitData = {a(:,1:2), data(:,3:4)};
boxplotGroup(splitData,'primaryLabels', {'a' 'b' 'c' 'd'}, 'SecondaryLabels', {'Range1', 'Range2'})
ylabel('Percentages')
Output:

2. Using function "boxplot"
a= [33.3333 100.0000 61.9048 95.2381;
57.1429 80.9524 66.6667 100.0000;
57.1429 85.7143 47.6190 95.2381;
42.8571 90.4762 52.3810 80.9524;
42.8571 95.2381 61.9048 85.7143;
57.1429 100.0000 71.4286 100.0000;
42.8571 100.0000 28.5714 85.7143;
61.9048 95.2381 76.1900 66.6667;
38.1000 100.0000 57.1429 76.1905;
71.4286 90.4762 52.3810 100.0000]
boxplot(a,'Labels',{'AM','b','a','c'})

Thanks.
The only significant difference in the figures you shared is the order the boxplots are in. See the inline comments below to produce an exact replication between the two functions.
% Input data
a= [33.3333 100.0000 61.9048 95.2381;
57.1429 80.9524 66.6667 100.0000;
57.1429 85.7143 47.6190 95.2381;
42.8571 90.4762 52.3810 80.9524;
42.8571 95.2381 61.9048 85.7143;
57.1429 100.0000 71.4286 100.0000;
42.8571 100.0000 28.5714 85.7143;
61.9048 95.2381 76.1900 66.6667;
38.1000 100.0000 57.1429 76.1905;
71.4286 90.4762 52.3810 100.0000]
% ******* boxplotGroup setup *******
% Note that the columns of 'a' are rearranged in the line below.
splitData = {a(:,[1,3]), a(:,[2,4])};
% Plot results
figure()
boxplotGroup(splitData,'primaryLabels', {'a' 'b' 'c' 'd'}, ...
'SecondaryLabels', {'Range1', 'Range2'}, 'interGroupSpace', 0)
% this section here ^^^^^^^^^^^^^^^^^^^^
% removes the space between the box groups
ylabel('Percentages')
grid on
ylim([25, 104])
% ******* boxplot setup *******
figure()
boxplot(a,'Labels',{'a' 'b' 'c' 'd'})
grid on
ylim([25, 104])

Matlaber
on 10 Mar 2020
Thanks. Brillant!
Is there a way to increase the label font size?
With this below, only the first line font increase.
set(gca,'FontSize',13)
Adam Danz
on 10 Mar 2020
Use the outputs
h = boxplotGroup(. . . );
set(h.axis,'FontSize',13)
set(h.axis2,'FontSize',13)
Matlaber
on 10 Mar 2020
It works well. Thanks.
Adam Danz
on 10 Mar 2020
Glad I could help. Thanks for testing the boxplotGroup function and providing feedback.
Matlaber
on 10 Mar 2020
my pleasure. I also leave a good comment on your function too.
Adam Danz
on 10 Mar 2020
Thank you!!
Matlaber
on 30 Apr 2020
Will it be possible to make one of the words in tha label in italic font?
From
boxplot(a,'Labels',{'a' 'b' 'c' 'd'})
to
boxplot(a,'Labels',{\it'a' 'b' 'c' 'd'})
Adam Danz
on 30 Apr 2020
ax.XAxis.FontAngle = 'italic';
where ax is your axis handle.
If you want 2 groups with 3 boxplots per group, your input will be a 1x3 cell array.
Each of the 3 cells will should contain 2 columns where column 1 are the data for the first boxplot of each group, column 2 are the data for the 2nd boxplot for each group
splitdata = {c(:,[1,4]),c(:,[2,5]),c(:,[3,6])};
Please let me know if you have any problems or need more clarification.
More Answers (1)
Akira Agata
on 6 Mar 2020
0 votes
I believe the simple way is to separate the plot for each group and use xlabel to add 'Peaks', 'Concat', etc.
The following is an example:
figure
subplot(1,2,1)
boxplot(rand(100,2),{'a','b'})
xlabel('Peaks','FontSize',12)
subplot(1,2,2)
boxplot(rand(100,2),{'a','b'})
xlabel('Concat','FontSize',12)

1 Comment
Matlaber
on 7 Mar 2020
Thanks. Is there a away to combine both boxplot together?
Categories
Find more on Measurements and Feature Extraction in Help Center and File Exchange
Tags
See Also
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)