# gaitsetpy.eda.statistics

This module contains functions for statistical analysis of sensor data.

Maintainer: @aharshit123456

View Source

      1'''
      2This module contains functions for statistical analysis of sensor data.
      3
      4Maintainer: @aharshit123456
      5'''
      6
      7import matplotlib.pyplot as plt
      8import numpy as np
      9
     10def plot_sensor_with_features(sliding_windows, features, start_idx, end_idx, sensor_name="shank", num_windows=10, save=False):
     11    """
     12    @brief Plots sliding windows of a sensor's time series data with overlaid statistical features.
     13
     14    This function plots the first `num_windows` sliding windows within the given `start_idx` and `end_idx`
     15    for a specified sensor and overlays feature values at their corresponding time indices.
     16    It also displays entropy and dominant frequency in a separate plot.
     17
     18    @param[in] sliding_windows List of dictionaries, where each dictionary contains:
     19                   - 'name': sensor name (str)
     20                   - 'data': List of time-series windows (each as a Pandas Series)
     21    @param[in] features List of dictionaries, where each dictionary contains:
     22                   - 'name': sensor name (str)
     23                   - 'features': Dictionary of extracted feature lists
     24    @param[in] start_idx Start index of the time window to be plotted.
     25    @param[in] end_idx End index of the time window to be plotted.
     26    @param[in] sensor_name Name of the sensor to be plotted (default: "shank").
     27    @param[in] num_windows Number of sliding windows to plot (default: 10).
     28    @param[in] save If True, saves the plot to a file instead of displaying it.
     29
     30    @return None
     31    """
     32
     33    fig, axes = plt.subplots(2, 1, figsize=(20, 10), gridspec_kw={'height_ratios': [3, 1]})
     34
     35    # Extract sensor windows
     36    sensor_windows = next((sw['data'] for sw in sliding_windows if sw['name'] == sensor_name), None)
     37    if sensor_windows is None:
     38        print(f"Sensor '{sensor_name}' not found in sliding_windows.")
     39        return
     40
     41    # Extract corresponding features
     42    sensor_features = next((feat['features'] for feat in features if feat['name'] == sensor_name), None)
     43    if sensor_features is None:
     44        print(f"Sensor '{sensor_name}' not found in features.")
     45        return
     46
     47    # Filter windows based on start_idx and end_idx
     48    filtered_windows = [series for series in sensor_windows if start_idx <= series.index[0] and series.index[-1] <= end_idx]
     49
     50    if not filtered_windows:
     51        print(f"No windows found in the specified index range ({start_idx} - {end_idx}).")
     52        return
     53
     54    # Store entropy & frequency features for separate plotting
     55    entropy_values = []
     56    dominant_frequencies = []
     57
     58    # Plot first `num_windows` windows
     59    for i in range(min(num_windows, len(filtered_windows))):
     60        series = filtered_windows[i]  # Each window is a Pandas Series
     61
     62        # Extract time and signal values
     63        time_values = series.index.to_numpy()  # Time is the index
     64        signal_values = series.values  # Sensor readings
     65
     66        # Determine actual start and end indices for this window
     67        window_start, window_end = time_values[0], time_values[-1]
     68
     69        # Plot time series data
     70        axes[0].plot(time_values, signal_values, alpha=0.6)
     71
     72        # Mark start and end of each window with vertical dotted lines
     73        axes[0].axvline(x=window_start, color='black', linestyle='dotted', alpha=0.7)
     74        axes[0].axvline(x=window_end, color='black', linestyle='dotted', alpha=0.7)
     75
     76        # Overlay statistical features
     77        for feature, marker in zip(['mean', 'rms', 'peak_height', 'mode', 'median'], ['x', 'o', 'v', '<', '^']):
     78            if feature in sensor_features and len(sensor_features[feature]) > i:
     79                feature_value = sensor_features[feature][i]
     80                if feature_value != 0:  # Skip zero values
     81                    closest_index = np.argmin(np.abs(signal_values - feature_value))
     82                    closest_time = time_values[closest_index]
     83                    axes[0].scatter(closest_time, feature_value, color='red', marker=marker, s=100)
     84
     85        # Store entropy & frequency features for separate plotting
     86        if 'entropy' in sensor_features and len(sensor_features['entropy']) > i:
     87            entropy_values.append(sensor_features['entropy'][i])
     88        if 'dominant_frequency' in sensor_features and len(sensor_features['dominant_frequency']) > i:
     89            dominant_frequencies.append(sensor_features['dominant_frequency'][i])
     90
     91    # Labels and title for time-series plot
     92    axes[0].set_xlabel('Time')
     93    axes[0].set_ylabel(f'{sensor_name} Signal')
     94    axes[0].set_title(f'First {num_windows} windows of {sensor_name} in range {start_idx}-{end_idx} with Features')
     95
     96    # Frequency-domain & entropy plot (axes[1])
     97    if dominant_frequencies:
     98        window_indices = list(range(len(dominant_frequencies)))
     99        axes[1].plot(window_indices, dominant_frequencies, label="Dominant Frequency", marker="o", linestyle="dashed", color="blue")
    100
    101    if entropy_values:
    102        axes[1].bar(window_indices, entropy_values, alpha=0.6, label="Entropy", color="green")
    103
    104    axes[1].set_xlabel("Window Index")
    105    axes[1].set_ylabel("Feature Value")
    106    axes[1].set_title("Frequency & Entropy Features")
    107    axes[1].legend()
    108
    109    plt.tight_layout()
    110
    111    # Save or show plot
    112    if save:
    113        file_path = input("Enter the file path to save the plot (e.g., 'plot.png'): ")
    114        plt.savefig(file_path, dpi=300)
    115        print(f"Plot saved at {file_path}")
    116    else:
    117        plt.show()

