Skip to main content

twhy

Whole-slide microscopy, ordinary images, and scientific PDFs, right in your terminal.

twhy is a zoomable, full-screen image viewer made of actual terminal characters. Open an OME-TIFF, SVS, or OME-Zarr slide, explore multichannel fluorescence, inspect a PNG, or page through a PDF. No browser, image server, X11, graphics protocol, or GPU required.

I had a use case for this on a remote cluster with thousands of images. Sometimes I just needed the tissue's shape, a rough count of regions of interest, or to tell a big chunk of tissue from a few tiny core needle biopsies. An ASCII-art representation of a preview from the image pyramid seemed like it would do the job.

Then working in tmux, switching the active area of the terminal with either the mouse or keyboard, got me wondering... just how far can we push a text-based image viewer? And thus began twhy. I've been having a little fun with AI slop along the way, and now it opens PDFs and lets me draw polygons on pathology images. It's ridiculous, but I'm actually going to use it.

Real recording of twhy zooming through multiplex immunofluorescence and revealing CD8 signal in cyan on blue DAPI nuclei

Real terminal footage: 59-channel multiplex microscopy, DAPI and CD8. Channel selection and zoom, no mock interface.

See it in action

These are short, automatically looping recordings of twhy itself. Click any clip to view it at full GIF size.

Whole-slide H&E SVS
twhy zooming from an SVS whole-slide tissue overview to individual nuclei in a real H&E image
Zoom from whole-slide tissue context into individual nuclei.
An ordinary PNG. Featuring a cat.
twhy zooming into an orange-and-white cat in a sunlit windowsill illustration
PNG, JPEG, WebP: zoom and pan familiar images, too.
A scientific PDF
twhy switching pages in a scientific PDF and zooming into a transformer architecture diagram
Turn pages, then zoom into figures. PDF support is standard.
Polygon selections
twhy drawing a yellow polygon selection around a tissue core and preparing it for GeoJSON export
Select rectangles or polygons; export GeoJSON, text, ANSI art, or PNG.

Install

Python 3.11+. The PyPI distribution, terminal command, and Python import all share the name twhy.

Install the standalone command without changing packages in a scientific Python environment:

uv tool install twhy
# or: pipx install twhy
# or: python -m pip install twhy

From a cloned checkout, for development:

python -m pip install -e '.[dev]'

PDF support is included in the standard install. No special extra or system PDF converter is needed.

Quickstart

twhy photo.png                         # PNG, JPEG, WebP, and more
twhy paper.pdf                         # page navigation and progressive detail
twhy slide.svs                         # Aperio whole-slide RGB
twhy slide.ome.tif                     # OME-TIFF, grayscale or multichannel
twhy /data/sample.ome.zarr             # local OME-Zarr

# Compose two fluorescence channels with chosen colors:
twhy slide.ome.tif --channel 0 --channel 2 \
  --channel-color 0 blue --channel-color 2 cyan

The initial view fits the image. Wheel zoom is anchored to the pointer; pan with the mouse or arrow keys. The terminal sidebar keeps channels, colors, and contrast controls at hand.

Why a terminal viewer?

  • Whole-slide without whole-slide RAM use: regional TIFF/SVS reads and pyramids, with bounded previews and useful zoomed-out overviews.
  • Multichannel, not just RGB: select channels, change pseudocolors, and adjust each marker's display window and gamma without modifying source pixels.
  • PDFs and everyday images: ordinary images use in-memory pyramids; PDFs refine progressively from a quick preview to higher-detail pages.
  • Real characters: colored ▀ half-blocks, Braille detail, shape-oriented Unicode art, and portable ASCII modes.
  • Selection and export: copy/save terminal text, colored ANSI, shareable PNGs, and GeoJSON polygons/rectangles.
  • Reusable Python library: sampling, intensity normalization, composition, and rendering are available without opening the interactive terminal UI.

twhy works over ordinary terminal sessions, including environments where a desktop image viewer is inconvenient. It is an exploratory display, not a color-managed diagnostic viewer and not a substitute for measuring the original pixels.

The keys you'll actually use

