首页 > 解决方案 > 自定义误差线图的 CapSize

问题描述

我正在errorbar为自己编写一个自定义函数。但是我不知道怎么控制的CapSize,好像是在默认的errorbar里控制的;放大或缩小不会放大 Cap。我的代码的简化版本如下 -

function myErrorbar(x, y, h)
for i = 1:length(x)
    y1 = y(i)-h(i);
    y2 = y(i)+h(i);

    x1 = x(i)-0.1*h(i);
    x2 = x(i)+0.1*h(i);
    % errorbar
    line([x(i), x(i)], [y1, y2]); hold on 
    % caps
    line([x1, x2], [y1, y1])
    line([x1, x2], [y2, y2])
end

在上面的代码中,我将大写的大小固定为两边的 h 的 10%。我想控制倾覆,就像它可以在默认情况下完成一样。可以使用以下代码测试代码

x = 1:10:100;
y = [20 30 45 40 60 65 80 75 95 90];
err = 8*ones(size(y));
myErrorbar(x,y,err)

标签: matlabplotgraphicsmatlab-figure

解决方案


就像 Adriaan 在他的评论中提到的那样,这可以通过向XLim要绘制的轴的属性添加一个侦听器来实现。请参阅下面的代码和注释以获取解释。

这个想法是XLim在绘制垂直线之后获得,然后确定轴的每个帽的宽度分数XLim,并在更改时使用它来相应地缩放帽XLim

function myErrorbar(ax, x, y, err, color)

    % color input argument handling
    if ~exist('color', 'var') || isempty(color)
        color = lines(1); % default lightblue color
    end

    % first plot the vertical lines (so XLim is set to right value)
    y_bot = y - err;
    y_top = y + err;
    % errorbar
    l = line([x; x], [y_bot; y_top], 'color', color);
    hold on

    % get the current XLim
    x_fracs = NaN(size(x)); % variable to store fractions of XLim
    cur_xlim = diff(ax.XLim); % current XLim

    % plot the caps
    x_left = x - 0.1 .* err;
    x_right = x + 0.1 .* err;

    c_top = line([x_left; x_right], [y_top; y_top], 'color', color);
    c_bot = line([x_left; x_right], [y_bot; y_bot], 'color', color);

    % determine width fraction of current x limit
    x_fracs = (x_right - x_left) ./ cur_xlim;

    % add listener for xlim
    addlistener(ax, 'XLim', 'PostGet', @updateCaps);

    % --------------------------------------------------------------------------

    % callback to update cap width
    function updateCaps(hProperty, eventData)

        % update XLim
        cur_xlim = diff(ax.XLim);

        % determine new cap widths and positions
        cap_width = x_fracs .* cur_xlim;
        x_left = x - 0.5 .* cap_width;
        x_right = x + 0.5 .* cap_width;

        % set cap line x and y data
        for k = 1:length(x)
            c_top(k).XData = [x_left(k), x_right(k)];
            c_bot(k).XData = [x_left(k), x_right(k)];
        end
    end
end

推荐阅读