用于自定义误差线图的 CapSize

CapSize for a customized errorbar plot

我正在为自己编写自定义的 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)

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

想法是在绘制垂直线后得到 XLim,然后确定轴的每个帽的宽度分数 XLim,并在 XLim 时使用它相应地缩放帽=11=]被改变了。

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