Seeable
Seeable is a live visual explorer for multidimensional Python data. Pass an
array to seeable.view() and start exploring, without choosing a plot first.
import numpy as np
import seeable
data = np.random.random((50, 128, 128))
viewer = seeable.view(data)
data[20:30, 40:90, 40:90] *= 5
viewer.refresh()
viewer.snapshot("seeable.png") # the visualisation
viewer.snapshot("window.png", canvas_only=False) # sidebar included
# Or refresh a desktop viewer automatically every 500 ms.
live_viewer = seeable.view(data, live=True)
# Reuse the same visual configuration with compatible data.
saved_view = viewer.export_state()
another_viewer = seeable.view(data.copy())
another_viewer.apply_state(saved_view)
# Or persist that configuration for a future session.
viewer.save_state("seeable-view.json")
another_viewer.load_state("seeable-view.json")
Lists, tuples, ranges, buffers and anything else that already holds numbers are
accepted directly. NumPy arrays need no extra. Pandas and Polars DataFrames, Xarray DataArrays and
Datasets, chunked Dask and Zarr arrays, PyTorch tensors, and JAX arrays come
with the extra of the same name; SciPy sparse matrices come with sparse, and
HDF5 files with hdf5 -- a whole file is browsable as the tree of datasets it
holds, each read only where it is looked at. Arrow tables come with arrow,
Pillow images with images, AnnData with anndata, and CuPy arrays with cupy. Dictionaries of any supported
value are browsable as a tree, and lists of dictionaries or column-oriented
dictionaries are recognised as record tables. Anything else can be made
viewable — see Custom sources.
The native Qt interface draws its own heatmaps, with pan and cursor-centred zoom, dimension remapping, slice controls, and value probes.
Install
pip install -e '.[all]'
The first renderer is a desktop Qt application. In a Jupyter kernel,
seeable.view(data) returns the same viewer and displays an inline widget when
it is the cell's final value. Install the jupyter extra for this mode. The
inline surface shares viewer state and refresh behaviour with Qt; a WebGL canvas
will eventually replace its lightweight Python-rendered preview.
It includes X/Y/Z role controls and sliders for the remaining dimensions.
Custom sources
Anything can be made viewable by presenting it as a Seeable. Only shape,
dtype, dimensions, name, metadata, and get_slice are required; the
rest of the interface describes optional abilities and defaults to "this source
does not have that".
import seeable
class MeshField(seeable.Seeable):
def __init__(self, mesh):
self.mesh = mesh
@property
def shape(self):
return self.mesh.grid.shape
@property
def dtype(self):
return self.mesh.grid.dtype
@property
def dimensions(self):
return ("depth", "row", "column")
@property
def name(self):
return self.mesh.label
@property
def metadata(self):
return {"source": "MeshField", "attrs": {"units": self.mesh.units}}
def get_slice(self, selection):
return self.mesh.grid[selection] # only the visible region
seeable.view(MeshField(mesh))
A Seeable presents a source rather than copying it: get_slice is asked only
for the region on screen, so a lazy, chunked, or remote source stays that way.
To have seeable.view() accept your object directly, either give it a
__seeable__() method returning a Seeable, or register a rule for it:
class Mesh:
def __seeable__(self):
return MeshField(self)
seeable.view(mesh)
# ...or, for a type you do not own:
seeable.register(lambda data: isinstance(data, Mesh), MeshField)
Registered rules are consulted before the built-in ones, so they can take over a type Seeable already recognises.
A source made of named parts — a dictionary, an Xarray Dataset, a group of
grids — reports them as children, and nested parts become dotted paths:
class Survey(seeable.Seeable):
@property
def children(self):
return {"north": MeshField(self.north), "south": MeshField(self.south)}
seeable.view(survey).select_variable("north")
Keyboard
| Key | Action |
|---|---|
← → |
Step the active slider |
Space |
Play or pause |
A |
Auto range |
R |
Reset pan, zoom and probe |
Ctrl+S / Ctrl+O |
Save or load the view state |
Ctrl+Shift+S |
Save an image |
? |
List the shortcuts |
Current scope
- Custom Qt heatmaps and 1D line views with pan, cursor-centred zoom, and double-click reset; 3D uses linked slice views, plus an orbitable WebGL point cloud where QtWebEngine is installed.
- The opening view is chosen from what the source is, not only from how many axes it has.
- Bar charts for named values:
seeable.view({"apples": 3, "pears": 7}). - Scatter plots for rows of coordinates: an
(N, 2)array is points, and a third column colours them. - Line charts for numeric tables, drawn against the index -- a dated DataFrame opens as a time series.
- Labelled axes on every heatmap, reading the source's own coordinates.
- Clickable value probes for inspecting coordinates and values in visible image and volume slices.
- Horizontal and vertical profiles through any probed heatmap cell.
- Semantic Xarray dimension names and metadata.
- Composite sources — dictionaries, Xarray Datasets — browsable by part, with nested leaves such as
sensors.temperature, inline scalar/list inspection, and a bounded structure summary. - Searchable, sortable record tables with field visibility controls, full-row inspection, and field-driven histograms and scatter plots.
- Native Pandas and Polars DataFrame exploration with the same table and numeric-field tools.
- Dask arrays, on their own or behind Xarray, stay lazy until their visible region is rendered.
- A source that is slow to read is fetched in the background, so scrubbing never freezes the window, and a source that fails says so in the status bar.
- Coordinate-aware time scrubbing and play/pause for Xarray time dimensions.
- Manual updates through
viewer.refresh()and optional periodic desktop refresh withlive=True. - Inline notebook previews and slice controls with the
jupyterextra. - Colour pictures shown as pictures: an eight-bit array ending in three or four channels is drawn in its own colours rather than as one plane per channel.
- Contrast clipped to a percentile pair by default, a gamma control, and maximum/attenuated/mean/minimum projections through a volume, where attenuation dims what stands behind something.
- Fourteen palettes drawn in the selector: the perceptually uniform viridis, plasma, inferno, magma and cividis, a diverging map built in CIELAB for signed data, plus gray, spectrum, and single-hue ramps for channel overlays.
- Exportable dimension mappings, slice selections, and colour settings.
- A public
Seeableinterface, a__seeable__()protocol, andseeable.register()for custom sources.
True GPU volume rendering is the next renderer: the cube view currently draws a density-filtered point cloud through WebGL, and always in viridis regardless of the selected palette.
Metadata
Release files for seeable 0.1.0
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 | Actions |
|---|---|---|---|---|
| seeable-0.1.0.tar.gz | 134.1 kB | With provenance | Details for seeable-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| seeable-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for seeable-0.1.0-py3-none-any.whl |
Total release size: 240.0 kB
Release files / seeable-0.1.0.tar.gz
| Download URL | seeable-0.1.0.tar.gz |
|---|---|
| Size | 134.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
04f18cb55b3a62b58689ec14aaca0176868240e3d961ebfb145df8ea7e581295
|
|
BLAKE2b-256 checksum How to use checksums |
d7872dc90346b9a6497d5ebfacf02c5e4fc2743ffe1ccf8b1cb6149b14cff66c
|
| 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 1, 2026.
Transparency logRelease files / seeable-0.1.0-py3-none-any.whl
| Download URL | seeable-0.1.0-py3-none-any.whl |
|---|---|
| Size | 105.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c8aa75b6de2271aab459404c86a98ad7593c4e12886e9cfc8dd15907aa016a2c
|
|
BLAKE2b-256 checksum How to use checksums |
4e80b6b6d96077a3f5426525306932e7e7f7b21a457eb548af0c006b6d2e6509
|
| 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 1, 2026.
Transparency logSecurity for seeable 0.1.0
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
Both files in this release have been uploaded with provenance metadata.
Attestation for seeable-0.1.0.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 1, 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.
To learn more about protecting yourself from malicious actors, visit our package security documentation.