Skip to content

visualdynamics.plot.truncation

truncation

The cut, drawn on the record it will be made from.

Two numbers do not tell you whether the kept stretch sits on the part of the record you meant. Drawn, it does: the discarded ends are greyed over — grey because cut-away data is reference, not subject — and the span between them is the control, the averaging region's own grammar: take it by an edge to move that instant, by the middle to slide the whole window along the record.

The drag settles before it is said (the filter corner's lesson, 2026-08-28): the shading follows the hand move by move — cheap, four rectangle corners — and changed is emitted once, at release, because whoever listens stores the span, re-reads staleness and re-settles the report.

Classes:

Name Description
TruncationOverlay

The truncation as marks on a time history plot.

Classes

TruncationOverlay

TruncationOverlay(
    plot: Any,
    truncation: Truncation,
    first: float,
    last: float,
    colors: Mapping[str, str],
    parent: Any = None,
)

Bases: QObject

The truncation as marks on a time history plot.

Owns every item it adds and takes them all away again on remove, so a redraw cannot leave a shade behind. It reports a settled drag and does not act on it: what a new span means — storing it, restating the table — belongs to whoever put the overlay up.

Methods:

Name Description
set_truncation

Restate the marks for a span set elsewhere, silently.

Source code in src/visualdynamics/plot/truncation.py
def __init__(self, plot: Any, truncation: Truncation,
             first: float, last: float,
             colors: Mapping[str, str], parent: Any = None) -> None:
    super().__init__(parent)
    import pyqtgraph as pg

    self.plot: Any = plot
    self.truncation: Truncation = truncation
    self.first: float = float(first)
    self.last: float = float(last)
    self.colors: dict[str, str] = dict(colors)
    #: set while this overlay writes its own region, so a
    #: programmatic restate does not read as a drag —
    #: `setRegion` raises both region signals, unlike an
    #: InfiniteLine's `setValue`
    self._restating = False

    shade = QColor(self.colors['specification_curve'])
    shade.setAlpha(SHADE_ALPHA)
    self.shades: list[Any] = []
    for _ in range(2):
        zone = pg.LinearRegionItem(
            values=(self.first, self.first), movable=False,
            brush=pg.mkBrush(shade), pen=pg.mkPen(None))
        zone.setZValue(15)          # over the trace: it dims it
        for line in zone.lines:
            line.setPen(pg.mkPen(None))
        self.plot.addItem(zone, ignoreBounds=True)
        self.shades.append(zone)
    # the span's edges are the handles, the foreground's dashed
    # line — the corner line's own dress, because it is the same
    # kind of thing: a draggable boundary that is not data
    self.region: Any = pg.LinearRegionItem(
        values=(truncation.start, truncation.stop), movable=True,
        brush=pg.mkBrush(QColor(0, 0, 0, 0)),
        pen=pg.mkPen(self.colors['plot_foreground'], width=2),
        hoverPen=pg.mkPen(self.colors['filter_preview'], width=2),
        bounds=(self.first, self.last))
    self.region.setZValue(20)
    self.region.sigRegionChanged.connect(self._dragging)
    self.region.sigRegionChangeFinished.connect(self._dragged)
    self.plot.addItem(self.region, ignoreBounds=True)
    self._shade_ends(truncation.start, truncation.stop)
Methods:
set_truncation
set_truncation(truncation: Truncation) -> None

Restate the marks for a span set elsewhere, silently.

Source code in src/visualdynamics/plot/truncation.py
def set_truncation(self, truncation: Truncation) -> None:
    """Restate the marks for a span set elsewhere, silently."""
    self.truncation = truncation
    self._restating = True
    try:
        self.region.setRegion((truncation.start, truncation.stop))
    finally:
        self._restating = False
    self._shade_ends(truncation.start, truncation.stop)