gaitsetpy.eda

eda: Provides exploratory data analysis tools for gait datasets.

This module provides both the new class-based EDA analyzers and legacy function-based API. All EDA analyzers inherit from BaseEDAAnalyzer and are registered with the EDAManager.

Features:

  • Comprehensive visualization of sensor data (thigh, shank, trunk)
  • Statistical analysis and summaries
  • Feature visualization and overlay
  • Dataset comparison and analysis

Maintainer: @aharshit123456

  1"""
  2eda: Provides exploratory data analysis tools for gait datasets.
  3
  4This module provides both the new class-based EDA analyzers and legacy function-based API.
  5All EDA analyzers inherit from BaseEDAAnalyzer and are registered with the EDAManager.
  6
  7Features:
  8- Comprehensive visualization of sensor data (thigh, shank, trunk)
  9- Statistical analysis and summaries
 10- Feature visualization and overlay
 11- Dataset comparison and analysis
 12
 13Maintainer: @aharshit123456
 14"""
 15
 16# Import the new class-based EDA analyzers
 17from .analyzers import (
 18    DaphnetVisualizationAnalyzer,
 19    SensorStatisticsAnalyzer
 20)
 21
 22# Import legacy functions for backward compatibility
 23from .visualization import (
 24    plot_thigh_data,
 25    plot_shank_data,
 26    plot_trunk_data,
 27    plot_all_data,
 28    plot_all_thigh_data,
 29    plot_all_shank_data,
 30    plot_all_trunk_data,
 31    plot_all_datasets
 32)
 33
 34from .statistics import plot_sensor_with_features
 35
 36# Import managers
 37from ..core.managers import EDAManager
 38
 39# Register all EDA analyzers with the manager
 40def _register_analyzers():
 41    """Register all available EDA analyzers with the EDAManager."""
 42    manager = EDAManager()
 43    manager.register_analyzer("daphnet_visualization", DaphnetVisualizationAnalyzer)
 44    manager.register_analyzer("sensor_statistics", SensorStatisticsAnalyzer)
 45
 46# Auto-register analyzers when module is imported
 47_register_analyzers()
 48
 49# Convenient access to the EDA manager
 50def get_eda_manager():
 51    """Get the singleton EDAManager instance."""
 52    return EDAManager()
 53
 54# Helper function to get available analyzers
 55def get_available_analyzers():
 56    """Get list of available EDA analyzer names."""
 57    return EDAManager().get_available_components()
 58
 59# Helper function to analyze data using manager
 60def analyze_data(analyzer_name: str, data, **kwargs):
 61    """
 62    Analyze data using the EDAManager.
 63    
 64    Args:
 65        analyzer_name: Name of the EDA analyzer
 66        data: Input data to analyze
 67        **kwargs: Additional arguments for analysis
 68        
 69    Returns:
 70        Analysis results dictionary
 71    """
 72    return EDAManager().analyze_data(analyzer_name, data, **kwargs)
 73
 74# Helper function to visualize data using manager
 75def visualize_data(analyzer_name: str, data, **kwargs):
 76    """
 77    Create visualizations using the EDAManager.
 78    
 79    Args:
 80        analyzer_name: Name of the EDA analyzer
 81        data: Input data to visualize
 82        **kwargs: Additional arguments for visualization
 83    """
 84    return EDAManager().visualize_data(analyzer_name, data, **kwargs)
 85
 86# Convenient wrapper functions for common operations
 87def plot_daphnet_data(data, names=None, sensor_type='all', dataset_index=0):
 88    """
 89    Plot Daphnet dataset using the DaphnetVisualizationAnalyzer.
 90    
 91    Args:
 92        data: Input data (DataFrame or list of DataFrames)
 93        names: List of dataset names
 94        sensor_type: Type of sensor to plot ('all', 'thigh', 'shank', 'trunk')
 95        dataset_index: Index of dataset to plot (if data is a list)
 96    """
 97    analyzer = DaphnetVisualizationAnalyzer()
 98    analyzer.visualize(data, sensor_type=sensor_type, dataset_index=dataset_index, names=names or [])
 99
