如何为MATLAB errorbar plot的点和垂直线设置不同的图例?

时间:2015-01-20 09:21:40

标签: matlab matlab-figure

我有errorbar图表显示平均值和标准差。我希望有一个圈子的传奇项目,平均值,以及一个单独的栏。像,

--------------------------
| o mean                 |
| | standard deviation   |
--------------------------

MWE

errorbar([1 2], [2 3], [0.1 0.2], 'o');
legend('mean +- stddev', 'Location','north')

给了我这个

enter image description here

2 个答案:

答案 0 :(得分:5)

这样做的一种方法是添加一条不可见的线条。试试这个:

errorbar([1 2], [2 3], [0.1 0.2], 'o');
hold on;
plot(1,3,'-b');
legend('Mean','Standard deviation','Location','north');

答案 1 :(得分:5)

这建立在Jens Boldsen's answer之上,并添加以下内容:

  • 可以旋转表示图例中错误栏的线条,使其垂直,或保持默认水平方向;
  • 该行的末尾是"关闭" 短线

该方法非常通用,因为它支持:

  • 任意颜色 linestyle 标记作为errorbar的参数。请注意,实际条形图始终绘制为实线,没有标记(使用指定的颜色)。这是按errorbar行为。
  • 新创建的短线随图例移动
  • 这些行的宽度是可配置参数。此外,errobar的长度是垂直情况下的参数。两者都以相对于图例的标准化单位定义。

由于R2014b中引入的图形对象的变化,该方法略有不同,具体取决于Matlab版本。此外,图例中的errobar线可以是水平的或垂直的。 所以有四个案例

案例I:Pre-R2014b,图例中的水平误差栏

