IQView
High-Performance Static RF Spectrogram Viewer
IQView is a streamlined, high-performance GUI application designed for deep analysis of In-phase and Quadrature (IQ) signals. Built with Python, PyQt6, and PyOpenGL, it provides a fluid experience for exploring large RF captures in the time and frequency domains.
🚀 Key Features
- Lazy Rendering Engine: Explore ultra-long captures (e.g. 1 hour+) without RAM exhaustion by computing FFTs on-demand only for the visible viewport.
- Dynamic Filtering: Zero-cost frequency-domain BPF/BSF with realistic roll-offs for real-time spectrogram isolation. Zero-phase time-domain BPF/BSF in detail pop-ups for perfect phase alignment and exact band cancellation.
- WAV Audio File Support: Native loading of
.wavfiles with automatic channel downmixing and float32 normalization ([-1.0, 1.0]) without any external audio dependencies. - Advanced Markers & Region Overlays: Locked delta and center markers for precise timing and frequency measurements. Drag-and-drop interactive Region Overlays (
X-Region,Y-Region,Rect,Polygon,Ellipse) with manual add capabilities and independent vertex manipulation for polygons. - Statistical Analysis: Instant computation of Min, Max, Mean, Median, and Integrated Power for selected segments, with linear/logarithmic power-domain averaging.
- Desktop Integration & Dynamic Loading: One-click installation of desktop shortcuts and file associations for
.iq,.bin, and.matfiles. Drag-and-drop / dynamic loading of.matfiles from Recent Files with support for.mat.overlayssidecar files. - Background Version Checker: Non-blocking background checks for updates on startup via PyPI to alert users of newer versions without UI lag.
- Offline Debian Packaging: Support for bundling dependencies locally (wheels) to enable offline installation in isolated environments.
💻 Installation
For Users
Install the latest package directly from PyPI:
pip install iqview
Note: Under Linux/Debian systems, ensure system packages python3-pip and libxcb-cursor0 (required for Qt rendering) are installed.
Offline Debian Installation (for Isolated Environments)
For secure or offline environments, you can bundle dependencies into the Debian package. Build the offline wheels and package using the scripts:
# 1. Build project with offline wheels bundled
python scripts/build_project.py --offline-wheels
# 2. Build the .deb package incorporating offline wheels
python scripts/make_deb.py --offline-wheels
Then install the resulting .deb using:
sudo apt install ./dist/iqview_*.deb
The installer automatically uses the bundled offline wheels to satisfy pip dependencies without calling out to the internet.
For Developers
Clone the repository and install in editable mode:
git clone https://github.com/omernaf/IQView.git
cd IQView
pip install -e .
Desktop Integration
To add IQView to your Start Menu and associate it with common IQ file extensions:
iqview --install-desktop
To associate .mat files specifically (which requires specific fields Y, XDelta, InputCenter):
iqview --install-mat
📖 Quick Start
Open an IQ file directly from the command line:
iqview -f signals.iq -r 20e6 -c 2.44e9 -t complex64
Or open an audio file (e.g. WAV):
iqview -f audio.wav -t audio
-r: Sample Rate ($f_s$)-c: Center Frequency ($f_c$)-t: Data Type (e.g.complex64,int16,float32, oraudio/audfor WAV audio)
Dynamic Filename Parameter Auto-detection
If you omit the sample rate (-r) or center frequency (-c) flags, IQView will automatically parse the file name for standard notation. For example, a file named capture_10Msps_433MHz.bin will be auto-loaded with a sample rate of $10\text{ MHz}$ and a center frequency of $433\text{ MHz}$.
🐍 Python API & Plugin Debugging
You can launch IQView directly from a Python script or IDE using the iqview.view() function. This is especially useful for plugin development, as it allows you to set breakpoints in your IDE and debug plugins interactively.
Opening a File
import iqview
# Opens the file and auto-detects sample rate and center frequency from the filename
iqview.view("path/to/capture_20Msps_2.4GHz.cf32")
Passing Raw Arrays (Great for Synthetic Signals)
import numpy as np
import iqview
fs = 2e6
t = np.arange(int(fs * 0.5)) / fs
x = np.exp(2j * np.pi * 250e3 * t) # CW tone at +250 kHz
iqview.view(x, fs=fs, fc=2.4e9, name="Test Signal")
Full Signature
iqview.view(source=None, fs=1e6, fc=0.0, fft_size=1024, dtype='complex64', name=None, lazy=None)
source: File path (str), NumPy array (np.ndarray), orNone(empty canvas).fs/fc: Sample rate and center frequency (ignored if auto-detected from filename).fft_size: Spectrogram frequency resolution (default 1024).dtype: Data type (e.g.,'complex64','int16') if not auto-detected.name: Custom window title.lazy: Override lazy rendering mode (True/False).
🧪 Mathematical Foundations
1. Spectrogram Rendering
The spectrogram is computed using the Short-Time Fourier Transform (STFT). Each vertical slice represents the power spectral density of a windowed segment:
$$X[k] = \sum_{n=0}^{N-1} x[n] \cdot w[n] e^{-j \frac{2\pi}{N} kn}$$
Where $w[n]$ is the chosen window function (e.g., Hamming, Hann). The visual dB level is calculated as: $$\text{Level}{\text{dB}} = 20 \log{10}(|X[k]| + \epsilon)$$ $\epsilon$ is a small constant ($10^{-10}$) to prevent $\log(0)$.
2. Time Domain Modes
IQView provides several ways to visualize raw samples $x[n] = I[n] + jQ[n]$:
| Mode | Formula |
|---|---|
| Magnitude | $|x[n]| = \sqrt{I[n]^2 + Q[n]^2}$ |
| Magnitude [dB] | $20 \log_{10}(|x[n]|)$ |
| Magnitude² [dB] | $10 \log_{10}(|x[n]|^2)$ |
| Phase | $\phi[n] = \arctan2(Q[n], I[n])$ |
| Inst. Frequency | $f_{\text{inst}}[n] = \frac{\phi[n] - \phi[n-1]}{2\pi} \cdot f_s$ |
3. Integrated Power
In the Frequency Domain view, selecting a region $[f_1, f_2]$ computes the integrated power within that bandwidth: $$\text{Total Power} = \sum_{k \in {f_1, f_2}} |X[k]|^2$$ For dB displays, this is converted via $10 \log_{10}$ to represent total power relative to full scale.
4. Optimized Complex BPF
For the main spectrogram display, IQView applies an optimized frequency-domain mask to the FFT results:
- Design: A standard IIR low-pass filter (Elliptic, Butterworth, etc.) is designed for the target bandwidth.
- Evaluate: The filter's complex frequency response $H(f)$ is evaluated at each FFT bin frequency using
sosfreqz. - Apply: Each FFT row is multiplied by the response magnitude: $X_{\text{filt}}[k] = X[k] \cdot |H(f_k)|$. This provides zero-cost filtering with realistic visual roll-offs. For time-domain analysis in pop-up tabs, the original sample-by-sample IIR filter is still used to maintain phase and signal integrity.
⌨️ Controls & Shortcuts
General
| Key | Action |
|---|---|
| T | Enter Time Marker placement mode |
| F | Enter Frequency/Magnitude Marker placement mode |
| Ctrl (Hold) | Enter Zoom Mode (Left-click & drag to box zoom) |
| Ctrl + Z | Undo last zoom level |
| Middle-Click | Close active analysis tab |
Markers
- Draggable: Hover over a marker; it turns red and can be dragged.
- Locked Delta: Lock the distance between $M_1$ and $M_2$ to move them together.
- Locked Center: Lock the midpoint between $M_1$ and $M_2$ to expand/shrink symmetrically.
🛠️ CLI Reference
| Flag | Description | Default |
|---|---|---|
-f, --file |
Path to binary IQ or audio (.wav) file | None |
--stdin |
Read binary IQ data from stdin pipe | False |
-r, --rate |
Sample rate in Hz | 1 MHz |
-c, --fc |
Center frequency in Hz | 0 Hz |
-t, --type |
Data type (int16, float32, complex64, complex128, audio, aud) |
complex64 |
-s, --fft |
FFT bin size (Power of 2) | 1024 |
--lazy |
Force on-demand viewport rendering | Settings |
--full |
Force full-file upfront rendering | Settings |
--profile |
Run with cProfile for performance debugging | False |
⚙️ Configuration
IQView saves its state in the system registry or config files via QSettings. You can adjust default colormaps, themes (Dark/Light), and FFT defaults in the Settings Dialog within the app.
📚 Detailed Documentation
For a deep dive into the specific features and mathematical foundations of each analysis view, please refer to the dedicated documentation files:
- 🌌 Spectrogram View: STFT, windowing, colormaps, and OpenGL rendering.
- ⏳ Time Domain View: Plot modes, marker locking logic, and statistics.
- 📶 Frequency Domain View: FFT analysis, PSD estimation, preprocessing operators, and integrated power.
- 👁️ Eye Diagram View: Symbol timing visualization, fractional Nsps, and phase alignment.
- ✨ Scatter Plot View: IQ constellation visualization, integer downsampling, carrier phase, and 3-tier frequency offset tuning.
- 🔌 Plugin Developer Guide: Guide for creating and testing custom DSP plugins.
📄 License
This project is licensed under the MIT License - see the LICENSE file for details. Original author: Omer Naftali (omernaf).
Metadata
Release files for iqview 0.7.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| iqview-0.7.2.tar.gz | 1.4 MB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| iqview-0.7.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 2.8 MB
Release files / iqview-0.7.2.tar.gz
| Download URL | iqview-0.7.2.tar.gz |
|---|---|
| Size | 1.4 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
69a95cea991522bfbf930628ab488cbd635aa44f6b1f3d2f8eb98a42f0ba0191
|
|
BLAKE2b-256 checksum How to use checksums |
dcf658186d5b4a3b700392b81da98d96c70c0e20ad1fe18ffe5781171ab3413c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.
Transparency logRelease files / iqview-0.7.2-py3-none-any.whl
| Download URL | iqview-0.7.2-py3-none-any.whl |
|---|---|
| Size | 1.4 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5584c2051ae9d8a4197e60de89558e15f31283fbb2eba2724667ed26ca458b33
|
|
BLAKE2b-256 checksum How to use checksums |
8864338e80b8a7c108bf66cdefa1371db0feed0427a7a20606a90cdc7fa7453d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.
Transparency logSecurity for iqview 0.7.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for iqview-0.7.2.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.