100def analyze_sensor_statistics(data):
101    """
102    Analyze sensor statistics using the SensorStatisticsAnalyzer.
103    
104    Args:
105        data: Input data (DataFrame or list of DataFrames)
106        
107    Returns:
108        Dictionary containing statistical analysis results
109    """
110    analyzer = SensorStatisticsAnalyzer()
111    return analyzer.analyze(data)
112
113def plot_sensor_features(sliding_windows, features, sensor_name='shank', start_idx=0, end_idx=1000, num_windows=10):
114    """
115    Plot sensor data with overlaid features using the SensorStatisticsAnalyzer.
116    
117    Args:
118        sliding_windows: List of sliding window dictionaries
119        features: List of feature dictionaries
120        sensor_name: Name of the sensor to plot
121        start_idx: Start index of the time window
122        end_idx: End index of the time window
123        num_windows: Number of sliding windows to plot
124    """
125    analyzer = SensorStatisticsAnalyzer()
126    analyzer.visualize(sliding_windows, features, sensor_name=sensor_name, 
127                      start_idx=start_idx, end_idx=end_idx, num_windows=num_windows)
128
129__all__ = [
130    # New class-based analyzers
131    'DaphnetVisualizationAnalyzer',
132    'SensorStatisticsAnalyzer',
133    # Legacy functions for backward compatibility
134    'plot_thigh_data',
135    'plot_shank_data',
136    'plot_trunk_data',
137    'plot_all_data',
138    'plot_all_thigh_data',
139    'plot_all_shank_data',
140    'plot_all_trunk_data',
141    'plot_all_datasets',
142    'plot_sensor_with_features',
143    # Manager functions
144    'get_eda_manager',
145    'get_available_analyzers',
146    'analyze_data',
147    'visualize_data',
148    # Convenient wrapper functions
149    'plot_daphnet_data',
150    'analyze_sensor_statistics',
151    'plot_sensor_features'
152]
class DaphnetVisualizationAnalyzer(gaitsetpy.core.base_classes.BaseEDAAnalyzer):
 18class DaphnetVisualizationAnalyzer(BaseEDAAnalyzer):
 19    """
 20    EDA analyzer for Daphnet dataset visualization.
 21    
 22    This analyzer provides comprehensive visualization capabilities for Daphnet dataset
 23    including thigh, shank, and trunk sensor data.
 24    """
 25    
 26    def __init__(self):
 27        super().__init__(
 28            name="daphnet_visualization",
 29            description="Comprehensive visualization analyzer for Daphnet dataset sensor data"
 30        )
 31        self.config = {
 32            'figsize': (20, 16),
 33            'colors': {
 34                'no_freeze': 'orange',
 35                'freeze': 'purple'
 36            },
 37            'alpha': 0.6
 38        }
 39    
 40    def analyze(self, data: Union[pd.DataFrame, List[pd.DataFrame]], **kwargs) -> Dict[str, Any]:
 41        """
 42        Analyze the data and return statistical summaries.
 43        
 44        Args:
 45            data: Input data to analyze
 46            **kwargs: Additional arguments
 47            
 48        Returns:
 49            Dictionary containing analysis results
 50        """
 51        if isinstance(data, list):
 52            # Multiple datasets
 53            results = {}
 54            for i, df in enumerate(data):
 55                results[f'dataset_{i}'] = self._analyze_single_dataset(df)
 56            return results
 57        else:
 58            # Single dataset
 59            return self._analyze_single_dataset(data)
 60    
 61    def _analyze_single_dataset(self, df: pd.DataFrame) -> Dict[str, Any]:
 62        """Analyze a single dataset."""
 63        # Basic statistics
 64        stats = {
 65            'shape': df.shape,
 66            'columns': df.columns.tolist(),
 67            'annotation_distribution': df['annotations'].value_counts().to_dict() if 'annotations' in df.columns else {},
 68            'missing_values': df.isnull().sum().to_dict(),
 69            'data_range': {
 70                'min': df.select_dtypes(include=[np.number]).min().to_dict(),
 71                'max': df.select_dtypes(include=[np.number]).max().to_dict()
 72            }
 73        }
 74        
 75        # Sensor-specific statistics
 76        sensor_stats = {}
 77        for sensor in ['thigh', 'shank', 'trunk']:
 78            if sensor in df.columns:
 79                sensor_stats[sensor] = {
 80                    'mean': df[sensor].mean(),
 81                    'std': df[sensor].std(),
 82                    'min': df[sensor].min(),
 83                    'max': df[sensor].max()
 84                }
 85        
 86        stats['sensor_statistics'] = sensor_stats
 87        return stats
 88    
 89    def visualize(self, data: Union[pd.DataFrame, List[pd.DataFrame]], **kwargs):
 90        """
 91        Create visualizations of the data.
 92        
 93        Args:
 94            data: Input data to visualize
 95            **kwargs: Additional arguments including sensor_type, dataset_index, names
 96        """
 97        sensor_type = kwargs.get('sensor_type', 'all')
 98        dataset_index = kwargs.get('dataset_index', 0)
 99        names = kwargs.get('names', [])
