comparison aim-mat/tools/xticklabel_rotate.m @ 4:537f939baef0 tip

various bug fixes and changed copyright message
author Stefan Bleeck <bleeck@gmail.com>
date Tue, 16 Aug 2011 14:37:17 +0100
parents
children
comparison
equal deleted inserted replaced
3:20ada0af3d7d 4:537f939baef0
1 function hText = xticklabel_rotate(XTick,rot,varargin)
2 %hText = xticklabel_rotate(XTick,rot,XTickLabel,varargin) Rotate XTickLabel
3 %
4 % Syntax: xticklabel_rotate
5 %
6 % Input:
7 % {opt} XTick - vector array of XTick positions & values (numeric)
8 % uses current XTick values or XTickLabel cell array by
9 % default (if empty)
10 % {opt} rot - angle of rotation in degrees, 90° by default
11 % {opt} XTickLabel - cell array of label strings
12 % {opt} [var] - "Property-value" pairs passed to text generator
13 % ex: 'interpreter','none'
14 % 'Color','m','Fontweight','bold'
15 %
16 % Output: hText - handle vector to text labels
17 %
18 % Example 1: Rotate existing XTickLabels at their current position by 90°
19 % xticklabel_rotate
20 %
21 % Example 2: Rotate existing XTickLabels at their current position by 45° and change
22 % font size
23 % xticklabel_rotate([],45,[],'Fontsize',14)
24 %
25 % Example 3: Set the positions of the XTicks and rotate them 90°
26 % figure; plot([1960:2004],randn(45,1)); xlim([1960 2004]);
27 % xticklabel_rotate([1960:2:2004]);
28 %
29 % Example 4: Use text labels at XTick positions rotated 45° without tex interpreter
30 % xticklabel_rotate(XTick,45,NameFields,'interpreter','none');
31 %
32 % Example 5: Use text labels rotated 90° at current positions
33 % xticklabel_rotate([],90,NameFields);
34 %
35 % Note : you can not RE-RUN xticklabel_rotate on the same graph.
36 %
37
38
39
40 % This is a modified version of xticklabel_rotate90 by Denis Gilbert
41 % Modifications include Text labels (in the form of cell array)
42 % Arbitrary angle rotation
43 % Output of text handles
44 % Resizing of axes and title/xlabel/ylabel positions to maintain same overall size
45 % and keep text on plot
46 % (handles small window resizing after, but not well due to proportional placement with
47 % fixed font size. To fix this would require a serious resize function)
48 % Uses current XTick by default
49 % Uses current XTickLabel is different from XTick values (meaning has been already defined)
50
51 % Brian FG Katz
52 % bfgkatz@hotmail.com
53 % 23-05-03
54 % Modified 03-11-06 after user comment
55 % Allow for exisiting XTickLabel cell array
56 % Modified 03-03-2006
57 % Allow for labels top located (after user comment)
58 % Allow case for single XTickLabelName (after user comment)
59 % Reduced the degree of resizing
60 % Modified 11-jun-2010
61 % Response to numerous suggestions on MatlabCentral to improve certain
62 % errors.
63
64 % Other m-files required: cell2mat
65 % Subfunctions: none
66 % MAT-files required: none
67 %
68 % See also: xticklabel_rotate90, TEXT, SET
69
70 % Based on xticklabel_rotate90
71 % Author: Denis Gilbert, Ph.D., physical oceanography
72 % Maurice Lamontagne Institute, Dept. of Fisheries and Oceans Canada
73 % email: gilbertd@dfo-mpo.gc.ca Web: http://www.qc.dfo-mpo.gc.ca/iml/
74 % February 1998; Last revision: 24-Mar-2003
75
76 % check to see if xticklabel_rotate has already been here (no other reason for this to happen)
77 if isempty(get(gca,'XTickLabel')),
78 error('xticklabel_rotate : can not process, either xticklabel_rotate has already been run or XTickLabel field has been erased') ;
79 end
80
81 % if no XTickLabel AND no XTick are defined use the current XTickLabel
82 %if nargin < 3 & (~exist('XTick') | isempty(XTick)),
83 % Modified with forum comment by "Nathan Pust" allow the current text labels to be used and property value pairs to be changed for those labels
84 if (nargin < 3 || isempty(varargin{1})) & (~exist('XTick') | isempty(XTick)),
85 xTickLabels = get(gca,'XTickLabel') ; % use current XTickLabel
86 if ~iscell(xTickLabels)
87 % remove trailing spaces if exist (typical with auto generated XTickLabel)
88 temp1 = num2cell(xTickLabels,2) ;
89 for loop = 1:length(temp1),
90 temp1{loop} = deblank(temp1{loop}) ;
91 end
92 xTickLabels = temp1 ;
93 end
94 varargin = varargin(2:length(varargin));
95 end
96
97 % if no XTick is defined use the current XTick
98 if (~exist('XTick') | isempty(XTick)),
99 XTick = get(gca,'XTick') ; % use current XTick
100 end
101
102 %Make XTick a column vector
103 XTick = XTick(:);
104
105 if ~exist('xTickLabels'),
106 % Define the xtickLabels
107 % If XtickLabel is passed as a cell array then use the text
108 if (length(varargin)>0) & (iscell(varargin{1})),
109 xTickLabels = varargin{1};
110 varargin = varargin(2:length(varargin));
111 else
112 xTickLabels = num2str(XTick);
113 end
114 end
115
116 if length(XTick) ~= length(xTickLabels),
117 error('xticklabel_rotate : must have same number of elements in "XTick" and "XTickLabel"') ;
118 end
119
120 %Set the Xtick locations and set XTicklabel to an empty string
121 set(gca,'XTick',XTick,'XTickLabel','')
122
123 if nargin < 2,
124 rot = 90 ;
125 end
126
127 % Determine the location of the labels based on the position
128 % of the xlabel
129 hxLabel = get(gca,'XLabel'); % Handle to xlabel
130 xLabelString = get(hxLabel,'String');
131
132 % if ~isempty(xLabelString)
133 % warning('You may need to manually reset the XLABEL vertical position')
134 % end
135
136 set(hxLabel,'Units','data');
137 xLabelPosition = get(hxLabel,'Position');
138 y = xLabelPosition(2);
139
140 %CODE below was modified following suggestions from Urs Schwarz
141 y=repmat(y,size(XTick,1),1);
142 % retrieve current axis' fontsize
143 fs = get(gca,'fontsize');
144
145 % Place the new xTickLabels by creating TEXT objects
146 hText = text(XTick, y, xTickLabels,'fontsize',fs);
147
148 % Rotate the text objects by ROT degrees
149 %set(hText,'Rotation',rot,'HorizontalAlignment','right',varargin{:})
150 % Modified with modified forum comment by "Korey Y" to deal with labels at top
151 % Further edits added for axis position
152 xAxisLocation = get(gca, 'XAxisLocation');
153 if strcmp(xAxisLocation,'bottom')
154 set(hText,'Rotation',rot,'HorizontalAlignment','right',varargin{:})
155 else
156 set(hText,'Rotation',rot,'HorizontalAlignment','left',varargin{:})
157 end
158
159 % Adjust the size of the axis to accomodate for longest label (like if they are text ones)
160 % This approach keeps the top of the graph at the same place and tries to keep xlabel at the same place
161 % This approach keeps the right side of the graph at the same place
162
163 set(get(gca,'xlabel'),'units','data') ;
164 labxorigpos_data = get(get(gca,'xlabel'),'position') ;
165 set(get(gca,'ylabel'),'units','data') ;
166 labyorigpos_data = get(get(gca,'ylabel'),'position') ;
167 set(get(gca,'title'),'units','data') ;
168 labtorigpos_data = get(get(gca,'title'),'position') ;
169
170 set(gca,'units','pixel') ;
171 set(hText,'units','pixel') ;
172 set(get(gca,'xlabel'),'units','pixel') ;
173 set(get(gca,'ylabel'),'units','pixel') ;
174
175 origpos = get(gca,'position') ;
176
177 % textsizes = cell2mat(get(hText,'extent')) ;
178 % Modified with forum comment from "Peter Pan" to deal with case when only one XTickLabelName is given.
179 x = get( hText, 'extent' );
180 if iscell( x ) == true
181 textsizes = cell2mat( x ) ;
182 else
183 textsizes = x;
184 end
185
186 largest = max(textsizes(:,3)) ;
187 longest = max(textsizes(:,4)) ;
188
189 laborigext = get(get(gca,'xlabel'),'extent') ;
190 laborigpos = get(get(gca,'xlabel'),'position') ;
191
192 labyorigext = get(get(gca,'ylabel'),'extent') ;
193 labyorigpos = get(get(gca,'ylabel'),'position') ;
194 leftlabdist = labyorigpos(1) + labyorigext(1) ;
195
196 % assume first entry is the farthest left
197 leftpos = get(hText(1),'position') ;
198 leftext = get(hText(1),'extent') ;
199 leftdist = leftpos(1) + leftext(1) ;
200 if leftdist > 0, leftdist = 0 ; end % only correct for off screen problems
201
202 % botdist = origpos(2) + laborigpos(2) ;
203 % newpos = [origpos(1)-leftdist longest+botdist origpos(3)+leftdist origpos(4)-longest+origpos(2)-botdist]
204 %
205 % Modified to allow for top axis labels and to minimize axis resizing
206 if strcmp(xAxisLocation,'bottom')
207 newpos = [origpos(1)-(min(leftdist,labyorigpos(1)))+labyorigpos(1) ...
208 origpos(2)+((longest+laborigpos(2))-get(gca,'FontSize')) ...
209 origpos(3)-(min(leftdist,labyorigpos(1)))+labyorigpos(1)-largest ...
210 origpos(4)-((longest+laborigpos(2))-get(gca,'FontSize'))]
211 else
212 newpos = [origpos(1)-(min(leftdist,labyorigpos(1)))+labyorigpos(1) ...
213 origpos(2) ...
214 origpos(3)-(min(leftdist,labyorigpos(1)))+labyorigpos(1)-largest ...
215 origpos(4)-(longest)+get(gca,'FontSize')]
216 end
217 set(gca,'position',newpos) ;
218
219 % readjust position of text labels after resize of plot
220 set(hText,'units','data') ;
221 for loop= 1:length(hText),
222 set(hText(loop),'position',[XTick(loop), y(loop)]) ;
223 end
224
225 % adjust position of xlabel and ylabel
226 laborigpos = get(get(gca,'xlabel'),'position') ;
227 set(get(gca,'xlabel'),'position',[laborigpos(1) laborigpos(2)-longest 0]) ;
228
229 % switch to data coord and fix it all
230 set(get(gca,'ylabel'),'units','data') ;
231 set(get(gca,'ylabel'),'position',labyorigpos_data) ;
232 set(get(gca,'title'),'position',labtorigpos_data) ;
233
234 set(get(gca,'xlabel'),'units','data') ;
235 labxorigpos_data_new = get(get(gca,'xlabel'),'position') ;
236 set(get(gca,'xlabel'),'position',[labxorigpos_data(1) labxorigpos_data_new(2)]) ;
237
238
239 % Reset all units to normalized to allow future resizing
240 set(get(gca,'xlabel'),'units','normalized') ;
241 set(get(gca,'ylabel'),'units','normalized') ;
242 set(get(gca,'title'),'units','normalized') ;
243 set(hText,'units','normalized') ;
244 set(gca,'units','normalized') ;
245
246 if nargout < 1,
247 clear hText
248 end
249