Function Plugins
What Function Plugins Do
Function plugins transform one selected table column into another table column. In the main window, the user selects:
an input column,
an output column,
a function from the Functions dropdown,
an optional offset.
PhysPlot reads the input column as a one-dimensional numeric array, calls the
plugin’s transform(values) function, then writes the returned values into
the output column.
Where Functions Appear in the UI
Discovered function plugins are available in:
Simple Mode’s 2. Mathematical Transformation panel.
The transform dropdown used when building replayable workflow steps.
PhysPlot discovers function files at startup and again on File → Reload Config Modules.
Layman Example
If column 1 contains time and column 2 contains voltage, a function plugin can
create a new column containing voltage squared or baseline removed
voltage. The plugin only needs to know how to transform one list of numbers.
Required File Location
Put new function files in:
config/transformations/
Use a clear filename, for example:
config/transformations/15_normalize.py
Required Structure
Every function plugin must define:
transform(values)Function that receives the input column as a one-dimensional
floatNumPy array (a copy; blank or text cells areNaN) and returns one value per row.
Optional:
DISPLAY_NAMEText shown in the Function dropdown (default: the file name).
DEFAULT_LABELRead only by the legacy plot window. It does not name the output column; leave Output empty and PhysPlot names it
<input>_<DISPLAY_NAME>.
The first line of the module docstring is shown as the menu tooltip.
Minimal Template
"""Normalize transform for PhysPlot."""
import numpy as np
DISPLAY_NAME = "Normalize"
def transform(values):
"""transform(values) -> numpy.ndarray
Normalize the selected table column between 0 and 1.
Parameters:
values (Sequence[float]): One-dimensional selected table column.
Returns:
numpy.ndarray: Normalized values with the same length as input.
"""
values = np.asarray(values, dtype=float)
minimum = np.nanmin(values)
maximum = np.nanmax(values)
if maximum == minimum:
return np.zeros_like(values)
return (values - minimum) / (maximum - minimum)
Step-by-Step: Build a New Function
Create a new file in
config/transformations/(for exampleconfig/transformations/15_normalize.py).Define
DISPLAY_NAMEfor the GUI entry (optional).Implement
transform(values)and return one value per input row.Choose File → Reload Config Modules (or restart PhysPlot) so the function appears in the Function dropdown.
Let an AI Assistant Write It
You can get a finished function without writing code. The guide file config/transformations/AI_GUIDE.md tells an AI assistant exactly what PhysPlot expects and includes a complete, tested example. Build Modules with an AI Assistant explains the method for every kind of module.
Download the guide. Open the link above and click Download raw file (the ↓ button).
Start a new chat with ChatGPT, Claude, Gemini, Copilot or another assistant, and attach
AI_GUIDE.md. Give it:the formula, with the units of the input and of the result;
two or three example inputs with the results you expect, so it can check itself;
optionally a few rows of the column.
Say what you want, for example:
My FTIR spectra have the X column in wavenumber (cm^-1). I want a transformation that converts it to wavelength in nm so I can compare with UV-Vis data. Zero or negative values should become empty cells. For example, 4000 cm^-1 should give 2500 nm. Please call it "cm^-1 to nm" in the menu.
Save the reply in
Documents/PhysPlot/config/transformations/under the file name the assistant gives, such as20_wavenumber_to_wavelength.py(File → Open Config Folder opens theconfigfolder). Choose File → Reload Config Modules, pick the function in Function, click Apply and check a few values.If PhysPlot shows an error, paste the whole message into the chat. The assistant sends a corrected complete file; save it over the old one and reload.
Keep the file name once you use the function: saved sequences refer to it by name. A transformation sees one column, so a calculation that combines two columns (sample divided by reference, for example) needs a different approach; the assistant will say so.
Function Categories
Common categories used by PhysPlot plugins include:
Identity/basic: pass-through operations.
Power/reciprocal:
x^2,x^3,1/x.Log/exp:
log10,ln,e^x.Trigonometric:
sin,cos,tan, inverse trig.Domain-specific: custom transforms such as baseline correction.
Practical Rules
Return the same number of values that you received.
Use
numpy.asarray(values, dtype=float)if you need NumPy operations.Avoid changing files, opening windows, or modifying the table directly.
Handle edge cases such as blank columns, zeros, or repeated values. Blank or non-numeric cells arrive as
NaN.Do not name a file after a built-in transformation (
normalize_max,multiply,add,subtract,divide,log,log10,baseline_subtract); such files are skipped. Keep theNN_prefix.
Sequences and Headless Runs
Applying a function plugin records a TransformColumnStep in the protocol
sequence. Its function_name is the file stem, and the Simple Mode offset
(and multiplier) are stored as parameters:
TransformColumnStep(
input_column="Voltage",
function_name="02_square",
output="Voltage_sq",
params={"multiplier": 1.0, "offset": 0.5},
)
The step computes transform(values) * multiplier + offset. The backend
resolves the name against the same folders the GUI uses (Documents/PhysPlot/
config/transformations first, then the bundled config/transformations),
so Apply This Sequence, exported Sequence.py files and bulk runs replay
the plugin without the GUI. Notebooks can call it directly by file stem or
DISPLAY_NAME:
pp.transform("Voltage", "02_square", output="Voltage_sq")
pp.transform("Voltage", "x^2", output="Voltage_sq")
Extra keyword arguments are passed to transform(values, **params). Renaming
or deleting a plugin file breaks saved sequences that use it.
Existing Examples
See:
config/transformations/01_identity.pyconfig/transformations/05_log10.pyconfig/transformations/14_xrd_baseline_remove.py