Glowbar, fluxbox and hexmatrix

Show observations, summaries and density with individually named plot parts.

6 min readPlotting

Three signature plots show observations beside their summary. Each takes a table (a pandas or polars DataFrame, or a dict of columns) plus column names, seaborn-style, and names every part for you. Hover a real fluxbox on the semantic plots page to see those names. In the examples, df is your table and ax an axes.

Glowbar

gb = fp.glowbar(df, x="condition", y="APP/GAPDH", units="subject", ax=ax)

# Paired or repeated measures: connect each unit across conditions.
gb = fp.glowbar(df, x="condition", y="signal", units="mouse",
                connect_identical_points_across_x_values=True, ax=ax)

Every observation is a dot. Beside each group sits a slim bar that glows — its ink densest at the centre of the distribution and fading to hard caps at the interval ends — with the mean as a heavy, haloed line across the bar and the median as a V-notch cut into both of its edges. The interval is mean ± SEM by default, glowing around the mean; interval="iqr" spans the box of a box plot and glows around the median, "sd" gives mean ± SD, and a callable values -> (low, high) is accepted. Default groups use ColorBrewer’s YlGnBu, then YlOrRd.

With units= every unit (animal, subject, cell) keeps a fixed lane and colour derived from the table, never from the values, so plots of different measures made from one table agree dot for dot — even when a unit is missing from one of them. Unit colours are equal perceptual steps (CAM02-UCS) of each group’s ColorBrewer map between shade_range=(88, 22) lightness, dealt across lanes so neighbours always contrast (interleave_shades=True), and rimmed in a deeper shade of themselves so the palest dots stay crisp (point_edge="rim"). Connectors are a quiet neutral grey and break at a unit’s missing category rather than bridging it.

Part Role Default ID
interval glow box <category>.glow
interval caps cap <category>.caps
mean line mean <category>.mean
median notch median <category>.median
a unit’s points point <unit>.points, <unit>.point.<k>
a unit’s connector line <unit>.line
points without units point <category>.points, <category>.point.<k>

Each category series carries a glowbar manifest payload with the exact statistics drawn (n, mean, median, sd, sem, q1, q3, interval, low, high, center, x, groupColor), and each unit series its identity (units, unit, categories, colors); the manifest’s plotType is "glowbar". Series names default to the category and unit values; series= and unit_series= (a mapping or a callable) rename them.

Every visual choice is a keyword (see fp.glowbar for all of them):

It returns a GlowbarResult (.ax, .categories, .stats, .group_colors, .point_colors, .series, .unit_series, .artists). The fluxplot repository’s examples/glowbar_example.py draws both designs shown above (unpaired and paired).

Fluxbox

The fluxbox is the glowbar with a box plot for its summary — the same call, the same lanes, colours, connectors and names, so the two can be swapped for one another dot for dot:

fb = fp.fluxbox(df, x="condition", y="APP/GAPDH", units="subject", ax=ax)

Beside each group sits a slim box (Q1–Q3), a half-strength wash of the group colour (box_alpha=0.5). The median is a solid line across it in the group’s own hue — deepened, or on a dark background lifted, only as far as it takes to differ from the box by median_contrast=30 units of perceived lightness, so it reads for any palette and theme; the whiskers (and fliers) share that colour, so the box is the only wash. The mean is a V-notch cut into both edges of the box — the glowbar’s median notch; a mean outside the box (a strongly skewed group) keeps its mark as the same two V’s drawn solid, pointing in at the whisker. The capless whiskers reach the most extreme observations within whis × IQR of the box (1.5 — Tukey’s rule, exactly plt.boxplot’s whiskers), "range", or a (low, high) pair of percentiles. Observations beyond the whiskers are not drawn again as fliers — the points already show them — unless the points are hidden (show_fliers="auto").

Part Role Default ID
box (Q1–Q3) box <category>.box
whiskers whisker <category>.whiskers
whisker caps (show_caps=True) cap <category>.caps
median line median <category>.median
mean notch mean <category>.mean
fliers (points hidden) flier <category>.fliers
points and connectors point, line as for the glowbar

