Одним из решений является изменение пределов осей и '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
И вот получившийся сюжет:
![альтернативный текст](https://i.stack.imgur.com/nUvhU.png)
Обратите внимание, что расстояние между делениями 100 и 102 по оси Y составляет такое же количество пикселей, как и расстояние между делениями 1010. > и 1012 делений по оси 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 на основе кода в этом ответе. . На данный момент вот урезанная версия (т.е. без проверки ошибок или справки), которую вы можете использовать:
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]);
И это даст те же результаты масштабирования, что и раньше.
person
gnovice
schedule
09.11.2010