# scopekit `scopekit` is a Python library for creating high-performance, interactive oscilloscope-style plots for large time-series datasets using `matplotlib`. It is designed to handle millions of data points smoothly by automatically decimating data for the current view. When zoomed out, it displays a performance-optimized "envelope" view, and when zoomed in, it seamlessly transitions to show detailed raw data. ## Installation To install the package from your local repository, run: ```bash pip install . ``` ## Quickstart Example Here is a simple example of how to create a plot with `scopekit`. ```python import numpy as np from scopekit import OscilloscopePlot # 1. Generate some sample data fs = 1e7 # 10 MHz sampling rate duration = 0.1 # 0.1 seconds of data t = np.arange(0, duration, 1/fs) # A 50 Hz signal with some high-frequency noise x = np.sin(2 * np.pi * 50 * t) + np.sin(2 * np.pi * 1e3 * t) * 0.2 # 2. Create an OscilloscopePlot instance # The plot automatically handles decimation and display modes. plot = OscilloscopePlot(t, x, name="Sample Waveform") # 3. Render the plot # This creates the matplotlib figure and axes. plot.render() # 4. Show the plot # The plot is now interactive: zoom with the mouse and use the toolbar. plot.show() ``` ## API Reference The primary interface for the library is the `OscilloscopePlot` class. ### `OscilloscopePlot` #### `__init__` ```python def __init__( self, t: Union[np.ndarray, List[np.ndarray]], x: Union[np.ndarray, List[np.ndarray]], name: Union[str, List[str]] = "Waveform", trace_colors: Optional[List[str]] = None, max_plot_points: int = 10000, mode_switch_threshold: float = 10e-3, min_y_range: Optional[float] = None, y_margin_fraction: float = 0.15, signal_line_width: float = 1.0, signal_alpha: float = 0.75, envelope_alpha: float = 0.75, region_alpha: float = 0.4, region_zorder: int = -5, envelope_window_samples: Optional[int] = None, ): ``` #### Methods ```python def add_line( self, t: Union[np.ndarray, List[np.ndarray]], data: Union[np.ndarray, List[np.ndarray]], label: str = "Line", color: Optional[str] = None, alpha: float = 0.75, linestyle: str = "-", linewidth: float = 1.0, display_mode: int = MODE_BOTH, trace_idx: int = 0, zorder: int = 5, ) -> None: ``` ```python def add_ribbon( self, t: Union[np.ndarray, List[np.ndarray]], center_data: Union[np.ndarray, List[np.ndarray]], width: Union[float, np.ndarray], label: str = "Ribbon", color: str = "gray", alpha: float = 0.6, display_mode: int = MODE_DETAIL, trace_idx: int = 0, zorder: int = 2, ) -> None: ``` ```python def add_envelope( self, min_data: Union[np.ndarray, List[np.ndarray]], max_data: Union[np.ndarray, List[np.ndarray]], label: str = "Envelope", color: Optional[str] = None, alpha: float = 0.4, display_mode: int = MODE_ENVELOPE, trace_idx: int = 0, zorder: int = 1, ) -> None: ``` ```python def add_regions( self, regions: np.ndarray, label: str = "Regions", color: str = "crimson", alpha: float = 0.4, display_mode: int = MODE_BOTH, trace_idx: int = 0, zorder: int = -5, ) -> None: ``` ```python def render(self) -> None: ``` ```python def show(self) -> None: ``` ```python def save(self, filepath: str) -> None: ``` ```python def home(self) -> None: ``` ```python def refresh(self) -> None: ```