Coordinates and Expressions
Two small concepts appear everywhere in a Jarvis-PLOT file: the coordinate dict (how a column maps to a visual axis) and the expression (the string that computes a value from columns). Learn them once and they read the same in every layer and transform.
The coordinate dict
In a layer's coordinates, each visual axis (x, y, z, c, …) is given a small dict.
In a layer, the only field you need is expr:
coordinates:
x: {expr: mass} # column `mass` → x axis
y: {expr: "np.log10(xsec)"} # an expression → y axis
z: {expr: LogL} # scalar field for image/contour/voronoi methods
c: {expr: chi2} # per-point color for scatter
Which keys a method expects:
| Visual key | Meaning | Used by |
|---|---|---|
x, y |
position | almost every method |
z |
scalar field | pcolormesh, contour, contourf, voronoi, tripcolor, … |
c |
per-point color | scatter |
left, right, bottom |
ternary composition | tri* methods on axtri |
u, v |
vector components | quiver |
Full coordinate dict (transforms)
Inside a transform (e.g. profile, make_density_core), a coordinate carries more
fields, because the transform produces new columns on a grid:
x:
expr: "np.log10(mass)" # how to compute the input value (required)
name: xx # name of the output column the transform writes
lim: [0.1, 10] # range used for binning/gridding
scale: log # linear | log
| Field | Used in layer | Used in transform | Meaning |
|---|---|---|---|
expr |
✔ | ✔ | Expression computing the value (required) |
name |
— | ✔ | Output column name produced by the transform |
lim |
— | ✔ | [min, max] range for binning/gridding |
scale |
— | ✔ | linear or log axis treatment |
So a typical pattern is: a profile/density transform reads raw columns via expr and
writes tidy grid columns via name (e.g. xx, yy, z0); the layer's coordinates then
reference those grid columns by expr: xx.
Expressions
Any expr, filter, or add_column.expr string is evaluated against the current DataFrame.
Column names are variables; standard math and NumPy are available.
expr: "mass / 1000" # arithmetic
expr: "np.log10(xsec)" # NumPy via np.*
expr: "np.sqrt(x**2 + y**2)"
expr: "exp(LogL)" # bare math functions also work
filter: "(x > 0) & (y < 100)" # boolean masks for `filter`
filter: "np.isfinite(z0)"
Available functions
| Group | Names |
|---|---|
| Basic | exp, log, ln, sqrt, abs, Abs, root |
| Trig | sin, cos, tan, sec, csc, cot, sinc, asin, acos, atan, atan2, … |
| Hyperbolic | sinh, cosh, tanh, asinh, acosh, atanh, … |
| Reductions | Min, Max |
| Constants | Pi, E, Inf |
| Statistics | Gauss(x, mean, sigma), Normal(x, mean, sigma), LogGauss(x, mean, sigma), Heaviside(x) |
| NumPy | any np.* function (e.g. np.where, np.maximum, np.clip) |
For boolean filters use the elementwise operators & (and), | (or), ~ (not), and wrap
each comparison in parentheses: (a > 0) & (b < 1).
User-defined helpers
Interpolators declared in the top-level Functions block, and
operators registered with Jarvis-Operas, become callable inside expressions by name. For
example, a Functions entry named FASER2 can be used as FASER2(x) in any expr.