正如@bdecaf 在评论中所指出的,您可以为 z 刻度更改时编写一个事件处理程序,以便相应地自定义刻度标签。这是使用无证的 http://undocumentedmatlab.com/blog/property-value-change-listeners 功能性 https://stackoverflow.com/a/18419244/97160.
这很方便,因为我们仍然让 MATLAB 根据轴可用的屏幕空间自动决定要使用的最佳刻度数,我们只需自定义显示标签的格式。
Example:
function customize_ticks_example()
% data
[adj,XYZ] = bucky;
[r,c] = find(adj);
edges = [r c];
points = XYZ';
e = edges';
e(end+1,:) = 1;
e = e(:);
p = points(:,e);
p(:,3:3:end) = NaN;
% plot
hFig = figure;
line(p(1,:), p(2,:), p(3,:), ...
'LineWidth',2, 'Marker','.', 'MarkerSize',20);
ax = handle(gca);
view(3), grid on, box on
xlabel x, ylabel y, zlabel z
rotate3d on
% listen to changes on ZTick property
ev = handle.listener(ax, findprop(ax,'ZTick'), ...
'PropertyPostSet', @onZTickChange);
setappdata(hFig, 'my_ztick_listener', ev);
end
function onZTickChange(~,e)
% get the new 'ZTick', and format them as needed
labels = num2str(e.NewValue(:),'%g $');
% update the 'ZTickLabel'
set(double(e.AffectedObject), 'ZTickLabel',labels)
end
当然,标签不必是数字,您可以使用任何自定义标签,只要您有某种比例,您可以沿着该比例插入值来确定要使用的标签。
EDIT:
一种更简单的方法设置事件监听器 http://www.mathworks.com/help/matlab/ref/handle.addlistener.html:
ev = addlistener(gca, 'ZTick', 'PostSet', @onZTickChange);
(在这种情况下,不需要存储ev
在 GUI 内setappdata
. 这个语法 http://www.mathworks.com/help/matlab/matlab_oop/events-and-listeners--syntax-and-techniques.html#brb6soq将侦听器绑定到 GUI 对象的生命周期)。
EDIT 2:
为了回应评论,这是另一个例子:
function example_manual_ticks
%% some 3d plot
hFig = figure;
sphere
view(3), grid on, box on
xlabel x, ylabel y, zlabel z
%% create a hidden copy of the axis
hax1 = gca;
hax2 = copyobj(hax1, hFig);
set(hax2, 'Visible','off', 'Color','none', 'HitTest','off', ...
'XLimMode','manual', 'YLimMode','manual', 'ZLimMode','manual')
delete(get(hax2, 'Children'))
uistack(hax2, 'bottom')
% sync axes on 3d rotation
hlink = linkprop([hax1,hax2], {'CameraPosition','CameraUpVector'});
setappdata(hax1, 'my_axes_linkprop', hlink);
rotate3d on
% respnd to changes in ZTick axis property
ev = addlistener(hax2, 'ZTick', 'PostSet',@(o,e) onZTickChange(o,e,hax1));
%% animation
el = 90 .* sin(linspace(0,2*pi,100) + asin(1/3));
for n=1:numel(el)
view(-37.5, el(n))
drawnow
end
end
function onZTickChange(~,e,ax)
% determine number of ticks
num_ticks = numel(e.NewValue);
new_num_ticks = num_ticks - 1;
% interpolate new ticks along the axis limits
limits = get(ax, 'ZLim');
zticks = linspace(limits(1), limits(2), new_num_ticks);
zticks_labels = num2str(zticks(:), '%.2f ($)');
% update ticks
set(ax, 'ZTick',zticks, 'ZTickLabel',zticks_labels)
drawnow
end
这个想法是创建一个隐藏的copy http://www.mathworks.com/help/matlab/ref/copyobj.html的轴,保持同步 http://www.mathworks.com/help/matlab/ref/linkprop.html与原来的 3D 旋转。第二个轴将具有自动刻度线,而我们可以根据需要自定义第一个轴的刻度线(类似于我们在隐藏轴上注册刻度线更改时的回调之前)。
我再次使用这个隐藏轴作为让 MATLAB 处理确定给定视图的最佳刻度数的任务的方法(这比为了找出投影轴(以像素为单位)。
在上面的示例中,我只是将刻度数设置为比自动数少一({2,4,10}
代替{3,5,11}
),但您可以使用任何您想要的映射。