Skip to main content

Colorize and combine multiple FITS images for making visually aesthetic scientific plots

Project description

multicolorfits

Colorize and combine multiple FITS images for visually aesthetic scientific plots — with any number of image layers, in any colors.

version 3.0.0

API documentation: https://multicolorfits.readthedocs.io

DOI ASCL PyPI version Downloads License Python Powered by Astropy Documentation Status Sponsor

Sharing / customization: please play around — BSD 3-Clause License.

If you find this useful for your work, giving me (Phil Cigan) a nod in your acknowledgements would be greatly appreciated. For a formal citation, see CITATION.cff (GitHub Cite this repository), BibTeX from the ASCL entry on ADS (ascl:1909.002), or the Zenodo DOI (Export panel; ADS also indexes 10.5281/zenodo.3256061).


multicolorfits GUI

What's new in v3

Version 3 rebuilds the project as a proper package without traits / traitsui / pyface / PyQt. The core library uses only the scientific stack (numpy, astropy, scipy, matplotlib, scikit-image). GUIs and other capabilities are optional extras — easiest path is pip install "multicolorfits[all]" (browser GUI, desktop GUI, alignment, overlays, and signed-stretch helpers in one go).

  • Browser GUI (primary): FastAPI + local webpage — mcf.gui() / mcf-web (preferred for interactive work: faster Fast preview, including the combined image)
  • Desktop GUI: PySide6 — mcf.gui_qt() / mcf-qt

Scripting remains backward-compatible with v2 (to_grey_rgb, colorize_image, combine_multicolor, …). New capabilities include Lab / RYB compositing modes, in-GUI layer alignment, palettes, overlays, session save/restore, transparent cutouts, and more — see below and MIGRATION.md.

Dependencies

Required: numpy, matplotlib, astropy, scipy, scikit-image

Requires Python 3.9+.

Recommended install pulls every optional capability (web, qt, reproject, overlays, pysymlog) so you do not have to pick extras by hand. Individual extras are listed below if you want a leaner install.

Extra Provides
[all] Everything below (recommended default)
[web] Browser GUI (fastapi, uvicorn)
[qt] Desktop GUI (PySide6)
[reproject] FITS reprojection / alignment
[overlays] Compass, beam, scale bar (skyplothelper)
[pysymlog] Symmetric-log stretch helper

Installation

Most users should install with all extras:

pip install "multicolorfits[all]"

That gives you both GUIs, on-the-fly alignment, plot overlays, and related helpers. Then launch with:

mcf-web
# or: mcf-qt

Core library only (scripting, no GUI):

pip install multicolorfits

A la carte extras if you prefer a smaller install, e.g. browser GUI alone:

pip install "multicolorfits[web]"

From a clone (development, with tests):

pip install -e ".[all,test]"

Conda + [qt]. The browser GUI ([web]) needs no Qt and is safe in shared conda stacks. [qt] / [all] pull PySide6 from PyPI (a Qt6 runtime). Mixing that — or leftover pip PyQt6 — into a conda-forge Qt5 env can core-dump interactive plt.show() while headless Agg still works. Prefer [web] in shared conda Qt5 environments; install the desktop GUI in a dedicated env. Audit / repair: see docs/installation.md.

For AI agents / LLMs

multicolorfits exposes a capability map that agents (and newcomers) can ingest without guessing the API:

import multicolorfits as mcf
mcf.overview()            # mental model, conventions, task index
mcf.recipes('cutout')     # copy-paste recipes matching a keyword
cat = mcf.overview(as_dict=True)   # structured catalog for tools

