Skip to main content

eyepiece

Plotting and animation primitives for astronomical imaging simulations.

What eyepiece is

eyepiece provides ax-first, stateless figure functions for the plots that recur across direct-imaging work: log-scaled and diverging image displays, side-by-side and A/B comparison panels, radial profiles and contrast curves, corner plots, orbit and sky-track scenes, optical-train schematics, and a multi-sink animation recorder that grabs frames once and writes them to any combination of gif, mp4, and html. Every primitive takes plain arrays in and returns a small result object holding the axes and the artists it drew, so callers can update or extend a figure without re-deriving which line or image object came from where.

Figure style (color, colormaps, and mode) is resolved through hwostyle at call time, not at import time. import eyepiece never activates a style or touches matplotlib's rcParams. Without an active hwostyle mode, primitives fall back to a fixed light-mode palette, so eyepiece also works as a standalone plotting library.

What eyepiece is not

  • Not a simulation library. eyepiece takes arrays and returns figures; it never imports a simulation, orbit, or optics package.
  • Not a style engine. Color, colormap, and mode definitions live in hwostyle; eyepiece only reads them at call time.
  • Not a data pipeline. Aggregating or transforming simulation output before plotting is the caller's job.

What is in it

Every name below is importable straight from eyepiece; the submodules that implement them are internal organization.

  • Images. imshow_log (log scale clipped to a floor, so a zero-valued pixel cannot break the norm), imshow_diverging (symmetric norm about zero), show_field (amplitude and phase panels of a complex field), compare_row (several images sharing one norm and colorbar), and triptych (A, B, and a ratio or residual comparison panel, side by side).
  • Distributions. corner, corner_overlay (a second sample set laid over an existing triangle plot), hist_vs_pdf, and cov_ellipse.
  • Profiles. plot_radial (a precomputed radial profile line), plot_contrast_curve (a contrast curve with inner/outer working angle shading and reference floor curves, drawn once per axes even across repeated calls, with each curve taking the next palette color so two calls on one axes are distinguishable), and radial_profile_plot (computes the profile via hwoutils and plots it in one call, under the [hwo] extra).
  • Scenes. trail (a 2D or 3D trajectory with depth-cued markers), sky_fan (weighted candidate sky tracks with an inner-working-angle disk), and fading_track.
  • Schematics. rail (an optical-train diagram built from a plain (label, glyph) element list, over the GLYPHS vocabulary), and schematic, a preset wrapper over rail for the imager and coronagraph trains that come up constantly.
  • Layout. Pixel-edge extent helpers (extent_lod, extent_arcsec, extent_au, ...) with matching axis labelers, plus Frame and SourceStyles for keeping several panels of one scene consistent.
  • Output. save_fig for a styled write to disk, record (a context manager that opens every sink at once and takes frames from a loop the caller drives) and animate (which binds a figure, a draw function, and a frame source into the public Animation type it returns), and PRESETS of measured fps/dpi pairs.

Usage

import eyepiece as ep

result = ep.imshow_log(psf, extent=ep.extent_lod_from_pixels(psf.shape[0], 0.5))
ep.label_lod(result.ax)
ep.save_fig(result.fig, "psf")

Every primitive returns a small result object carrying the axes it drew on and the artists it made (keyed by the ARTIST_KEYS vocabulary), so a caller can keep working on the figure without hunting for the objects again. An image primitive also returns an .update that redraws with new data through the same transform, which is what makes animation a few lines:

frames = [cube[k] for k in range(len(cube))]
result = ep.imshow_log(frames[0])


def draw(fig, k):
    result.update(frames[k])


ep.animate(result.fig, draw, len(frames), fps=10).save("run.mp4", "run.gif")

rail draws a miniature optical-train diagram from a plain element list, so a physics panel can sit beside a reminder of which plane it shows:

import eyepiece as ep

result = ep.rail(
    [("Pupil", "pupil"), ("FPM", "fpm"), ("Lyot", "lyot"), ("Focal", "focal")],
    highlight="FPM",
)
ep.save_fig(result.fig, "coronagraph_rail")

Status

eyepiece is young: the primitives above are implemented and tested, and the public API may still shift before 1.0.

Installation

pip install eyepiece

Unit conversions used by a small number of layout helpers (arcsecond and AU extents) and radial_profile_plot's profile computation are optional and pull in hwoutils:

pip install eyepiece[hwo]

License

MIT

Metadata

Release files for eyepiece 0.3.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 eyepiece 0.3.0
File Size Uploaded
eyepiece-0.3.0.tar.gz 60.6 kB Details

Built distribution (wheel)

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

Total release size: 119.8 kB

Release files / eyepiece-0.3.0.tar.gz

Download URL eyepiece-0.3.0.tar.gz
Size 60.6 kB
Tags Source
SHA-256 checksum
How to use checksums
346b7ffd25f0579874200c4c32661ce5d4bfe2809bb9ab79bc74fb96de0ef5f4
BLAKE2b-256 checksum
How to use checksums
f05036c7a4e1d351f0a7415879aa0755d92c25421e27b8246125db581ad69c14
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 Aug 28, 2026.

Transparency log

Release files / eyepiece-0.3.0-py3-none-any.whl

Download URL eyepiece-0.3.0-py3-none-any.whl
Size 59.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1231b94f1c8d4d1c8e92a541f269102da042d2196a72470f26b76c22dc2e5d9b
BLAKE2b-256 checksum
How to use checksums
c19ca473c456b8e7e137a0fe2f45af239d51133215e488dad14022d2e4eee2d6
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 Aug 28, 2026.

Transparency log

Release history Release notifications | RSS feed

0.15.0

2 release files

0.14.0

2 release files

0.13.0

2 release files

0.12.0

2 release files

0.11.0

2 release files

0.10.0

2 release files

0.9.0

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

2 release files

0.3.1

2 release files

This release

0.3.0 This release

2 release files

0.2.0

2 release files

0.1.0

2 release files

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