bleeck@4: function hText = xticklabel_rotate(XTick,rot,varargin) bleeck@4: %hText = xticklabel_rotate(XTick,rot,XTickLabel,varargin) Rotate XTickLabel bleeck@4: % bleeck@4: % Syntax: xticklabel_rotate bleeck@4: % bleeck@4: % Input: bleeck@4: % {opt} XTick - vector array of XTick positions & values (numeric) bleeck@4: % uses current XTick values or XTickLabel cell array by bleeck@4: % default (if empty) bleeck@4: % {opt} rot - angle of rotation in degrees, 90° by default bleeck@4: % {opt} XTickLabel - cell array of label strings bleeck@4: % {opt} [var] - "Property-value" pairs passed to text generator bleeck@4: % ex: 'interpreter','none' bleeck@4: % 'Color','m','Fontweight','bold' bleeck@4: % bleeck@4: % Output: hText - handle vector to text labels bleeck@4: % bleeck@4: % Example 1: Rotate existing XTickLabels at their current position by 90° bleeck@4: % xticklabel_rotate bleeck@4: % bleeck@4: % Example 2: Rotate existing XTickLabels at their current position by 45° and change bleeck@4: % font size bleeck@4: % xticklabel_rotate([],45,[],'Fontsize',14) bleeck@4: % bleeck@4: % Example 3: Set the positions of the XTicks and rotate them 90° bleeck@4: % figure; plot([1960:2004],randn(45,1)); xlim([1960 2004]); bleeck@4: % xticklabel_rotate([1960:2:2004]); bleeck@4: % bleeck@4: % Example 4: Use text labels at XTick positions rotated 45° without tex interpreter bleeck@4: % xticklabel_rotate(XTick,45,NameFields,'interpreter','none'); bleeck@4: % bleeck@4: % Example 5: Use text labels rotated 90° at current positions bleeck@4: % xticklabel_rotate([],90,NameFields); bleeck@4: % bleeck@4: % Note : you can not RE-RUN xticklabel_rotate on the same graph. bleeck@4: % bleeck@4: bleeck@4: bleeck@4: bleeck@4: % This is a modified version of xticklabel_rotate90 by Denis Gilbert bleeck@4: % Modifications include Text labels (in the form of cell array) bleeck@4: % Arbitrary angle rotation bleeck@4: % Output of text handles bleeck@4: % Resizing of axes and title/xlabel/ylabel positions to maintain same overall size bleeck@4: % and keep text on plot bleeck@4: % (handles small window resizing after, but not well due to proportional placement with bleeck@4: % fixed font size. To fix this would require a serious resize function) bleeck@4: % Uses current XTick by default bleeck@4: % Uses current XTickLabel is different from XTick values (meaning has been already defined) bleeck@4: bleeck@4: % Brian FG Katz bleeck@4: % bfgkatz@hotmail.com bleeck@4: % 23-05-03 bleeck@4: % Modified 03-11-06 after user comment bleeck@4: % Allow for exisiting XTickLabel cell array bleeck@4: % Modified 03-03-2006 bleeck@4: % Allow for labels top located (after user comment) bleeck@4: % Allow case for single XTickLabelName (after user comment) bleeck@4: % Reduced the degree of resizing bleeck@4: % Modified 11-jun-2010 bleeck@4: % Response to numerous suggestions on MatlabCentral to improve certain bleeck@4: % errors. bleeck@4: bleeck@4: % Other m-files required: cell2mat bleeck@4: % Subfunctions: none bleeck@4: % MAT-files required: none bleeck@4: % bleeck@4: % See also: xticklabel_rotate90, TEXT, SET bleeck@4: bleeck@4: % Based on xticklabel_rotate90 bleeck@4: % Author: Denis Gilbert, Ph.D., physical oceanography bleeck@4: % Maurice Lamontagne Institute, Dept. of Fisheries and Oceans Canada bleeck@4: % email: gilbertd@dfo-mpo.gc.ca Web: http://www.qc.dfo-mpo.gc.ca/iml/ bleeck@4: % February 1998; Last revision: 24-Mar-2003 bleeck@4: bleeck@4: % check to see if xticklabel_rotate has already been here (no other reason for this to happen) bleeck@4: if isempty(get(gca,'XTickLabel')), bleeck@4: error('xticklabel_rotate : can not process, either xticklabel_rotate has already been run or XTickLabel field has been erased') ; bleeck@4: end bleeck@4: bleeck@4: % if no XTickLabel AND no XTick are defined use the current XTickLabel bleeck@4: %if nargin < 3 & (~exist('XTick') | isempty(XTick)), bleeck@4: % 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: if (nargin < 3 || isempty(varargin{1})) & (~exist('XTick') | isempty(XTick)), bleeck@4: xTickLabels = get(gca,'XTickLabel') ; % use current XTickLabel bleeck@4: if ~iscell(xTickLabels) bleeck@4: % remove trailing spaces if exist (typical with auto generated XTickLabel) bleeck@4: temp1 = num2cell(xTickLabels,2) ; bleeck@4: for loop = 1:length(temp1), bleeck@4: temp1{loop} = deblank(temp1{loop}) ; bleeck@4: end bleeck@4: xTickLabels = temp1 ; bleeck@4: end bleeck@4: varargin = varargin(2:length(varargin)); bleeck@4: end bleeck@4: bleeck@4: % if no XTick is defined use the current XTick bleeck@4: if (~exist('XTick') | isempty(XTick)), bleeck@4: XTick = get(gca,'XTick') ; % use current XTick bleeck@4: end bleeck@4: bleeck@4: %Make XTick a column vector bleeck@4: XTick = XTick(:); bleeck@4: bleeck@4: if ~exist('xTickLabels'), bleeck@4: % Define the xtickLabels bleeck@4: % If XtickLabel is passed as a cell array then use the text bleeck@4: if (length(varargin)>0) & (iscell(varargin{1})), bleeck@4: xTickLabels = varargin{1}; bleeck@4: varargin = varargin(2:length(varargin)); bleeck@4: else bleeck@4: xTickLabels = num2str(XTick); bleeck@4: end bleeck@4: end bleeck@4: bleeck@4: if length(XTick) ~= length(xTickLabels), bleeck@4: error('xticklabel_rotate : must have same number of elements in "XTick" and "XTickLabel"') ; bleeck@4: end bleeck@4: bleeck@4: %Set the Xtick locations and set XTicklabel to an empty string bleeck@4: set(gca,'XTick',XTick,'XTickLabel','') bleeck@4: bleeck@4: if nargin < 2, bleeck@4: rot = 90 ; bleeck@4: end bleeck@4: bleeck@4: % Determine the location of the labels based on the position bleeck@4: % of the xlabel bleeck@4: hxLabel = get(gca,'XLabel'); % Handle to xlabel bleeck@4: xLabelString = get(hxLabel,'String'); bleeck@4: bleeck@4: % if ~isempty(xLabelString) bleeck@4: % warning('You may need to manually reset the XLABEL vertical position') bleeck@4: % end bleeck@4: bleeck@4: set(hxLabel,'Units','data'); bleeck@4: xLabelPosition = get(hxLabel,'Position'); bleeck@4: y = xLabelPosition(2); bleeck@4: bleeck@4: %CODE below was modified following suggestions from Urs Schwarz bleeck@4: y=repmat(y,size(XTick,1),1); bleeck@4: % retrieve current axis' fontsize bleeck@4: fs = get(gca,'fontsize'); bleeck@4: bleeck@4: % Place the new xTickLabels by creating TEXT objects bleeck@4: hText = text(XTick, y, xTickLabels,'fontsize',fs); bleeck@4: bleeck@4: % Rotate the text objects by ROT degrees bleeck@4: %set(hText,'Rotation',rot,'HorizontalAlignment','right',varargin{:}) bleeck@4: % Modified with modified forum comment by "Korey Y" to deal with labels at top bleeck@4: % Further edits added for axis position bleeck@4: xAxisLocation = get(gca, 'XAxisLocation'); bleeck@4: if strcmp(xAxisLocation,'bottom') bleeck@4: set(hText,'Rotation',rot,'HorizontalAlignment','right',varargin{:}) bleeck@4: else bleeck@4: set(hText,'Rotation',rot,'HorizontalAlignment','left',varargin{:}) bleeck@4: end bleeck@4: bleeck@4: % Adjust the size of the axis to accomodate for longest label (like if they are text ones) bleeck@4: % This approach keeps the top of the graph at the same place and tries to keep xlabel at the same place bleeck@4: % This approach keeps the right side of the graph at the same place bleeck@4: bleeck@4: set(get(gca,'xlabel'),'units','data') ; bleeck@4: labxorigpos_data = get(get(gca,'xlabel'),'position') ; bleeck@4: set(get(gca,'ylabel'),'units','data') ; bleeck@4: labyorigpos_data = get(get(gca,'ylabel'),'position') ; bleeck@4: set(get(gca,'title'),'units','data') ; bleeck@4: labtorigpos_data = get(get(gca,'title'),'position') ; bleeck@4: bleeck@4: set(gca,'units','pixel') ; bleeck@4: set(hText,'units','pixel') ; bleeck@4: set(get(gca,'xlabel'),'units','pixel') ; bleeck@4: set(get(gca,'ylabel'),'units','pixel') ; bleeck@4: bleeck@4: origpos = get(gca,'position') ; bleeck@4: bleeck@4: % textsizes = cell2mat(get(hText,'extent')) ; bleeck@4: % Modified with forum comment from "Peter Pan" to deal with case when only one XTickLabelName is given. bleeck@4: x = get( hText, 'extent' ); bleeck@4: if iscell( x ) == true bleeck@4: textsizes = cell2mat( x ) ; bleeck@4: else bleeck@4: textsizes = x; bleeck@4: end bleeck@4: bleeck@4: largest = max(textsizes(:,3)) ; bleeck@4: longest = max(textsizes(:,4)) ; bleeck@4: bleeck@4: laborigext = get(get(gca,'xlabel'),'extent') ; bleeck@4: laborigpos = get(get(gca,'xlabel'),'position') ; bleeck@4: bleeck@4: labyorigext = get(get(gca,'ylabel'),'extent') ; bleeck@4: labyorigpos = get(get(gca,'ylabel'),'position') ; bleeck@4: leftlabdist = labyorigpos(1) + labyorigext(1) ; bleeck@4: bleeck@4: % assume first entry is the farthest left bleeck@4: leftpos = get(hText(1),'position') ; bleeck@4: leftext = get(hText(1),'extent') ; bleeck@4: leftdist = leftpos(1) + leftext(1) ; bleeck@4: if leftdist > 0, leftdist = 0 ; end % only correct for off screen problems bleeck@4: bleeck@4: % botdist = origpos(2) + laborigpos(2) ; bleeck@4: % newpos = [origpos(1)-leftdist longest+botdist origpos(3)+leftdist origpos(4)-longest+origpos(2)-botdist] bleeck@4: % bleeck@4: % Modified to allow for top axis labels and to minimize axis resizing bleeck@4: if strcmp(xAxisLocation,'bottom') bleeck@4: newpos = [origpos(1)-(min(leftdist,labyorigpos(1)))+labyorigpos(1) ... bleeck@4: origpos(2)+((longest+laborigpos(2))-get(gca,'FontSize')) ... bleeck@4: origpos(3)-(min(leftdist,labyorigpos(1)))+labyorigpos(1)-largest ... bleeck@4: origpos(4)-((longest+laborigpos(2))-get(gca,'FontSize'))] bleeck@4: else bleeck@4: newpos = [origpos(1)-(min(leftdist,labyorigpos(1)))+labyorigpos(1) ... bleeck@4: origpos(2) ... bleeck@4: origpos(3)-(min(leftdist,labyorigpos(1)))+labyorigpos(1)-largest ... bleeck@4: origpos(4)-(longest)+get(gca,'FontSize')] bleeck@4: end bleeck@4: set(gca,'position',newpos) ; bleeck@4: bleeck@4: % readjust position of text labels after resize of plot bleeck@4: set(hText,'units','data') ; bleeck@4: for loop= 1:length(hText), bleeck@4: set(hText(loop),'position',[XTick(loop), y(loop)]) ; bleeck@4: end bleeck@4: bleeck@4: % adjust position of xlabel and ylabel bleeck@4: laborigpos = get(get(gca,'xlabel'),'position') ; bleeck@4: set(get(gca,'xlabel'),'position',[laborigpos(1) laborigpos(2)-longest 0]) ; bleeck@4: bleeck@4: % switch to data coord and fix it all bleeck@4: set(get(gca,'ylabel'),'units','data') ; bleeck@4: set(get(gca,'ylabel'),'position',labyorigpos_data) ; bleeck@4: set(get(gca,'title'),'position',labtorigpos_data) ; bleeck@4: bleeck@4: set(get(gca,'xlabel'),'units','data') ; bleeck@4: labxorigpos_data_new = get(get(gca,'xlabel'),'position') ; bleeck@4: set(get(gca,'xlabel'),'position',[labxorigpos_data(1) labxorigpos_data_new(2)]) ; bleeck@4: bleeck@4: bleeck@4: % Reset all units to normalized to allow future resizing bleeck@4: set(get(gca,'xlabel'),'units','normalized') ; bleeck@4: set(get(gca,'ylabel'),'units','normalized') ; bleeck@4: set(get(gca,'title'),'units','normalized') ; bleeck@4: set(hText,'units','normalized') ; bleeck@4: set(gca,'units','normalized') ; bleeck@4: bleeck@4: if nargout < 1, bleeck@4: clear hText bleeck@4: end bleeck@4: