#!/usr/bin/env python3 """ Visualize HR data from two CSV files with max value alignment """ import pandas as pd import matplotlib.pyplot as plt import numpy as np from datetime import datetime, timedelta import seaborn as sns def load_and_visualize_hr_data(): """Load and visualize HR data from both CSV files with max value alignment""" # Load the first CSV file (with timestamps) print("Loading 2025-06-10_16_26.CSV...") df1 = pd.read_csv("2025-06-10_16_26.CSV") print(f"Dataset 1 shape: {df1.shape}") print(f"Dataset 1 columns: {df1.columns.tolist()}") print(f"Dataset 1 HR range: {df1['hr'].min():.1f} - {df1['hr'].max():.1f}") # Load the second CSV file (HR only) print("\nLoading history_20250610_165414_HR.csv...") df2 = pd.read_csv("history_20250610_165414_HR.csv") print(f"Dataset 2 shape: {df2.shape}") print(f"Dataset 2 columns: {df2.columns.tolist()}") print(f"Dataset 2 HR range: {df2['HR'].min():.1f} - {df2['HR'].max():.1f}") # Find the maximum values and their indices max_hr1 = df1["hr"].max() max_idx1 = df1["hr"].idxmax() max_hr2 = df2["HR"].max() max_idx2 = df2["HR"].idxmax() print(f"\nDataset 1 max HR: {max_hr1:.1f} at index {max_idx1}") print(f"Dataset 2 max HR: {max_hr2:.1f} at index {max_idx2}") # Create time indices for both datasets df1["time_seconds"] = df1.index # Use index as time in seconds df2["time_seconds"] = df2.index # Use index as time in seconds # Align datasets by shifting so max values occur at the same time # We'll align both to time = 0 at their respective max points df1["time_aligned"] = df1["time_seconds"] - max_idx1 df2["time_aligned"] = df2["time_seconds"] - max_idx2 print(f"\nAfter alignment:") print( f"Dataset 1 time range: {df1['time_aligned'].min():.1f} to {df1['time_aligned'].max():.1f} seconds" ) print( f"Dataset 2 time range: {df2['time_aligned'].min():.1f} to {df2['time_aligned'].max():.1f} seconds" ) # Create the visualization plt.style.use("seaborn-v0_8") fig, axes = plt.subplots(2, 2, figsize=(15, 10)) fig.suptitle( "Heart Rate Data Visualization (Max Values Aligned)", fontsize=16, fontweight="bold", ) # Plot 1: Time series of both datasets (aligned) axes[0, 0].plot( df1["time_aligned"], df1["hr"], "o-", alpha=0.7, markersize=3, label=f"Dataset 1 (max: {max_hr1:.1f})", color="blue", ) axes[0, 0].plot( df2["time_aligned"], df2["HR"], "s-", alpha=0.7, markersize=3, label=f"Dataset 2 (max: {max_hr2:.1f})", color="red", ) # Highlight the max values axes[0, 0].axvline( x=0, color="black", linestyle="--", alpha=0.5, label="Max values aligned" ) axes[0, 0].scatter([0], [max_hr1], color="blue", s=100, zorder=5, marker="*") axes[0, 0].scatter([0], [max_hr2], color="red", s=100, zorder=5, marker="*") axes[0, 0].set_xlabel("Time (seconds, aligned to max)") axes[0, 0].set_ylabel("Heart Rate (bpm)") axes[0, 0].set_title("Heart Rate Over Time (Aligned at Max Values)") axes[0, 0].legend() axes[0, 0].grid(True, alpha=0.3) # Plot 2: Distribution comparison axes[0, 1].hist( df1["hr"], bins=20, alpha=0.7, label="Dataset 1", color="blue", density=True ) axes[0, 1].hist( df2["HR"], bins=20, alpha=0.7, label="Dataset 2", color="red", density=True ) axes[0, 1].axvline( max_hr1, color="blue", linestyle="--", alpha=0.8, label=f"Max 1: {max_hr1:.1f}" ) axes[0, 1].axvline( max_hr2, color="red", linestyle="--", alpha=0.8, label=f"Max 2: {max_hr2:.1f}" ) axes[0, 1].set_xlabel("Heart Rate (bpm)") axes[0, 1].set_ylabel("Density") axes[0, 1].set_title("Heart Rate Distribution") axes[0, 1].legend() axes[0, 1].grid(True, alpha=0.3) # Plot 3: Box plot comparison data_for_box = [df1["hr"], df2["HR"]] labels = ["Dataset 1\n(2025-06-10_16_26)", "Dataset 2\n(history_20250610_165414)"] bp = axes[1, 0].boxplot(data_for_box, tick_labels=labels, patch_artist=True) bp["boxes"][0].set_facecolor("lightblue") bp["boxes"][1].set_facecolor("lightcoral") axes[1, 0].set_ylabel("Heart Rate (bpm)") axes[1, 0].set_title("Heart Rate Distribution Comparison") axes[1, 0].grid(True, alpha=0.3) # Plot 4: Overlay plot around max values (zoomed in view) # Show ±20 seconds around the aligned max values window = 20 df1_window = df1[(df1["time_aligned"] >= -window) & (df1["time_aligned"] <= window)] df2_window = df2[(df2["time_aligned"] >= -window) & (df2["time_aligned"] <= window)] if len(df1_window) > 0: axes[1, 1].plot( df1_window["time_aligned"], df1_window["hr"], "o-", alpha=0.8, markersize=4, label=f"Dataset 1", color="blue", linewidth=2, ) if len(df2_window) > 0: axes[1, 1].plot( df2_window["time_aligned"], df2_window["HR"], "s-", alpha=0.8, markersize=4, label=f"Dataset 2", color="red", linewidth=2, ) axes[1, 1].axvline( x=0, color="black", linestyle="--", alpha=0.5, label="Max alignment" ) axes[1, 1].scatter( [0], [max_hr1], color="blue", s=150, zorder=5, marker="*", edgecolor="black" ) axes[1, 1].scatter( [0], [max_hr2], color="red", s=150, zorder=5, marker="*", edgecolor="black" ) axes[1, 1].set_xlabel("Time (seconds, aligned to max)") axes[1, 1].set_ylabel("Heart Rate (bpm)") axes[1, 1].set_title(f"Zoomed View Around Max Values (±{window}s)") axes[1, 1].legend() axes[1, 1].grid(True, alpha=0.3) plt.tight_layout() # Save the plot output_file = "hr_data_visualization_aligned.png" plt.savefig(output_file, dpi=300, bbox_inches="tight") print(f"\nVisualization saved as: {output_file}") # Show the plot plt.show() # Print detailed statistics print("\n" + "=" * 60) print("DETAILED STATISTICS (MAX VALUES ALIGNED)") print("=" * 60) print("\nDataset 1 (2025-06-10_16_26.CSV):") print(f" Records: {len(df1)}") print(f" Mean HR: {df1['hr'].mean():.1f} bpm") print(f" Median HR: {df1['hr'].median():.1f} bpm") print(f" Max HR: {max_hr1:.1f} bpm (at original index {max_idx1})") print(f" Std Dev: {df1['hr'].std():.1f} bpm") print(f" Range: {df1['hr'].min():.1f} - {df1['hr'].max():.1f} bpm") print("\nDataset 2 (history_20250610_165414_HR.csv):") print(f" Records: {len(df2)}") print(f" Mean HR: {df2['HR'].mean():.1f} bpm") print(f" Median HR: {df2['HR'].median():.1f} bpm") print(f" Max HR: {max_hr2:.1f} bpm (at original index {max_idx2})") print(f" Std Dev: {df2['HR'].std():.1f} bpm") print(f" Range: {df2['HR'].min():.1f} - {df2['HR'].max():.1f} bpm") print(f"\nAlignment Info:") print(f" Max HR difference: {abs(max_hr1 - max_hr2):.1f} bpm") print( f" Time shift applied: Dataset 1 shifted by -{max_idx1}s, Dataset 2 shifted by -{max_idx2}s" ) print("\n" + "=" * 60) return df1, df2 if __name__ == "__main__": print("Starting HR data visualization with max value alignment...") df1, df2 = load_and_visualize_hr_data() print("Visualization complete!")