View License

Download apps, toolboxes, and other File Exchange content using Add-On Explorer in MATLAB.

» Watch video

Highlights from
rotateXLabels( ax, angle, varargin )

4.7 | 43 ratings Rate this file 90 Downloads (last 30 days) File Size: 18.1 KB File ID: #27812 Version:
image thumbnail

rotateXLabels( ax, angle, varargin )


Ben Tordoff (view profile)


01 Jun 2010 (Updated )

Rotate x-tick labels to any angle, preserving font settings and coping with resize, zoom, pan etc

| Watch this File

File Information

<b>NB: As of R2014b this functionality is built into MATLAB axes using the 'XTickLabelRotation' property.</b>
This function rotates the x-tick labels on a plot. An arbitrary angle can be specified for the text and the label justification adjusts appropriately to ensure the labels lie below the ticks. The axes font properties are preserved in the labels, which will update in response to font changes. Changes to the axes limits are also handled.
Main features:
* Arbitrary angle of rotation
* Justification adjusts appropriately for the specified angle
* Axes font property changes are reflected
* Labels move correctly when zooming and panning

As with other functions that achieve the same result, this works by replacing the xtick labels with text objects. Handles to the created text objects are returned for you to tinker with.


Rotate X Tick Labels For Multi Axes inspired this file.

This file inspired Shaded Correlation Table, Machine Learning With Matlab, and X Yrotalabel Rotate X Axis And Y Axis Labels.

MATLAB release MATLAB 7.10 (R2010a)
MATLAB Search Path
Tags for This File   Please login to tag files.
Please login to add a comment or rating.
Comments and Ratings (76)
10 Jun 2016 John

John (view profile)

30 May 2016 Abhinav

Excellent codes, works very well.

26 Feb 2016 Kevin

Kevin (view profile)

Works perfectly

19 Jan 2016 Mohamed BENALLAL

Works good ! thank's

12 Oct 2015 Tanmay Rajpathak


04 Aug 2015 jimmy Hsu

Thanks a lot!!!

01 Jul 2015 Aaron Diaz

I had to change the addListeners() function to the following to get it to work in R2015a

function addListeners( ax )
% Create listeners. We store the array of listeners in the axes to make
% sure that they have the same life-span as the axes they are listening to.
axh = handle( ax );
listeners = [
addlistener( axh, findprop( axh, 'FontName' ), 'PostSet', @onAxesFontChanged )
addlistener( axh, findprop( axh, 'FontSize' ), 'PostSet', @onAxesFontChanged )
addlistener( axh, findprop( axh, 'FontWeight' ), 'PostSet', @onAxesFontChanged )
addlistener( axh, findprop( axh, 'FontAngle' ), 'PostSet', @onAxesFontChanged )
addlistener( axh, findprop( axh, 'FontUnits' ), 'PostSet', @onAxesFontChanged )
addlistener( axh, findprop( axh, 'OuterPosition' ), 'PostSet', @onAxesPositionChanged )
addlistener( axh, findprop( axh, 'XLim' ), 'PostSet', @onAxesLimitsChanged )
addlistener( axh, findprop( axh, 'YLim' ), 'PostSet', @onAxesLimitsChanged )
addlistener( axh, findprop( axh, 'XAxisLocation' ), 'PostSet', @onXAxisLocationChanged )
setappdata( ax, 'RotateXLabelsListeners', listeners );
end % addListeners

24 Jun 2015 Sanjay

Sanjay (view profile)

Excellent ! Works as promised. No fuss.

19 Jun 2015 Carlos Vladimir Rodríguez Caballero

Awesome. This code perfectly works. Here you get your five stars. =)

01 Apr 2015 Stefan Grandl

Cool, works as it should (tested in <=R2013b).
Big Pro: you can specify the handle to the plot/subplot whose labels shall be rotated, and don't need to set this axes active for automatic determinations.

05 Jan 2015 Thomas Rutten

Hi Nikolas,

I met the same problem with 2014b and solved it like this:

Add at beginning to rotatexlabels.m

if ~verLessThan('matlab','8.4.0')
% execute code for R2014b or higher
% execute code for R2014a or earlier
(put this end just before the first function [maxStringLength] = parseInputs( varargin ).

Good luck,


Comment only
04 Dec 2014 Nikolas

03 Dec 2014 Nikolas

Dear friend,

I am working with Matlab14b and your function shows the following error:

No constructor 'handle.listener' with matching signature found.

Error in rotateXLabels/addListeners (line 390)
listeners = [

Error in rotateXLabels/repositionAxes (line 214)
addListeners( ax );

Error in rotateXLabels (line 37)
repositionAxes( ax );

When I was working with Matlab 14a it was operating correctly, could you please recommend me ways to solve this problem?

Thank you

Comment only
16 Nov 2014 Nikolai Slavov

very simple to deploy and producing the desired result !

24 Oct 2014 Filipe

Filipe (view profile)

Hey Ben, awesome job with this one! I was just in need of something like this. Just one detail... When I run your code everything goes well except for the plot title which lowers slightly. Any way of fixing this?

Filipe Belga

Comment only
21 Oct 2014 Sebastian D'Amico

Ok I've found out the reason: removing the function repositionXLabel makes the labels to go outside the plot when zomming in.



14 Oct 2014 Sebastian D'Amico

Hi Ben,

many thanks for your amazing script. I have one question for you: if I profile your function the most of the execution time (about 66%) comes from "repositionXLabel", ( in particular from "ext = get( textLabels(ll), 'Extent' )" ). I do not understand what this function is used for (line 49) also because it works even if i comment that out. I'm sure the funcion is there for a reason, could you please give me some further info?
Thanks again,


Comment only
30 Sep 2014 goc3

goc3 (view profile)

This was very helpful. I tried various user-created functions to rotate text tick labels (cell array of strings) for the x-axis tick label. This is the only one I found that can rotate text tick labels on subplots without changing the subplots' sizes. Thanks.

23 Sep 2014 DIEGO

DIEGO (view profile)

Excellent work.

18 Sep 2014 R Bakker

Good work.
Got an issue when YDir is reversed.
Here is the fix, starting at line 137:

reverse = xor(strcmpi( get( ax, 'XAxisLocation' ), 'Top' ),strcmpi( get( ax, 'YDir' ), 'Reverse' ))
if reverse,
y = ylim(2);
y = ylim(1);

Comment only
09 Aug 2014 Peking University

01 Aug 2014 Chen Chen

21 Jul 2014 John Yang

Fulfill my need. Works for subplot, too. Thanks,

18 Jun 2014 Robert

Robert (view profile)

Great! But not working with the pre-release of 2014b.

11 Jun 2014 Eduardo


22 May 2014 Chris

Chris (view profile)

very useful, thanks

07 May 2014 Quan Wang

Quan Wang (view profile)


Comment only
27 Jan 2014 Art Blair

Having problems with this. consider
set(gca, 'xlim', [0,15]);

The labels do not update correctly. 13,14,&15 don't show. Adding 'xtick',[0:15] to the set command didn't help.
Using matlab 7.12.0 on an xp box.

Comment only
17 Oct 2013 Amit

Amit (view profile)

Nice function.

Follow-on to the discussion about imagesc
Had some trouble (position of labels) using this with imagesc. Solved it modifying the following

line 139: y = ylim(1);
line 141: y = ylim(2);
line 357: pos = [0 ylim(2)];
line 359: pos = [0 ylim(1)];

Still a remaining problem. If colorbar is visible the figure sizing is not correct.
Not sure how to fix this part.

Comment only
24 Sep 2013 Patrick Cloke

Very useful! Some errors when saving a figure and reopening them (it looks like the old axes is trying to be modified).

19 Sep 2013 Adam Finnefrock

19 Aug 2013 Forest

Forest (view profile)

things are not right if one set the axis reverse as:

Comment only
18 Aug 2013 Forest

Forest (view profile)

Pretty good and handy tool to display long strings as X tick label!

06 Aug 2013 Jaroslaw Tuszynski

Idea is great and it works for some plots. I had issues with plots being incorrectly resized that required code changes. I also had some blots for which this function placed tick labels inside the plot area. So it needs more debugging and possibly a tutorial page with examples.

04 Jul 2013 Dinesh Jayaraman

11 Jun 2013 Gadi

Gadi (view profile)

I've pinpointed the issue with the "Index exceeds matrix dimensions." error and it's a bug somewhere else.

It has to do with "hold on" somehow adding 2 new tick marks to the figure.

Here is how to reproduce it on 2012a:

dat = 1:5;
fh = figure;
hold all;
set(gca,'XTickLabel', dat);

If you would remove "hold on", no error.

06 May 2013 Muthu Annamalai

Thanks for sharing! Do you have any ideas on applying this to the Y-axis ?

26 Apr 2013 Jorge

Jorge (view profile)

18 Mar 2013 Andrea

Andrea (view profile)

19 Feb 2013 M H

M H (view profile)

Very nice function!!

the imagesc() workaround would be to create a copy of the function e.g. 'rotateXLabelsIMGSC()' and change

'y = ylim(2);' to 'y = ylim(1);' in line 124
'y = ylim(1);' to 'y = ylim(2);' in line 126

..would be nicer to catch the imagesc()-case by an 'if' but I am not sure if there is a handle/handle-combination to do it...

08 Feb 2013 Ben Tordoff

Ben Tordoff (view profile)

Hi Fernando & Martin, could one of you post (or email me) an example? When I try the obvious:

rotateXLabels(gca, 45)

it all looks fine. Also, which MATLAB version, just in case it matters?

Comment only
08 Feb 2013 Ben Tordoff

Ben Tordoff (view profile)

Thanks Matt, that's an interesting bug you've found.

I think we can do something slightly better and remove everything to do with rotated labels when the axes are cleared. I'll post an update that does this for you to try. Hopefully it won't break any existing functionality.

Comment only
07 Feb 2013 Matt Jardin

Hey Ben. Very useful function indeed! I may have found an odd issue that occurs if you run cla on the axis that contains rotated x-axis labels. In that case, the next time you trigger one of the listeners that your function sets up, an error is thrown because all of the properties it expects to find have been cleared. I hacked a quick fix by checking inside of each of the listener callbacks to check if the particular axis property is empty. If so, I remove the listeners. Perhaps you have a better suggestion? Thanks again for the function.

05 Oct 2012 Jingmin

Thanks!! Just what I needed.

05 Oct 2012 Matlab2010

great! eg rotateXLabels(gca, 40);

17 Sep 2012 Fernando

I have the same problem of Martin

Comment only
08 Aug 2012 Edward

Edward (view profile)

08 Jul 2012 Martin

Martin (view profile)

Love the function, but have one problem: when I use it with imagesc() the labels end up on the top of the graph and inside the face of the graph. How can I move them to be outside?

22 Jun 2012 Sam

Sam (view profile)

Thanks for the sweet function. However, I'm also getting an "Index exceeds matrix dimensions" error with R2012a, and I isolated what's causing the problem for me at least (although I have no idea why). The code below simulates the scenario I'm working on. When I set 'YGrid' to 'on', I get the error that follows the code. No error when I leave out a 'YGrid' specification. (Note that the code seems to execute just fine despite the error, so it's not a huge deal.)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

% Create fake data
%%% 14 groups of 4 percentages, each group adding to 100
data = zeros(14,4) ;
data(:,1) = randi(100,14,1) ;
for y = 2:3
for x = 1:14
if sum(data(x,:)) == 100
data(x,y) = randi(100-sum(data(x,:)),1,1) ;
for x = 1:14
data(x,4) = 100 - sum(data(x,:)) ;

% Make grouped bar graph
bar(data,'grouped') ;
xlabels = char('Grp01','Grp02','Grp03','Grp04','Grp05','Grp06','Grp07','Grp08','Grp09','Grp10','Grp11','Grp12','Grp13','Grp14') ;
set(gca,'XTickLabel',xlabels,'YLim',[0 100],'YGrid','on')

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Here's the error message:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Index exceeds matrix dimensions.

Error in rotateXLabels/getLabelHeight (line 226)
oldUnits = get( textLabels(1), 'Units' );

Error in rotateXLabels/repositionXLabel (line 204)
labelHeight = getLabelHeight(ax);

Error in rotateXLabels/onAxesLimitsChanged (line 353)
repositionXLabel( ax );

Warning: Error occurred while evaluating listener callback.
> In graphics/private/clo at 83
In cla at 29
In newplot>ObserveAxesNextPlot at 125
In newplot at 74
In bar at 76

11 Jun 2012 Ben Tordoff

Ben Tordoff (view profile)

Hi Vaibhav, any chance you could post a version of the code that doesn't require a data-file? You can use RAND etc to generate some fake data. The important thing is that the range of the data (both in x and y) is similar to the data that you are having trouble with.

Comment only
10 Jun 2012 Vaibhav Jain

Hi Ben,

Thank you for your function. It works absolutely perfect but I am facing a problem when converting the x ticks to mm/dd hh:mm format using datetick command. The eroor message arises specifically when I increase the number of x ticks beyond a certain limit (more than 8 in this case) using linspace command.

Please look at the following code. I have tried to explain its steps in the commented lines. In the end I am pasting the error message I get on running. I would like to know your views on it. Thanks again!

% textdata is a <168x1 double> array with values in 'dd/mm hh:mm:ss' format

% Converts mm/dd hh:mm to numeric values,1);
% data is a <168x1 double> array with numeric format