100        
101        if isinstance(data, list):
102            if dataset_index < len(data):
103                df = data[dataset_index]
104                dataset_name = names[dataset_index] if dataset_index < len(names) else f"Dataset {dataset_index}"
105            else:
106                print(f"Dataset index {dataset_index} out of range")
107                return
108        else:
109            df = data
110            dataset_name = names[0] if names else "Dataset"
111        
112        if sensor_type == 'all':
113            self._plot_all_sensors(df, dataset_name)
114        elif sensor_type == 'thigh':
115            self._plot_thigh_data(df, dataset_name)
116        elif sensor_type == 'shank':
117            self._plot_shank_data(df, dataset_name)
118        elif sensor_type == 'trunk':
119            self._plot_trunk_data(df, dataset_name)
120        else:
121            print(f"Unknown sensor type: {sensor_type}")
122    
123    def _plot_thigh_data(self, df: pd.DataFrame, dataset_name: str):
124        """Plot thigh sensor data."""
125        print(f"Plotting thigh data for {dataset_name}")
126        
127        # Filter data
128        df_filtered = df[df.annotations > 0] if 'annotations' in df.columns else df
129        
130        if df_filtered.empty:
131            print("No valid data to plot")
132            return
133        
134        # Create figure
135        fig, axes = plt.subplots(4, 1, sharex=True, figsize=self.config['figsize'])
136        fig.suptitle(f"Thigh Data from {dataset_name}")
137        
138        # Separate freeze and no-freeze data
139        if 'annotations' in df.columns:
140            neg = df_filtered[df_filtered.annotations == 1]  # No freeze
141            pos = df_filtered[df_filtered.annotations == 2]  # Freeze
142        else:
143            neg = df_filtered
144            pos = pd.DataFrame()
145        
146        # Plot each component
147        components = ['thigh_h_fd', 'thigh_v', 'thigh_h_l', 'thigh']
148        labels = ['Horizontal Forward', 'Vertical', 'Horizontal Lateral', 'Overall']
149        
150        for i, (component, label) in enumerate(zip(components, labels)):
151            if component in df_filtered.columns:
152                # Plot main signal
153                axes[i].plot(df_filtered.index, df_filtered[component])
154                axes[i].set_ylabel(f"{label} Thigh Acceleration")
155                
156                # Plot annotations if available
157                if not neg.empty:
158                    axes[i].scatter(neg.index, neg[component], 
159                                  c=self.config['colors']['no_freeze'], 
160                                  label="no freeze", alpha=self.config['alpha'])
161                if not pos.empty:
162                    axes[i].scatter(pos.index, pos[component], 
163                                  c=self.config['colors']['freeze'], 
164                                  label="freeze", alpha=self.config['alpha'])
165                
166                axes[i].legend()
167        
168        plt.xlabel("Time")
169        plt.tight_layout()
170        plt.show()
171    
172    def _plot_shank_data(self, df: pd.DataFrame, dataset_name: str):
173        """Plot shank sensor data."""
174        print(f"Plotting shank data for {dataset_name}")
175        
176        # Filter data
177        df_filtered = df[df.annotations > 0] if 'annotations' in df.columns else df
178        
179        if df_filtered.empty:
180            print("No valid data to plot")
181            return
182        
183        # Create figure
184        fig, axes = plt.subplots(4, 1, sharex=True, figsize=self.config['figsize'])
185        fig.suptitle(f"Shank Data from {dataset_name}")
186        
187        # Separate freeze and no-freeze data
188        if 'annotations' in df.columns:
189            neg = df_filtered[df_filtered.annotations == 1]  # No freeze
190            pos = df_filtered[df_filtered.annotations == 2]  # Freeze
191        else:
192            neg = df_filtered
193            pos = pd.DataFrame()
194        
195        # Plot each component
196        components = ['shank_h_fd', 'shank_v', 'shank_h_l', 'shank']
197        labels = ['Horizontal Forward', 'Vertical', 'Horizontal Lateral', 'Overall']
198        
199        for i, (component, label) in enumerate(zip(components, labels)):
200            if component in df_filtered.columns:
201                # Plot main signal
202                axes[i].plot(df_filtered.index, df_filtered[component])
203                axes[i].set_ylabel(f"{label} Shank Acceleration")
204                
205                # Plot annotations if available
206                if not neg.empty:
207                    axes[i].scatter(neg.index, neg[component], 
208                                  c=self.config['colors']['no_freeze'], 
209                                  label="no freeze", alpha=self.config['alpha'])
210                if not pos.empty:
211                    axes[i].scatter(pos.index, pos[component], 
212                                  c=self.config['colors']['freeze'], 
213                                  label="freeze", alpha=self.config['alpha'])
214                
215                axes[i].legend()
216        
217        plt.xlabel("Time")
218        plt.tight_layout()
219        plt.show()
220    
221    def _plot_trunk_data(self, df: pd.DataFrame, dataset_name: str):
222        """Plot trunk sensor data."""
223        print(f"Plotting trunk data for {dataset_name}")
224        
225        # Filter data
226        df_filtered = df[df.annotations > 0] if 'annotations' in df.columns else df
227        
228        if df_filtered.empty:
229            print("No valid data to plot")
230            return
231        
232        # Create figure
233        fig, axes = plt.subplots(4, 1, sharex=True, figsize=self.config['figsize'])
234        fig.suptitle(f"Trunk Data from {dataset_name}")
235        
236        # Separate freeze and no-freeze data
237        if 'annotations' in df.columns:
238            neg = df_filtered[df_filtered.annotations == 1]  # No freeze
239            pos = df_filtered[df_filtered.annotations == 2]  # Freeze
240        else:
241            neg = df_filtered
242            pos = pd.DataFrame()
243        
244        # Plot each component
245        components = ['trunk_h_fd', 'trunk_v', 'trunk_h_l', 'trunk']
246        labels = ['Horizontal Forward', 'Vertical', 'Horizontal Lateral', 'Overall']
247        
248        for i, (component, label) in enumerate(zip(components, labels)):
249            if component in df_filtered.columns:
250                # Plot main signal
251                axes[i].plot(df_filtered.index, df_filtered[component])
252                axes[i].set_ylabel(f"{label} Trunk Acceleration")
253                
254                # Plot annotations if available
255                if not neg.empty:
256                    axes[i].scatter(neg.index, neg[component], 
257                                  c=self.config['colors']['no_freeze'], 
258                                  label="no freeze", alpha=self.config['alpha'])
259                if not pos.empty:
260                    axes[i].scatter(pos.index, pos[component], 
261                                  c=self.config['colors']['freeze'], 
262                                  label="freeze", alpha=self.config['alpha'])
263                
264                axes[i].legend()
265        
266        plt.xlabel("Time")
267        plt.tight_layout()
268        plt.show()
269    
270    def _plot_all_sensors(self, df: pd.DataFrame, dataset_name: str):
271        """Plot all sensor data in a combined view."""
272        print(f"Plotting all sensor data for {dataset_name}")
273        
274        # Create figure with subplots for each sensor
275        fig, axes = plt.subplots(3, 1, sharex=True, figsize=self.config['figsize'])
276        fig.suptitle(f"All Sensor Data from {dataset_name}")
277        
278        # Filter data
279        df_filtered = df[df.annotations > 0] if 'annotations' in df.columns else df
280        
281        if df_filtered.empty:
282            print("No valid data to plot")
283            return
284        
285        sensors = ['thigh', 'shank', 'trunk']
286        for i, sensor in enumerate(sensors):
287            if sensor in df_filtered.columns:
288                axes[i].plot(df_filtered.index, df_filtered[sensor])
289                axes[i].set_ylabel(f"{sensor.capitalize()} Acceleration")
290                
291                # Add annotations if available
292                if 'annotations' in df_filtered.columns:
293                    neg = df_filtered[df_filtered.annotations == 1]
294                    pos = df_filtered[df_filtered.annotations == 2]
295                    
296                    if not neg.empty:
297                        axes[i].scatter(neg.index, neg[sensor], 
298                                      c=self.config['colors']['no_freeze'], 
299                                      label="no freeze", alpha=self.config['alpha'])
300                    if not pos.empty:
301                        axes[i].scatter(pos.index, pos[sensor], 
302                                      c=self.config['colors']['freeze'], 
303                                      label="freeze", alpha=self.config['alpha'])
304                    
305                    axes[i].legend()
306        
307        plt.xlabel("Time")
308        plt.tight_layout()
309        plt.show()

EDA analyzer for Daphnet dataset visualization.

