【问题标题】:How to compute confidence intervals and plot them on a bar plot如何计算置信区间并将它们绘制在条形图上
【发布时间】:2019-12-10 12:22:42
【问题描述】:

我怎样才能从一个条形图中绘制一个条形

data = 1x10 cell ,其中单元格中的每个值都有不同的尺寸,例如 3x100、3x40、66x2 等。

我的目标是获得一个条形图,其中我将有 10 组条形图,并且在每组中,每个值都有 3 个条形图。在条形图上,我希望它显示值的中位数,并且我想计算置信区间并另外显示它。

在此示例中,没有柱状组,但我的意思是向您展示我希望如何显示置信区间。在site,我在这里找到了这个例子,他们提供了一个解决方案,他们有这个命令行

e1 = errorbar(mean(data), ci95);

但我的问题是找不到任何 ci95

那么,有没有其他有效的方法来做到这一点,而无需安装或下载额外的服务?

【问题讨论】:

  • 您的问题是如何在 matlab 中获得 95% 的置信区间(在某些情况下)或如何绘制条形图?
  • 如果你想为单元格中的每个元素设置三个条,你想如何从 66×2 大小的元素中制作三个条?一根柱子的高度应该为零吗?
  • @Argyll 问题是如何绘制置信区间
  • @PatrickHappel 图片与条数无关。这只是为了显示我想要一个置信区间在我的柱上
  • @CroatiaHR:置信区间总是与平均值、标准差等的估计值相关联。置信区间假设一个潜在分布,您需要在其他地方确认其真实性。你了解它的工作原理吗?

标签: matlab plot bar-chart confidence-interval


【解决方案1】:

由于我不确定您的数据是什么样子,因为在您的问题中您说单元格的元素包含具有不同维度的数据,例如

3x100、3x40、66x2

我假设您的数据可以按列或行排列,并且并非所有数据都需要三个条形。

由于您没有提供一小段数据供我们测试,我生成了一些人工数据:

data = cell(1,10);

% Random length of the data
l = randi(500, 10, 1) + 50;  

% Random "width" of the data, with 3 more likely
w = randi(4, 10, 1);
w(w==4) = 3;
% random "direction" of the data
d = randi(2, 10, 1);

% sigma of the data (in fraction of mean)
sigma = rand(10,1) / 3;

% means of the data
dmean = randi(150,10,1);
dsigma = dmean.*sigma;

for c = 1 : 10
    if d(c) == 1
        data{c} = randn(l(c), w(c)) .* dsigma(c) + dmean(c);
    else
        data{c} = randn(w(c), l(c)) .* dsigma(c) + dmean(c);
    end
end

接下来是

在条形图上,我希望它显示值的中位数,并且我想计算置信区间并另外显示它。

您确定要绘制中位数吗?一些数据的中位数与数据的方差无关,因此不需要任何类型的误差线。我猜你想显示平均值。如果您真的想显示中位数,box plot 可能是更好的选择。

以下代码计算并绘制条形图中的平均值:

means = zeros(numel(data),3);
stds = zeros(numel(data),3);
n = zeros(numel(data),3);
for c = 1:numel(data)
    d = data{c};
    if size(d,1) < size(d,2)
        d = d';
    end
    cols = size(d,2);
    means(c, 1:cols) = nanmean(d);
    stds(c, 1:cols) = nanstd(d);
    n(c, 1:cols) = sum(~isnan((d)));
end

b = bar(means);

现在,我们需要计算误差线的长度。典型的选择是standard deviation of the data(已经由上面的代码计算,存储在stds)、standard error 或 95% 置信区间(这是标​​准误差的 1.96 倍,假设基础数据遵循@ 987654324@).

% for standard deviation use stds

% for standard error
ste = stds./sqrt(n);

% for 95% confidence interval
ci95 = 1.96 * ste;

最后一件事是绘制误差线。在这里,我选择了您在问题中询问的 ci95,如果您想更改它,只需将调用中的变量更改为 errorbar

