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

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

Отображения графика столько же линий сколько существуют столбцы в 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

Смотрите также

Классы

Похожие темы