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