nautechsystems/nautilus_trader · error · ValueError
Grid has {rows * cols} cells but {len(charts)} charts were c
Error message
Grid has {rows * cols} cells but {len(charts)} charts were configured; provide a larger GridLayout via TearsheetConfig.layout What it means
_calculate_grid_layout checks that the chosen subplot grid can hold every configured chart: len(charts) must be <= rows*cols. With a custom TearsheetConfig.layout (a plotly GridLayout) the grid dimensions are user-supplied, so an under-sized layout is rejected instead of silently dropping charts.
Source
Thrown at python/nautilus_trader/analysis/tearsheet.py:2526
if num_charts <= 2:
rows, cols = 1, num_charts
heights = [1.0 / rows] * rows
elif num_charts <= 4:
rows, cols = 2, 2
heights = [1.0 / rows] * rows
elif num_charts <= 6:
rows, cols = 3, 2
heights = [1.0 / rows] * rows
else:
cols = 2
rows = max(4, (num_charts + cols - 1) // cols)
heights = [0.50, 0.22, 0.16, 0.12] if rows == 4 else [1.0 / rows] * rows
v_spacing = 0.10
h_spacing = 0.10
if len(charts) > rows * cols:
raise ValueError(
f"Grid has {rows * cols} cells but {len(charts)} charts were configured; "
f"provide a larger GridLayout via TearsheetConfig.layout",
)
specs = []
titles = []
chart_idx = 0
for _ in range(rows):
row_specs: list[dict[str, Any] | None] = []
for _ in range(cols):
if chart_idx < len(charts):
chart = charts[chart_idx]
chart_name = chart.name
spec = _TEARSHEET_CHART_SPECS.get(chart_name, {})
subplot_type = spec.get("type", "scatter")
default_title = spec.get("title", chart_name.replace("_", " ").title())View on GitHub (pinned to a4b06ed870)
Solutions
- Enlarge the custom layout (more rows/cols) so rows*cols >= len(config.charts)
- Or remove charts from TearsheetConfig.charts until they fit
- Or drop the custom layout (layout=None) to let the function auto-size rows/cols for any chart count
Example fix
# before
layout = GridLayout(grid=[[{'colspan': 2}, None], [{}, {}]]) # 4 cells
config = TearsheetConfig(charts=[c1, c2, c3, c4, c5], layout=layout)
# ValueError: Grid has 4 cells but 5 charts were configured
# after
layout = GridLayout(grid=[[{'colspan': 2}, None], [{}, {}], [{}, {}]]) # 6 cells
config = TearsheetConfig(charts=[c1, c2, c3, c4, c5], layout=layout) Defensive patterns
Strategy: validation
Validate before calling
if config.layout is not None:
cells = config.layout.rows * config.layout.cols # adapt to your GridLayout accessor
assert len(config.charts) <= cells, (
f'{len(config.charts)} charts > {cells} grid cells; enlarge layout or trim charts'
)
create_tearsheet(returns=result, config=config) Try / catch
try:
create_tearsheet(returns=result, config=config)
except ValueError as e:
if 'Grid has' in str(e):
config = TearsheetConfig(charts=config.charts, layout=None) # auto-size
create_tearsheet(returns=result, config=config)
else:
raise Prevention
- Prefer layout=None (auto) unless hand-tuning is required
- When appending charts in code, recompute required cells: rows = ceil(n / cols)
- Add a config unit test asserting len(charts) <= rows*cols for your shipped layout
When it happens
Trigger: Passing TearsheetConfig(layout=GridLayout with e.g. 2x2=4 cells) together with 5+ charts in config.charts; or a custom layout whose row/col product is smaller than the charts list even when auto-layout would have sufficed.
Common situations: Hand-tuning a tearsheet layout then adding more charts later; copying a layout sized for the default chart set into a config that appends custom charts.
Related errors
- No tearsheet chart registered under '{chart_name}'.{hint} Re
- Chart renderer must be callable, was {type(renderer)}
- {name} must not be None
- Theme '{name}' not found.{suggestion_text} Available themes:
- Theme name cannot be empty
AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16).
Data as JSON: /api/errors/f3367b2a5d02fa12.
Report an issue: GitHub.