Q: Special formatting of tickmarks?
Tickmarks are the only labels in Matlab that do not accept formatting:
it is impossible to include special symbols, vary orientation, color, etc. The workaround is to replace them with
TEXT objects. Unfortunately, some extra not-so-trivial measures have to be taken to ensure the labels stay
in place if the figure is resized or axes are moved. XTICKS function (below) is an attempt to do so.
This plot has been produced by the following commands:
xl=[12 8 6 4 3 2];
xs=strcat('^{\pi}/_{',cellstr(num2str(xl(:))),'}'); % fills the labels using TeX noation
cl=num2cell(interp1((0:.1:1)'*.5,jet(11),1./xl),2); % create pretty colors
xticks(pi./xl,xs,{'color'},cl);
function h=xticks(varargin)
%XTICKS enables rich formatting of tickmarks
% XTICKS(X,LABEL) creates tickmarks at positions X
% X should be a vector,
% LABEL may be a cell array of the same size, or char matrix with lenght(X) rows
% any TeX notation can be used.
%
% XTICKS(X) creates labels automaticly
%
% XTICKS(...,'Property',Value,...) passes TEXT properties
%
% H=XTICKS(...) returns handles of TEXT objects
%
% Note:
% Tickmarks created this way are sensitive to YLIM: if it is changed, tickmarks
% may move. Calling XTICKS without any arguments after changing YLIM restores them.
%
% Example:
% XTICKS([0 pi 2*pi],{'Zero','\pi','2\pi'},'rotation',45,'fontsize',14)
% 6/4/01 ashcherbina@ucsd.edu
fig = gcbo; %if executed as a callback
if isempty(fig), fig=gcf;end
u = findobj(fig, 'Tag','SpecialXTick');
if ~isempty(u)
axs = get(u,'parent');
axs=cat(1,axs{:});
else
axs=[];
end
% if moving, just update all ticks
if (isempty(varargin) & ~isempty(u))
if length(u)==0 set(gcbo,'ResizeFcn',[]);return; end;
for ax=unique(axs)'
tm=u(axs==ax); %ticks belonging to this axis
tm=sort(tm);
pos=get_positions(ax);
set(tm,{'position'},pos);
end
return;
end
% get ticks and labels
ax=gca;
xpos=get(ax,'Xtick');
str=cellstr(get(ax,'XtickLabel'));
if ~isempty(varargin) & ~isstr(varargin{1}),
xpos=varargin{1};
set(ax,'Xtick',xpos);
str=cellstr(get(ax,'XtickLabel'));
if length(varargin)>1 & length(varargin{2})>1,
str=varargin{2};
if ~iscell(str), str=cellstr(str);end;
varargin={varargin{3:end}};
else
varargin={varargin{2:end}};
end
xpos=xpos(:);
str={str{:}}';
visible=(xpos>=min(xlim) & xpos<=max(xlim));
xpos=xpos(visible);
str={str{visible}}';
set(ax,'Xtick',xpos);
end
if ~isempty(axs)
tm=u(axs==ax); %ticks belonging to the current axis
if ~isempty(tm)
% ticks exist - delete them
delete(tm);
end
end
% fix limits & tickmarks
ylim(ylim);
xlim(xlim);
set(ax,'XtickMode','MANUAL','XtickLabelMode','MANUAL','Xticklabel',[]);
pos=get_positions(ax);
N=length(pos);
%create text objects
hh=text(zeros(N,1),zeros(N,1),str);
hh=sort(hh);
set(hh,{'position'},pos,...
{'string'},str,...
'horizontalalignment','center',...
'clipping','off',...
'Tag','SpecialXTick',...
varargin{:});
set(gcf,'ResizeFcn','xticks'); % establish figure callback
if nargout>0, h=hh;end;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function pos=get_positions(ax)
YSPACE=10; %spacing between the axis and the labels, points
unit=get(ax,'units');
set(ax,'units','points');
rect=actual_pos(ax);
set(ax,'units',unit);
xpos=get(ax,'Xtick');
yl=get(ax,'Ylim');
y=yl(1)-YSPACE/rect(4)*diff(yl);
ypos=repmat(y,1,length(xpos));
zpos=0*ypos;
pos=num2cell([xpos(:),ypos(:),zpos(:)],2);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function rr=actual_pos(ax)
% ACTUAL_POS - get the *actual* axis position
% r=ACTUAL_POS(AX) returns the actual axis rectangle, which may be
% different from get(AX,'Position') if data aspect is set manually.
% If called without arguments, gca assumed
% ashcherbina@ucsd.edu, 2000
if nargin==0 ax=gca;end;
r=get(ax,'position');
rr=r;
if strcmp(get(ax,'DataAspectRatioMode'),'manual')
dar=get(ax,'DataAspectRatio');
units = get(ax,'units');
set(ax,'units','pixels');
r=get(ax,'position');
set(ax,'units',units)
xl=diff(xlim)./dar(1);
yl=diff(ylim)./dar(2);
p_r=yl/xl; %plot ratio
b_r=r(4)/r(3);% box ratio
if (p_r>b_r) %vertical positions are correct
% actual width
ax=r(4)/p_r;
%extra width
ex=(r(3)-ax)/2;
rr(1)=rr(1)+ex/r(3)*rr(3);
rr(3)=ax/r(3)*rr(3);
else % horizontal positions are correct
% actual height
ax=r(3)*p_r;
%extra height
ex=(r(4)-ax)/2;
rr(2)=rr(2)+ex/r(4)*rr(4);
rr(4)=ax/r(4)*rr(4);
end
end