datetick('x','dd/mm HH:MM:SS','keepticks');
% linspace('first value of DateTime array', 'last value of DateTime array',
% 'number of XTicks in between')


rotateXLabels(gca, 90)

Error message:
??? Index exceeds matrix dimensions.

Error in ==> rotateXLabels>createNewLabels at 132
textLabels(ll) = text( ...

Error in ==> rotateXLabels at 35
h = createNewLabels( ax, vals, labels, angle );

Error in ==> HourlyTempPlot at 29
rotateXLabels(gca, 90)

- Vaibhav Jain

Comment only
10 Jun 2012 Vaibhav Jain

29 Feb 2012 Jacques Pecreaux

Worked perfectly in 2 minutes.
A great and user-friendly file.
Some warnings about latex markups while using no interpreter but it's harmless so far
Thanks for sharing!

21 Feb 2012 Ben Tordoff

Ben Tordoff (view profile)

OK, I've submitted an update that will hopefully fix the printing issues. Please keep a backup of the old version in case this change breaks something else (it passes all my tests, but they probably don't cover all uses). The update should appear here in the next few days. When it does, let me know if it helped.


Comment only
21 Feb 2012 Ben Tordoff

Ben Tordoff (view profile)

Hi Johan, I can see the problem. I am using "normalized" coordinates for the text used as the labels. It seems that with the units set to normalized they don't print, but if I set them to something else they do. I have no idea why this would be.

