What happens
On a lane chart (a single X or mR chart with by=[] on a study that has factors, sorted by subgroup then time), the main data trace is one go.Scatter with mode='lines+markers' over the whole sequence (processbehavior/plotting/renderers.py, the "Main data trace" block around line 139). So the last point of each lane is joined to the first point of the next lane by a line that crosses the boundary.
On a 24-lane chart of four annual points per organisation, every lane ends high (2024) and the next begins low (2021), so each boundary shows a steep drop. Zoomed to four lanes, the picture reads as four climbs and four collapses. The collapses are not in the data; they are the sort order.
Why it matters
The lane chart's whole purpose is that the eye reads the pattern within each subgroup at a glance. A drawn segment that spans two subgroups says something the data does not, and a reader who does not know the convention will take it for an event. Everything else on the chart (points, limits, centre line, lane boundaries, labels, hover) is correct and should not change.
Proposed change
Do not draw a connector between the last point of one lane and the first point of the next. Two ways, either is fine:
- Insert a
None y-value at each lane boundary in the trace (connectgaps=False is Plotly's default, so the line breaks there). One trace, so legend, hover, and highlight_signals are unchanged. The boundary positions are already known: add_lane_boundaries in processbehavior/plotting/lane_boundaries.py receives them.
- One trace per lane with
showlegend=False after the first. More traces; slower on large K.
Option 1 is the lighter change. The beyond_limits highlight trace is separate and unaffected.
Scope
- Only when lane boundaries are being drawn (a stratified sequence on one axis). Plain single-series X/mR charts and faceted charts (
facet=True, one subgroup per panel) have no cross-lane connector and need nothing.
chart_table, statistics, and signals untouched: plotting only.
- Test: build a two-lane X chart, assert the main trace's y contains a
None between the lanes (or that the number of drawn segments equals the number of lanes), and that the point count is unchanged.
Context
Seen on the synthetic 24-ACO dataset from #114 (24 lanes × 4 years). Zooming in on lanes 1 to 4 shows the artefact clearly; the full chart hides it in the density.
What happens
On a lane chart (a single X or mR chart with
by=[]on a study that has factors, sorted by subgroup then time), the main data trace is onego.Scatterwithmode='lines+markers'over the whole sequence (processbehavior/plotting/renderers.py, the "Main data trace" block around line 139). So the last point of each lane is joined to the first point of the next lane by a line that crosses the boundary.On a 24-lane chart of four annual points per organisation, every lane ends high (2024) and the next begins low (2021), so each boundary shows a steep drop. Zoomed to four lanes, the picture reads as four climbs and four collapses. The collapses are not in the data; they are the sort order.
Why it matters
The lane chart's whole purpose is that the eye reads the pattern within each subgroup at a glance. A drawn segment that spans two subgroups says something the data does not, and a reader who does not know the convention will take it for an event. Everything else on the chart (points, limits, centre line, lane boundaries, labels, hover) is correct and should not change.
Proposed change
Do not draw a connector between the last point of one lane and the first point of the next. Two ways, either is fine:
Noney-value at each lane boundary in the trace (connectgaps=Falseis Plotly's default, so the line breaks there). One trace, so legend, hover, andhighlight_signalsare unchanged. The boundary positions are already known:add_lane_boundariesinprocessbehavior/plotting/lane_boundaries.pyreceives them.showlegend=Falseafter the first. More traces; slower on large K.Option 1 is the lighter change. The
beyond_limitshighlight trace is separate and unaffected.Scope
facet=True, one subgroup per panel) have no cross-lane connector and need nothing.chart_table, statistics, and signals untouched: plotting only.Nonebetween the lanes (or that the number of drawn segments equals the number of lanes), and that the point count is unchanged.Context
Seen on the synthetic 24-ACO dataset from #114 (24 lanes × 4 years). Zooming in on lanes 1 to 4 shows the artefact clearly; the full chart hides it in the density.