Skip to main content

phosphor

GPU-accelerated real-time sweep renderer for multichannel timeseries data. Built on WebGPU and Qt, phosphor renders thousands of channels at high sample rates with minimal CPU overhead.

Designed for neuroscience and real-time signal monitoring -- push (n_samples, n_channels) numpy arrays and phosphor handles downsampling, autoscaling, and rendering.

Installation

pip install phosphor

Quick Start

import numpy as np
from PySide6.QtWidgets import QApplication
from phosphor import SweepConfig, SweepWidget

app = QApplication([])

widget = SweepWidget(SweepConfig(
    n_channels=128,
    srate=30000.0,
    display_dur=2.0,
    n_visible=64,
))
widget.show()

# Push data from any source -- shape: (n_samples, n_channels), float32
widget.push_data(np.random.randn(500, 128).astype(np.float32))

app.exec()

Embedding in an Existing Qt Application

SweepWidget is a standard QWidget that can be added to any layout:

from PySide6.QtWidgets import QMainWindow, QVBoxLayout, QWidget
from phosphor import SweepConfig, SweepWidget

class MyWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.sweep = SweepWidget(SweepConfig(n_channels=64, srate=1000.0))
        self.setCentralWidget(self.sweep)

    def on_new_data(self, data):
        self.sweep.push_data(data)

Runtime Configuration

Update parameters without recreating the widget:

from phosphor import SweepConfig

widget.update_config(SweepConfig(
    n_channels=256,
    srate=30000.0,
    display_dur=4.0,
    n_visible=128,
))

Built-in Demo

python -m phosphor
python -m phosphor --channels 256 --srate 30000 --visible 64 --dur 2.0

Keyboard Controls

Key Action
Up / Down Scroll channels by 1
Page Up / Page Down Scroll channels by one page
[ / ] Halve / double visible channel count
- / = Y-axis zoom out / in (disables autoscale)
A Toggle autoscale
, / . Halve / double display duration

Future: Migration to fastplotlib

Phosphor currently uses custom WGSL shaders and raw wgpu-py for rendering. The plan is to migrate to fastplotlib (built on pygfx) once both libraries reach 1.0 (targeting mid-2026), which would eliminate the custom shader maintenance burden. The migration can happen in stages:

  1. Keep SweepBuffer -- the CPU-side circular buffer with incremental min/max downsampling is the core of phosphor's performance story. Neither pygfx nor fastplotlib provide built-in min/max downsampling for line data, so this logic stays.
  2. Replace GPURenderer + WGSL shaders with fastplotlib's LineStack, feeding it the already-downsampled min/max columns from SweepBuffer. This drops the custom pipeline/shader code and gains fastplotlib's built-in axes, colormapping, and interaction tools.
  3. Evaluate whether ChannelPlotWidget can be simplified or replaced by fastplotlib's Figure/Subplot layout, retaining the keyboard controls and channel pagination UX.

Development

We use uv for development.

  1. Fork and clone the repository
  2. uv sync to create a virtual environment and install dependencies
  3. uv run pre-commit install to set up linting and formatting hooks
  4. uv run pytest tests to run the test suite
  5. Submit a PR against the dev branch

Metadata

Release files for phosphor 0.11.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for phosphor 0.11.0
File Size Uploaded
phosphor-0.11.0.tar.gz 82.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for phosphor 0.11.0
File Interpreter ABI Platform
phosphor-0.11.0-py3-none-any.whl Python 3 none any Details

Total release size: 149.3 kB

Release files / phosphor-0.11.0.tar.gz

Download URL phosphor-0.11.0.tar.gz
Size 82.3 kB
Tags Source
SHA-256 checksum
How to use checksums
7c1569aa875578783e400f61cff0115d10538ebeb5398c5fc9e4a2ab3a9d59a6
BLAKE2b-256 checksum
How to use checksums
5d16fda166d81807392d2eee3f7fe60a6a661705241fff1ae3028a161ed77703
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / phosphor-0.11.0-py3-none-any.whl

Download URL phosphor-0.11.0-py3-none-any.whl
Size 67.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
79413d65abd7b7c3d468ffc2b09a52b8b89ae10dbb4dcfb06fb00ea834613653
BLAKE2b-256 checksum
How to use checksums
81f6858d2d1f2a445b5737d9c95f97243d7275d15a22142a969194727f98974a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

0.12.0

2 release files

This release

0.11.0 This release

2 release files

0.9.2

2 release files

0.9.1

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4

2 release files

0.3

2 release files

0.2

2 release files

0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page