Оптимизированный класс графика для отображения переменного количества линий

В этом примере показано, как оптимизировать класс графика для отображения переменного количества линий. Он повторно использует существующие объекты линий, что может улучшить эффективность графика, особенно если количество строк изменяется не часто. Для более простой версии этого графика без оптимизации смотрите Класс диаграммы с переменным количеством линий.

На графике отображаются столько линии, сколько столбцов в YData матрица с круговыми маркерами в локальной экстреме. Следующий код демонстрирует, как:

  • Задайте два свойства, называемые PlotLineArray и ExtremaLine которые хранят объекты для линий и маркеров, соответственно.

  • Реализуйте setup метод, который инициализирует ExtremaLine объект.

  • Реализуйте update метод, который получает размер PlotLineArray, а затем добавляет или вычитает объекты из этого массива в соответствии с количеством столбцов в 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

См. также

Классы

Похожие темы