This analyzer provides comprehensive visualization capabilities for Daphnet dataset including thigh, shank, and trunk sensor data.

DaphnetVisualizationAnalyzer()
26    def __init__(self):
27        super().__init__(
28            name="daphnet_visualization",
29            description="Comprehensive visualization analyzer for Daphnet dataset sensor data"
30        )
31        self.config = {
32            'figsize': (20, 16),
33            'colors': {
34                'no_freeze': 'orange',
35                'freeze': 'purple'
36            },
37            'alpha': 0.6
38        }

Initialize the EDA analyzer.

Args: name: Name of the EDA analyzer description: Description of the EDA analyzer

config
def analyze( self, data: Union[pandas.core.frame.DataFrame, List[pandas.core.frame.DataFrame]], **kwargs) -> Dict[str, Any]:
40    def analyze(self, data: Union[pd.DataFrame, List[pd.DataFrame]], **kwargs) -> Dict[str, Any]:
41        """
42        Analyze the data and return statistical summaries.
43        
44        Args:
45            data: Input data to analyze
46            **kwargs: Additional arguments
47            
48        Returns:
49            Dictionary containing analysis results
50        """
51        if isinstance(data, list):
52            # Multiple datasets
53            results = {}
54            for i, df in enumerate(data):
55                results[f'dataset_{i}'] = self._analyze_single_dataset(df)
56            return results
57        else:
58            # Single dataset
59            return self._analyze_single_dataset(data)

Analyze the data and return statistical summaries.

Args: data: Input data to analyze **kwargs: Additional arguments

Returns: Dictionary containing analysis results

def visualize( self, data: Union[pandas.core.frame.DataFrame, List[pandas.core.frame.DataFrame]], **kwargs):
 89    def visualize(self, data: Union[pd.DataFrame, List[pd.DataFrame]], **kwargs):
 90        """
 91        Create visualizations of the data.
 92        
 93        Args:
 94            data: Input data to visualize
 95            **kwargs: Additional arguments including sensor_type, dataset_index, names
 96        """
 97        sensor_type = kwargs.get('sensor_type', 'all')
 98        dataset_index = kwargs.get('dataset_index', 0)
 99        names = kwargs.get('names', [])
100        
101        if isinstance(data, list):
102            if dataset_index < len(data):
103                df = data[dataset_index]
104                dataset_name = names[dataset_index] if dataset_index < len(names) else f"Dataset {dataset_index}"
105            else:
106                print(f"Dataset index {dataset_index} out of range")
107                return
108        else:
109            df = data
110            dataset_name = names[0] if names else "Dataset"
111        
112        if sensor_type == 'all':
113            self._plot_all_sensors(df, dataset_name)
114        elif sensor_type == 'thigh':
115            self._plot_thigh_data(df, dataset_name)
116        elif sensor_type == 'shank':
117            self._plot_shank_data(df, dataset_name)
118        elif sensor_type == 'trunk':
119            self._plot_trunk_data(df, dataset_name)
120        else:
121            print(f"Unknown sensor type: {sensor_type}")

Create visualizations of the data.

Args: data: Input data to visualize **kwargs: Additional arguments including sensor_type, dataset_index, names

