【问题标题】:axis equal in a Matlab loglog plotMatlab loglog图中的轴相等
【发布时间】:2010-11-09 12:15:02
【问题描述】:

在 Matlab 中命令“轴相等”:

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

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

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

结果

而不是

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

我的问题是:

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

【问题讨论】:

    标签: matlab plot logarithm


    【解决方案1】:

    一种解决方案是您自己修改axes limits'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 轴上 100 和 102 刻度线之间的间距与 1010 之间的间距相同的像素数 和 1012 刻度线在 x 轴上,从而使一个轴上的十年等于另一轴上的十年。

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

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

    但是,为了禁用 MATLAB 的自动坐标区调整行为,您仍然必须将坐标区限制设置为相同的值在更新 @ 时将 limit mode properties 设置为 'manual' 987654330@房产:

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

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

    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]);
    

    这将提供与以前相同的缩放结果。

    【讨论】:

    • 不错。这类似于我找到的解决方案,虽然我希望有更自动的东西(例如没有手动设置轴),所以我从轴()中获取了限制。但是,问题在于,当您更改纵横比时,限制可能会发生变化(除非像您所做的那样手动设置它们)...
    • 比较你的例子和我做的更仔细,我意识到解决方案根本不一样。我实际上不明白你做了什么......具体来说,我不明白你为什么需要logScale(但它显然有效!)
    • @Yossi:cmets 不够大,我无法解释所有内容,所以我会尽快更新我的答案,解释它是如何工作的。
    猜你喜欢
    • 1970-01-01
    • 2015-01-05
    • 1970-01-01
    • 1970-01-01
    • 2013-07-09
    • 1970-01-01
    • 1970-01-01
    • 2012-10-22
    • 2017-08-06
    相关资源
    最近更新 更多