-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathxticklabel_rotate.m
201 lines (165 loc) · 7.55 KB
/
xticklabel_rotate.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
function hText = xticklabel_rotate(XTick,rot,varargin)
%hText = xticklabel_rotate(XTick,rot,XTickLabel,varargin) Rotate XTickLabel
%
% Syntax: xticklabel_rotate
%
% Input:
% {opt} XTick - vector array of XTick positions & values (numeric)
% uses current XTick values by default (if empty)
% {opt} rot - angle of rotation in degrees, 90° by default
% {opt} XTickLabel - cell array of label strings
% {opt} [var] - "Property-value" pairs passed to text generator
% ex: 'interpreter','none'
% 'Color','m','Fontweight','bold'
%
% Output: hText - handle vector to text labels
%
% Example 1: Rotate existing XTickLabels at their current position by 90°
% xticklabel_rotate
%
% Example 2: Rotate existing XTickLabels at their current position by 45°
% xticklabel_rotate([],45)
%
% Example 3: Set the positions of the XTicks and rotate them 90°
% figure; plot([1960:2004],randn(45,1)); xlim([1960 2004]);
% xticklabel_rotate([1960:2:2004]);
%
% Example 4: Use text labels at XTick positions rotated 45° without tex interpreter
% xticklabel_rotate(XTick,45,NameFields,'interpreter','none');
%
% Example 5: Use text labels rotated 90° at current positions
% xticklabel_rotate([],90,NameFields);
%
% Note : you can not re-run xticklabel_rotate on the same graph
% This is a modified version of xticklabel_rotate90 by Denis Gilbert
% Modifications include Text labels (in the form of cell array)
% Arbitrary angle rotation
% Output of text handles
% Resizing of axes and title/xlabel/ylabel positions to maintain same overall size
% and keep text on plot
% (handles small window resizing after, but not well due to proportional placement with
% fixed font size. To fix this would require a serious resize function)
% Uses current XTick by default
% Uses current XTickLabel is different from XTick values (meaning has been already defined)
% Brian FG Katz
% 23-05-03
% Other m-files required: cell2mat
% Subfunctions: none
% MAT-files required: none
%
% See also: xticklabel_rotate90, TEXT, SET
% Based on xticklabel_rotate90
% Author: Denis Gilbert, Ph.D., physical oceanography
% Maurice Lamontagne Institute, Dept. of Fisheries and Oceans Canada
% email: [email protected] Web: http://www.qc.dfo-mpo.gc.ca/iml/
% February 1998; Last revision: 24-Mar-2003
% check to see if xticklabel_rotate has already been here (no other reasdon for this to happen)
if isempty(get(gca,'XTickLabel')),
error('xticklabel_rotate : can not process, either xticklabel_rotate has already been run or XTickLabel field has been erased') ;
end
% if no XTickLabel AND no XTick are defined use the current XTickLabel
if nargin < 3 & (~exist('XTick') | isempty(XTick)),
xTickLabels = get(gca,'XTickLabel') ; % use current XTickLabel
% remove trailing spaces if exist (typical with auto generated XTickLabel)
temp1 = num2cell(xTickLabels,2) ;
for loop = 1:length(temp1),
temp1{loop} = deblank(temp1{loop}) ;
end
xTickLabels = temp1 ;
end
% if no XTick is defined use the current XTick
if (~exist('XTick') | isempty(XTick)),
XTick = get(gca,'XTick') ; % use current XTick
end
%Make XTick a column vector
XTick = XTick(:);
if ~exist('xTickLabels'),
% Define the xtickLabels
% If XtickLabel is passed as a cell array then use the text
if (length(varargin)>0) & (iscell(varargin{1})),
xTickLabels = varargin{1};
varargin = varargin(2:length(varargin));
else
xTickLabels = num2str(XTick);
end
end
if length(XTick) ~= length(xTickLabels),
error('xticklabel_rotate : must have smae number of elements in "XTick" and "XTickLabel"') ;
end
%Set the Xtick locations and set XTicklabel to an empty string
set(gca,'XTick',XTick,'XTickLabel','')
if nargin < 2,
rot = 90 ;
end
% Determine the location of the labels based on the position
% of the xlabel
hxLabel = get(gca,'XLabel'); % Handle to xlabel
xLabelString = get(hxLabel,'String');
% if ~isempty(xLabelString)
% warning('You may need to manually reset the XLABEL vertical position')
% end
set(hxLabel,'Units','data');
xLabelPosition = get(hxLabel,'Position');
y = xLabelPosition(2);
%CODE below was modified following suggestions from Urs Schwarz
y=repmat(y,size(XTick,1),1);
% retrieve current axis' fontsize
fs = get(gca,'fontsize');
% Place the new xTickLabels by creating TEXT objects
hText = text(XTick, y, xTickLabels,'fontsize',fs);
% Rotate the text objects by ROT degrees
set(hText,'Rotation',rot,'HorizontalAlignment','right',varargin{:})
% Adjust the size of the axis to accomodate for longest label (like if they are text ones)
% This approach keeps the top of the graph at the same place and tries to keep xlabel at the same place
% This approach keeps the right side of the graph at the same place
set(get(gca,'xlabel'),'units','data') ;
labxorigpos_data = get(get(gca,'xlabel'),'position') ;
set(get(gca,'ylabel'),'units','data') ;
labyorigpos_data = get(get(gca,'ylabel'),'position') ;
set(get(gca,'title'),'units','data') ;
labtorigpos_data = get(get(gca,'title'),'position') ;
set(gca,'units','pixel') ;
set(hText,'units','pixel') ;
set(get(gca,'xlabel'),'units','pixel') ;
set(get(gca,'ylabel'),'units','pixel') ;
origpos = get(gca,'position') ;
textsizes = cell2mat(get(hText,'extent')) ;
longest = max(textsizes(:,4)) ;
laborigext = get(get(gca,'xlabel'),'extent') ;
laborigpos = get(get(gca,'xlabel'),'position') ;
labyorigext = get(get(gca,'ylabel'),'extent') ;
labyorigpos = get(get(gca,'ylabel'),'position') ;
leftlabdist = labyorigpos(1) + labyorigext(1) ;
% assume first entry is the farthest left
leftpos = get(hText(1),'position') ;
leftext = get(hText(1),'extent') ;
leftdist = leftpos(1) + leftext(1) ;
if leftdist > 0, leftdist = 0 ; end % only correct for off screen problems
botdist = origpos(2) + laborigpos(2) ;
newpos = [origpos(1)-leftdist longest+botdist origpos(3)+leftdist origpos(4)-longest+origpos(2)-botdist] ;
set(gca,'position',newpos) ;
% readjust position of nex labels after resize of plot
set(hText,'units','data') ;
for loop= 1:length(hText),
set(hText(loop),'position',[XTick(loop), y(loop)]) ;
end
% adjust position of xlabel and ylabel
laborigpos = get(get(gca,'xlabel'),'position') ;
set(get(gca,'xlabel'),'position',[laborigpos(1) laborigpos(2)-longest 0]) ;
% switch to data coord and fix it all
set(get(gca,'ylabel'),'units','data') ;
set(get(gca,'ylabel'),'position',labyorigpos_data) ;
set(get(gca,'title'),'position',labtorigpos_data) ;
set(get(gca,'xlabel'),'units','data') ;
labxorigpos_data_new = get(get(gca,'xlabel'),'position') ;
set(get(gca,'xlabel'),'position',[labxorigpos_data(1) labxorigpos_data_new(2)]) ;
% Reset all units to normalized to allow future resizing
set(get(gca,'xlabel'),'units','normalized') ;
set(get(gca,'ylabel'),'units','normalized') ;
set(get(gca,'title'),'units','normalized') ;
set(hText,'units','normalized') ;
set(gca,'units','normalized') ;
if nargout < 1,
clear hText
end