class SensorStatisticsAnalyzer(gaitsetpy.core.base_classes.BaseEDAAnalyzer):
312class SensorStatisticsAnalyzer(BaseEDAAnalyzer):
313    """
314    EDA analyzer for sensor data statistics and feature visualization.
315    
316    This analyzer provides statistical analysis and feature visualization capabilities
317    for sensor data including sliding windows and extracted features.
318    """
319    
320    def __init__(self):
321        super().__init__(
322            name="sensor_statistics",
323            description="Statistical analysis and feature visualization for sensor data"
324        )
325        self.config = {
326            'figsize': (20, 10),
327            'feature_markers': {
328                'mean': 'x',
329                'rms': 'o',
330                'peak_height': 'v',
331                'mode': '<',
332                'median': '^'
333            }
334        }
335    
336    def analyze(self, data: Union[pd.DataFrame, List[pd.DataFrame]], **kwargs) -> Dict[str, Any]:
337        """
338        Analyze sensor data and return statistical summaries.
339        
340        Args:
341            data: Input data to analyze
342            **kwargs: Additional arguments
343            
344        Returns:
345            Dictionary containing analysis results
346        """
347        if isinstance(data, list):
348            # Multiple datasets
349            results = {}
350            for i, df in enumerate(data):
351                results[f'dataset_{i}'] = self._compute_statistics(df)
352            return results
353        else:
354            # Single dataset
355            return self._compute_statistics(data)
356    
357    def _compute_statistics(self, df: pd.DataFrame) -> Dict[str, Any]:
358        """Compute comprehensive statistics for a dataset."""
359        stats = {
360            'basic_stats': df.describe().to_dict(),
361            'correlation_matrix': df.corr().to_dict() if len(df.select_dtypes(include=[np.number]).columns) > 1 else {},
362            'skewness': df.skew().to_dict(),
363            'kurtosis': df.kurtosis().to_dict()
364        }
365        
366        # Add sensor-specific statistics
367        sensor_stats = {}
368        for sensor in ['thigh', 'shank', 'trunk']:
369            if sensor in df.columns:
370                sensor_data = df[sensor].dropna()
371                sensor_stats[sensor] = {
372                    'mean': sensor_data.mean(),
373                    'std': sensor_data.std(),
374                    'variance': sensor_data.var(),
375                    'min': sensor_data.min(),
376                    'max': sensor_data.max(),
377                    'range': sensor_data.max() - sensor_data.min(),
378                    'median': sensor_data.median(),
379                    'q25': sensor_data.quantile(0.25),
380                    'q75': sensor_data.quantile(0.75),
381                    'iqr': sensor_data.quantile(0.75) - sensor_data.quantile(0.25)
382                }
383        
384        stats['sensor_statistics'] = sensor_stats
385        return stats
386    
387    def visualize(self, sliding_windows: List[Dict], features: List[Dict], **kwargs):
388        """
389        Create visualizations of sensor data with overlaid features.
390        
391        Args:
392            sliding_windows: List of sliding window dictionaries
393            features: List of feature dictionaries
394            **kwargs: Additional arguments including sensor_name, start_idx, end_idx, num_windows
395        """
396        sensor_name = kwargs.get('sensor_name', 'shank')
397        start_idx = kwargs.get('start_idx', 0)
398        end_idx = kwargs.get('end_idx', 1000)
399        num_windows = kwargs.get('num_windows', 10)
400        save = kwargs.get('save', False)
401        
402        self._plot_sensor_with_features(sliding_windows, features, start_idx, end_idx, 
403                                      sensor_name, num_windows, save)
404    
405    def _plot_sensor_with_features(self, sliding_windows: List[Dict], features: List[Dict], 
406                                 start_idx: int, end_idx: int, sensor_name: str = "shank", 
407                                 num_windows: int = 10, save: bool = False):
408        """
409        Plot sliding windows of sensor data with overlaid statistical features.
410        
411        Args:
412            sliding_windows: List of sliding window dictionaries
413            features: List of feature dictionaries
414            start_idx: Start index of the time window
415            end_idx: End index of the time window
416            sensor_name: Name of the sensor to plot
417            num_windows: Number of sliding windows to plot
418            save: Whether to save the plot
419        """
420        fig, axes = plt.subplots(2, 1, figsize=self.config['figsize'], 
421                                gridspec_kw={'height_ratios': [3, 1]})
422        
423        # Extract sensor windows
424        sensor_windows = next((sw['data'] for sw in sliding_windows if sw['name'] == sensor_name), None)
425        if sensor_windows is None:
426            print(f"Sensor '{sensor_name}' not found in sliding_windows.")
427            return
428        
429        # Extract corresponding features
430        sensor_features = next((feat['features'] for feat in features if feat['name'] == sensor_name), None)
431        if sensor_features is None:
432            print(f"Sensor '{sensor_name}' not found in features.")
433            return
434        
435        # Filter windows based on start_idx and end_idx
436        filtered_windows = [series for series in sensor_windows 
437                           if start_idx <= series.index[0] and series.index[-1] <= end_idx]
438        
439        if not filtered_windows:
440            print(f"No windows found in the specified index range ({start_idx} - {end_idx}).")
441            return
442        
443        # Store entropy & frequency features for separate plotting
444        entropy_values = []
445        dominant_frequencies = []
446        
447        # Plot first num_windows windows
448        for i in range(min(num_windows, len(filtered_windows))):
449            series = filtered_windows[i]
450            
451            # Extract time and signal values
452            time_values = series.index.to_numpy()
453            signal_values = series.values
454            
455            # Determine actual start and end indices for this window
456            window_start, window_end = time_values[0], time_values[-1]
457            
458            # Plot time series data
459            axes[0].plot(time_values, signal_values, alpha=0.6)
460            
461            # Mark start and end of each window with vertical dotted lines
462            axes[0].axvline(x=window_start, color='black', linestyle='dotted', alpha=0.7)
463            axes[0].axvline(x=window_end, color='black', linestyle='dotted', alpha=0.7)
464            
465            # Overlay statistical features
466            for feature_name, marker in self.config['feature_markers'].items():
467                if feature_name in sensor_features and len(sensor_features[feature_name]) > i:
468                    feature_value = sensor_features[feature_name][i]
469                    if feature_value != 0:  # Skip zero values
470                        closest_index = np.argmin(np.abs(signal_values - feature_value))
471                        closest_time = time_values[closest_index]
472                        axes[0].scatter(closest_time, feature_value, color='red', 
473                                      marker=marker, s=100, label=feature_name if i == 0 else "")
474            
475            # Store entropy & frequency features for separate plotting
476            if 'entropy' in sensor_features and len(sensor_features['entropy']) > i:
477                entropy_values.append(sensor_features['entropy'][i])
478            if 'dominant_frequency' in sensor_features and len(sensor_features['dominant_frequency']) > i:
479                dominant_frequencies.append(sensor_features['dominant_frequency'][i])
480        
481        # Labels and title for time-series plot
482        axes[0].set_xlabel('Time')
483        axes[0].set_ylabel(f'{sensor_name} Signal')
484        axes[0].set_title(f'First {num_windows} windows of {sensor_name} in range {start_idx}-{end_idx} with Features')
485        axes[0].legend()
486        
487        # Frequency-domain & entropy plot
488        if dominant_frequencies:
489            window_indices = list(range(len(dominant_frequencies)))
490            axes[1].plot(window_indices, dominant_frequencies, 
491                        label="Dominant Frequency", marker="o", linestyle="dashed", color="blue")
492        
493        if entropy_values:
494            axes[1].bar(window_indices, entropy_values, alpha=0.6, label="Entropy", color="green")
495        
496        axes[1].set_xlabel("Window Index")
497        axes[1].set_ylabel("Feature Value")
498        axes[1].set_title("Frequency & Entropy Features")
499        axes[1].legend()
500        
501        plt.tight_layout()
502        
503        # Save or show plot
504        if save:
505            file_path = input("Enter the file path to save the plot (e.g., 'plot.png'): ")
506            plt.savefig(file_path, dpi=300)
507            print(f"Plot saved at {file_path}")
508        else:
509            plt.show() 

EDA analyzer for sensor data statistics and feature visualization.

This analyzer provides statistical analysis and feature visualization capabilities for sensor data including sliding windows and extracted features.

SensorStatisticsAnalyzer()
320    def __init__(self):
321        super().__init__(
322            name="sensor_statistics",
323            description="Statistical analysis and feature visualization for sensor data"
324        )
325        self.config = {
326            'figsize': (20, 10),
327            'feature_markers': {
328                'mean': 'x',
329                'rms': 'o',
330                'peak_height': 'v',
331                'mode': '<',
332                'median': '^'
333            }
334        }

