16

在 Matlab 中,命令“轴相等”:

设置纵横比,使 x、y 和 z 轴上相等的刻度线增量大小相等。这使得 SPHERE(25) 看起来像一个球体,而不是一个椭球体

但是,在使用loglog绘图功能时,这不能“正常”工作。我想要发生的是我得到一个纵横比,以便给定因素占据相同的视觉距离。实际发生的是

>> loglog(2.^[1:20]*1e10,(2.^[1:20]).^2)
>> axis equal

结果是

替代文字

而不是

替代文字

这样可以很容易地观察到斜率 2(从平方),这样就不会有那么多额外的空白。

我的问题是:

是否有一个 Matlab 命令可以为我执行此操作?或者,以前有没有人解决过这个问题?

4

1 回答 1

11

一种解决方案是让您自己修改轴限制'DataAspectRatio'属性,以便一个轴上的十年等于另一轴上的十年。以下是您可以如何为您的示例执行此操作的方法:

loglog(2.^[1:20]*1e10,(2.^[1:20]).^2);   %# Plot your sample data
xLimits = [1e10 1e16];                   %# Limits for the x axis
yLimits = [1 1e12];                      %# Limits for the y axis
logScale = diff(yLimits)/diff(xLimits);  %# Scale between the x and y ranges
powerScale = diff(log10(yLimits))/...    %# Scale between the x and y powers
             diff(log10(xLimits));
set(gca,'Xlim',xLimits,'YLim',yLimits,...              %# Set the limits and the
        'DataAspectRatio',[1 logScale/powerScale 1]);  %#   data aspect ratio
set(gca,'XTick',[1e10 1e12 1e14 1e16]);  %# Change the x axis tick marks

这是结果图:

替代文字

请注意,y 轴上 10 0和 10 2刻度线之间的空间跨度与 x 轴上 10 10和 10 12刻度线之间的空间相同的像素数,因此使一个轴上的十进制等于十年。

如果您不想更改坐标区限制,而是想使用 MATLAB 选择的默认限制,您可以简单地从坐标区获取限制来执行计算:

xLimits = get(hAxes,'XLim');
yLimits = get(hAxes,'YLim');

但是,为了禁用 MATLAB 的自动坐标区调整行为,您仍然必须将坐标区限制设置为相同的值,或者在更新属性时将限制模式属性设置为:'manual''DataAspectRatio'

set(gca,'Xlim',xLimits,'YLim',yLimits,...
        'DataAspectRatio',[1 logScale/powerScale 1]);
%# OR...
set(gca,'XLimMode','manual','YLimMode','manual',...
        'DataAspectRatio',[1 logScale/powerScale 1]);

如果所有这些看起来都需要做很多工作,那么您可以通过将它们全部放入一个函数中来简化事情。实际上,我将根据此答案中的代码decades_equalMathWorks File Exchange提交一个函数。目前,您可以使用以下精简版本(即没有错误检查或帮助):

function decades_equal(hAxes,xLimits,yLimits)

  if (nargin < 2) || isempty(xLimits)
    xLimits = get(hAxes,'XLim');
  end
  if (nargin < 3) || isempty(yLimits)
    yLimits = get(hAxes,'YLim');
  end

  logScale = diff(yLimits)/diff(xLimits);
  powerScale = diff(log10(yLimits))/diff(log10(xLimits));

  set(hAxes,'Xlim',xLimits,...
            'YLim',yLimits,...
            'DataAspectRatio',[1 logScale/powerScale 1]);

end

您可以按如下方式调用该函数:

loglog(2.^[1:20]*1e10,(2.^[1:20]).^2);   %# Plot your sample data
decades_equal(gca);                      %# Make the decades equal sizes


这个怎么运作...

您可能想知道我如何选择上面的比例因子背后的逻辑是什么。当试图使每个轴的显示大小相等时,我们必须考虑轴范围内的十进制数和大小。在上面的代码中,我基本上是在计算每个轴的平均十年大小,然后使用平均十年大小的比率来相应地缩放轴。例如,diff(yLimits)给出 y 轴的总大小,并diff(log10(yLimits))给出在 y 轴上显示的十进制数(即十的幂)。

如果我像这样重新排序上述代码中的操作,这可能更容易看出:

yDecade = diff(yLimits)/diff(log10(yLimits));  %# Average y decade size
xDecade = diff(xLimits)/diff(log10(xLimits));  %# Average x decade size
set(gca,'XLim',xLimits,'YLim',yLimits,...
        'DataAspectRatio',[1 yDecade/xDecade 1]);

这将给出与以前相同的缩放结果。

于 2010-11-09T17:20:29.393 回答