Как сделать так, чтобы предыдущие входные данные постепенно исчезали на графике Matlab, когда я добавляю новые входные данные - PullRequest
0 голосов
/ 03 декабря 2018

Допустим, у меня есть этот очень простой цикл

for i=1:10
    [xO, yO, xA, yA, xB, yB, xC, yC] = DoSomething(i);
    line([xO,xA,xB,xC],[yO,yA,yB,yC]);
    pause(0.1);
end

Координаты, которые я строю, соответствуют соединениям многотельной системы, и я моделирую их положение с течением времени (см. Образецграфик здесь):

Periodic plot

Поскольку некоторые ссылки перемещаются периодически, возникает путаница, чтобы визуально отслеживать движение.По этой причине теперь возникает вопрос: как я могу нарисовать линии таким образом, чтобы при построении новой линии предыдущие линии постепенно исчезали?Другими словами, чтобы у меня был градиент от самых последних построенных данных (наиболее непрозрачных) к самым старым данным (все более прозрачным, пока они полностью не исчезнут).

Таким образом, когда вта же позиция, что и у очень старых данных, замечу, что это новая.

Ответы [ 3 ]

0 голосов
/ 03 декабря 2018

Решение для Matlab 2018a или более поздней версии (или ранее, не позднее 2012a)

Поскольку четвертый параметр цвета в качестве альфа-значения больше не поддерживается в Matlab 2018a (и, очевидно, былникогда не предполагал, как указал Крис Луенго), здесь решение, которое работает в Matlab 2018a с использованием функции patchline из обмена файлами (кредит Бретту Шоелсону).

% init the figure
figure(); axes();
hold on; xlim([-1 0.5]); ylim([0 1]);

% set fraction of alpha value to take
alpha_fraction = 0.7;
n_iterations = 200;

% looping variable to prevent deleting and calling already deleted lines
% i.e. to keep track of which lines are already deleted
delete_from = 1;

for i=1:n_iterations
    % your x, y data
    [x, y] = doSomething(i);

    % create line with transparency using patchline
    p(i) = patchline(x,y, 'linewidth', 1, 'edgecolor', 'k');

    % set alpha of line to fraction of previous alpha value
    % only do when first line is already plotted
    if i > 1
        % loop over all the previous created lines up till this iteration
        % when it still exists (delete from that index)
        for j = delete_from:i-1       
            % Update the alpha to be a fraction of the previous alpha value
            p(j).EdgeAlpha = p(j).EdgeAlpha*alpha_fraction;

            % delete barely visible lines
            if p(j).EdgeAlpha < 0.01 && delete_from > j
                delete(p(j));
                % exclude deleted line from loop, so edgealpha is not
                % called again
                delete_from = j;
            end
        end
    end
    % pause and behold your mechanism 
    pause(0.1);
end

Я включил удаление едва видимых линий, как предложено @Wolfie (моя собственная, возможно, менее изящная реализация)

А здесь демонстрация механизма быстрого выпуска:

Quick-release-mechanism

0 голосов
/ 04 декабря 2018

Я добавляю второй ответ, чтобы четко разделить два совершенно разных подхода.Мой 1-й ответ использует недокументированную (и по состоянию на 2018b, амортизированную) прозрачность для линий.

Этот ответ предлагает другой подход для рисования линий, который не имеет проблем с совместимостью (эти две «функции» могут быть реализованы независимо):

  • Создание фиксированных n линий и обновлениеих положение, а не создание растущего числа линий.
  • Перекрасьте линии, постепенно переходя в белый цвет, вместо изменения прозрачности.

Вот код, подробности см. в комментариях:

% "Buffer" size, number of historic lines to keep, and governs the 
% corresponding fade increments.
nFade = 100;

% Set up some demo values for plotting around a circle
dt = 0.05; a = 0:dt:2*pi+(dt*nFade); n = numel(a); b = a.*4;
[x1,y1] = pol2cart( a, ones(1,n) ); [x2,y2] = pol2cart( b, 0.4*ones(1,n) ); 
x = [zeros(1,n); x1; x1+x2]; y = [zeros(1,n); y1; y1+y2]; 

% Initialise the figure, set up axes etc
f = figure(1); clf; xlim([-1.5,1.5]); ylim([-1.5,1.5]);

% Draw all of the lines, initially not showing because NaN vs NaN
lines = arrayfun( @(x)line(NaN,NaN), 1:nFade, 'uni', 0 );
% Set up shorthand for recolouring all the lines
recolour = @(lines) arrayfun( @(x) set( lines{x},'Color',ones(1,3)*(x/nFade) ), 1:nFade );

for ii = 1:n
    % Shift the lines around so newest is at the start
    lines = [ lines(end), lines(1:end-1) ]; 
    % Overwrite x/y data for oldest line to be newest line
    set( lines{1}, 'XData', x(:,ii), 'YData', y(:,ii) );
    % Update all colours
    recolour( lines );           
    % Pause for animation           
    pause(0.01);
end

Результат:

demo

0 голосов
/ 03 декабря 2018

Вы можете сделать это, изменив 4-й Color атрибут прошлых строк.

Вот демо-результат, в котором я потушил 10% прозрачности каждого кадра, так что только самые последние 10 строк

fade plot demo

Вот код, см. мои комментарии для деталей:

% Set up some demo values for plotting around a circle
a = 0:0.1:2*pi; n = numel(a);
[x,y] = pol2cart( a, ones(1,n) );

% Initialise the figure, set up axes etc
f = figure(1); clf; xlim([-1,1]); ylim([-1,1]);
% Array of graphics objects to store the lines. Could use a cell array.
lines = gobjects( 1, n );
% "Buffer" size, number of historic lines to keep, and governs the 
% corresponding fade increments.
nFade = 10;

% Main plotting loop
for ii = 1:n
    % Plot the line
    lines(ii) = line( [0,x(ii)], [0,y(ii)] );
    % Loop over past lines.
    % Note that we only need to go back as far as ii-nFade, earlier lines
    % will already by transparent with this method!
    for ip = max(1,ii-nFade):ii
        % Set the 4th Color attribute value (the alpha) as a percentage
        % from the current index. Could do this various ways.
        lines(ip).Color(4) = max( 0, 1 - (ii-ip)/nFade );
    end
    % Delay for animation
    pause(0.1);
end

Возможно, вы захотите сделать некоторыеуправление графиком / памятью, если у вас много строк.Вы можете удалить прозрачные линии, добавив что-то вроде

if lines(ii).Color(4) < 0.01
    delete(lines(ii));
end

в цикле.Таким образом, ваша фигура не будет иметь множество прозрачных остатков.


Примечания:

  • Я сгенерировал фактический GIF , используя imwrite на случайэто тоже интересно.
  • По-видимому, в R2018b была исключена функция «4-го значения цвета» (не уверен, что она когда-либо была официально задокументирована).

Получил достаточно голосов, чтобы мотивировать сделать немного более веселую демо ...

fader

...