The same source (multicolorfits/_overview.py) generates the static files llms.txt and llms-full.txt (inlined runnable recipe code; the full file also adds function signatures). Regenerate with python scripts/make_llms_txt.py — CI fails if they drift. On Read the Docs they are also served at the site root (https://multicolorfits.readthedocs.io/en/latest/llms.txt).

Usage

Interactive GUI

import multicolorfits as mcf

mcf.gui()       # browser GUI — recommended default ([all] or [web])
# mcf.gui_qt()  # PySide6 desktop GUI ([all] or [qt])
# mcf.mcf_gui() # still works as an alias for gui()

Prefer mcf.gui() / mcf-web for interactive work: the browser app has a much faster Fast preview path (including live updates of the combined image) while you tweak stretches, colors, and compositing. The Qt GUI shares the same session model and is fine when you want a native window; new preview performance work lands in the browser first.

Or from a terminal:

mcf-web
# mcf-qt

Typical workflow:

  1. Load and adjust each component image (stretch, levels, color, optional smoothing).
  2. Choose compositing mode / background; use Fast preview while iterating, then Plot Full Resolution for the WCS figure.
  3. Re-adjust and replot as needed.
  4. Save an image, FITS RGB cube, session JSON, or an export script. Sessions round-trip with Save Session… / Load Session… (or mcf.gui(state='session.json')).

If layers are on different pixel grids, use Align layers… (needs [reproject]), or reproject in a script first.

Scripting

import astropy.io.fits as pyfits
import multicolorfits as mcf

data1, hdr1 = pyfits.getdata('image1.fits', header=True)
data2, hdr2 = pyfits.getdata('image2.fits', header=True)   # same pixel grid

grey1 = mcf.to_grey_rgb(data1, rescalefn='asinh', min_max=[0., 1.2], gamma=2.2)
grey2 = mcf.to_grey_rgb(data2, rescalefn='sqrt',  min_max=[0., 0.8], gamma=2.2)

col1 = mcf.colorize_image(grey1, '#C11B17', colorintype='hex', gammacorr_color=2.2)
col2 = mcf.colorize_image(grey2, '#4CC417', colorintype='hex', gammacorr_color=2.2)

combined = mcf.combine_multicolor([col1, col2], gamma=2.2)

mcf.plot_combined_rgb(combined, hdr1, 'My 2-color image', './out.png')
mcf.save_rgb_fits('./out_rgb.fits', combined, hdr1)

PanelState.load_fits() / squeeze_image() drop degenerate FITS axes and strip ghost higher-axis WCS cards from nominally 2D headers.

If images are not on a common grid (included with [all], or install [reproject]):

data2_reproj = mcf.reproject_image(data2, hdr2, hdr1)

Mid-level session API

Both GUIs drive the same McfSession object, which you can also use in scripts:

from multicolorfits import McfSession

s = McfSession()
s.panels[0].load_fits('image1.fits')
s.panels[0].stretch = 'asinh'
s.panels[0].apply_zscale()
s.panels[0].color = '#C11B17'
s.compose.gamma = 2.2

combined = s.render_combined()
s.save_rgb_fits('./out_rgb.fits')
print(s.export_script())

Tutorials / examples

Also see the gallery images further below.

Features

  • Image panels in the GUI (default four; add more with + Add panel, up to 16)
    • Load by path, file browser, or upload (web GUI)
    • Note: layers must share a pixel grid to combine. Use Align layers… in the GUI or reproject_image / align_stack in scripts ([reproject]).
    • Scripts can still construct McfSession(n_panels=N) or call session.add_panel() / remove_panel() directly
  • Per-layer color (hex / picker), stretch (linear, sqrt, squared, log, power, sinh, asinh, …), min/max or percentile levels, zscale, optional Gaussian smoothing
  • Header editor per panel; save/load header text
  • Compositing modes: classic RGB sum; CIE Lab (recommended alternative); experimental HSV/HSL; subtractive RYB / CMYK; background black / white / transparent / custom color
  • Curated palettes and hue-wheel “tune colors”, with a color-vision safety check
  • Combined figure options: WCS tick format, gamma, canvas color (incl. transparent), channel legend, color-combination swatch, band labels
  • Optional WCS overlays (compass, beam, scale bar) via [overlays]
  • Fast preview (downsampled float32, including the combined image) and Plot Full Resolution WCS plot — snappiest in the browser GUI
  • Light / dark GUI theme
  • Save / load GUI sessions as JSON (paths + settings, not pixels) — resume later or preload with mcf.gui(state=…) / mcf-web --state
  • Save image (png/jpg/pdf/…), FITS RGB cube with provenance HISTORY, transparent cutouts for slides/stamps, and an export-script for recreating the plot
  • Cursor readout of sky coordinates and per-layer values on the combined view
  • Notebook embed (mcf.gui_embed) for Jupyter / Colab demos

Color mixing (CIE Lab and friends)

Classic combine_multicolor sums RGB channels. That is fast, but bright overlaps can wash out toward white. Lab mixing keeps hues more distinct:

combined = mcf.combine_multicolor_colorspace(
    [col1, col2], colorspace='lab', blend='screen', gamma=2.2)
blend Behavior Good for
'screen' (default) Accumulates brightness gracefully General use
'max' Brightest layer wins per pixel Preserving each layer's hue
'sum' Clipped sum Matching the classic RGB look
'mean' Average Mixing plain colors

colorspace='lab' is supported in the GUIs. 'hsv' / 'hsl' remain experimental. See docs/guide/color_compositing.md and examples/colorspace_comparison.md.

RYB and a proper background control (white / transparent / custom) replace the old “inverse” white-background trick without flipping hues.

WCS overlays (optional)

# Already included with: pip install "multicolorfits[all]"
pip install "multicolorfits[overlays]"   # pulls in skyplothelper
s.compose.show_compass = True
s.compose.show_beam = True          # needs BMAJ/BMIN in the FITS header
s.compose.show_scale_bar = True

plot_combined_rgb(...) accepts the same overlay flags; Export Script emits them when enabled. Advanced annotation (offset WCS, graticules, globes) remains in the companion skyplothelper package.

Browser GUI (detail)

# Prefer: pip install "multicolorfits[all]"
pip install "multicolorfits[web]"
mcf-web                 # or: python -c "import multicolorfits as mcf; mcf.gui()"
mcf-web --browser firefox
mcf-web --no-browser    # start server only; open the printed URL yourself
import multicolorfits as mcf
mcf.gui()                       # system default browser
mcf.gui(browser='firefox')      # or 'google-chrome', 'chromium', …
mcf.gui(open_browser=False)     # URL printed; open manually

A local server starts on http://127.0.0.1:8321 (browser opens automatically unless --no-browser / open_browser=False). Everything runs on your machine. See docs/tutorials/gui_web_walkthrough.md for layout details and more browser-selection notes.

Highlights: sectioned controls (Compositing, Colors, Axes, Canvas), Fast preview, palette picker, channel legend / swatch / band labels, optional overlays, grid-mismatch detection with one-click align, Save Image / FITS / session / export script, and transparent-cutout export.

Notebooks (Jupyter / Colab)

import multicolorfits as mcf

s = McfSession()
s.load_files(['a.fits', 'b.fits'], colors=['#f00', '#0ff'])
mcf.gui_embed(session=s, height=950)

See docs/tutorials/gui_notebook_embed.py.

Desktop GUI (PySide6)

# Prefer: pip install "multicolorfits[all]"
pip install "multicolorfits[qt]"
mcf-qt

Same core workflow in a native window with an embedded matplotlib WCS canvas. Prefer the browser GUI (mcf.gui()) when you want the fastest live combined preview; new interactive performance work lands there first.

Use a dedicated environment for [qt] if your main conda env already ships Qt5 / PyQt5 — see the conda note under Installation.

Spotted in the wild

A partial list of papers and posts with multicolorfits figures:


Motivation

  • Stretch levels and colors were slow to iterate in plain plotting scripts.
  • Photoshop / GIMP can make pretty images, but we often want a programmatic path that keeps WCS and FITS provenance.
  • Colorizing beyond pure red / green / blue (and beyond three layers) is useful for multi-wavelength work and press-ready figures.

Useful places to download tidy FITS for experiments:

The Kepler, M51, M101, and M106 examples below use Chandra OpenFits data.

Combining frames as pure red / green / blue is common — especially for filters that roughly match R, G, and B light:

M106 R,G,B optical bands.

But what if you only have two images (e.g. red and blue, no green)?

M51 with only Red and Blue.

Other times you may want:

  • Something eye-catching for a press release
Kepler's SNR with non-standard coloration.
  • Multi-wavelength (optical + radio + X-ray) in a more natural-looking palette
M101 from radio to X-ray.
  • More than three layers (e.g. X-ray sources on an RGB optical stack)
M51 RGB with X-ray sources in lime.
  • A white-background / inverted presentation style
M51 RGB inverted.

In v3, prefer the compositing Background control (white / transparent / custom) instead of the legacy inverse checkbox — bright colors stay true while empty sky fades to the chosen background.


Considerations / caveats

  • For sequential filter bands (e.g. G/R/I, J/H/K), combos near standard R/G/B (such as red + yellow + blue) usually look most natural.
  • Results are best when layer colors have similar luminance.
  • Some color choices can confuse overlaps (e.g. red + blue already make purple).
  • On-screen color is not the same as print CMYK; use the CMYK mix mode or a print workflow when preparing hardcopy.
  • Layers must share a pixel grid before combining — align in the GUI or with reproject_image / align_stack.
  • Large files: use Fast preview for interactive work; Plot Full Resolution when exporting.

Tests

pip install -e ".[test]"
pytest

Migrating from v2.x

See MIGRATION.md. Short version: scripting code runs unchanged; install with pip install "multicolorfits[all]" for GUIs and helpers, or pick [web] / [qt] à la carte; traits / traitsui / pyface / PyQt are no longer required.

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

multicolorfits-3.0.0.tar.gz (250.1 kB view details)

Uploaded Source

Built Distribution

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

multicolorfits-3.0.0-py3-none-any.whl (214.1 kB view details)

Uploaded Python 3

File details

Details for the file multicolorfits-3.0.0.tar.gz.

File metadata

  • Download URL: multicolorfits-3.0.0.tar.gz
  • Upload date:
  • Size: 250.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.10.9

File hashes

Hashes for multicolorfits-3.0.0.tar.gz
Algorithm Hash digest
SHA256 71ffba3f9c033d8fb7119ad4b28c10f974a9d043ef7725158b5166711820ede2
MD5 790db81ccc59c425493349cb0fa408d5
BLAKE2b-256 bcb04f09a074c2b0784211d182e179cf92271bdd63cc8a404642f82577c4f992

See more details on using hashes here.

File details

Details for the file multicolorfits-3.0.0-py3-none-any.whl.

File metadata

  • Download URL: multicolorfits-3.0.0-py3-none-any.whl
  • Upload date:
  • Size: 214.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.10.9

File hashes

Hashes for multicolorfits-3.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 32131b4dc636b4869fd99b38b91845bc91972928109efd9921b9301c9a8763ab
MD5 dd001b23f1fbced7d7e166fb811c43dd
BLAKE2b-256 5b51af1a966abbf0c6e5731e12f3c57c1890fc1a45b9bb52e6e9aff5fda14c0c

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