def plot_sensor_with_features( sliding_windows, features, start_idx, end_idx, sensor_name='shank', num_windows=10, save=False): View Source

     11def plot_sensor_with_features(sliding_windows, features, start_idx, end_idx, sensor_name="shank", num_windows=10, save=False):
     12    """
     13    @brief Plots sliding windows of a sensor's time series data with overlaid statistical features.
     14
     15    This function plots the first `num_windows` sliding windows within the given `start_idx` and `end_idx`
     16    for a specified sensor and overlays feature values at their corresponding time indices.
     17    It also displays entropy and dominant frequency in a separate plot.
     18
     19    @param[in] sliding_windows List of dictionaries, where each dictionary contains:
     20                   - 'name': sensor name (str)
     21                   - 'data': List of time-series windows (each as a Pandas Series)
     22    @param[in] features List of dictionaries, where each dictionary contains:
     23                   - 'name': sensor name (str)
     24                   - 'features': Dictionary of extracted feature lists
     25    @param[in] start_idx Start index of the time window to be plotted.
     26    @param[in] end_idx End index of the time window to be plotted.
     27    @param[in] sensor_name Name of the sensor to be plotted (default: "shank").
     28    @param[in] num_windows Number of sliding windows to plot (default: 10).
     29    @param[in] save If True, saves the plot to a file instead of displaying it.
     30
     31    @return None
     32    """
     33
     34    fig, axes = plt.subplots(2, 1, figsize=(20, 10), gridspec_kw={'height_ratios': [3, 1]})
     35
     36    # Extract sensor windows
     37    sensor_windows = next((sw['data'] for sw in sliding_windows if sw['name'] == sensor_name), None)
     38    if sensor_windows is None:
     39        print(f"Sensor '{sensor_name}' not found in sliding_windows.")
     40        return
     41
     42    # Extract corresponding features
     43    sensor_features = next((feat['features'] for feat in features if feat['name'] == sensor_name), None)
     44    if sensor_features is None:
     45        print(f"Sensor '{sensor_name}' not found in features.")
     46        return
     47
     48    # Filter windows based on start_idx and end_idx
     49    filtered_windows = [series for series in sensor_windows if start_idx <= series.index[0] and series.index[-1] <= end_idx]
     50
     51    if not filtered_windows:
     52        print(f"No windows found in the specified index range ({start_idx} - {end_idx}).")
     53        return
     54
     55    # Store entropy & frequency features for separate plotting
     56    entropy_values = []
     57    dominant_frequencies = []
     58
     59    # Plot first `num_windows` windows
     60    for i in range(min(num_windows, len(filtered_windows))):
     61        series = filtered_windows[i]  # Each window is a Pandas Series
     62
     63        # Extract time and signal values
     64        time_values = series.index.to_numpy()  # Time is the index
     65        signal_values = series.values  # Sensor readings
     66
     67        # Determine actual start and end indices for this window
     68        window_start, window_end = time_values[0], time_values[-1]
     69
     70        # Plot time series data
     71        axes[0].plot(time_values, signal_values, alpha=0.6)
     72
     73        # Mark start and end of each window with vertical dotted lines
     74        axes[0].axvline(x=window_start, color='black', linestyle='dotted', alpha=0.7)
     75        axes[0].axvline(x=window_end, color='black', linestyle='dotted', alpha=0.7)
     76
     77        # Overlay statistical features
     78        for feature, marker in zip(['mean', 'rms', 'peak_height', 'mode', 'median'], ['x', 'o', 'v', '<', '^']):
     79            if feature in sensor_features and len(sensor_features[feature]) > i:
     80                feature_value = sensor_features[feature][i]
     81                if feature_value != 0:  # Skip zero values
     82                    closest_index = np.argmin(np.abs(signal_values - feature_value))
     83                    closest_time = time_values[closest_index]
     84                    axes[0].scatter(closest_time, feature_value, color='red', marker=marker, s=100)
     85
     86        # Store entropy & frequency features for separate plotting
     87        if 'entropy' in sensor_features and len(sensor_features['entropy']) > i:
     88            entropy_values.append(sensor_features['entropy'][i])
     89        if 'dominant_frequency' in sensor_features and len(sensor_features['dominant_frequency']) > i:
     90            dominant_frequencies.append(sensor_features['dominant_frequency'][i])
     91
     92    # Labels and title for time-series plot
     93    axes[0].set_xlabel('Time')
     94    axes[0].set_ylabel(f'{sensor_name} Signal')
     95    axes[0].set_title(f'First {num_windows} windows of {sensor_name} in range {start_idx}-{end_idx} with Features')
     96
     97    # Frequency-domain & entropy plot (axes[1])
     98    if dominant_frequencies:
     99        window_indices = list(range(len(dominant_frequencies)))
    100        axes[1].plot(window_indices, dominant_frequencies, label="Dominant Frequency", marker="o", linestyle="dashed", color="blue")
    101
    102    if entropy_values:
    103        axes[1].bar(window_indices, entropy_values, alpha=0.6, label="Entropy", color="green")
    104
    105    axes[1].set_xlabel("Window Index")
    106    axes[1].set_ylabel("Feature Value")
    107    axes[1].set_title("Frequency & Entropy Features")
    108    axes[1].legend()
    109
    110    plt.tight_layout()
    111
    112    # Save or show plot
    113    if save:
    114        file_path = input("Enter the file path to save the plot (e.g., 'plot.png'): ")
    115        plt.savefig(file_path, dpi=300)
    116        print(f"Plot saved at {file_path}")
    117    else:
    118        plt.show()

@brief Plots sliding windows of a sensor's time series data with overlaid statistical features.

This function plots the first `num_windows` sliding windows within the given `start_idx` and `end_idx` for a specified sensor and overlays feature values at their corresponding time indices. It also displays entropy and dominant frequency in a separate plot.

@param[in] sliding_windows List of dictionaries, where each dictionary contains: - 'name': sensor name (str) - 'data': List of time-series windows (each as a Pandas Series) @param[in] features List of dictionaries, where each dictionary contains: - 'name': sensor name (str) - 'features': Dictionary of extracted feature lists @param[in] start_idx Start index of the time window to be plotted. @param[in] end_idx End index of the time window to be plotted. @param[in] sensor_name Name of the sensor to be plotted (default: "shank"). @param[in] num_windows Number of sliding windows to plot (default: 10). @param[in] save If True, saves the plot to a file instead of displaying it.

@return None