Initialize the EDA analyzer.

Args: name: Name of the EDA analyzer description: Description of the EDA analyzer

config
def analyze( self, data: Union[pandas.core.frame.DataFrame, List[pandas.core.frame.DataFrame]], **kwargs) -> Dict[str, Any]:
336    def analyze(self, data: Union[pd.DataFrame, List[pd.DataFrame]], **kwargs) -> Dict[str, Any]:
337        """
338        Analyze sensor data and return statistical summaries.
339        
340        Args:
341            data: Input data to analyze
342            **kwargs: Additional arguments
343            
344        Returns:
345            Dictionary containing analysis results
346        """
347        if isinstance(data, list):
348            # Multiple datasets
349            results = {}
350            for i, df in enumerate(data):
351                results[f'dataset_{i}'] = self._compute_statistics(df)
352            return results
353        else:
354            # Single dataset
355            return self._compute_statistics(data)

Analyze sensor data and return statistical summaries.

Args: data: Input data to analyze **kwargs: Additional arguments

Returns: Dictionary containing analysis results

def visualize(self, sliding_windows: List[Dict], features: List[Dict], **kwargs):
387    def visualize(self, sliding_windows: List[Dict], features: List[Dict], **kwargs):
388        """
389        Create visualizations of sensor data with overlaid features.
390        
391        Args:
392            sliding_windows: List of sliding window dictionaries
393            features: List of feature dictionaries
394            **kwargs: Additional arguments including sensor_name, start_idx, end_idx, num_windows
395        """
396        sensor_name = kwargs.get('sensor_name', 'shank')
397        start_idx = kwargs.get('start_idx', 0)
398        end_idx = kwargs.get('end_idx', 1000)
399        num_windows = kwargs.get('num_windows', 10)
400        save = kwargs.get('save', False)
401        
402        self._plot_sensor_with_features(sliding_windows, features, start_idx, end_idx, 
403                                      sensor_name, num_windows, save)

Create visualizations of sensor data with overlaid features.

Args: sliding_windows: List of sliding window dictionaries features: List of feature dictionaries **kwargs: Additional arguments including sensor_name, start_idx, end_idx, num_windows

def plot_thigh_data(daphnetThigh, daphnetNames, i):
19def plot_thigh_data(daphnetThigh, daphnetNames, i):
20    """
21    Plot thigh acceleration data for a specific dataset.
22    Args:
23        daphnetThigh (list): List of DataFrames containing thigh acceleration data.
24        daphnetNames (list): List of dataset names.
25        i (int): Index of the dataset to plot.
26    """
27    print(daphnetNames[i])
28    fig, axes = plt.subplots(4, 1, sharex=True, sharey=True, figsize=(20, 16))
29    fig.suptitle("Thigh Data from " + daphnetNames[i])
30    plt.xlabel("Time")
31
32    df = daphnetThigh[i]
33    df = df[df.annotations > 0]  # Filter out rows with no annotations
34    neg = df[df.annotations == 1]  # No freeze
35    pos = df[df.annotations == 2]  # Freeze
36
37    # Plot horizontal forward thigh acceleration
38    ax1 = axes[0]
39    ax1.plot(df.thigh_h_fd)
40    ax1.set_ylabel("Horizontal Forward Thigh Acceleration")
41    ax1.scatter(neg.index, neg.thigh_h_fd, c='orange', label="no freeze")
42    ax1.scatter(pos.index, pos.thigh_h_fd, c='purple', label="freeze")
43    ax1.legend()
44
45    # Plot vertical thigh acceleration
46    ax2 = axes[1]
47    ax2.plot(df.thigh_v)
48    ax2.set_ylabel("Vertical Thigh Acceleration")
49    ax2.scatter(neg.index, neg.thigh_v, c='orange', label="no freeze")
50    ax2.scatter(pos.index, pos.thigh_v, c='purple', label="freeze")
51    ax2.legend()
52
53    # Plot horizontal lateral thigh acceleration
54    ax3 = axes[2]
55    ax3.plot(df.thigh_h_l)
56    ax3.set_ylabel("Horizontal Lateral Thigh Acceleration")
57    ax3.scatter(neg.index, neg.thigh_h_l, c='orange', label="no freeze")
58    ax3.scatter(pos.index, pos.thigh_h_l, c='purple', label="freeze")
59    ax3.legend()
60
61    # Plot overall thigh acceleration
62    ax4 = axes[3]
63    ax4.plot(df.thigh)
64    ax4.set_ylabel("Overall Thigh Acceleration")
65    ax4.scatter(neg.index, neg.thigh, c='orange', label="no freeze")
66    ax4.scatter(pos.index, pos.thigh, c='purple', label="freeze")
67    ax4.legend()
68
69    plt.tight_layout()
70    plt.show()

Plot thigh acceleration data for a specific dataset. Args: daphnetThigh (list): List of DataFrames containing thigh acceleration data. daphnetNames (list): List of dataset names. i (int): Index of the dataset to plot.

def plot_shank_data(daphnetShank, daphnetNames, i):
 73def plot_shank_data(daphnetShank, daphnetNames, i):
 74    """
 75    Plot shank acceleration data for a specific dataset.
 76    Args:
 77        daphnetShank (list): List of DataFrames containing shank acceleration data.
 78        daphnetNames (list): List of dataset names.
 79        i (int): Index of the dataset to plot.
 80    """
 81    print(daphnetNames[i])
 82    fig, axes = plt.subplots(4, 1, sharex=True, sharey=True, figsize=(20, 16))
 83    fig.suptitle("Shank Data from " + daphnetNames[i])
 84    plt.xlabel("Time")
 85
 86    df = daphnetShank[i]
 87    df["shank"] = np.sqrt(df["shank_h_l"]**2 + df["shank_v"]**2 + df["shank_h_fd"]**2)
 88    df = df[df.annotations > 0]
 89    neg = df[df.annotations == 1]
 90    pos = df[df.annotations == 2]
 91
 92    ax1 = axes[0]
 93    ax1.plot(df.shank_h_fd)
 94    ax1.set_ylabel("Horizontal Forward Shank Acceleration")
 95    ax1.scatter(neg.index, neg.shank_h_fd, c='orange', label="no freeze")
 96    ax1.scatter(pos.index, pos.shank_h_fd, c='purple', label="freeze")
 97    ax1.legend()
 98
 99    ax2 = axes[1]
