【问题标题】:Plotting 4 curves in a single plot, with 3 y-axes在单个图中绘制 4 条曲线,带有 3 个 y 轴
【发布时间】:2010-12-15 16:45:53
【问题描述】:

我有 4 组值:y1y2y3y4 和一组 x。 y 值的范围不同,我需要将它们绘制为单独的曲线,并在 y 轴上使用不同的值集。

简单地说,我需要 3 个具有不同值(比例)的 y 轴来绘制同一个图。

任何帮助表示赞赏,或在哪里寻找提示。

【问题讨论】:

    标签: matlab plot


    【解决方案1】:

    这是向您介绍File Exchange. 的好机会尽管最近该组织遭受了一些非常不幸的界面设计选择,但它仍然是解决常见问题的预打包解决方案的绝佳资源。尽管这里的许多人已经为您提供了如何实现这一目标的血腥细节(@prm!),但几年前我也有类似的需求,发现addaxis 工作得很好。 (曾经是File Exchange pick of the week!)它启发了later, probably better mods。这是一些示例输出:


    (来源:mathworks.com

    我刚刚在File Exchange.搜索了“plotyy”

    虽然了解发生的事情很重要,但有时您只需要完成工作,而不是自己动手。 Matlab Central 非常适合。

    【讨论】:

    • x轴有类似的吗?
    • 我不喜欢任何关于文件交换的解决方案(我可以找到)。它们不允许您将所有 Y 轴放在一侧或另一侧。我发现交替的面看起来很难看。唯一一个允许所有到一侧的方法对于初学者来说实现起来很复杂。
    【解决方案2】:

    在两个轴之外很难找到多尺度图......幸运的是,在 Matlab 中这是可能的,但您必须完全重叠轴并使用刻度线,以免隐藏信息。

    下面是一个很好的工作示例。我希望这是您正在寻找的(虽然颜色可能会更好)!

    close all
    clear all 
    
    display('Generating data');
    
    x = 0:10;
    y1 = rand(1,11);
    y2 = 10.*rand(1,11);
    y3 = 100.*rand(1,11);
    y4 = 100.*rand(1,11);
    
    display('Plotting');
    
    figure;
    ax1 = gca;
    get(ax1,'Position')
    set(ax1,'XColor','k',...
        'YColor','b',...
        'YLim',[0,1],...
        'YTick',[0, 0.2, 0.4, 0.6, 0.8, 1.0]);
    line(x, y1, 'Color', 'b', 'LineStyle', '-', 'Marker', '.', 'Parent', ax1)
    
    ax2 = axes('Position',get(ax1,'Position'),...
               'XAxisLocation','bottom',...
               'YAxisLocation','left',...
               'Color','none',...
               'XColor','k',...
               'YColor','r',...
               'YLim',[0,10],...
               'YTick',[1, 3, 5, 7, 9],...
               'XTick',[],'XTickLabel',[]);
    line(x, y2, 'Color', 'r', 'LineStyle', '-', 'Marker', '.', 'Parent', ax2)
    
    ax3 = axes('Position',get(ax1,'Position'),...
               'XAxisLocation','bottom',...
               'YAxisLocation','right',...
               'Color','none',...
               'XColor','k',...
               'YColor','g',...
               'YLim',[0,100],...
               'YTick',[0, 20, 40, 60, 80, 100],...
               'XTick',[],'XTickLabel',[]);
    line(x, y3, 'Color', 'g', 'LineStyle', '-', 'Marker', '.', 'Parent', ax3)
    
    ax4 = axes('Position',get(ax1,'Position'),...
               'XAxisLocation','bottom',...
               'YAxisLocation','right',...
               'Color','none',...
               'XColor','k',...
               'YColor','c',...
               'YLim',[0,100],...
               'YTick',[10, 30, 50, 70, 90],...
               'XTick',[],'XTickLabel',[]);
    line(x, y4, 'Color', 'c', 'LineStyle', '-', 'Marker', '.', 'Parent', ax4)
    


    (来源:pablorodriguez.info

    【讨论】:

      【解决方案3】:

      在您的情况下,有 3 个额外的 y 轴(总共 4 个),上面说明了可用于实现您想要的和处理其他情况的最佳代码:

      clear
      clc
      
      x = linspace(0,1,10);
      N = numel(x);
      y = rand(1,N);
      y_extra_1 = 5.*rand(1,N)+5;
      y_extra_2 = 50.*rand(1,N)+20;
      Y = [y;y_extra_1;y_extra_2];
      
      xLimit = [min(x) max(x)];
      xWidth = xLimit(2)-xLimit(1);
      numberOfExtraPlots = 2;
      a = 0.05;
      N_ = numberOfExtraPlots+1;
      
      for i=1:N_
          L=1-(numberOfExtraPlots*a)-0.2;
          axesPosition = [(0.1+(numberOfExtraPlots*a)) 0.1 L 0.8];
          if(i==1)
              color = [rand(1),rand(1),rand(1)];
              figure('Units','pixels','Position',[200 200 1200 600])
              axes('Units','normalized','Position',axesPosition,...
                  'Color','w','XColor','k','YColor',color,...
                  'XLim',xLimit,'YLim',[min(Y(i,:)) max(Y(i,:))],...
                  'NextPlot','add');
              plot(x,Y(i,:),'Color',color);
              xlabel('Time (s)');
      
              ylab = strcat('Values of dataset 0',num2str(i));
              ylabel(ylab)
      
              numberOfExtraPlots = numberOfExtraPlots - 1;
          else
              color = [rand(1),rand(1),rand(1)];
              axes('Units','normalized','Position',axesPosition,...
                  'Color','none','XColor','k','YColor',color,...
                  'XLim',xLimit,'YLim',[min(Y(i,:)) max(Y(i,:))],...
                  'XTick',[],'XTickLabel',[],'NextPlot','add');
              V = (xWidth*a*(i-1))/L;
              b=xLimit+[V 0];
              x_=linspace(b(1),b(2),10);
              plot(x_,Y(i,:),'Color',color);
              ylab = strcat('Values of dataset 0',num2str(i));
              ylabel(ylab)
      
              numberOfExtraPlots = numberOfExtraPlots - 1;
          end
      end
      

      The code above will produce something like this:

      【讨论】:

        【解决方案4】:

        我知道plotyy 允许您有两个 y 轴,但没有“plotyyy”!

        也许您可以将 y 值归一化以具有相同的比例(最小/最大归一化、zscore 标准化等),然后您可以使用普通的plot, hold 序列轻松绘制它们。

        这是一个例子:

        %# random data
        x=1:20;
        y = [randn(20,1)*1 + 0 , randn(20,1)*5 + 10 , randn(20,1)*0.3 + 50];
        
        %# plotyy
        plotyy(x,y(:,1), x,y(:,3))
        
        %# orginial
        figure
        subplot(221), plot(x,y(:,1), x,y(:,2), x,y(:,3))
        title('original'), legend({'y1' 'y2' 'y3'})
        
        %# normalize: (y-min)/(max-min) ==> [0,1]
        yy = bsxfun(@times, bsxfun(@minus,y,min(y)), 1./range(y));
        subplot(222), plot(x,yy(:,1), x,yy(:,2), x,yy(:,3))
        title('minmax')
        
        %# standarize: (y - mean) / std ==> N(0,1)
        yy = zscore(y);
        subplot(223), plot(x,yy(:,1), x,yy(:,2), x,yy(:,3))
        title('zscore')
        
        %# softmax normalization with logistic sigmoid ==> [0,1]
        yy = 1 ./ ( 1 + exp( -zscore(y) ) );
        subplot(224), plot(x,yy(:,1), x,yy(:,2), x,yy(:,3))
        title('softmax')
        

        【讨论】:

        【解决方案5】:

        您可以尝试的一种可能性是创建 3 个轴,将前两个的 'Color' 属性设置为 'none',以便所有图都可见。您必须调整轴的宽度、位置和 x 轴限制,以使 3 个 y 轴并排而不是彼此重叠。您还需要从 2 个轴上删除 x 轴刻度线和标签,因为它们将相互重叠。

        这是一个通用实现,它计算轴的正确位置和 x 轴限制的偏移量,以保持绘图正确排列:

        %# Some sample data:
        x = 0:20;
        N = numel(x);
        y1 = rand(1,N);
        y2 = 5.*rand(1,N)+5;
        y3 = 50.*rand(1,N)-50;
        
        %# Some initial computations:
        axesPosition = [110 40 200 200];  %# Axes position, in pixels
        yWidth = 30;                      %# y axes spacing, in pixels
        xLimit = [min(x) max(x)];         %# Range of x values
        xOffset = -yWidth*diff(xLimit)/axesPosition(3);
        
        %# Create the figure and axes:
        figure('Units','pixels','Position',[200 200 330 260]);
        h1 = axes('Units','pixels','Position',axesPosition,...
                  'Color','w','XColor','k','YColor','r',...
                  'XLim',xLimit,'YLim',[0 1],'NextPlot','add');
        h2 = axes('Units','pixels','Position',axesPosition+yWidth.*[-1 0 1 0],...
                  'Color','none','XColor','k','YColor','m',...
                  'XLim',xLimit+[xOffset 0],'YLim',[0 10],...
                  'XTick',[],'XTickLabel',[],'NextPlot','add');
        h3 = axes('Units','pixels','Position',axesPosition+yWidth.*[-2 0 2 0],...
                  'Color','none','XColor','k','YColor','b',...
                  'XLim',xLimit+[2*xOffset 0],'YLim',[-50 50],...
                  'XTick',[],'XTickLabel',[],'NextPlot','add');
        xlabel(h1,'time');
        ylabel(h3,'values');
        
        %# Plot the data:
        plot(h1,x,y1,'r');
        plot(h2,x,y2,'m');
        plot(h3,x,y3,'b');
        

        这是结果图:

        【讨论】:

          【解决方案6】:

          PLOTYY 允许两个不同的 y 轴。或者您可以从文件交换中查看LayerPlot。我想我应该问一下您是否考虑过使用HOLD 或者只是重新调整数据并使用常规的旧图?

          OLD,不是 OP 想要的: SUBPLOT 允许您将图形窗口分成多个轴。然后,如果您只想显示一个 x 轴,或进行一些其他自定义,您可以独立操作每个轴。

          【讨论】:

          • 没有。不是这个。我需要它们在一个图形上,在一个图形上。
          • 哦,看来我们对情节和缩放有相同的想法!
          • @Amro - 有点,我的缩放想法将类似于将所有向量除以它们的最大值。你的例子很复杂!
          猜你喜欢
          • 1970-01-01
          • 2021-07-18
          • 2021-11-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-10-17
          相关资源
          最近更新 更多