Skip to main content

No project description provided

Project description

wskr

A modular, pluggable Matplotlib “image‐in‐terminal” backend.

What is wskr?

wskr lets you render Matplotlib figures as inline images in terminals that support Kitty, iTerm2, or Sixel protocols. It cleanly separates:

  • Transports (wskr.tty.*): how to talk to the terminal (e.g. Kitty image protocol, Sixel, etc.).
  • Backends (wskr.mpl.*): a generic Matplotlib FigureCanvas/FigureManager that uses a Transport to size and send a PNG.
  • Rich integration (wskr.rich.*): display plots in a rich console using the same transport layer.

Features

  • Kitty backend out of the box (via KittyTransport)
  • Planned support for iTerm2 & Sixel
  • Registry of transports so you can add new protocols without touching Matplotlib code
  • Automatic resizing to fill your terminal viewport while preserving aspect ratio
  • rich renderables for embedding plots in TUI applications

Installation

pip install wskr

Quick start

import matplotlib
# choose one of: wskr (generic), wskr_kitty, wskr_sixel, wskr_iterm2
matplotlib.use("wskr_kitty")
import matplotlib.pyplot as plt

# make a simple plot...
plt.plot([0, 1, 2], [10, 20, 15], marker="o")
plt.title("Hello, terminal!")
plt.show()   # renders inline via Kitty protocol

Using with Rich

from rich.console import Console
from jkit.plot import make_plot_grid
from wskr.rich.plt import RichPlot

console = Console()
fig, ax = make_plot_grid(1, 1)
ax.plot([0,1,2], [2,3,1], c="w")
rich_plot = RichPlot(fig, desired_width=40, desired_height=10)
console.print(rich_plot)

Extending to new protocols

To add a new terminal protocol (e.g. MyTerm) for inline Matplotlib rendering:

✅ Step 1: Implement a Custom Transport

Create a class that inherits from ImageTransport and implements:

from wskr.tty.base import ImageTransport

class MyTermTransport(ImageTransport):
    def get_window_size_px(self) -> tuple[int, int]:
        # return (width_px, height_px)
        ...

    def send_image(self, png_bytes: bytes) -> None:
        # display image in terminal
        ...

    def init_image(self, png_bytes: bytes) -> int:
        # optional: upload image once, return an ID
        ...

Then register it:

from wskr.tty.registry import register_image_transport
register_image_transport("myterm", MyTermTransport)

✅ Step 2: Define a Matplotlib Backend

Use the shared base classes for minimal boilerplate:

import matplotlib.pyplot as plt
from matplotlib import _api
from matplotlib.backend_bases import _Backend
from matplotlib.backends.backend_agg import FigureCanvasAgg
from matplotlib._pylab_helpers import Gcf

from wskr.mpl.base_backend import BaseFigureManager
from myterm_module import MyTermTransport  # your transport from Step 1

plt.style.use("dark_background")


class MyTermFigureManager(BaseFigureManager):
    def __init__(self, canvas: FigureCanvasAgg, num: int = 1):
        super().__init__(canvas, num, MyTermTransport)


class MyTermFigureCanvas(FigureCanvasAgg):
    manager_class = _api.classproperty(lambda _: MyTermFigureManager)


@_Backend.export
class _BackendMyTermAgg(_Backend):
    FigureCanvas = MyTermFigureCanvas
    FigureManager = MyTermFigureManager

    @classmethod
    def draw_if_interactive(cls):
        manager = Gcf.get_active()
        if manager and manager.canvas.figure.get_axes():
            cls.show()

    @classmethod
    def show(cls, *args, **kwargs):
        manager = Gcf.get_active()
        if manager:
            manager.show(*args, **kwargs)
            Gcf.destroy_all()

✅ Step 3: Add It to pyproject.toml

[project.entry-points."matplotlib.backends"]
wskr_myterm = "your_module_path"

✅ Step 4: Use It

import matplotlib
matplotlib.use("wskr_myterm")

import matplotlib.pyplot as plt
plt.plot([1, 2, 3])
plt.show()

Testing

pytest

License

GPL-3.0-only

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

wskr-0.0.3.tar.gz (15.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

wskr-0.0.3-py3-none-any.whl (20.5 kB view details)

Uploaded Python 3

File details

Details for the file wskr-0.0.3.tar.gz.

File metadata

  • Download URL: wskr-0.0.3.tar.gz
  • Upload date:
  • Size: 15.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.6.14

File hashes

Hashes for wskr-0.0.3.tar.gz
Algorithm Hash digest
SHA256 0b6d224a4bdaa894b22e11a4ef6e7f8e3fe9c25e7df8e0fad060e5327b3a4ab2
MD5 4600d69c83169645aae5f9310ddfa8b6
BLAKE2b-256 dc6bccce2bc598bd473531262fa17d5df40a9ad889859b83b6daf187c52931bd

See more details on using hashes here.

File details

Details for the file wskr-0.0.3-py3-none-any.whl.

File metadata

  • Download URL: wskr-0.0.3-py3-none-any.whl
  • Upload date:
  • Size: 20.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.6.14

File hashes

Hashes for wskr-0.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 8fcabb90c107cb58bb5fbed11c5c66278bbadfc96c42bc1c2b364f13b6e7d654
MD5 2410bc2abd45a40892d19eee07f3b7ea
BLAKE2b-256 7080ceddddb7f5206a86fd36f73bb7300410b7c2740609dde2c54bc41e441564

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page