Action Key or gesture
Zoom; pan; fit image Wheel or +/-; arrows or drag; r/Home
Next/previous PDF page or OME series ] / [ or PageDown / PageUp; p to jump
Toggle a channel; focus another Click channel/Space; , and .
Adjust channel color or contrast h (hue); l/u (limits); g (gamma); a (auto window)
Switch artwork / strict ASCII m / M; t toggles artwork color; f toggles fullscreen
Select region s rectangle; v polygon
Export a selection y/Y text, i/I PNG, t/T ANSI, j/J GeoJSON (copy/save)
Help or quit ? / q

From terminal annotations to full-resolution ROIs

The useful part of the joke: draw regions in twhy, save their coordinates as GeoJSON, and let Omeify extract them from the original image. This example uses a calibrated OME-TIFF, series 0. You also need the omeify command on your PATH; with isolated tool installs, install it separately using uv tool install omeify.

# Open the source and choose where to save the annotations.
twhy slide.ome.tif --series 0 --output-geojson-clip regions.geojson

Zoom to the view you need, then press s for a rectangle or v for a polygon and draw. Close a polygon with Enter; a adds another region in the same view. Press Shift+J to save all the regions before quitting.

# Export one full-resolution image per region, with lossless compression.
omeify crop slide.ome.tif --series 0 \
  --geojson regions.geojson -o regions.ome.tif \
  --shatter by_index --compression Deflate --no-overwrite

This writes regions-01.ome.tif, regions-02.ome.tif, and so on, retaining all channels from the selected series. Omit --shatter by_index to put the regions into separate image series in one OME-TIFF instead.

Full-resolution pixels, not a screenshot: Omeify reads the original image, not the terminal preview. Polygon crops use their bounding rectangles, not polygon masks; keep the GeoJSON for the outlines. Use the same source image, series, and orientation in both steps. Annotation placement follows the terminal grid, so zoom in before drawing for finer boundaries. More crop options.

Supported files

Format What twhy does
OME-TIFF Regional, pyramidal microscopy viewing and channel composition
Aperio SVS RGB whole-slide viewing using available stored levels
OME-Zarr Local and HTTP(S) stores, regional chunk reads, supported NGFF multiscales
PNG, JPEG, WebP, BMP, TGA, PPM Ordinary raster viewing with zoom and pan
GIF, APNG, animated WebP View a selected frame (not animation playback)
PDF Navigate pages; progressively improve raster detail; copy embedded text from a rectangular selection

For advanced flags, channel/series semantics, color modes, cache limits, clipboard behavior, and format caveats, use the full reference. Architecture notes are in docs/architecture.md.

Try a synthetic microscopy example

The repo includes a deterministic fixture generator that creates public-safe, synthetic tissue-like RGB and multichannel OME-TIFFs. It is a renderer demonstration, not a biological simulation.

python examples/make_demo.py --output-directory /tmp/twhy-demo
twhy /tmp/twhy-demo/synthetic-mif.ome.tif --channel 0 --channel 2

Python API

import numpy as np
from twhy import TextRenderer

pixels = np.linspace(0, 1, 256**2).reshape(256, 256)
frame = TextRenderer(mode="detail", color=False).render(pixels, columns=80)
print(frame.to_text())

Optional remote sources

Local files are the main workflow. twhy also supports HTTP(S) images/PDFs (bounded download) and HTTP(S) OME-Zarr (regional chunk reads). For native S3 or S3-compatible stores, install twhy[s3] and use your normal AWS credentials or an endpoint override. No S3 setup is needed for local images, slides, or PDFs. Remote input reference.

Release media and provenance

These GIFs are edited recordings of the real twhy terminal viewer. Showcase sources:

License

Apache-2.0. See LICENSE.

Metadata

Release files for twhy 0.2.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 twhy 0.2.0
File Size Uploaded Provenance Actions
twhy-0.2.0.tar.gz 236.9 kB Without provenance Details for twhy-0.2.0.tar.gz

Built distribution (wheel)

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

Total release size: 353.7 kB

Release files / twhy-0.2.0.tar.gz

Download URL twhy-0.2.0.tar.gz
Size 236.9 kB
Tags Source
SHA-256 checksum
How to use checksums
e4e2470f2088a79c411c127d285bf0e680392bd2ff2ee7729df3cb498b652294
BLAKE2b-256 checksum
How to use checksums
1bcccd3266a2096a20ae23f3521876385e611a9275ab04780de157d34fa346d1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.17

Release files / twhy-0.2.0-py3-none-any.whl

Download URL twhy-0.2.0-py3-none-any.whl
Size 116.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
61172f8cc7959ade2e9b3dd81e43f663e183bceae5ca1196462c984fae3a3320
BLAKE2b-256 checksum
How to use checksums
4dbbb1078990376149bdbec644bf6dab9432b773a8c3c33fcc3cae1a0a2138e5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.17

Security for twhy 0.2.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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A 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.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files No provenance

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