I will see if I can re-arrange the code to use something other than normalized units without breaking something else (zooming, panning, titles, etc).



Comment only
07 Feb 2012 Johan Carlson

On screen everything looks fine. However, when I try to print, the tick labels disappear, same as for Wolfgang. I'm running MATLAB 2011b ( on Windows 7 (x64 version). All plot settings are at the default.

Other than that, great function!

Here's the test script that used:

clear all
close all

x = 1:0.2:2.8;
y = x.^2;
xlab = get(gca,'XTickLabel');
xlab = num2str(xlab);
xlabel('X axis label');
ylabel('Y axis label');
title('Plot title');
rotateXLabels(gca, 45)
set(gcf, 'PaperPositionMode', 'auto');

Comment only
27 Jan 2012 Pablo

Pablo (view profile)

13 Oct 2011 Chris Sparrow

yes I am using an old version of Matlab - thanks for the suggestion. Great script btw!

Comment only
13 Oct 2011 Ben Tordoff

Ben Tordoff (view profile)

Hi Chris, are you by any chance using a version of MATLAB older than R2010a?

If so, you may still be able to get it to work by replacing the '~' with a real variable name, but bear in mind this hasn't been developed or tested on older releases.

Cheers. Ben

Comment only
12 Oct 2011 Chris Sparrow

I get the following error:
>> rotateXLabels( gca(), 22 )
??? Error: File: rotateXLabels.m Line: 310 Column: 33
Unexpected MATLAB operator.

line 310 is function onAxesFontChanged( ~, ~ )

it will work if I commnet out the functions having ( ~, ~ )
any thoughts why I have this error?


Comment only
12 Oct 2011 Ben Tordoff

Ben Tordoff (view profile)

Hi Wolfgang, I've just tried this using the example in the help and printing using the lines you provided and the labels appear OK. Could you provide a more detailed example that shows the problem? There may be some setting of your figure that makes a difference.

Cheers. Ben

Comment only
12 Oct 2011 Wolfgang

Hi Ben,

