Main Content

用于显示不定数量的线条的优化图类

此示例说明如何优化一个图类以显示不定数量的线条。它重用现有线条对象,这可以提高图的性能,尤其是在线条的数量不经常变化的情况下。有关未经优化的此图的更简单版本,请参阅具有可变数量的线条的图类

图显示的线条数与 YData 矩阵中的列数一样多,在局部极值处有圆形标记。以下代码说明如何:

  • 定义两个属性,名称分别为 PlotLineArrayExtremaLine,分别用于存储线条和标记的对象。

  • 实现用于初始化 ExtremaLine 对象的 setup 方法。

  • 实现用于获取 PlotLineArray 的大小的 update 方法,然后根据 YData 中的列数在该数组中加减对象。

要定义该类,请将以下代码复制到编辑器中,并将其以名称 OptimLocalExtremaChart.m 保存在可写文件夹中。

classdef OptimLocalExtremaChart < matlab.graphics.chartcontainer.ChartContainer
    % c = OptimLocalExtremaChart('XData',X,'YData',Y,Name,Value,...)
    % plots one line with markers at local extrema for every column of matrix Y. 
    % You can also specify the additonal name-value arguments, 'MarkerColor' 
    % and 'MarkerSize'.
    
    properties
        XData (:,1) double = NaN
        YData (:,:) double = NaN
        MarkerColor {validatecolor} = [1 0 0]
        MarkerSize (1,1) double = 5
    end
    properties(Access = private,Transient,NonCopyable)
        PlotLineArray (:,1) matlab.graphics.chart.primitive.Line
        ExtremaLine (:,1) matlab.graphics.chart.primitive.Line
    end
    
    methods(Access = protected)
        function setup(obj)
            obj.ExtremaLine = matlab.graphics.chart.primitive.Line(...
                'Parent', obj.getAxes(), 'Marker', 'o', ...
                'MarkerEdgeColor', 'none', 'LineStyle',' none');
        end
        function update(obj)
            % Get the axes
            ax = getAxes(obj);
            
            % Create extra lines as needed
            p = obj.PlotLineArray;
            nPlotLinesNeeded = size(obj.YData, 2);
            nPlotLinesHave = numel(p);
            for n = nPlotLinesHave+1:nPlotLinesNeeded
                p(n) = matlab.graphics.chart.primitive.Line('Parent', ax, ...
                    'SeriesIndex', n, 'LineWidth', 2);
            end
            
            % Update the lines
            for n = 1:nPlotLinesNeeded
                p(n).XData = obj.XData;
                p(n).YData = obj.YData(:,n);
            end
            
            % Delete unneeded lines
            delete(p((nPlotLinesNeeded+1):numel(p)))
            obj.PlotLineArray = p(1:nPlotLinesNeeded);
            
            % Replicate x-coordinate vectors to match size of YData
            newx = repmat(obj.XData(:),1,size(obj.YData,2));
            
            % Find local minima and maxima and plot markers
            tfmin = islocalmin(obj.YData,1);
            tfmax = islocalmax(obj.YData,1);
            obj.ExtremaLine.XData = [newx(tfmin); newx(tfmax)];
            obj.ExtremaLine.YData = [obj.YData(tfmin); obj.YData(tfmax)];
            obj.ExtremaLine.MarkerFaceColor = obj.MarkerColor;
            obj.ExtremaLine.MarkerSize = obj.MarkerSize;
            
            % Make sure the extrema are on top
            uistack(obj.ExtremaLine, 'top');
        end
    end
end

保存类文件后,可以创建图的实例。例如:

x = linspace(0,2)';
y = cos(5*x)./(1+x.^2);
c = OptimLocalExtremaChart('XData',x,'YData',y);

现在,创建一个 for 循环,该循环在每次迭代时向图中添加一个线条。图对象会保留所有现有线条,并为每个 i 另外添加一个线条。

for i=1:10
    y = cos(5*x+i)./(1+x.^2);
    c.YData = [c.YData y];
end

另请参阅

相关主题