TraceKit Visualization API¶
Version: 0.1.0 | Last Updated: 2026-01-08
The TraceKit Visualization API provides comprehensive plotting functions for waveform and spectral analysis. All visualization functions are accessible from the top-level API as tk.plot_*().
Overview¶
TraceKit provides a complete suite of visualization functions organized by category:
Time-Domain Visualization¶
tk.plot_waveform()- Time-domain waveform plottingtk.plot_multi_channel()- Multi-channel stacked plotstk.plot_xy()- X-Y (Lissajous) plots
Frequency-Domain Visualization¶
tk.plot_spectrum()- Frequency-domain spectrum plottingtk.plot_fft()- FFT magnitude spectrum plottingtk.plot_psd()- Power spectral density plotstk.plot_spectrogram()- Time-frequency spectrogramstk.plot_waterfall()- 3D waterfall plots
Digital Signal Visualization¶
tk.plot_timing()- Digital timing diagramstk.plot_logic_analyzer()- Logic analyzer style plots
Signal Integrity & Analysis¶
tk.plot_eye()- Eye diagrams for signal integritytk.plot_bathtub()- Bathtub curves for BER analysistk.plot_bode()- Bode magnitude and phase plotstk.plot_phase()- Phase relationship plotstk.plot_histogram()- Amplitude distribution histograms
All functions support:
- Automatic unit selection (time/frequency)
- Custom styling (colors, labels, titles, sizes)
- High-resolution file export (PNG, PDF, SVG)
- GUI and non-GUI (server) environments
- Publication-quality output
- Interactive and non-interactive modes
Quick Start¶
import tracekit as tk
# Load a trace
trace = tk.load("signal.wfm")
# Plot time-domain waveform
tk.plot_waveform(trace)
# Plot frequency spectrum
tk.plot_spectrum(trace)
# Plot FFT with custom settings
tk.plot_fft(trace, freq_unit="MHz", log_scale=True)
API Reference¶
tk.plot_waveform()¶
Plot time-domain waveform with automatic time unit selection.
Signature:
tk.plot_waveform(
trace,
ax=None,
time_unit="auto",
show_grid=True,
color="C0",
label=None,
show_measurements=None,
title=None,
xlabel="Time",
ylabel="Amplitude",
show=True,
save_path=None,
figsize=(10, 6)
)
Parameters:
trace(WaveformTrace): Waveform trace to plotax(Axes, optional): Matplotlib axes object. If None, creates new figuretime_unit(str): Time unit - "s", "ms", "us", "ns", or "auto" (default: "auto")show_grid(bool): Display grid lines (default: True)color(str): Line color (default: "C0")label(str, optional): Legend labelshow_measurements(dict, optional): Dictionary of measurements to annotatetitle(str, optional): Plot titlexlabel(str): X-axis label prefix (default: "Time")ylabel(str): Y-axis label (default: "Amplitude")show(bool): Call plt.show() to display (default: True)save_path(str, optional): Path to save figurefigsize(tuple): Figure size in inches (width, height) (default: (10, 6))
Returns:
Figure: Matplotlib Figure object
Example:
import tracekit as tk
trace = tk.load("signal.wfm")
# Basic usage
tk.plot_waveform(trace)
# Custom styling
fig = tk.plot_waveform(
trace,
title="Captured Signal",
time_unit="us",
color="blue",
ylabel="Voltage (V)",
show=False,
save_path="waveform.png"
)
tk.plot_spectrum()¶
Plot frequency-domain magnitude spectrum with automatic frequency unit selection.
Signature:
tk.plot_spectrum(
trace,
ax=None,
freq_unit="auto",
db_ref=None,
show_grid=True,
color="C0",
title=None,
window="hann",
xscale="log",
show=True,
save_path=None,
figsize=(10, 6),
xlim=None,
ylim=None,
fft_result=None,
log_scale=True
)
Parameters:
trace(WaveformTrace): Waveform trace to analyzeax(Axes, optional): Matplotlib axes objectfreq_unit(str): Frequency unit - "Hz", "kHz", "MHz", "GHz", or "auto" (default: "auto")db_ref(float, optional): Reference for dB scalingshow_grid(bool): Display grid lines (default: True)color(str): Line color (default: "C0")title(str, optional): Plot titlewindow(str): Window function for FFT (default: "hann")xscale(str): X-axis scale - "linear" or "log" (deprecated, use log_scale)show(bool): Call plt.show() to display (default: True)save_path(str, optional): Path to save figurefigsize(tuple): Figure size in inches (default: (10, 6))xlim(tuple, optional): X-axis limits (min, max) in selected unitsylim(tuple, optional): Y-axis limits (min, max) in dBfft_result(tuple, optional): Pre-computed FFT (frequencies, magnitudes)log_scale(bool): Use logarithmic frequency axis (default: True)
Returns:
Figure: Matplotlib Figure object
Example:
import tracekit as tk
trace = tk.load("signal.wfm")
# Basic usage
tk.plot_spectrum(trace)
# With custom settings
tk.plot_spectrum(
trace,
freq_unit="MHz",
log_scale=True,
xlim=(1, 100),
ylim=(-80, 0),
save_path="spectrum.png"
)
# Using pre-computed FFT
freq, mag = tk.fft(trace)
tk.plot_spectrum(trace, fft_result=(freq, mag))
tk.plot_fft()¶
Plot FFT magnitude spectrum with automatic frequency unit selection. This is a convenience function that combines FFT computation and visualization.
Signature:
tk.plot_fft(
trace,
ax=None,
show=True,
save_path=None,
title=None,
xlabel="Frequency",
ylabel="Magnitude (dB)",
figsize=(10, 6),
freq_unit="auto",
log_scale=True,
show_grid=True,
color="C0",
window="hann",
xlim=None,
ylim=None
)
Parameters:
trace(WaveformTrace): Waveform trace to analyzeax(Axes, optional): Matplotlib axes objectshow(bool): Call plt.show() to display (default: True)save_path(str, optional): Path to save figuretitle(str, optional): Plot title (default: "FFT Magnitude Spectrum")xlabel(str): X-axis label prefix (default: "Frequency")ylabel(str): Y-axis label (default: "Magnitude (dB)")figsize(tuple): Figure size in inches (default: (10, 6))freq_unit(str): Frequency unit - "Hz", "kHz", "MHz", "GHz", or "auto" (default: "auto")log_scale(bool): Use logarithmic frequency axis (default: True)show_grid(bool): Display grid lines (default: True)color(str): Line color (default: "C0")window(str): Window function for FFT (default: "hann")xlim(tuple, optional): X-axis limits (min, max)ylim(tuple, optional): Y-axis limits (min, max)
Returns:
Figure: Matplotlib Figure object
Example:
import tracekit as tk
trace = tk.load("signal.wfm")
# Basic usage
tk.plot_fft(trace)
# Custom FFT plot
fig = tk.plot_fft(
trace,
title="Signal FFT Analysis",
freq_unit="MHz",
log_scale=True,
xlim=(0.1, 100),
ylim=(-100, 0),
figsize=(12, 6),
show=False,
save_path="fft.png"
)
tk.plot_multi_channel()¶
Plot multiple channels in stacked subplots with synchronized time axes.
Signature:
tk.plot_multi_channel(
traces,
names=None,
shared_x=True,
colors=None,
time_unit="auto",
show_grid=True,
figsize=None,
title=None
)
Parameters:
traces(list[WaveformTrace]): List of traces to plotnames(list[str], optional): Channel names for labels. If None, uses CH1, CH2, etc.shared_x(bool): Share x-axis across subplots (default: True)colors(list[str], optional): List of colors for each tracetime_unit(str): Time unit - "s", "ms", "us", "ns", or "auto" (default: "auto")show_grid(bool): Display grid lines (default: True)figsize(tuple, optional): Figure size in inches (width, height)title(str, optional): Overall figure title
Returns:
Figure: Matplotlib Figure object
Example:
import tracekit as tk
# Load multiple channels
ch1 = tk.load("channel1.wfm")
ch2 = tk.load("channel2.wfm")
ch3 = tk.load("channel3.wfm")
# Plot all channels
fig = tk.plot_multi_channel(
[ch1, ch2, ch3],
names=["CLK", "DATA", "CS"],
title="SPI Bus Signals"
)
# Custom colors
fig = tk.plot_multi_channel(
[ch1, ch2],
names=["Input", "Output"],
colors=["blue", "red"],
figsize=(12, 8)
)
Use Cases:
- Multi-channel oscilloscope data visualization
- Bus signal analysis (I2C, SPI, UART)
- Comparing multiple related signals
- Trigger and data signal correlation
tk.plot_xy()¶
Create X-Y (Lissajous) plots showing phase relationships between two signals.
Signature:
Parameters:
x_trace(WaveformTrace or ndarray): X-axis waveformy_trace(WaveformTrace or ndarray): Y-axis waveformax(Axes, optional): Matplotlib axes objectcolor(str): Line/marker color (default: "C0")marker(str): Marker style (default: "")alpha(float): Transparency (0.0 to 1.0) (default: 0.7)title(str, optional): Plot title
Returns:
Figure: Matplotlib Figure object
Example:
import tracekit as tk
# Load two phase-shifted signals
ch1 = tk.load("signal_x.wfm")
ch2 = tk.load("signal_y.wfm")
# Create Lissajous figure
fig = tk.plot_xy(ch1, ch2, title="Phase Relationship")
# With markers
fig = tk.plot_xy(
ch1, ch2,
marker="o",
alpha=0.5,
color="purple"
)
Use Cases:
- Visualizing phase relationships
- Checking signal orthogonality
- Analyzing quadrature signals (I/Q)
- Detecting phase drift
tk.plot_psd()¶
Plot Power Spectral Density showing power distribution across frequencies.
Signature:
tk.plot_psd(
trace,
ax=None,
freq_unit="auto",
show_grid=True,
color="C0",
title=None,
window="hann",
xscale="log"
)
Parameters:
trace(WaveformTrace): Waveform trace to analyzeax(Axes, optional): Matplotlib axes objectfreq_unit(str): Frequency unit - "Hz", "kHz", "MHz", "GHz", or "auto" (default: "auto")show_grid(bool): Display grid lines (default: True)color(str): Line color (default: "C0")title(str, optional): Plot titlewindow(str): Window function for FFT (default: "hann")xscale(str): X-axis scale - "linear" or "log" (default: "log")
Returns:
Figure: Matplotlib Figure object
Example:
import tracekit as tk
trace = tk.load("noisy_signal.wfm")
# Plot PSD
fig = tk.plot_psd(trace)
# With linear frequency axis
fig = tk.plot_psd(
trace,
freq_unit="MHz",
xscale="linear",
title="Power Spectral Density"
)
Use Cases:
- Noise characterization
- Signal power analysis
- Interference detection
- Frequency content analysis
tk.plot_spectrogram()¶
Create time-frequency spectrogram showing how spectrum evolves over time.
Signature:
tk.plot_spectrogram(
trace,
ax=None,
time_unit="auto",
freq_unit="auto",
cmap="viridis",
vmin=None,
vmax=None,
title=None,
window="hann",
nperseg=None,
nfft=None,
overlap=None
)
Parameters:
trace(WaveformTrace): Waveform trace to analyzeax(Axes, optional): Matplotlib axes objecttime_unit(str): Time unit - "s", "ms", "us", "ns", or "auto" (default: "auto")freq_unit(str): Frequency unit - "Hz", "kHz", "MHz", "GHz", or "auto" (default: "auto")cmap(str): Colormap name (default: "viridis")vmin(float, optional): Minimum dB value for color scalingvmax(float, optional): Maximum dB value for color scalingtitle(str, optional): Plot titlewindow(str): Window function (default: "hann")nperseg(int, optional): Segment length for STFTnfft(int, optional): FFT length (overrides nperseg)overlap(float, optional): Overlap fraction (0.0 to 1.0, default: 0.5)
Returns:
Figure: Matplotlib Figure object
Example:
import tracekit as tk
trace = tk.load("chirp_signal.wfm")
# Basic spectrogram
fig = tk.plot_spectrogram(trace)
# With custom settings
fig = tk.plot_spectrogram(
trace,
nperseg=1024,
overlap=0.75,
cmap="hot",
title="Chirp Signal Spectrogram"
)
Use Cases:
- Time-varying frequency analysis
- Chirp signal analysis
- Transient detection
- Frequency hopping visualization
- FM/AM signal analysis
tk.plot_waterfall()¶
Create 3D waterfall plot showing spectrum evolution with depth visualization.
Signature:
tk.plot_waterfall(
data,
time_axis=None,
freq_axis=None,
sample_rate=1.0,
nperseg=256,
noverlap=None,
cmap="viridis",
ax=None
)
Parameters:
data(ndarray): Input signal (1D) or pre-computed spectrogram (2D)time_axis(ndarray, optional): Time axis for signalfreq_axis(ndarray, optional): Frequency axis (if pre-computed)sample_rate(float): Sample rate in Hz (default: 1.0)nperseg(int): Segment length for FFT (default: 256)noverlap(int, optional): Overlap between segmentscmap(str): Colormap for amplitude coloring (default: "viridis")ax(3D Axes, optional): Existing 3D axes to plot on
Returns:
tuple: (Figure, Axes)
Example:
import tracekit as tk
trace = tk.load("fm_signal.wfm")
# Create waterfall plot
fig, ax = tk.plot_waterfall(
trace.data,
sample_rate=trace.metadata.sample_rate
)
# With custom parameters
fig, ax = tk.plot_waterfall(
trace.data,
sample_rate=1e6,
nperseg=512,
cmap="hot"
)
Use Cases:
- Spectrum monitoring over time
- Radio frequency analysis
- EMI/EMC testing visualization
- Frequency stability analysis
tk.plot_timing()¶
Create digital timing diagrams with protocol decode overlay support.
Signature:
tk.plot_timing(
traces,
names=None,
annotations=None,
time_unit="auto",
show_grid=True,
figsize=None,
title=None,
time_range=None,
threshold="auto"
)
Parameters:
traces(list[WaveformTrace]): List of traces to plot (analog or digital)names(list[str], optional): Channel names for labelsannotations(list[list[Annotation]], optional): Protocol annotations per channeltime_unit(str): Time unit - "s", "ms", "us", "ns", or "auto" (default: "auto")show_grid(bool): Show vertical grid lines (default: True)figsize(tuple, optional): Figure size in inchestitle(str, optional): Overall figure titletime_range(tuple, optional): (start, end) time range in secondsthreshold(float or str): Threshold for analog-to-digital conversion (default: "auto")
Returns:
Figure: Matplotlib Figure object
Example:
import tracekit as tk
# Load digital signals
clk = tk.load("clock.wfm")
data = tk.load("data.wfm")
cs = tk.load("chip_select.wfm")
# Create timing diagram
fig = tk.plot_timing(
[clk, data, cs],
names=["CLK", "DATA", "CS"],
title="SPI Communication"
)
# With time range zoom
fig = tk.plot_timing(
[clk, data],
names=["Clock", "Data"],
time_range=(0, 1e-6), # First microsecond
time_unit="ns"
)
Use Cases:
- Digital protocol debugging
- Timing relationship visualization
- Setup and hold time analysis
- Protocol decode verification
tk.plot_logic_analyzer()¶
Create logic analyzer style display with bus grouping support.
Signature:
tk.plot_logic_analyzer(
traces,
names=None,
bus_groups=None,
time_unit="auto",
show_grid=True,
figsize=None,
title=None
)
Parameters:
traces(list[DigitalTrace]): List of digital tracesnames(list[str], optional): Channel namesbus_groups(dict, optional): Dictionary mapping bus names to channel indices- Example:
{"DATA": [0, 1, 2, 3], "ADDR": [4, 5, 6, 7]} time_unit(str): Time unit (default: "auto")show_grid(bool): Show vertical grid lines (default: True)figsize(tuple, optional): Figure sizetitle(str, optional): Plot title
Returns:
Figure: Matplotlib Figure object
Example:
import tracekit as tk
# Load 8 data lines
traces = [tk.load(f"d{i}.wfm") for i in range(8)]
# Plot with bus grouping
fig = tk.plot_logic_analyzer(
traces,
names=[f"D{i}" for i in range(8)],
bus_groups={"DATA": [0, 1, 2, 3, 4, 5, 6, 7]}
)
# Multiple buses
fig = tk.plot_logic_analyzer(
traces,
bus_groups={
"DATA": [0, 1, 2, 3],
"ADDR": [4, 5, 6, 7]
}
)
Use Cases:
- Multi-bit bus visualization
- Parallel data analysis
- Address/data bus monitoring
- Digital system debugging
tk.plot_eye()¶
Create eye diagram for signal integrity analysis with clock recovery.
Signature:
tk.plot_eye(
trace,
bit_rate=None,
clock_recovery="edge",
samples_per_bit=None,
ui_count=2,
ax=None,
cmap="hot",
alpha=0.3,
show_measurements=True,
title=None,
colorbar=False
)
Parameters:
trace(WaveformTrace): Input waveform (serial data signal)bit_rate(float, optional): Bit rate in bits/second. Auto-recovered if Noneclock_recovery(str): Method for clock recovery - "fft" or "edge" (default: "edge")samples_per_bit(int, optional): Samples per bit period (auto-calculated if None)ui_count(int): Number of Unit Intervals to display (default: 2)ax(Axes, optional): Matplotlib axes objectcmap(str): Colormap for density visualization (default: "hot")alpha(float): Transparency for overlaid traces (default: 0.3)show_measurements(bool): Annotate eye opening measurements (default: True)title(str, optional): Plot titlecolorbar(bool): Show colorbar for density plot (default: False)
Returns:
Figure: Matplotlib Figure object
Example:
import tracekit as tk
trace = tk.load("serial_data.wfm")
# With known bit rate
fig = tk.plot_eye(trace, bit_rate=1e9) # 1 Gbps
# Auto-recover clock
fig = tk.plot_eye(
trace,
clock_recovery="fft",
show_measurements=True,
cmap="viridis"
)
# High-speed SerDes analysis
fig = tk.plot_eye(
trace,
bit_rate=10e9, # 10 Gbps
ui_count=1,
colorbar=True
)
Use Cases:
- High-speed serial link analysis
- Signal integrity verification
- Jitter analysis
- BER estimation
- Compliance testing (PCIe, USB, SATA, etc.)
tk.plot_bathtub()¶
Create bathtub curve showing BER vs. sampling position for timing margin analysis.
Signature:
Parameters:
trace(WaveformTrace): Input waveform tracebit_rate(float, optional): Bit rate in bits/secondber_target(float): Target bit error rate for margin calculation (default: 1e-12)ax(Axes, optional): Matplotlib axes objecttitle(str, optional): Plot title
Returns:
Figure: Matplotlib Figure object
Example:
import tracekit as tk
trace = tk.load("serdes_output.wfm")
# Create bathtub curve
fig = tk.plot_bathtub(
trace,
bit_rate=1e9,
ber_target=1e-12
)
# Different BER target
fig = tk.plot_bathtub(
trace,
bit_rate=10e9,
ber_target=1e-15,
title="10G SerDes Bathtub Curve"
)
Use Cases:
- Determining optimal sampling point
- Timing margin analysis
- BER extrapolation
- Link budget analysis
- Compliance margin verification
tk.plot_bode()¶
Create Bode plot with magnitude and phase response.
Signature:
tk.plot_bode(
frequencies,
magnitude,
phase=None,
magnitude_db=True,
phase_degrees=True,
show_margins=False,
fig=None
)
Parameters:
frequencies(ndarray): Frequency array in Hzmagnitude(ndarray or complex ndarray): Magnitude array or complex transfer function H(s)phase(ndarray, optional): Phase array in radians (ignored if magnitude is complex)magnitude_db(bool): If True, magnitude is already in dB (default: True)phase_degrees(bool): Convert phase to degrees (default: True)show_margins(bool): Annotate gain and phase margins (default: False)fig(Figure, optional): Existing figure to plot on
Returns:
Figure: Matplotlib Figure object
Example:
import tracekit as tk
import numpy as np
# Define frequency range
freqs = np.logspace(1, 6, 1000) # 10 Hz to 1 MHz
# Complex transfer function (low-pass filter)
H = 1 / (1 + 1j * freqs / 10000)
# Create Bode plot
fig = tk.plot_bode(freqs, H)
# With separate magnitude and phase
mag_db = 20 * np.log10(np.abs(H))
phase_rad = np.angle(H)
fig = tk.plot_bode(
freqs,
mag_db,
phase_rad,
magnitude_db=True,
show_margins=True
)
Use Cases:
- Filter frequency response analysis
- Control system stability analysis
- Amplifier characterization
- Feedback loop analysis
- Gain and phase margin determination
tk.plot_phase()¶
Create phase plot (X-Y plot) showing phase relationships between signals.
Signature:
Parameters:
trace1(WaveformTrace or ndarray): Signal for X-axistrace2(WaveformTrace or ndarray, optional): Signal for Y-axis. If None, uses delayed trace1delay(int): Sample delay for self-phase plot when trace2=None (default: 1)delay_samples(int, optional): Alias for delay parameterax(Axes, optional): Existing axes to plot on
Returns:
tuple: (Figure, Axes)
Example:
import tracekit as tk
# Load two signals
sig_x = tk.load("signal_x.wfm")
sig_y = tk.load("signal_y.wfm")
# Phase relationship plot
fig, ax = tk.plot_phase(sig_x, sig_y)
# Self-phase plot (attractor)
fig, ax = tk.plot_phase(sig_x, delay_samples=10)
# Quadrature signals
i_signal = tk.load("i_channel.wfm")
q_signal = tk.load("q_channel.wfm")
fig, ax = tk.plot_phase(i_signal, q_signal)
Use Cases:
- Phase relationship visualization
- Lissajous figures
- I/Q signal analysis
- Chaos analysis (strange attractors)
- Feedback system analysis
tk.plot_histogram()¶
Create histogram of signal amplitude distribution with optional statistics.
Signature:
Parameters:
trace(WaveformTrace or ndarray): Input trace or arraybins(int, str, or ndarray): Number of bins or binning strategy (default: "auto")density(bool): Normalize to probability density (default: True)show_stats(bool): Show mean and standard deviation lines (default: True)show_kde(bool): Overlay kernel density estimate (default: False)ax(Axes, optional): Existing axes to plot on
Returns:
tuple: (Figure, Axes, stats_dict)
Example:
import tracekit as tk
trace = tk.load("noisy_signal.wfm")
# Basic histogram
fig, ax, stats = tk.plot_histogram(trace)
print(f"Mean: {stats['mean']:.3f} V")
print(f"Std Dev: {stats['std']:.3f} V")
# With KDE overlay
fig, ax, stats = tk.plot_histogram(
trace,
bins=50,
show_kde=True,
show_stats=True
)
# Custom binning
fig, ax, stats = tk.plot_histogram(
trace,
bins=np.linspace(-1, 1, 100),
density=False
)
Use Cases:
- Noise distribution analysis
- Signal quality assessment
- Detecting multi-level signals
- Statistical characterization
- Gaussian/non-Gaussian noise identification
Style Presets¶
TraceKit provides comprehensive style presets for different output contexts. Style presets control appearance, resolution, fonts, and layout for publication-quality output.
Available Presets¶
Publication Preset¶
Optimized for academic papers and technical publications:
import tracekit as tk
from tracekit.visualization import apply_style_preset
with apply_style_preset("publication"):
trace = tk.load("signal.wfm")
tk.plot_waveform(trace, save_path="figure.pdf")
Features:
- High DPI (300)
- LaTeX-compatible fonts
- Optimized for PDF/SVG export
- Clean, professional appearance
- Suitable for IEEE, ACM, and other academic journals
Presentation Preset¶
Optimized for slides and presentations:
Features:
- Larger fonts for visibility
- High contrast colors
- Bold lines
- Optimized for projectors
- 16:9 aspect ratio friendly
Screen Preset¶
Optimized for interactive viewing and desktop displays:
Features:
- Medium DPI (100)
- Comfortable font sizes
- Balanced colors
- Quick rendering
- Default for interactive work
Print Preset¶
Optimized for printed output on paper:
Features:
- High DPI (300)
- Grayscale-friendly colors
- Clear line styles
- Optimized for black & white printing
Using Style Presets¶
Context Manager (Recommended):
import tracekit as tk
from tracekit.visualization import apply_style_preset
# Temporary style application
with apply_style_preset("publication"):
fig1 = tk.plot_waveform(trace1)
fig2 = tk.plot_fft(trace2)
# Reverts to previous style after block
# Multiple plots with same style
with apply_style_preset("presentation"):
for i, trace in enumerate(traces):
tk.plot_waveform(trace, save_path=f"slide_{i}.png")
Custom Overrides:
# Apply preset with custom modifications
with apply_style_preset("publication", overrides={"font.size": 14}):
tk.plot_spectrum(trace)
Creating Custom Presets¶
Create your own presets based on existing ones:
from tracekit.visualization import create_custom_preset, register_preset
# Create custom preset
custom = create_custom_preset(
"my_style",
base_preset="publication",
font_size=12,
line_width=2.0,
dpi=600
)
# Register for future use
register_preset(custom)
# Use it
with apply_style_preset("my_style"):
tk.plot_waveform(trace)
Listing Available Presets¶
from tracekit.visualization import list_presets
presets = list_presets()
print("Available presets:", presets)
# Output: ['publication', 'presentation', 'screen', 'print', ...]
Accessibility Features¶
TraceKit provides comprehensive accessibility features to ensure visualizations are usable by all users, including those with color vision deficiencies.
Colorblind-Safe Palettes¶
All TraceKit visualizations use colorblind-safe color palettes by default:
import tracekit as tk
from tracekit.visualization import get_colorblind_palette
# Get colorblind-safe colormap
cmap = get_colorblind_palette("viridis")
# Use in plots
tk.plot_spectrogram(trace, cmap=cmap)
Available Colorblind-Safe Colormaps:
"viridis"- Perceptually uniform, colorblind-safe (default)"plasma"- High contrast, warm colors"cividis"- Optimized specifically for colorblind users"inferno"- High contrast, warm-to-cool
Multi-Line Distinguishability¶
For multi-line plots, TraceKit combines colors with line styles for maximum distinguishability:
from tracekit.visualization import get_multi_line_styles
# Get distinct styles for 4 lines
styles = get_multi_line_styles(4)
# Apply to plots
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
for i, (color, linestyle) in enumerate(styles):
ax.plot(data[i], color=color, linestyle=linestyle)
Features:
- Combines colorblind-safe colors with varied line styles
- Ensures plots are readable in grayscale
- Automatic cycling through patterns
- WCAG 2.1 compliant contrast ratios
Pre-Defined Line Styles¶
from tracekit.visualization import LINE_STYLES
print(LINE_STYLES)
# ['solid', 'dashed', 'dotted', 'dashdot']
Qualitative Color Palette¶
For categorical data:
from tracekit.visualization import COLORBLIND_SAFE_QUALITATIVE
# Use first 5 colors
colors = COLORBLIND_SAFE_QUALITATIVE[:5]
# Apply to bar chart or categorical plot
for i, color in enumerate(colors):
plt.bar(i, values[i], color=color)
Alt-Text Generation¶
Generate descriptive text for accessibility tools:
from tracekit.visualization import generate_alt_text
trace = tk.load("signal.wfm")
fig = tk.plot_waveform(trace)
# Generate alt text
alt_text = generate_alt_text(fig, trace)
print(alt_text)
# "Time-domain waveform plot showing signal with frequency 1.5 MHz,
# amplitude range -0.5V to 0.5V, duration 10 microseconds"
Pass/Fail Formatting¶
Format test results with symbols in addition to colors:
from tracekit.visualization import format_pass_fail
result = format_pass_fail(True) # "✓ PASS"
result = format_pass_fail(False) # "✗ FAIL"
# Use in annotations
ax.text(0.5, 0.5, format_pass_fail(test_passed))
Accessibility Checklist¶
When creating visualizations:
- ✓ Use default colorblind-safe palettes
- ✓ Combine colors with line styles for multi-line plots
- ✓ Ensure text has sufficient contrast (WCAG AA: 4.5:1 minimum)
- ✓ Provide alt-text for screen readers
- ✓ Use symbols in addition to colors for critical information
- ✓ Test plots in grayscale
Example - Fully Accessible Plot:
import tracekit as tk
from tracekit.visualization import (
apply_style_preset,
get_multi_line_styles,
generate_alt_text
)
# Load data
traces = [tk.load(f"ch{i}.wfm") for i in range(4)]
# Apply accessible style
with apply_style_preset("publication"):
# Get accessible line styles
styles = get_multi_line_styles(4)
# Create plot with distinct styles
fig, ax = plt.subplots(figsize=(10, 6))
for trace, (color, linestyle), name in zip(traces, styles, names):
ax.plot(
trace.time_vector,
trace.data,
color=color,
linestyle=linestyle,
label=name,
linewidth=2
)
ax.legend()
ax.grid(True, alpha=0.3)
ax.set_xlabel("Time (s)")
ax.set_ylabel("Amplitude (V)")
# Generate alt text
alt_text = "Multi-channel waveform showing 4 synchronized signals..."
# Save with high DPI
fig.savefig("accessible_plot.png", dpi=300)
Advanced Usage¶
Combining Multiple Visualization Functions¶
Create comprehensive analysis plots combining multiple visualization types:
import tracekit as tk
import matplotlib.pyplot as plt
trace = tk.load("signal.wfm")
# Create multi-panel figure
fig = plt.figure(figsize=(12, 10))
# Time domain
ax1 = plt.subplot(2, 2, 1)
tk.plot_waveform(trace, ax=ax1, show=False)
# Frequency domain
ax2 = plt.subplot(2, 2, 2)
tk.plot_spectrum(trace, ax=ax2, show=False)
# Histogram
ax3 = plt.subplot(2, 2, 3)
fig_hist, ax3, stats = tk.plot_histogram(trace, ax=ax3, show=False)
# Eye diagram (if serial data)
ax4 = plt.subplot(2, 2, 4)
fig_eye = tk.plot_eye(trace, ax=ax4, show=False)
plt.tight_layout()
plt.savefig("comprehensive_analysis.png", dpi=300)
Non-GUI Mode (Server Environments)¶
For headless servers or automated pipelines, set matplotlib to use the 'Agg' backend:
import matplotlib
matplotlib.use('Agg') # Must be called before importing tracekit
import tracekit as tk
trace = tk.load("signal.wfm")
# Generate plots without display
tk.plot_waveform(trace, show=False, save_path="waveform.png")
tk.plot_fft(trace, show=False, save_path="fft.png")
tk.plot_eye(trace, show=False, save_path="eye.png")
tk.plot_spectrogram(trace, show=False, save_path="spectrogram.png")
Publication-Quality Plots¶
Generate high-resolution plots suitable for publications:
import tracekit as tk
trace = tk.load("signal.wfm")
# High-quality FFT plot
fig = tk.plot_fft(
trace,
figsize=(8, 5), # Appropriate size for publication
show=False,
save_path="fft.pdf" # Vector format for scaling
)
The plots are saved at 300 DPI by default, suitable for most publications.
Multiple Trace Overlay¶
To overlay multiple traces on the same plot:
import matplotlib.pyplot as plt
import tracekit as tk
trace1 = tk.load("signal1.wfm")
trace2 = tk.load("signal2.wfm")
# Create figure
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 8))
# Plot waveforms
tk.plot_waveform(trace1, ax=ax1, color='blue', label='Signal 1', show=False)
tk.plot_waveform(trace2, ax=ax1, color='red', label='Signal 2', show=False)
ax1.legend()
# Plot spectra
tk.plot_spectrum(trace1, ax=ax2, color='blue', show=False)
tk.plot_spectrum(trace2, ax=ax2, color='red', show=False)
plt.tight_layout()
plt.savefig("comparison.png", dpi=300)
Custom Axis Limits¶
Control frequency and amplitude ranges:
import tracekit as tk
trace = tk.load("signal.wfm")
# Focus on specific frequency range
tk.plot_spectrum(
trace,
xlim=(1e6, 10e6), # 1-10 MHz
ylim=(-80, 0), # -80 to 0 dB
freq_unit="MHz",
log_scale=False # Linear scale for narrow range
)
Pre-computed FFT Results¶
For efficiency when creating multiple plots from the same data:
import tracekit as tk
trace = tk.load("signal.wfm")
# Compute FFT once
freq, mag = tk.fft(trace)
# Create multiple plots without recomputing
tk.plot_spectrum(trace, fft_result=(freq, mag),
title="Full Spectrum", show=False, save_path="full.png")
tk.plot_spectrum(trace, fft_result=(freq, mag),
xlim=(1, 10), freq_unit="MHz",
title="Zoomed Spectrum", show=False, save_path="zoom.png")
Integration with TraceKit Workflow¶
Complete Analysis Workflow¶
import tracekit as tk
# Load signal
trace = tk.load("signal.wfm")
# Perform measurements
freq = tk.frequency(trace)
rise = tk.rise_time(trace)
thd_val = tk.thd(trace)
print(f"Frequency: {freq:.2f} Hz")
print(f"Rise time: {rise:.2e} s")
print(f"THD: {thd_val:.1f} dB")
# Visualize
tk.plot_waveform(trace, title=f"Signal @ {freq/1e6:.2f} MHz")
tk.plot_fft(trace, title=f"FFT (THD: {thd_val:.1f} dB)")
Filtering and Visualization¶
import tracekit as tk
# Load noisy signal
trace = tk.load("noisy_signal.wfm")
# Apply low-pass filter
filtered = tk.low_pass(trace, cutoff=10e6)
# Compare original and filtered
import matplotlib.pyplot as plt
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 8))
tk.plot_waveform(trace, ax=ax1, label="Original", color="gray", show=False)
tk.plot_waveform(filtered, ax=ax1, label="Filtered", color="blue", show=False)
ax1.legend()
ax1.set_title("Time Domain Comparison")
tk.plot_spectrum(trace, ax=ax2, color="gray", show=False)
tk.plot_spectrum(filtered, ax=ax2, color="blue", show=False)
ax2.set_title("Frequency Domain Comparison")
plt.tight_layout()
plt.savefig("filtering_comparison.png", dpi=300)
Supported File Formats¶
When saving plots, the file format is automatically detected from the extension:
- PNG (
.png) - Raster format, 300 DPI - PDF (
.pdf) - Vector format, scalable - SVG (
.svg) - Vector format, web-friendly - JPEG (
.jpg,.jpeg) - Compressed raster - TIFF (
.tiff,.tif) - High-quality raster
Example:
import tracekit as tk
trace = tk.load("signal.wfm")
# Save in different formats
tk.plot_waveform(trace, show=False, save_path="waveform.png")
tk.plot_waveform(trace, show=False, save_path="waveform.pdf")
tk.plot_waveform(trace, show=False, save_path="waveform.svg")
Window Functions¶
Both plot_spectrum() and plot_fft() support various window functions via the window parameter:
"hann"(default) - Good general-purpose window"hamming"- Similar to Hann, slightly different sidelobe characteristics"blackman"- Excellent sidelobe rejection"bartlett"- Triangular window"rectangular"- No windowing (spectral leakage)"kaiser"- Adjustable sidelobe characteristics
Example:
import tracekit as tk
trace = tk.load("signal.wfm")
# Compare different windows
import matplotlib.pyplot as plt
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
for ax, window in zip(axes.flat, ["hann", "blackman", "hamming", "kaiser"]):
tk.plot_fft(trace, ax=ax, window=window,
title=f"{window.capitalize()} Window", show=False)
plt.tight_layout()
plt.savefig("window_comparison.png", dpi=300)
Matplotlib Backend Configuration¶
TraceKit automatically handles matplotlib backends, but you can configure them manually:
GUI Environments¶
import matplotlib
matplotlib.use('TkAgg') # or 'Qt5Agg', 'GTK3Agg', etc.
import tracekit as tk
trace = tk.load("signal.wfm")
tk.plot_waveform(trace) # Opens interactive window
Non-GUI Environments (Servers, Docker, etc.)¶
import matplotlib
matplotlib.use('Agg') # Non-interactive backend
import tracekit as tk
trace = tk.load("signal.wfm")
tk.plot_waveform(trace, show=False, save_path="output.png")
Jupyter Notebooks¶
%matplotlib inline # Or 'notebook' for interactive
import tracekit as tk
trace = tk.load("signal.wfm")
tk.plot_waveform(trace) # Displays inline
Troubleshooting¶
Plot Not Displaying¶
If plots don't display:
- Check matplotlib backend:
import matplotlib; print(matplotlib.get_backend()) - Ensure
show=True(default) - Try calling
plt.show()manually - Check if running in non-GUI environment
Memory Issues with Large Files¶
For very large traces:
import tracekit as tk
# Use decimation for display
from tracekit.visualization.optimization import decimate_for_display
trace = tk.load("large_file.wfm")
decimated_data = decimate_for_display(trace.data, max_points=10000)
# Create temporary trace for visualization
import numpy as np
viz_trace = tk.WaveformTrace(
data=decimated_data,
metadata=trace.metadata
)
tk.plot_waveform(viz_trace)
Font/Text Issues¶
If fonts appear incorrect:
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = 'sans-serif'
plt.rcParams['font.size'] = 10
import tracekit as tk
# ... rest of code
See Also¶
- Loader API - Loading waveform data
- Analysis API - Signal analysis functions
- Component Analysis API - TDR, capacitance, inductance measurements
- Export API - Exporting data
- Reporting API - Report generation with charts
- matplotlib Documentation