Live Script animation 2025a
25 views (last 30 days)
Show older comments
The folowing code produces a nice on-time animation when run from the command line. Run as a Live Script, it produces an animation with a scroll bar and an export to movie button but the animation appears broken, having just a few frames and so does the mp4 if one exports it. How can I get this and similar codes to work in Live Scripts?
%% SIMPLE_PENDULUM_ANIM.m
% Standalone, command-line animation of a simple pendulum
% Emulates the same frame-stepped loop pattern as your working animation:
% - Construct t_anim = 0:dt:tf
% - Pre-create graphics objects
% - In a for-loop: compute state -> set(XData/YData) -> drawnow -> pause(dt)
% Includes diagnostics to confirm that many distinct frames are produced.
%% Housekeeping
clearvars;
close all hidden;
clc;
%% Parameters
% Pendulum physical parameters
L = 1.0; % length in meters
g = 9.81; % gravity in m/s^2
% Display amplitude and motion
amp_deg = 10; % small angle amplitude in degrees
A = deg2rad(amp_deg); % radians
theta0 = A; % initial angle amplitude
phi = 0; % phase shift
% Timing
frame_rate = 30; % frames per second
dt = 1/frame_rate; % step between frames
T = 2*pi*sqrt(L/g); % period of small oscillations
nPeriods = 4; % number of periods to show
t_final = nPeriods * T; % total animation time
t_anim = 0:dt:t_final; % time vector for animation
Nframes = numel(t_anim); % number of frames
% Print timing diagnostics
fprintf('Simple pendulum small-angle animation\n');
fprintf(' L = %.3f m, g = %.3f m/s^2\n', L, g);
fprintf(' Small-angle period T = %.4f s\n', T);
fprintf(' frame_rate = %d fps, dt = %.6f s\n', frame_rate, dt);
fprintf(' nPeriods = %d, t_final = %.4f s, Nframes = %d\n', nPeriods, t_final, Nframes);
%% Prescribed motion (small-angle)
% theta(t) = A * cos(omega * t + phi)
omega = sqrt(g/L); % small-angle angular frequency
theta_anim = theta0 * cos(omega * t_anim + phi);
% Position of bob
x_anim = L * sin(theta_anim);
y_anim = -L * cos(theta_anim);
% Diagnostics: max per-step changes and distinct-frame count
dx = [0, diff(x_anim)];
dy = [0, diff(y_anim)];
dmax = max(abs([dx(:), dy(:)]), [], 2).';
tol_distinct = 1e-9; % anything larger than this counts as a new frame
nDistinct = 1 + sum(dmax(2:end) > tol_distinct);
fprintf(' Max |Δx| per step = %.6g, Max |Δy| per step = %.6g\n', max(abs(dx)), max(abs(dy)));
fprintf(' Distinct frames (|Δ| > %.1e): %d / %d\n', tol_distinct, nDistinct, Nframes);
%% Figure and axes
fig = figure('Position',[100,100,600,600],'Name','Simple Pendulum Animation');
axis equal;
grid on;
hold on;
% Axis limits with padding
pad = 0.2;
xlim([-L - pad, L + pad]);
ylim([-L - pad, pad]);
xlabel('X (m)');
ylabel('Y (m)');
title(sprintf('Simple Pendulum — A = %.1f°; %.0f fps; %d periods', amp_deg, frame_rate, nPeriods));
%% Graphics objects (pre-create; update via set)
% Pivot
pivot_plot = plot(0, 0, 'ko', 'MarkerSize', 6, 'MarkerFaceColor', 'k');
% Rod as a line from pivot to bob
rod_plot = plot([0, x_anim(1)], [0, y_anim(1)], 'k-', 'LineWidth', 3);
% Bob as a filled circle
bob_size = 14; % marker size
bob_plot = plot(x_anim(1), y_anim(1), 'ro', 'MarkerSize', bob_size, 'MarkerFaceColor', 'r', 'LineWidth', 1.5);
% Optional trail to visualize motion
trail_len = max(1, round(0.5*frame_rate)); % 0.5 s trail
trail_plot = plot(nan, nan, '-', 'Color', [0.2 0.6 1.0], 'LineWidth', 1);
% Time text
time_text = text(-L - 0.15, 0.05, sprintf('t = %.3f s', 0), 'FontSize', 12);
drawnow;
%% Animation loop
fprintf('Animating...\n');
for k = 1:Nframes
% Current tip coordinates
xk = x_anim(k);
yk = y_anim(k);
% Update rod
set(rod_plot, 'XData', [0, xk], 'YData', [0, yk]);
% Update bob
set(bob_plot, 'XData', xk, 'YData', yk);
% Update trail
i0 = max(1, k - trail_len + 1);
set(trail_plot, 'XData', x_anim(i0:k), 'YData', y_anim(i0:k));
% Update time text
set(time_text, 'String', sprintf('t = %.3f s', t_anim(k)));
% Draw and pace
drawnow;
if k < Nframes
pause(dt);
end
% Optional per-frame diagnostic printing (sparse)
if mod(k, round(frame_rate)) == 0 || k == 1 || k == Nframes
fprintf(' Frame %4d / %4d: (x,y) = (%.5f, %.5f), |Δ|_max = %.3g\n', ...
k, Nframes, xk, yk, dmax(k));
end
end
fprintf('Done.\n');
0 Comments
Answers (1)
Tridib
on 3 Nov 2025 at 6:30
The code actually works fine for me both in the Command Window and in Live Scripts.
However, from what I understand, the problem in Live Scripts seems to be that for-loops with "drawnow" or "pause" do not run in real time. Instead, the Live Editor only takes a few snapshots during the loop, so just a handful of frames are displayed. As a result, when using the "Export to Video" button in Live Scripts, the exported video contains only those few captured frames, making the animation appear choppy or incomplete.
A possible workaround could be to try capturing each frame manually using "getframe" within the loop and then saving them to a video file with "VideoWriter". For smoother playback in Live Scripts, it might help to store all frames first and then play them back using tools like "implay" or by adding a slider to move through the animation.
For more information, refer to these documentations:
Hope this helps!
See Also
Categories
Find more on Animation in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!