This works fine with me, but the x-Axis labels are not printed into a png-file via
set(gcf, 'PaperPositionMode', 'auto');

Can you reproduce this, and do you have a solution.

Comment only
04 Aug 2011 Thijs

Thijs (view profile)

First rotate script I came across that works without issues (yet ;) ) on subplots.

Thank you!

29 Mar 2011 Denzel Li

Hi Ben and Miranda:
The program is cool, especially comparing to other rotation programs which may not adjust the text object position well. Also the code style is clear.
For my previous request of setting the axis to the top, I just manually set the y to a proper value in creatNewLabels(...) and it works.

Comment only
14 Feb 2011 Miranda

Hi Ben,
Thank you for this nice program. One disadvantage is that the labels are very close to the x-axes, especially if I choose an angle of -90 or 90. I thought of including an extra space in the labels:
if 0 <= angle && angle < 180
labels = cellfun(@(x) horzcat(x,' '),labels,'UniformOutput', false);
labels = cellfun(@(x) horzcat(' ',x),labels,'UniformOutput', false);
Maybe an extra if-expression is needed for the labels on XAxisLocation top...

Comment only
11 Feb 2011 Ben Tordoff

Ben Tordoff (view profile)

Hi Denzel, my first attempt at getting this to work is on its way through the approval process now. You should see it arrive on here in the next day or two.

Comment only
08 Feb 2011 Denzel Li

Hi Ben:
Thanks for your quick reply. Having xticklabels on top and yticklabels on right are especially useful when displaying heatmap with labels. Please keep me updated. Thanks.

Comment only
01 Feb 2011 Ben Tordoff

Ben Tordoff (view profile)

Hi Denzel,
this hack works by replacing the tick labels with text objects and removing the existing tick labels. This means that setting properties of the tick labels (fonts, position etc) will no longer have any effect. I'll have a look and see if I can make them honour the "XAxisLocation" property, but I suspect that even then you will need to set it before rotating the labels. Watch this space...


Comment only
31 Jan 2011 Denzel Li

Hi Ben:
Thanks for the great tool. However it only produces xticklabels which is at the bottom and not on the top. That is, even with the function call:
set(gca, 'XAxisLocation', 'top');
the xticklabels are still at the bottom. Please note that get(gca,XAxisLocation') returns 'top'.
Please let me know if anyone has any suggestion. Thanks.


Comment only
06 Oct 2010 Dan Glaser

Thanks, the positioning now works great.

06 Oct 2010 Ben Tordoff

Ben Tordoff (view profile)

Hi Dan. I'm hoping this latest update will have fixed your problem. Please let me know if it doesn't.

Cheers. Ben

Comment only
01 Oct 2010 Dan Glaser

Thanks Ben,
I appreciate you looking into this!

Comment only
30 Sep 2010 Ben Tordoff

Ben Tordoff (view profile)

Hi Dan. Having done some testing, it looks like text object positions are only stored to the nearest pixel. This means that when you call rotateXLabels, any labels that are drawn at the same pixel location will store their position as the same value. This seems to be a limitation of MATLAB's normalised position units or at least a restriction imposed when you switch to them. I will see if it's possible to achieve the same label behavior without using normalised coordinates as this may fix your problem. Watch this space...

Cheers. Ben

Comment only
29 Sep 2010 Dan Glaser

This works beautifully, but when it is used with a plot that has a very large number of x tick labels (1000 for example) it does not position them correctly.

Initially of course in this case, they labels are all overlapping, but after zooming it can be seen that they do not position equally and some are directly on top of each other.

Does anyone have any suggestions?

Comment only
29 Sep 2010 Dan Glaser

27 Sep 2010 Suresh Joel

Suresh Joel (view profile)

Some function arguments missing? (line 256 col 33)

Comment only
30 Sep 2010 1.1

Switch to using normalized units for labels to prevent loss of accuracy with hundreds/thousands of labels.

07 Feb 2011 1.2

Should now honour the "XAxisLocation" property of the axes.

21 Feb 2012 1.3

Switch to using data coordinates internally to allow printing to work. Please keep the old version in case this breaks something else!

28 Mar 2013 1.4

Improve behavior when "cla" is called on the axes.

08 Oct 2014 1.5

* On MATLAB R2014b, just use XTickLabelRotation instead

01 Sep 2016

Updated license

Contact us