100    ax2.plot(df.shank_v)
101    ax2.set_ylabel("Vertical Shank Acceleration")
102    ax2.scatter(neg.index, neg.shank_v, c='orange', label="no freeze")
103    ax2.scatter(pos.index, pos.shank_v, c='purple', label="freeze")
104    ax2.legend()
105
106    ax3 = axes[2]
107    ax3.plot(df.shank_h_l)
108    ax3.set_ylabel("Horizontal Lateral Shank Acceleration")
109    ax3.scatter(neg.index, neg.shank_h_l, c='orange', label="no freeze")
110    ax3.scatter(pos.index, pos.shank_h_l, c='purple', label="freeze")
111    ax3.legend()
112
113    ax4 = axes[3]
114    ax4.plot(df.shank)
115    ax4.set_ylabel("Overall Shank Acceleration")
116    ax4.scatter(neg.index, neg.shank, c='orange', label="no freeze")
117    ax4.scatter(pos.index, pos.shank, c='purple', label="freeze")
118    ax4.legend()
119
120    plt.tight_layout()
121    plt.show()

Plot shank acceleration data for a specific dataset. Args: daphnetShank (list): List of DataFrames containing shank acceleration data. daphnetNames (list): List of dataset names. i (int): Index of the dataset to plot.

def plot_trunk_data(daphnetTrunk, daphnetNames, i):
124def plot_trunk_data(daphnetTrunk, daphnetNames, i):
125    """
126    Plot trunk acceleration data for a specific dataset.
127    Args:
128        daphnetTrunk (list): List of DataFrames containing trunk acceleration data.
129        daphnetNames (list): List of dataset names.
130        i (int): Index of the dataset to plot.
131    """
132    print(daphnetNames[i])
133    fig, axes = plt.subplots(4, 1, sharex=True, sharey=True, figsize=(20, 16))
134    fig.suptitle("Trunk Data from " + daphnetNames[i])
135    plt.xlabel("Time")
136
137    df = daphnetTrunk[i]
138    df["trunk"] = np.sqrt(df["trunk_h_l"]**2 + df["trunk_v"]**2 + df["trunk_h_fd"]**2)
139    df = df[df.annotations > 0]
140    neg = df[df.annotations == 1]
141    pos = df[df.annotations == 2]
142
143    ax1 = axes[0]
144    ax1.plot(df.trunk_h_fd)
145    ax1.set_ylabel("Horizontal Forward Trunk Acceleration")
146    ax1.scatter(neg.index, neg.trunk_h_fd, c='orange', label="no freeze")
147    ax1.scatter(pos.index, pos.trunk_h_fd, c='purple', label="freeze")
148    ax1.legend()
149
150    ax2 = axes[1]
151    ax2.plot(df.trunk_v)
152    ax2.set_ylabel("Vertical Trunk Acceleration")
153    ax2.scatter(neg.index, neg.trunk_v, c='orange', label="no freeze")
154    ax2.scatter(pos.index, pos.trunk_v, c='purple', label="freeze")
155    ax2.legend()
156
157    ax3 = axes[2]
158    ax3.plot(df.trunk_h_l)
159    ax3.set_ylabel("Horizontal Lateral Trunk Acceleration")
160    ax3.scatter(neg.index, neg.trunk_h_l, c='orange', label="no freeze")
161    ax3.scatter(pos.index, pos.trunk_h_l, c='purple', label="freeze")
162    ax3.legend()
163
164    ax4 = axes[3]
165    ax4.plot(df.trunk)
166    ax4.set_ylabel("Overall Trunk Acceleration")
167    ax4.scatter(neg.index, neg.trunk, c='orange', label="no freeze")
168    ax4.scatter(pos.index, pos.trunk, c='purple', label="freeze")
169    ax4.legend()
170
171    plt.tight_layout()
172    plt.show()

Plot trunk acceleration data for a specific dataset. Args: daphnetTrunk (list): List of DataFrames containing trunk acceleration data. daphnetNames (list): List of dataset names. i (int): Index of the dataset to plot.

def plot_all_data(daphnetThigh, daphnetShank, daphnetTrunk, daphnetNames, i):
191def plot_all_data(daphnetThigh, daphnetShank, daphnetTrunk, daphnetNames, i):
192    """
193    Plot thigh, shank, and trunk acceleration data for a specific dataset.
194    Args:
195        daphnetThigh (list): List of DataFrames containing thigh acceleration data.
196        daphnetShank (list): List of DataFrames containing shank acceleration data.
197        daphnetTrunk (list): List of DataFrames containing trunk acceleration data.
198        daphnetNames (list): List of dataset names.
199        i (int): Index of the dataset to plot.
200    """
201    plot_thigh_data(daphnetThigh, daphnetNames, i)
202    plot_shank_data(daphnetShank, daphnetNames, i)
203    plot_trunk_data(daphnetTrunk, daphnetNames, i)

Plot thigh, shank, and trunk acceleration data for a specific dataset. Args: daphnetThigh (list): List of DataFrames containing thigh acceleration data. daphnetShank (list): List of DataFrames containing shank acceleration data. daphnetTrunk (list): List of DataFrames containing trunk acceleration data. daphnetNames (list): List of dataset names. i (int): Index of the dataset to plot.

def plot_all_thigh_data(daphnetThigh, daphnetNames):
175def plot_all_thigh_data(daphnetThigh, daphnetNames):
176    """Plot thigh acceleration data for all datasets."""
177    for i in range(len(daphnetThigh)):
178        plot_thigh_data(daphnetThigh, daphnetNames, i)