绘制完数据和图例后,代码将遵循以下步骤:

  1. 获取传奇的孩子
  2. 在这些孩子中找到合适的行
  3. 获取 x y 坐标
  4. 利用这些坐标,在每一端创建两条短线。将这些线条作为传奇的子项,以便它们随之移动。
  5. 该代码已在Matlab R2010b中进行了测试。

    %// Define graph aspect
    color_spec = 'r';       %// color of data and bars.
    linestyle_spec = '--';  %// linestyle for data. The bars are always solid
    marker_spec = 'o';      %// marker for data
    wid = .12;              %// width of bar in legend. Normalized units
    
    %// Plot errobar
    h_er = errorbar([1 2], [2 3], [0.1 0.2], [color_spec linestyle_spec marker_spec]); 
    
    %// Add dummy line for legend (as per Jens Boldsen) and create legend
    hold on;
    plot(0,0,color_spec); %// linestyle is always solid with no marker
    h_le = legend('Mean','Standard deviation','Location','north');
    
    %// Add short lines at each end of line in the legend
    c_le = get(h_le, 'Children');                                                %// step 1
    h_li = findobj(c_le, 'linestyle','-', 'color',color_spec, 'marker','none');  %// step 2
    h_li = h_li(1); %// in case there's more than one
    li_x = get(h_li,'XData');                                                    %// step 3
    li_y = get(h_li,'YData');
    line(li_x([1 1]), li_y+wid*[-.5 .5], 'parent',h_le, 'color',color_spec);     %// step 4
    line(li_x([2 2]), li_y+wid*[-.5 .5], 'parent',h_le, 'color',color_spec);
    

    enter image description here

    案例II:R2014b,图例中的水平误差条

    在Matlab R2014b中,图例不再是轴对象,也没有子对象。因此,必须针对案例I修改步骤1和2:

    1. 创建图例时获取图例
    2. 在这些图标中查找相应的行
    3. 获取其x和y坐标
    4. 利用这些坐标,在每一端创建两条短线。使这些线与初始线共享父线,以便它们与图例一起移动。
    5. 此外,此Matlab版本中的新语法有助于简化代码。

      %// Define graph aspect
      color_spec = 'r';       %// color of data and bars.
      linestyle_spec = '--';  %// linestyle for data. The bars are always solid
      marker_spec = 'o';      %// marker for data
      wid = .12;              %// width of bar in legend. Normalized units
      
      %// Plot errobar
      h_er = errorbar([1 2], [2 3], [0.1 0.2], [color_spec linestyle_spec marker_spec]); 
      
      %// Add dummy line for legend (as per Jens Boldsen)
      hold on;
      plot(0,0,color_spec); %// linestyle is always solid with no marker
      
      %// Create legend and add short lines at each end of line in the legend
      [~, icons] = legend('Mean','Standard deviation','Location','north');           %// 1
      li = findobj(icons, 'type','line', 'linestyle','-');                           %// 2
      li = li(1); %// in case there's more than one
      li_x = li.XData;                                                               %// 3
      li_y = li.YData;
      line(li_x([1 1]), li_y+wid*[-.5 .5], 'parent',li.Parent, 'color',color_spec);  %// 4
      line(li_x([2 2]), li_y+wid*[-.5 .5], 'parent',li.Parent, 'color',color_spec);
      

      enter image description here

      案例III:Pre-R2014b,图例中的垂直错误栏

      这与案例I类似,但是有些人会对这些线条进行调整。 x y 坐标是必需的。此外,还引入了一个新参数来控制图例中错误栏的长度。

      %// Define graph aspect
      color_spec = 'r';       %// color of data and bars.
      linestyle_spec = '--';  %// linestyle for data. The bars are always solid
      marker_spec = 'o';      %// marker for data
      wid = .04;              %// width of bar in legend. Normalized units
      len = .45;              %// length of main bar in legend. Normalized units
      
      %// Plot errobar
      h_er = errorbar([1 2], [2 3], [0.1 0.2], [color_spec linestyle_spec marker_spec]); 
      
      %// Add dummy line for legend (as per Jens Boldsen) and create legend
      hold on;
      plot(0,0,color_spec); %// linestyle is always solid with no marker
      h_le = legend('Mean','Standard deviation','Location','north');
      
      %// Add short lines at each end of line in the legend
      c_le = get(h_le, 'Children');    
      h_li = findobj(c_le, 'linestyle','-', 'color',color_spec, 'marker','none');
      h_li = h_li(1); %// in case there's more than one
      set(h_li,'XData', repmat(mean(get(h_li,'XData')),1,2));
      set(h_li,'YData', mean(get(h_li,'YData'))+len*[-.5 .5]);
      li_x = get(h_li,'XData');
      li_y = get(h_li,'YData');
      line(li_x+wid*[-.5 .5], li_y([1 1]), 'parent',h_le, 'color',color_spec);
      line(li_x+wid*[-.5 .5], li_y([2 2]), 'parent',h_le, 'color',color_spec);
      

      enter image description here

      案例IV:R2014b,图例中的垂直错误栏

      同样,这与案例II类似,但有一些摆弄线条'坐标。

      %// Define graph aspect
      color_spec = 'r';       %// color of data and bars.
      linestyle_spec = '--';  %// linestyle for data. The bars are always solid
      marker_spec = 'o';      %// marker for data
      wid = .05;              %// width of small bars in legend. Normalized units
      len = .45;              %// length of main bar in legend. Normalized units
      
      %// Plot errobar
      h_er = errorbar([1 2], [2 3], [0.1 0.2], [color_spec linestyle_spec marker_spec]); 
      
      %// Add dummy line for legend (as per Jens Boldsen)
      hold on;
      plot(0,0,color_spec); %// linestyle is always solid with no marker
      
      %// Create legend, modify line and add short lines
      [~, icons] = legend('Mean','Standard deviation','Location','north');             
      li = findobj(icons, 'type','line', 'linestyle','-');
      li = li(1); %// in case there's more than one
      li.XData = repmat(mean(li.XData),1,2);                                           
      li.YData = mean(li.YData)+len*[-.5 .5];
      li_x = li.XData;
      li_y = li.YData;
      line(li_x+wid*[-.5 .5], li_y([1 1]), 'parent',li.Parent, 'color',color_spec);
      line(li_x+wid*[-.5 .5], li_y([2 2]), 'parent',li.Parent, 'color',color_spec);
      

      enter image description here