【问题标题】:Plot line-chart on the left axis uper the bar-chart on the right axis在左轴上绘制折线图,​​在右轴上绘制条形图
【发布时间】:2016-10-09 03:55:47
【问题描述】:

在具有两个 y 轴的图表中,一个用于折线图(左)和一个用于条形图(右),我希望条形图位于折线图下方以获得更好的可见性,而不是上方它。

正如你在这张图片上看到的(我希望你能看到),条形图显示了降水的演变,不同的线显示了叶绿素指数的演变,我的问题是条形图覆盖了线条我希望这条线更高。

这是我的脚本:

figure
yyaxis right
bar (meteo(:,1),meteo(:,14));
ylabel('Precipitation (mm)');
hold on
for i=1:6;
    a = [];
    b = [];
    color = ['r' 'm' 'b' 'c' 'g' 'y'];
    for j=0:6
        a(i,j+1)=matrice_5(j*6+i,1);%jour
        b(i,j+1)=matrice_5(j*6+i,3);%moyenne       
    end
        hold on
        yyaxis left
        plot(a(i,:),b(i,:),color(i),'LineWidth',1.5);  
end
title('Evolution of the mean of the chlorophyll index (HNT) - Charlotte variety');
xlabel('Day (2013)')
ylabel('Chlorophyll index (HNT)')
axis([735390 735442 32 50]);
set(gcf,'Position',[645 206 701 477]);
datetick('x','dd mmm','keepticks')
h=legend('0','50','100','150','200','250','precipitation','Location','best');
v = get(h,'title');
set(v,'string','Nitrogen rate in kg/ha');
set(h,'Position', [0.1793 0.1494 0.1127 0.2446]);
hold on
plot([735422 735422],[32 49],'Color',[.3 .3 .3]);
hold off

到目前为止,我只得到了一半的结果。我想将条形图放在左轴(y 轴左)上,将折线图放在右轴上。我想把叶绿素指数保留在左边。

感谢您的帮助

【问题讨论】:

    标签: matlab plot bar-chart


    【解决方案1】:

    这实际上是一个非常棒的问题,因为确实没有明确记录的方法可以做到这一点,并且在所有示例中,右侧轴上的任何内容都显示在顶部。即使在他们自己网站上的这个example 中,请注意他们在左轴上绘制bar 是多么小心。

    作为前言,yyaxis 不会创建单独的轴(就像 yyplot 过去那样),而是 rather just applies an additional NumericRuler to the same axes。如果它只是不同的axes,我们可以使用uistack以我们想要的任何方式重新排序轴,但是因为它们是相同axes,我们需要仔细观察在axes 属性中控制内容的 z 顺序。

    当我们查看这些属性时,yyaxis 会自动将坐标区的 SortMethod 从其默认值 depth 更改为 children。这使得出现在左轴中的任何对象都低于添加到右轴的任何对象。所以我们需要做的就是解决这个问题,将SortMethod改回默认值(depth),然后排序将取决于z位置,就像它通常在axes中一样。

    所以作为演示,让我们创建一些数据

    days = 0:5:35;
    conc = [515 420 370 250 135 120 60 20];
    temp = [29 23 27 25 20 23 23 17];
    

    像你一样创建图(一条线和一个条,右边有条)

    yyaxis right
    b = bar(days, temp, 'FaceColor', [0.8 0.8 0.8]);
    yyaxis left
    p = plot(days, conc, 'LineWidth', 2);
    

    现在如果我们更改SortMethod,它会将线对象置于顶部。

    set(gca, 'SortMethod', 'depth')
    

    【讨论】:

    • 谢谢。我确实喜欢你的建议,它几乎可以完成工作。正如您在我的问题图片上看到的那样,图表的每个条形都被黑色包围。所以当我应用你的代码集(gca,'SortMethod','depth')时。绘图线超出条形图的字体大小,但不超过那些黑色条形边框。知道为什么吗?顺便说一句:你怎么能像你在图表上那样取出轴?并且在您的条形图上没有边框?
    【解决方案2】:

    这很有帮助。只是为了提供更多示例,如果是两条线图,您需要显式指定 ZData 属性来控制堆栈顺序。

    days = 0:5:35;
    conc = [515 420 370 250 135 120 60 20];
    
    figure
    
    yyaxis left
    p1 = plot(days, conc, 'LineWidth', 4);
    
    yyaxis right
    p2 = plot(days, fliplr(conc), 'LineWidth', 4);
    
    % orange is on top
    

    get(gca,'SortMethod')
    set(gca, 'SortMethod', 'depth')
    
    % orange is still on top
    

    p1.ZData = ones(size(p1.XData));
    p2.ZData = zeros(size(p2.XData));
    
    % blue is on top
    

    【讨论】:

      【解决方案3】:

      将@Kouichi C. Nakamura 的出色答案封装在一个方便的函数中,该函数将其应用于轴的所有线,得到:

      function ax = setZData(ax,val)
          ax = arrayfun(@(x)setZData_ax(x,val),ax);
      
          function ax = setZData_ax(ax,val)
              ax.ZData = val*ones(size(ax.XData));
          end
      end
      

      或者一个完整的包装器

      function varargout = plotLeftOverRitht(LR,varargin)
      % wrapper to plot the left axis of dual-axis plot over the right axis
      
      %% process input
      % input string
      if strcmpi(LR,'left')
          LR = 'left';
          val = 1;
      elseif strcmpi(LR,'right')
          LR = 'right';
          val = 0;
      else
          error('plotLeftOverRitht:Input:LR',"The first input must be either 'left' or 'right'.")
      end
      
      % input: axis handle?
      if isa(varargin{1},'matlab.graphics.axis.Axes')
          ax = varargin{1};
          varargin = varargin(2:end);
      else
          ax = gca;
      end
      
      %% main function
      % activate left axis
      yyaxis( ax, LR);
      % call plot
      lines = plot(   ax, varargin{:});
      % set height
      setZData(lines,val);
      % set sorting order
      set(ax, 'SortMethod', 'depth')
      
      %% output
      if nargout > 0
          varargout = ax;
      end
      end
      

      这将上面的示例更改为

      days = 0:5:35;
      conc = [515 420 370 250 135 120 60 20];
      
      figure
      plotLeftOverRitht('left', days,conc, 'LineWidth',4)
      plotLeftOverRitht('right', days,fliplr(conc), 'LineWidth',4)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-09-01
        • 2020-05-06
        • 2018-02-08
        • 1970-01-01
        • 1970-01-01
        • 2019-07-15
        • 2014-08-22
        • 2019-05-24
        相关资源
        最近更新 更多