如何使MATLAB的xlim自动对称在0左右?

时间:2016-03-23 09:24:52

标签: matlab plot

我正在制作一个非常简单的散点图。

pts = [1 1; -2 1];
scatter(pts(:, 1), pts(:, 2));

如我们所见,MATLAB自动确定xlim-21,这对我来说是令人满意的。

令我恼火的是原点0没有居中。也就是说,x轴在0附近是不对称的。在这个特定示例中,我希望x轴从-22

我肯定能找到最大的绝对值,在这种情况下为2,并手动执行xlim([-2 2])。是否有更优雅的方式,比如我想象中的axis center

3 个答案:

答案 0 :(得分:2)

据我所知,没有自动化。你必须手动完成。对于单个轴,您可以使用:

xlim(max(abs(xlim)).*[-1 1])

对于使用所有(2或3)轴的单行代码:

axis(reshape([-1;1]*max(reshape(abs(axis),2,[])),1,[]))

答案 1 :(得分:1)

我可以想到两种方法,第一种是迄今为止最容易理解的......

设置您自己的分散功能(未经测试):

function h = yourScatter ( varargin )
  h = scatter ( varargin{:} );
  xlim(max(abs(h.Parent.XLim)).*[-1 1])
end

第二行与@Daniel回答相同。

然后你使用:

pts = [1 1; -2 1];
yourScatter(pts(:, 1), pts(:, 2));    

利用未记录的侦听器

使用一些未记录的侦听器执行的更复杂和完全自动化的方法。

首先我们创建一个用于创建轴的函数(该函数有一个监听器,它调用子函数,在添加数据后设置实际限制):

function ax = setupAutoXAxis
  ax = axes ( 'nextplot', 'add' );
  addlistener ( ax, 'MarkedClean', @updateAx );
end
function updateAx ( ax, event )
  % check that any children have been added
  if ~isempty ( ax.Children )
    % extract out all children XData
    currentLim = max(abs([ax.Children.XData]));
    % Check to see if it needs to be updated.
    if ~isempty ( currentLim ) && ~isequal ( ax.XLim, [-currentLim currentLim] )
      ax.XLim = [-currentLim currentLim];
    end
  end
end

然后你就这样使用它:

ax = setupAutoXAxis()
pts = [1 1; -2 1];
scatter ( ax, pts(:,1), pts(:,2) );

不幸的是,这不适用于添加更多图表 - 因为通过手动设置限制,MarkedClean事件不会被触发(我很惊讶)。我已经看过了,我能得到的最好的解决方法是添加另一个监听器,导致MarkedClean事件被触发(在添加实际子数据之前触发ChildAdded事件,所以我们无法使用它。)

function ax = setupAutoXAxis
  ax = axes ( 'nextplot', 'add' );
  addlistener ( ax, 'ChildAdded', @(a,b)set(ax,'XLimMode','auto') );
  addlistener ( ax, 'MarkedClean', @updateAx );
end
function updateAx ( ax, event )
  % check that any children have been added
  if ~isempty ( ax.Children )
    % extract out all children XData
    currentLim = max(abs([ax.Children.XData]));
    % Check to see if it needs to be updated.
    if ~isempty ( currentLim ) && ~isequal ( ax.XLim, [-currentLim currentLim] )
      ax.XLim = [-currentLim currentLim];
    end
  end
end

ax = setupAutoXAxis()
pts = [1 1; -2 1];
scatter ( ax, pts(:,1), pts(:,2) );
scatter ( ax, pts(:,1)+3, pts(:,2) );

有关信息,这是在R2015a上测试的。

答案 2 :(得分:0)

如果希望使用轴自动功能,该功能可以为轴限制选择“好的”端点,则可以使用以下方法:

plot([0:1:10], [0:2:20], '-k');   % example plot
axis auto;                        % not strictly necessary
limits = max( abs(gca().YLim) );  % take the larger of the two "nice" endpoints
ylim( [-limits, limits] );        % use this nice value for both endpoints