for c = 1:3
    size(means(:, c))
    size(b(c).XData)
    e = errorbar(b(c).XData + b(c).XOffset, means(:,c), ci95(:, c));
    e.LineStyle = 'none';
end

【讨论】:

  • 1.96 因子假定底层证券的正态分布。很高兴你能解释一切。但我认为对于 OP 来说,跳到 1.96 不一定有好处,因为他目前不知道置信区间的工作原理。
  • 我添加了计算 95% 置信区间的限制。我只是把它包括在内,因为它在标题中明确提到。它可能会帮助其他将要搜索它的人。
  • 我明白了。出于完全相同的原因,我更改了问题的标题 - 它更好地反映了该线程的内容,并且与旧标题相比实际上是可搜索的。
  • 解释得很好。
  • @PatrickHappel,由于一个小错误,您的代码对我不起作用。你能在最后一个for 循环之前添加一个hold on 语句吗?然后我可以删除下面的答案,以及tie up some other loose ends
【解决方案2】:

我发现 Patrick Happel 的答案不起作用,因为图形窗口(以及变量 b)被随后对 errorbar 的调用清除了。只需添加 hold on 命令即可解决此问题。为避免混淆,这里有一个新答案,它复制了 Patrick 的所有原始代码,加上我的小调整:

%% Old answer
%Just to be safe, let's clear everything
clear all

data = cell(1,10);

% Random length of the data
l = randi(500, 10, 1) + 50;  

% Random "width" of the data, with 3 more likely
w = randi(4, 10, 1);
w(w==4) = 3;
% random "direction" of the data
d = randi(2, 10, 1);

% sigma of the data (in fraction of mean)
sigma = rand(10,1) / 3;

% means of the data
dmean = randi(150,10,1);
dsigma = dmean.*sigma;

for c = 1 : 10
    if d(c) == 1
        data{c} = randn(l(c), w(c)) .* dsigma(c) + dmean(c);
    else
        data{c} = randn(w(c), l(c)) .* dsigma(c) + dmean(c);
    end
end
%============================================
%Next thing is 
%    On the bar, I want it to be shown the median of the values, and I
%    want to calculate the confidence interval and show it additionally.
%
%Are you really sure you want to plot the median? The median of some data
%is not connected to the variance of the data, and hus no type of error
%bars are required. I guess you want to show the mean. If you really want
%to show the median, a box plot might be a better alternative.
%
%The following code computes and plots the mean in a bar plot:
%============================================
means = zeros(numel(data),3);
stds = zeros(numel(data),3);
n = zeros(numel(data),3);
for c = 1:numel(data)
    d = data{c};
    if size(d,1) < size(d,2)
        d = d';
    end
    cols = size(d,2);
    means(c, 1:cols) = nanmean(d);
    stds(c, 1:cols) = nanstd(d);
    n(c, 1:cols) = sum(~isnan((d)));
end

b = bar(means);

%% New code
%This ensures that b continues to reference existing data in the next for
%loop, as the graphics objects can otherwise be deleted.  
hold on
%% Continuing Patrick Happel's answer
%============================================
%Now, we need to compute the length of the error bars. Typical choices are
%the standard deviation of the data (already computed by the code above,
%stored in stds), the standard error or the 95% confidence interval (which
%is the 1.96fold of the standard error, assuming the underlying data
%follows a normal distribution).
%============================================
% for standard deviation use stds

% for standard error
ste = stds./sqrt(n);

% for 95% confidence interval
ci95 = 1.96 * ste;
%============================================
%Last thing is to plot the error bars. Here I chose the ci95 as you asked
%in your question, if you want to change that, simply change the variable
%in the call to errorbar:
%============================================
for c = 1:3
    size(means(:, c))
    size(b(c).XData)
    e = errorbar(b(c).XData + b(c).XOffset, means(:,c), ci95(:, c));
    e.LineStyle = 'none';
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-16
    • 2020-11-19
    • 2021-04-08
    • 2012-11-01
    • 2021-07-05
    • 1970-01-01
    相关资源
    最近更新 更多