Plot thigh acceleration data for all datasets.

def plot_all_shank_data(daphnetShank, daphnetNames):
180def plot_all_shank_data(daphnetShank, daphnetNames):
181    """Plot shank acceleration data for all datasets."""
182    for i in range(len(daphnetShank)):
183        plot_shank_data(daphnetShank, daphnetNames, i)

Plot shank acceleration data for all datasets.

def plot_all_trunk_data(daphnetTrunk, daphnetNames):
185def plot_all_trunk_data(daphnetTrunk, daphnetNames):
186    """Plot trunk acceleration data for all datasets."""
187    for i in range(len(daphnetTrunk)):
188        plot_trunk_data(daphnetTrunk, daphnetNames, i)

Plot trunk acceleration data for all datasets.

def plot_all_datasets(daphnetThigh, daphnetShank, daphnetTrunk, daphnetNames):
205def plot_all_datasets(daphnetThigh, daphnetShank, daphnetTrunk, daphnetNames):
206    """Plot thigh, shank, and trunk acceleration data for all datasets."""
207    for i in range(len(daphnetThigh)):
208        plot_all_data(daphnetThigh, daphnetShank, daphnetTrunk, daphnetNames, i)

Plot thigh, shank, and trunk acceleration data for all datasets.

def plot_sensor_with_features( sliding_windows, features, start_idx, end_idx, sensor_name='shank', num_windows=10, save=False):
 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

def get_eda_manager():
51def get_eda_manager():
52    """Get the singleton EDAManager instance."""
53    return EDAManager()

Get the singleton EDAManager instance.

def get_available_analyzers():
56def get_available_analyzers():
57    """Get list of available EDA analyzer names."""
58    return EDAManager().get_available_components()

Get list of available EDA analyzer names.

def analyze_data(analyzer_name: str, data, **kwargs):
61def analyze_data(analyzer_name: str, data, **kwargs):
62    """
63    Analyze data using the EDAManager.
64    
65    Args:
66        analyzer_name: Name of the EDA analyzer
67        data: Input data to analyze
68        **kwargs: Additional arguments for analysis
69        
70    Returns:
71        Analysis results dictionary
72    """
73    return EDAManager().analyze_data(analyzer_name, data, **kwargs)

Analyze data using the EDAManager.

Args: analyzer_name: Name of the EDA analyzer data: Input data to analyze **kwargs: Additional arguments for analysis

Returns: Analysis results dictionary

def visualize_data(analyzer_name: str, data, **kwargs):
76def visualize_data(analyzer_name: str, data, **kwargs):
77    """
78    Create visualizations using the EDAManager.
79    
80    Args:
81        analyzer_name: Name of the EDA analyzer
82        data: Input data to visualize
83        **kwargs: Additional arguments for visualization
84    """
85    return EDAManager().visualize_data(analyzer_name, data, **kwargs)

Create visualizations using the EDAManager.

Args: analyzer_name: Name of the EDA analyzer data: Input data to visualize **kwargs: Additional arguments for visualization

def plot_daphnet_data(data, names=None, sensor_type='all', dataset_index=0):
88def plot_daphnet_data(data, names=None, sensor_type='all', dataset_index=0):
89    """
90    Plot Daphnet dataset using the DaphnetVisualizationAnalyzer.
91    
92    Args:
93        data: Input data (DataFrame or list of DataFrames)
94        names: List of dataset names
95        sensor_type: Type of sensor to plot ('all', 'thigh', 'shank', 'trunk')
96        dataset_index: Index of dataset to plot (if data is a list)
97    """
98    analyzer = DaphnetVisualizationAnalyzer()
99    analyzer.visualize(data, sensor_type=sensor_type, dataset_index=dataset_index, names=names or [])

Plot Daphnet dataset using the DaphnetVisualizationAnalyzer.

Args: data: Input data (DataFrame or list of DataFrames) names: List of dataset names sensor_type: Type of sensor to plot ('all', 'thigh', 'shank', 'trunk') dataset_index: Index of dataset to plot (if data is a list)

def analyze_sensor_statistics(data):
101def analyze_sensor_statistics(data):
102    """
103    Analyze sensor statistics using the SensorStatisticsAnalyzer.
104    
105    Args:
106        data: Input data (DataFrame or list of DataFrames)
107        
108    Returns:
109        Dictionary containing statistical analysis results
110    """
111    analyzer = SensorStatisticsAnalyzer()
112    return analyzer.analyze(data)

Analyze sensor statistics using the SensorStatisticsAnalyzer.

Args: data: Input data (DataFrame or list of DataFrames)

Returns: Dictionary containing statistical analysis results

def plot_sensor_features( sliding_windows, features, sensor_name='shank', start_idx=0, end_idx=1000, num_windows=10):
114def plot_sensor_features(sliding_windows, features, sensor_name='shank', start_idx=0, end_idx=1000, num_windows=10):
115    """
116    Plot sensor data with overlaid features using the SensorStatisticsAnalyzer.
117    
118    Args:
119        sliding_windows: List of sliding window dictionaries
120        features: List of feature dictionaries
121        sensor_name: Name of the sensor to plot
122        start_idx: Start index of the time window
123        end_idx: End index of the time window
124        num_windows: Number of sliding windows to plot
125    """
126    analyzer = SensorStatisticsAnalyzer()
127    analyzer.visualize(sliding_windows, features, sensor_name=sensor_name, 
128                      start_idx=start_idx, end_idx=end_idx, num_windows=num_windows)

Plot sensor data with overlaid features using the SensorStatisticsAnalyzer.

Args: sliding_windows: List of sliding window dictionaries features: List of feature dictionaries sensor_name: Name of the sensor to plot start_idx: Start index of the time window end_idx: End index of the time window num_windows: Number of sliding windows to plot