ось, равная на графике журнала Matlab - PullRequest
15 голосов
/ 09 ноября 2010

В Matlab команда 'axis равна':

устанавливает соотношение сторон так, чтобы равные приращения отметки на осях x, y и z были равны по размеру.Это делает СФЕРУ (25) похожей на сферу вместо эллипсоида

Однако при использовании функции построения loglog это не работает "должным образом".Я хотел бы, чтобы я получил соотношение сторон, чтобы данный фактор занимал одинаковое визуальное расстояние.В действительности

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

приводит к

alt text

, а не

alt text

Так чтоможно легко увидеть наклон 2 (из квадрата), чтобы не было лишних пробелов.

Мой вопрос:

Есть ли команда Matlab, которая делает это для меня?Или кто-нибудь решил эту проблему раньше?

1 Ответ

10 голосов
/ 09 ноября 2010

Одно из решений для вас - изменить свойства осей и '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

И вот результирующий график:

alt text

Обратите внимание, что пробел между 10 Отметки 0 и 10 2 на оси y охватывают то же количество пикселей, что и пространство между отметками 10 10 и 10 12 наось x, таким образом, делая десятилетие на одной оси равным десятилетию на другой.

Если вы не хотите изменять пределы осей, а вместо этого хотите использовать ограничения по умолчанию, выбранные 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_equal в MathWorks 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]);

И это даст те же результаты масштабирования, что и раньше.

...