spacr.qt.widgets.pivot_builder

Tabulate — drag columns onto rows and columns, get a table with its n.

The chrome over spacr.qt.widgets.pivot_spec. Everything about what the table contains is in there; this module is three drop wells, a stack of aggregation tick boxes and a grid.

Reused rather than rebuilt

The column well is spacr.qt.widgets.graph_builder.ColumnWell and the drag payload is COLUMN_MIME — the same list, the same classification of what is worth offering, and the same payload type, so a column dragged in the Graph Builder and a column dragged here are the same gesture. The drop targets are different, and that is the only reason there is a widget in here at all: a Graph Builder zone holds exactly one column, and a pivot axis holds a nest of them, outermost first.

What the grid shows, and what it refuses to

Every cell prints its n, under the statistics, whether or not n was ticked. An aggregate over 4 objects and one over 4 000 are three digits either way, and the only thing that tells them apart is the number this panel refuses to hide. Cells at or below LOW_N are drawn muted, so a table can be scanned for “which of these am I allowed to believe”.

An empty cell is blank, not zero. The rule and its reasoning are in spacr.qt.widgets.pivot_spec; the panel’s part is not to paper over it with a 0 because a QTableWidgetItem would rather have a number.

Plotting the result

There is no chart in here. PivotPanel.long_frame() hands the Graph Builder a tidy frame — one row per non-empty cell, one column per statistic — and the Graph Builder does what it already does. A second plotting implementation would be a second set of scale, facet and colour rules to keep in step with the first.

Classes

DropWell

One pivot axis: an ordered list of columns, filled by dropping.

PivotPanel

The well, the three axes, the aggregations and the grid.

PivotTable

The grid. Renders a PivotResult.

Module Contents

class spacr.qt.widgets.pivot_builder.DropWell(axis: str, parent=None)[source]

Bases: PySide6.QtWidgets.QWidget

One pivot axis: an ordered list of columns, filled by dropping.

A list rather than a single-slot zone, because a pivot axis is a nest: plateID then rowID then columnID is three keys on one axis and the order is the hierarchy. Drop order is that order, which is the only rule that needs no explanation at the moment a user drags something.

Removing is Delete, Backspace or a double-click. There is no drag-out: a column dragged from here to another well would have to decide whether it was a move or a copy, and getting that wrong silently loses an axis.

Parameters:
  • axis – which pivot axis this well holds. Must be a key of AXIS_LABELS; anything else RAISES here rather than drawing a well nothing can be dropped into.

  • parent – parent widget.

Build one axis well of the pivot shelf.

Parameters:
  • axis – which axis this well holds – a key of AXIS_LABELS.

  • parent – parent widget, or None.

Raises:

ValueError – if axis names no pivot axis.

clear() → None[source]

Empty the well.

columns() → Tuple[str, ...][source]

The columns dropped into this well.

Returns:

the column names, in drop order.

set_columns(columns) → None[source]

Replace the contents. Silent when nothing changes — the panel recomputes on every emission and a redundant pass over a million rows is a visible pause for no visible difference.

Parameters:

columns – the column names to hold, in order; empty names are dropped and the rest converted to strings.

class spacr.qt.widgets.pivot_builder.PivotPanel(parent=None)[source]

Bases: PySide6.QtWidgets.QWidget

The well, the three axes, the aggregations and the grid.

Parameters:

parent – parent widget.

Build the pivot shelf beside the table.

The shelf (“Pivot fields”) and the table (“Pivot table”) are sections of one CollapsibleSplitter (pivot_builder::panel): each folds by its heading, and the edge between them drags, opening at the old 300 / 900 split.

Parameters:

parent – parent widget, or None.

closeEvent(event)[source]

Stop background work before going away.

Parameters:

event – the Qt close event.

export_csv(path: str | None = None) → str | None[source]

Write the table as shown. Returns the path written, or None.

long_frame() → pandas.DataFrame[source]

The tidy summary — what plot_requested carries.

recompute() → spacr.qt.widgets.pivot_spec.PivotResult | None[source]

Rebuild the table. Refusals become a message, never a traceback.

set_frame(frame: pandas.DataFrame | None) → None[source]

Point the panel at a table.

Axis columns the new table does not have are dropped rather than carried over — a pivot half-resolved against the wrong frame would group by fewer keys than the wells claim.

Parameters:

frame – the table to pivot, or None; axis columns it lacks are removed from the wells.

set_spec(spec: spacr.qt.widgets.pivot_spec.PivotSpec) → None[source]

Push a whole spec in — restoring a saved table, or a preset.

Parameters:

spec – the pivot spec whose rows, columns, values, aggregations and quantile are loaded into the controls.

spec() → spacr.qt.widgets.pivot_spec.PivotSpec[source]

The spec the wells and tick boxes currently describe.

use_well_hierarchy() → None[source]

The preset: plate / row / column down the rows.

property result: spacr.qt.widgets.pivot_spec.PivotResult | None[source]

The pivot this panel is showing, if any.

Returns:

the result, or None before one has been computed.

class spacr.qt.widgets.pivot_builder.PivotTable(parent=None)[source]

Bases: PySide6.QtWidgets.QTableWidget

The grid. Renders a PivotResult.

One column per row key so the table can be copied out whole, then one per column-level combination. Every populated cell ends with its n; every empty one is blank.

Parameters:

parent – parent widget.

Create an empty pivot table view.

Parameters:

parent – parent widget, or None.

cell_text(row: int, col: int) → str[source]

What is actually painted in a body cell — for a test, and for a caller that wants the string rather than the float.

Parameters:
  • row – the table row.

  • col – the body column, counted after the row-key columns.

set_result(result: spacr.qt.widgets.pivot_spec.PivotResult | None) → None[source]

Show a computed pivot.

Parameters:

result – the pivot result, or None to clear.

property result: spacr.qt.widgets.pivot_spec.PivotResult | None[source]

The pivot being displayed, if any.

Returns:

the result, or None before one has been computed.

property truncated_cells: int[source]

Cells the grid refused to build. Non-zero means export, not scroll.