Generate publication-ready figure panels from Leica LIF microscopy files.
- Multichannel Figure Panels: Grayscale channel panels with color merge
- Automatic Scale Bars: Calculated from LIF metadata with nice round numbers
- Channel Labels: Customizable labels for each panel
- Z-Stack Support: Max projection, individual frames, or range selection
- Auto-Contrast: Optional percentile-based intensity normalization
- Metadata Table: Acquisition parameters displayed below figures
- PDF Output: Vector graphics suitable for publication
lif-figure uses uv, a fast Python package manager that handles dependencies automatically. If you don't have uv installed, run:
curl -LsSf https://astral.sh/uv/install.sh | shOr see the uv installation guide for other methods (Homebrew, Windows, etc.).
Why uv? It automatically manages Python versions and dependencies, so you don't need to worry about virtual environments or package conflicts. Just run the commands below and everything works.
uvx --from git+https://github.com/half-adder/lif-figure lif-figure input.lif --channels "DAPI,GFP,mCherry"uv tool install git+https://github.com/half-adder/lif-figure
lif-figure input.lif --channels "DAPI,GFP,mCherry"To get the latest version after installation:
uv tool upgrade lif-figurelif-figure input.lif --channels "DAPI,GFP,mCherry"This processes all series in the LIF file and outputs PDF figures to ./figures/.
Important: All series in the LIF file are expected to contain the same channels in the same order. The --channels argument defines the labels applied to each channel by index (first name = channel 0, second = channel 1, etc.). Series with a different number of channels will be skipped.
lif-figure input.lif \
--channels "DAPI,GFP,mCherry" \
--series "Image1,Image2" \
--output ./output \
--zstack max \
--auto-contrast \
--config lif-figure.yaml| Option | Short | Description |
|---|---|---|
--channels |
-c |
Channel names, comma-separated (required) |
--series |
-s |
Series to process, comma-separated (default: all) |
--series-index |
-si |
Series indices: 5, 2..5, -1, 3.., ..3 (0-indexed) |
--output |
-o |
Output directory (default: ./figures) |
--zstack |
-z |
Z-stack mode: max, max:START-END, frames (default: max) |
--config |
YAML config file path | |
--auto-contrast |
-a |
Enable auto-contrast (optional: LOW,HIGH percentiles) |
--no-metadata |
Hide acquisition metadata table | |
--per-slice-norm |
Normalize each Z-slice independently (default: across stack) | |
--background |
-bg |
Background color: black, white, transparent, or any color (default: black) |
max- Maximum intensity projection across all Z slicesmax:5-15- Max projection of Z slices 5 through 15frames- Output each Z slice as a separate PDFrows- All Z slices as rows in a single PDF (with Z-position labels)
When using frames or rows mode, intensity normalization is computed across the entire Z-stack by default. This ensures consistent brightness across slices, allowing you to compare intensity between Z positions. Use --per-slice-norm if you want each slice normalized independently.
Create lif-figure.yaml in your working directory (auto-detected) or specify with --config:
# Channel color overrides
colors:
DAPI: blue
GFP: green
mCherry: red
# Figure settings
dpi: 300
font_size: 12
scale_bar_height: 4
background: black
# Auto-contrast percentiles (optional)
auto_contrast_percentiles: [0.1, 99.9]Each series produces a PDF with:
- Individual grayscale panels for each channel (labeled)
- Color merge panel
- Scale bar with measurement
- Acquisition metadata table (optional)
Warning: Verify Metadata Accuracy
The acquisition metadata (objective, zoom, pixel size, etc.) is extracted from Leica's proprietary LIF format, which stores information in a complex and poorly documented XML structure. While we attempt to parse this correctly, values may be inaccurate or misinterpreted. Always verify critical measurements against your microscope's settings before publication.
See CONTRIBUTING.md for development setup, testing, and code style.
MIT