Each category series carries a fluxbox manifest payload with the exact statistics drawn (n, mean, median, sd, sem, q1, q3, iqr, whis, whiskerLow, whiskerHigh, outliers, x, groupColor); the manifest’s plotType is "fluxbox".

The box keywords are whis, box_width, box_alpha, box_offset, box_side, median_line_width, median_color (sets the median colour outright), median_contrast, mean_notch_depth, mean_notch_height, whisker_width, whisker_color, cap_size, cap_width, cap_color, flier_size, cut_color, and the switches show_mean, show_median, show_whiskers, show_caps and show_fliers. Every point, colour, connector and naming keyword is the glowbar’s. It returns a FluxboxResult with the same fields as a GlowbarResult. The fluxplot repository’s examples/fluxbox_example.py draws a complete example.

Hexmatrix

The hexmatrix tiles the plane with regular hexagons, each one a named part. One call covers a point cloud’s density, a 2D gradient of a third variable, and a matrix drawn on a hex lattice:

# Density with marginal histograms, jointplot-style:
hm = fp.hexmatrix(df, x="x", y="y", ax=ax, color="#4CB391", marginals=True)

# Log-log density with an identity line:
hm = fp.hexmatrix(df, x="wake", y="nrem", ax=ax, xscale="log", yscale="log",
                  norm="log", identity_line=True,
                  colorbar_label="Synapses per hexbin")

# Spatial density in 0.15 mm bins:
hm = fp.hexmatrix(df, x="ccf_x", y="ccf_z", ax=ax, aspect="equal", binwidth=0.15,
                  norm="log", colorbar_label="somata / hexbin")

# A gradient of a third variable, C:
hm = fp.hexmatrix(df, x="x", y="y", C="rate", reduce="median", ax=ax,
                  cmap="RdBu_r", center=0)

# A matrix drawn on a hex lattice:
hm = fp.hexmatrix(matrix=weights, ax=ax, gap=0.08)

Hexagons are addressed by their lattice position: row counts up the y axis and col along x, so <series>.hex.<row>.<col> names the same hexagon in every plot with the same extent and grid, whatever the data. They are regular on the page. aspect="auto" locks the axes’ box aspect so a later layout pass can’t squash them, and aspect="equal" bins in true data units. Log axes bin in log space.

The colour can be a count, stat="density"/"probability"/"percent" (optionally weights=), or a reduce of C (mean, median, sum, min, max, std, count or a callable). The scale is set by cmap/color (a single-hue ramp), norm (linear/log/sqrt or any Normalize), vmin/vmax, robust and center. Further keywords:

The colormap and colour limits are recipe controls, exactly as for fp.heatmap: Flux’s Colour scales editor can change them and regenerate the plot.

Part Role Default ID
all hexagons x-hexbin <series>.hexes
one hexagon x-hex <series>.hex.<row>.<col>
sparse or overlaid points point <series>-points.points, <series>-points.point.<k>
identity line reference-line reference-line.identity
marginal histograms (own panels) bar <series>-x.bar.<k>, <series>-y.bar.<k>

Each hexagon element also carries data-row, data-column, data-x, data-y, data-count and data-value attributes.

The series carries a hexmatrix manifest payload: the lattice (orientation, radius, aspect, scales, extent), the statistic, and every hexagon drawn (row, col, x, y, count, value). It also carries the usual field colour payload; the plotType is "hexmatrix". The call returns a HexMatrixResult (.ax, .hexes, .bins, .cmap, .norm, .colorbar, .marginal_axes, .points, .hex_id(row, col), .lookup(x, y)).

Hexagons stay individually addressable up to vector_limit (5000 by default; None uses the save’s generic threshold of 800 elements). A larger layer is rasterized like any heavy layer, but its hexagons stay in the manifest; pass force_vectors=True to fp.save to keep every hexagon addressable. On axes that share x or y with other panels, fp.hexmatrix leaves the box aspect unlocked, with a warning, rather than distorting the sibling panels. The fluxplot repository’s examples/hexmatrix_example.py draws all five variants shown above.

Search the docs

Search guides, workspaces, and reference topics.

↑ ↓ to move · Enter to open · Esc to close