Search code examples
matlabanimationplotmatlab-figure

How to update / animate a complicated figure in MATLAB?


I need to animate a complex figure consisting of a chain of rectangles, forming an arm. Here is an example of how this arm looks like when not animated :

Static plot

To animate this figure, I made the following code :

function renderFrame(fig, data)
    hold(ax, 'on'); % Need to hold so that new elements of the arm add themselves
    showMembers(fig, data); % Create patches and rotate them to the right angle to create members
    showJoints(fig, data); % Draw circles at the joints betwwen the members. Use the width of rectangle members  
    drawnow;
    hold(ax, 'off'); % Next rendering will replace this one; No need to hold
end

function rotateMember(fig, data, iMember, rotAngle)
    for iAngle = 1:rotAngle
        updateMemberAngle(data, i, 1); % Change thew data so the i-th member rotates by 1
        renderFrame(fig); % Show frame after the data was changed
    end
end

function main()
    fig = figure;
    ax = gca;
    axis(ax, 'equal');
    setAxis(data); % Set axis limits and create axis arrows with totalLength of the arm
    renderFrame(ax, data);
    rotateMember(fig, data, 3, 90); % Rotate 3rd member by 90 degrees
end

main()

But the frames of my animation doesn't clear at all. It results in this figure :

Moving plot

What am I doing wrong ? Is there a way to plot complicated figures with multiple parts and to animate it, by clearing frame ?

I looked into using newplot and nextplot, but MATLAB's documentation on the subject is incomplete, as always. I also tried creating graphic objects and then setting the data at each iteration, but it rejects an exception every time the figure is deleted since "graphics objects are deleted".


Solution

  • Found a way to clear the axis childrens, except the two axis quivers (arrows).

    Here is a code that works properly:

    function renderFrame(renderAxes, data)
    
        % CHECK IF THERE ARE MORE GRAPHIC OBJECTS THAN ONLY THE QUIVERS
        if ~(length(renderAxes.Children) == 2)
    
            % DELETE EVERYTHING EXCEPT THE AXIS QUIVERS THAT WERE RENDERED AT THE BEGINNING
            % MATLAB ADDS NEW GRAPHIC OBJECTS TO THE BEGINNING OF AX.CHILDREN
            delete(renderAxes.Children(1:length(renderAxes.Children)-2))
        end
    
        showMembers(renderAxes, data); % Create patches and rotate them to the right angle to create members
        showJoints(renderAxes, data); % Draw circles at the joints betwwen the members. Use the width of rectangle members  
        drawnow;
    end
    
    function rotateMember(ax, data, iMember, rotAngle)
        for iAngle = 1:rotAngle
            updateMemberAngle(data, i, 1); % Change thew data so the i-th member rotates by 1
            renderFrame(ax, data); % Show frame after the data was changed
        end
    end
    
    function main()
        fig = figure;
        ax = gca;
        axis(ax, 'equal');
    
        % HOLD AXES AT THE BEGINNING OF THE SCRIPT
        hold(ax, 'on');
    
        setAxis(data); % Set axis limits and create axis arrows with totalLength of the arm
        renderFrame(ax, data);
        rotateMember(ax, data, 3, 90); % Rotate 3rd member by 90 degrees
    end
    
    main()