Using plMapcalc in Jupyter
plMapcalc ships a Python function plmapcalc() that mirrors the full
command-line interface. You can call it directly from a Jupyter notebook or any
Python script — no subprocess, no shell quoting, just keyword arguments.
Importing
Place plmapcalc.py in the same directory as your notebook (or anywhere
on sys.path), then import the function:
from plmapcalc import plmapcalc
Function signature
plmapcalc( inputs, # list[str] — required *, outputs = None, # list[str] execute = None, # str — cell expression (-e) program = None, # str — path to .mc file (-p) execute_begin = None, # str — code run before scan program_begin = None, # str — file with begin code execute_end = None, # str — code run after scan program_end = None, # str — file with end code memory = 0, # int — MEM[] cells (-m) memory_read = None, # str — load MEM from file (-r) memory_store = None, # str — save MEM to file (-s) store_zeroes = False, # bool — include MEM[i]==0 in save threads = 1, # int — compute threads (-t) force = False, # bool — overwrite outputs (-f) quiet = 0, # int — 0=all 1=silent 2=progress only use_nan = False, # bool — treat NaN as value ignore_georef = False, # bool — skip CRS/extent checks gpu = False, # bool — run pixel kernel on GPU (--gpu) no_jit = False, # bool — disable JIT/CUDA, plain Python (--no-jit) # Spatial alignment (WarpedVRT — optional) crs = None, # str — target CRS, e.g. "EPSG:4326" (--crs) resolution = None, # str|float — "ref"|"highest"|"lowest"|N (--resolution) extent = None, # str — "ref"|"intersection"|"union" (--extent) resample = "nearest", # str — resampling method (--resample) on_progress = None, # callable(int) — progress callback 0-100 )
All arguments after inputs are keyword-only. Layer specifiers use
the same colon-separated syntax as the CLI:
"file.tif:band:shift_x:shift_y" for inputs and
"file.tif:dtype:nodata:compress" for outputs.
no_jit=True disables numba JIT and CUDA. The cell expression runs
as plain Python — full numpy support including dynamic slices
(IN[i:i+3]), dict, print(), etc.
Useful for complex expressions like BioClim or Köppen-Geiger that use variable
slices. Slower than JIT but there are no syntax restrictions.
Output verbosity (quiet)
By default (quiet=0) plMapcalc prints layer info, JIT status, progress
bar, and timing. In a notebook all output goes to stdout (white cell output
area). JIT compiler diagnostics from numba are suppressed automatically so they do not
cause the cell to render with red error styling.
| quiet | CLI equivalent | Output |
|---|---|---|
0 | (none) | Layer info, JIT status, progress bar, timing |
1 | -q | Silent — no output at all |
2 | -q -q | Progress bar only, no messages |
Shared global variables — G proxy
Variables set in execute (cell phase) are not accessible in
execute_begin or execute_end — each phase runs in its
own function scope. Use the built-in G object to share state
across all three phases. Works identically with
execute= and program=.
plmapcalc( inputs = ["ndvi.tif", "mask.tif"], execute_begin = "G.total = 0.0; G.count = 0", execute = "if IN[1] > 0: G.total += IN[0]; G.count += 1", execute_end = "MEM[0] = G.total / G.count if G.count > 0 else 0.0", memory = 1, memory_store = "stats.txt", force = True, )
If you omit memory=N but use literal MEM[N] indices,
plmapcalc auto-sizes the MEM array to max_index + 1 cells
and prints [INFO] MEM[] auto-sized to N cells. For dynamic indices
like MEM[COLS*ROW+COL] you must set memory=N explicitly.
Automatic spatial alignment (crs, resolution, extent)
By default all input layers must share identical CRS, pixel size and extent.
Passing any of crs, resolution, or extent
enables on-the-fly alignment via rasterio.vrt.WarpedVRT — no temp files:
plmapcalc( inputs = ["dem_10m.tif", "landcover_100m.tif"], outputs = ["result.tif:float32:-9999"], execute = "OUT[0] = IN[0] * IN[1]", resolution = "highest", # align to 10m grid extent = "intersection", # only common area resample = "nearest", # safe for discrete landcover )
CRS reprojection warning: when crs causes any layer
to be reprojected, plmapcalc prints a warning and processing is ~3–4×
slower. For large datasets, pre-reproject with gdalwarp or QGIS
Warp (Reproject layer), then run without crs=.
Progress callback (on_progress)
Pass a callable that receives an integer 0–100. Called after each tile,
it replaces the printed
98% line. Useful for custom progress
bars or notebook widgets:
# Simple tqdm progress bar from tqdm.auto import tqdm with tqdm(total=100, desc="plMapcalc") as bar: plmapcalc( inputs = ["input.tif"], outputs = ["output.tif:float32:-9999"], execute = "OUT[0] = IN[0] * 2", quiet = 1, on_progress = lambda p: bar.update(p - bar.n), )
When on_progress is provided, the printed percentage line is
suppressed. In the QGIS plugin, feedback.setProgress is used
automatically — the native QGIS progress bar is updated without any extra code.
Examples
Add two layers
from plmapcalc import plmapcalc plmapcalc( inputs = ["layer1.tif", "layer2.tif"], outputs = ["sum.tif:float32:-9999:DEFLATE"], execute = "OUT[0] = IN[0] + IN[1]", threads = 4, force = True, )
NDVI
plmapcalc( inputs = ["band4.tif", "band3.tif"], outputs = ["ndvi.tif:float32:-9999:DEFLATE2"], execute = "x=IN[0]+IN[1]; OUT[0]=-9999 if x==0 else (IN[0]-IN[1])/x", threads = 8, force = True, )
Statistics accumulated in MEM[], saved to file
plmapcalc( inputs = ["ndvi.tif", "mask.tif"], memory = 3, execute = "if IN[1]>0: MEM[0]+=1; MEM[1]+=IN[0]", execute_end = "MEM[2] = MEM[1]/MEM[0] if MEM[0]>0 else 0", memory_store = "stats.txt", )
Multi-pass patch area calculation
plmapcalc( inputs = ["patches.tif"], outputs = ["areas.tif:float64:-9999:LZW"], memory = 2000, execute = "if ITERATION()==1: MEM[int(IN[0])]+=1\nelse: OUT[0]=MEM[int(IN[0])]", execute_end = "if ITERATION()==1: RESTART()", force = True, )
Silent batch processing
import glob for path in glob.glob("input/*.tif"): out = path.replace("input/", "output/") plmapcalc( inputs = [path], outputs = [f"{out}:uint8:255"], execute = "OUT[0] = 1 if IN[0] > 0 else 0", force = True, quiet = 1, # silent )
Built-in help
Call help(plmapcalc) in any notebook cell to display the full
parameter reference in a readable plain-text format:
help(plmapcalc)
Numba JIT compiler messages are automatically suppressed during compilation so they do not taint the cell output with red error styling. The first run will show a brief JIT compilation … done. message, then all subsequent calls reuse the compiled kernel with no overhead.