Matlab对数图中的轴相等 [英] axis equal in a Matlab loglog plot

查看:262
本文介绍了Matlab对数图中的轴相等的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Matlab中,命令轴相等":

In Matlab the command 'axis equal':

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

sets the aspect ratio so that equal tick mark increments on the x-,y- and z-axis are equal in size. This makes SPHERE(25) look like a sphere, instead of an ellipsoid

但是,当使用loglog绘图功能时,这不能正常"工作.我想做的是得到一个长宽比,以便给定的 factor 占据相同的视觉距离.实际发生的是那件事

However, when using the loglog plotting function, this doesn't work "properly". What I would like to happen is that I get an aspect ratio so that a given factor occupies the same visual distance. What actually happens is that

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

结果

而不是

这样可以容易地观察到斜率2(从平方数开始),并且不会有所有额外的空白.

So that the slope 2 (from the squared) could be easily observed, and so that there wouldn't be all that extra white space.

我的问题是:

是否有一个Matlab命令可以帮我做到这一点?或者,有人解决过这个问题吗?

Is there a Matlab command that does this for me? Alternatively, has anyone solved this problem before?

推荐答案

一种解决方案是修改 使自己具有属性,以使一个轴上的十年等于另一个轴上的十年.对于您的示例,可以按照以下步骤进行操作:

One solution is for you to modify the axes limits and 'DataAspectRatio' properties yourself so that a decade on one axis equals a decade on the other. Here's how you can do it for your example:

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 刻度线之间的间距与10 10之间的间距相同. 和10 12 的刻度线位于x轴上,因此一个轴上的十进制等于另一个轴上的十进制.

Notice that the space between the 100 and 102 tick marks on the y axis spans the same number of pixels as the space between the 1010 and 1012 tick marks on the x axis, thus making a decade on one axis equal to a decade on the other.

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

If you don't want to change the axes limits, and instead want to use the default limits chosen by MATLAB, you can simply fetch the limits from the axes to perform the computations:

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

但是,要禁用MATLAB的自动轴大小调整行为,您仍然必须将轴限制设置为相同的值,或者设置

However, in order to disable MATLAB's automatic axes resizing behavior you will still have to either set the axes limits to the same values or set the limit mode properties to 'manual' when you update the 'DataAspectRatio' property:

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.这个答案.目前,这是您可以使用的精简版本(即没有错误检查或帮助):

If all of this seems like a lot of work, you can simplify things by putting it all into a function. I will actually be submitting a function decades_equal to the MathWorks File Exchange based on the code in this answer. For the time being, here is a trimmed down version (i.e. no error checking or help) that you can use:

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

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

And you can call the function as follows:

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轴上显示的十进制数(即10的幂).

You may be wondering what the logic is behind how I chose the scaling factors above. When trying to make the displayed size of a decade equal for each axes, we have to take into account both the number and sizes of decades within the axes ranges. In the above code, I am basically computing the average decade size for each axis, then using the ratios of the average decade sizes to scale the axes accordingly. For example, diff(yLimits) gives the total size of the y axis, and diff(log10(yLimits)) gives the number of decades (i.e. powers of ten) displayed on the y axis.

如果我像上面的代码那样对操作进行重新排序,可能会更容易看到:

This may be easier to see if I reorder the operations in the above code like so:

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

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

And this will give the same scaling results as before.

这篇关于Matlab对数图中的轴相等的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