from functools import partial from pathlib import Path import matplotlib.pyplot as plt import numpy as np from matplotlib import animation # from util import calculate_average_frame_rate, load_dataset from rich.progress import Progress, track scores_path = Path( "/home/fedex/mt/projects/thesis-kowalczyk-jan/Deep-SAD-PyTorch/infer/DeepSAD/subter_selective_test/inference/3_smoke_human_walking_2023-01-23.npy" ) # scores_path = Path( # "/home/fedex/mt/projects/thesis-kowalczyk-jan/Deep-SAD-PyTorch/infer/DeepSAD/subter_split_test/inference/3_smoke_human_walking_2023-01-23.npy" # ) # scores_path = Path( # "/home/fedex/mt/projects/thesis-kowalczyk-jan/Deep-SAD-PyTorch/infer/DeepSAD/subter_split_test/inference/1_loop_closure_illuminated_two_LiDARs_2023-01-23.npy" # ) # scores_path = Path( # "/home/fedex/mt/projects/thesis-kowalczyk-jan/Deep-SAD-PyTorch/infer/DeepSAD/esmera_split_test/inference/experiment_3.npy" # ) # dataset_path = Path( # "/home/fedex/mt/data/subter/1_loop_closure_illuminated_two_LiDARs_2023-01-23.bag" # ) # dataset_path = Path("/home/fedex/mt/data/subter/3_smoke_human_walking_2023-01-23.bag") # dataset = load_dataset(dataset_path) fps = 10 all_scores = np.load(scores_path) y_limit = 1.1 * np.max(all_scores[np.isfinite(all_scores)]) # y_limit = 10 # all_scores = np.where(all_scores > 10, 10, all_scores) # all_scores = all_scores.reshape(-1, 16).T #SUBTER # all_scores = all_scores.reshape(-1, 8).T # ESMERA all_scores = all_scores.reshape(-1, 1).T # ESMERA print(all_scores.shape, y_limit) fig, axes = plt.subplots( 1, 1, figsize=(7.68, 7.2), # 1, 1, figsize=(7.68, 7.2), gridspec_kw={"wspace": 0.10, "hspace": 0.10} ) axes = [axes] # fig, axes = plt.subplots( # 1, 8, figsize=(20.48, 7.2), gridspec_kw={"wspace": 0.05, "hspace": 0.05} # ) # Flatten the axes for easier indexing # axes = axes.flatten() last_running_avg = [None] * len(all_scores) # Function to calculate the running average with a dynamic window size def running_average_dynamic(data, current_frame, max_window=20): """Calculate the running average with dynamic window size up to max_window.""" window = min( current_frame, max_window ) # Use the minimum of current frame or the max window size return np.convolve(data, np.ones(window) / window, mode="valid") # Function to animate each subplot def animate(i, progress_bar, progress_task): for score_id, ax in enumerate(axes): ax.cla() # Clear the axes for the current frame ax.plot( all_scores[score_id][:i], label="Anomaly Score" ) # Plot the scores up to frame `i` if i > 0: avg_data = running_average_dynamic( all_scores[score_id][:i], current_frame=i, max_window=20 ) ax.plot(range(len(avg_data)), avg_data, color="orange", label="Running Avg") ax.set_xlim([0, all_scores[score_id].shape[0]]) # Set x limits ax.set_ylim([0, y_limit]) # Set y limits # ax.set_title(f"Score {score_id + 1}") # Add a title for each subplot ax.set_ylabel("Score", fontsize=10) # Add y-axis label ax.set_xlabel("Frame", fontsize=10) # Add y-axis label ax.legend(loc="upper right", fontsize=10) # Add a legend # Only show y-axis tick labels for the leftmost subplots # if score_id % 8 == 0: # First column of subplots # ax.set_ylabel("Score", fontsize=8) # Add y-axis label # else: # ax.set_yticklabels([]) # Remove y-axis tick labels # if score_id < 8: # ax.set_xticklabels([]) # Remove x-axis tick labels # ax.tick_params(labelsize=6) # Update the running average text every 10 frames if i % fps == 0 and i > 0: # Calculate the current running average value (up to last 20 frames) current_window = min(i, 20) last_running_avg[score_id] = np.mean( all_scores[score_id][i - current_window : i] ) # Display the last updated running average value (if available) if last_running_avg[score_id] is not None: ax.text( 0.05, 0.95, f"Current Avg: {last_running_avg[score_id]:>2.1f}", transform=ax.transAxes, fontsize=10, verticalalignment="top", horizontalalignment="left", color="black", fontfamily="monospace", ) progress_bar.update(progress_task, completed=i) # plt.subplots_adjust( # left=0.02, right=0.98, top=0.95, bottom=0.05, wspace=0.05, hspace=0.05 # ) with Progress() as progress: total = all_scores[0].shape[0] + 1 progress_task = progress.add_task("[cyan]Animating...", total=total) progress.update(progress_task, completed=0) animate_partial = partial( animate, progress_bar=progress, progress_task=progress_task ) # anim = animation.FuncAnimation(fig, animate_partial, frames=50, interval=1, blit=False) anim = animation.FuncAnimation( fig, animate_partial, frames=total, interval=1, blit=False ) # Save the animation as a single video animated_score_filename = f"{scores_path.stem}_selective.mp4" anim.save(animated_score_filename, writer=animation.FFMpegWriter(fps=fps)) progress.update(progress_task, completed=all_scores[0].shape[0] + 1) # Clear the figure after saving fig.clear()