Changes for .kilo/plan.md: 85 added lines, 0 removed lines.
Original line number
Diff line number
Diff line
# Task Plan: Implementing Gap-Aware Horizontal Layout in `plot_models.py`
## Purpose
The goal is to modify the visual representation of model fits in `PyAETNA/reporting/plot_models.py`. Currently, the plot shows a single continuous time series (with potential gaps) in one large left column. The new requirement is to split this left column into multiple **sub-columns**, where each sub-column represents one contiguous cluster of data points identified by `detect_data_clusters` from `plot_model_helpers.py`.
Crucially, we must ensure that the **horizontal scale** (time units per pixel) is identical across all sub-columns so that a specific duration looks visually the same regardless of which subplot it appears in. The rightmost KDE column must remain unchanged in its width ratio (fixed at 1 unit relative to the total left side).
## Strategy & Methodology
1.**Cluster Detection**: Use `detect_data_clusters` on the sorted time array to identify $N$ contiguous blocks of data.
2.
3.**Proportional Width Calculation**:
* Calculate the time span $\Delta T_i$ for each cluster $i$.
* Total left-side width is fixed at **6 units**.
* The weight for each sub-column $i$ will be: $W_i = \left( \frac{\Delta T_i}{\sum_{j=1}^{N} \Delta T_j} \right) \times 6$.
* The width of the KDE column is fixed at **1 unit**.
4.**Grid Construction**: Use `matplotlib.gridspec.GridSpec` with `width_ratios = [W_1, W_2, ..., W_N, 1]`.
5.**Adaptive Plotting Loop**: Iterate through the detected clusters. For each cluster, slice the underlying arrays (`t`, `y`, `dy`, etc.) and populate the corresponding column in the `GridSpec` (e.g., Overlay, Detrended, Residuals rows).
6.**Consistency Checks**: Ensure all sub-columns share a common Y-axis within their respective rows to allow comparison across time gaps.
## Implementation Steps
### Step 1: Import and Detection
Import the cluster detection utility and run it on the masked/sorted time array.
Iterate through `clusters`. For each cluster $i$, create the vertical stack of axes (Overlay $\to$ Detrended $\to$ Residuals).
```python
# Example for one row of columns (e.g. Overlay)
axes_overlay=[]
foriinrange(n_clusters):
ax=fig.add_subplot(gs[row_index,i],sharey=...)# sharey with previous cluster in same row
axes_overlay.append(ax)
# Inside the loop: slice data for current cluster index
start,end=clusters[i]
t_c=t[start:end+1]
y_c=y[start:end+1]
# ... plot on ax ...
```
### Step 5: Axis labels
Make sure that the plots with the data clusters have one shared y-axis label to the left of the left-most subplot and one shared x-axis label conveniently placed at the bottom-center of the series of clusters.
### Step 6: Final Verification
1.**Verify Imports**: Ensure `detect_data_clusters` is correctly imported and the name matches the alias used.
2.**Compilation Check**: Run `python -m py_compile PyAETNA/reporting/plot_models.py` to ensure no syntax errors or missing dependencies were introduced during refactoring.
3.**Visual Inspection**: Confirm that clusters with longer time spans appear physically wider on the screen and that the $x$ scale is perceptually identical across all columns.