Pine Script v6 table guide

Pine Script tables: cells, updates and chart placement

A Pine Script table displays a grid at a fixed chart position. Create its ID with table.new(), populate cells with table.cell(), and remove a rectangular selection with table.clear(). Coordinates are column first, row second, starting at zero. A table shows its latest state; moving the crosshair does not retrieve earlier table values.

Draft a table with AI

Map table.clear to an inclusive rectangle

For the 3-by-4 grid below, each cell prints its own column,row coordinate. The start_column and start_row arguments identify the top-left cell; end_column and end_row identify the bottom-right cell. Both ends belong to the selection. An omitted end coordinate defaults to its matching start coordinate, so omitting both ends selects one cell.

SelectionStart column,rowEnd column,rowExpected result
One cell1,11,1Only 1,1 disappears. Omitting both end arguments has this result.
Rectangle1,12,2Four cells: 1,1; 2,1; 1,2; 2,2.
Bottom row0,32,3Three cells; all other rows remain.
Whole grid0,02,3All 12 cells; the table ID still exists.
Outside the grid0,03,4Invalid: 3 and 4 are dimensions, not valid last indices.

A table.clear example you can inspect cell by cell

Paste this indicator into the Pine Editor and add it to a chart. With Rectangle selected, row 0 and row 3 stay intact, and only column 0 remains populated in rows 1 and 2. Change Clear selection to One cell: only 1,1 should disappear. None restores all 12 coordinate labels. The script redraws the grid before clearing, so every choice starts from the same known layout.

Coordinate experiment: 3 columns, 4 rows, no market data dependencypinescript
//@version=6
indicator("Table rectangle experiment", overlay = true)
string selection = input.string("Rectangle", "Clear selection", options = ["None", "One cell", "Rectangle", "Bottom row", "Whole grid"])
var table grid = table.new(position.top_right, 3, 4, border_width = 1, border_color = color.gray)

if barstate.islast
    for row = 0 to 3
        for col = 0 to 2
            table.cell(grid, col, row, str.tostring(col) + "," + str.tostring(row), text_color = color.white, bgcolor = color.navy)
    if selection == "One cell"
        table.clear(grid, 1, 1)
    else if selection == "Rectangle"
        table.clear(grid, start_column = 1, start_row = 1, end_column = 2, end_row = 2)
    else if selection == "Bottom row"
        table.clear(grid, 0, 3, 2, 3)
    else if selection == "Whole grid"
        table.clear(grid, 0, 0, 2, 3)

Create once, update deliberately, clear only what is stale

table.new() reserves the grid but does not populate it. table.cell() replaces all properties of a cell, including defaults for omitted arguments; table.cell_set_text() changes only its text. Clearing removes cell properties, while table.delete() removes the table object. Empty rows or columns can disappear from the rendered layout after clearing.

  • In the coordinate experiment, repeating table.cell() is intentional: it restores both text and background before applying a new selection.
  • For a dashboard with stable styling, initialize cells and then use setters for changing values. If you rewrite a cell, repeat the styles you want to keep.
  • For a shrinking list, clear the unused trailing rows. Guard against an empty range before calling clear; each start must be no greater than its end.
  • To retain a blank row and its styling, set its text to an empty string instead of clearing the row.

Keep indicator calculations outside the last-bar block

This second example calculates RSI and ATR for every bar, then formats their latest values for a two-column dashboard. The hidden plots expose the same unrounded series in TradingView's Data Window for comparison. The table uses one decimal for RSI and the symbol's tick precision for ATR, so rounding differences are expected.

  • At the rightmost bar, compare RSI check and ATR check in the Data Window with the formatted table values. Compare the same bar and length.
  • Move the crosshair to an older candle: the Data Window follows that candle, while this table keeps the latest values. That difference is expected.
  • On an open realtime bar, indicators recalculate with updates and barstate.islast remains true. Developing values can change before the bar closes.
  • A strategy normally calculates at bar close unless its execution settings change. Adding a table does not create extra strategy executions.
  • Moving ta.rsi() or ta.atr() inside the last-bar condition would skip their historical evaluations. Restrict rendering, not the series calculations.
Latest-value dashboard with a working position input and Data Window checkspinescript
//@version=6
indicator("RSI and ATR table", overlay = true)
string panelPosition = input.string(position.top_right, "Table position", options = [position.top_right, position.top_left, position.bottom_right, position.bottom_left])
int length = input.int(14, "Length", minval = 1)
float rsiValue = ta.rsi(close, length)
float atrValue = ta.atr(length)
plot(rsiValue, "RSI check", display = display.data_window)
plot(atrValue, "ATR check", display = display.data_window)
var table panel = table.new(panelPosition, 2, 4, bgcolor = color.navy, border_width = 1, border_color = color.gray)

if barstate.islast
    string rsiText = na(rsiValue) ? "Waiting for data" : str.tostring(rsiValue, "#.0")
    string atrText = na(atrValue) ? "Waiting for data" : str.tostring(atrValue, format.mintick)
    string barText = barstate.isconfirmed ? "Closed" : "Developing"
    table.cell(panel, 0, 0, "Metric", text_color = color.white)
    table.cell(panel, 1, 0, "Latest value", text_color = color.white)
    table.cell(panel, 0, 1, "RSI", text_color = color.white)
    table.cell(panel, 1, 1, rsiText, text_color = color.white)
    table.cell(panel, 0, 2, "ATR (price units)", text_color = color.white)
    table.cell(panel, 1, 2, atrText, text_color = color.white)
    table.cell(panel, 0, 3, "Bar", text_color = color.white)
    table.cell(panel, 1, 3, barText, text_color = color.white)

Chart positions and the bottom panel are different controls

Use a position.* constant for an anchor within the chart pane. TradingView also lets users move a script's tables into the bottom panel through its More menu. This is a chart interface action, not an extra position constant.

  • Choose bottom_right in the dashboard input: the table should move to that corner. The input is passed directly into table.new().
  • To test the separate bottom panel, open More in the script status line and select Move tables to bottom. Select Move tables to chart to return.
  • position.bottom_right still means the lower-right corner of a pane. It does not open the bottom panel.
  • overlay = true places this indicator in the main chart pane. For a separate-pane script, table.new() can use force_overlay = true to place its table on the main chart.
  • Keep labels short and inspect both a narrow pane and the bottom panel. Automatic cell sizing in these examples avoids hard-coded percentage widths.

Diagnose the failure before changing the layout

Use the coordinate experiment to separate an indexing problem from a market-data problem. A grid that renders correctly does not prove an indicator calculation or a trading rule is correct.

SymptomCheckNext step
Nothing appearsHas any cell been populated? Was the whole grid cleared?Select None in the experiment; review the order of cell and clear calls.
Column or row out of boundsDimensions versus last indicesFor the experiment, keep columns below 3 and rows below 4.
Colors disappear after a text updateA new table.cell() call omitted stylingRepeat the desired styles or use table.cell_set_text().
Old list entries remainRows no longer used were never clearedClear the stale rows with explicit inclusive endpoints.
RSI or ATR shows Waiting for dataSeries values are naCheck available history and length; do not replace unavailable values with a trading signal.
Table differs from an older candleA latest-value table is being compared to historical dataUse the Data Window plots for historical checks.

Give the coding agent a testable table specification

Provide the current script, grid dimensions, allowed positions, each cell's data source, and when rows should be cleared. Ask Pineify's Pine Script AI Coding Agent to draft or revise the code, then check the result in TradingView.

  • Example request: Keep a 2-column, 4-row RSI/ATR panel. Calculate both series on every bar, render on the last bar, show unavailable data explicitly, and preserve the Data Window plots.
  • For a variable list, include a concrete transition such as three populated data rows becoming one. Specify which header and remaining row must survive.
  • Review syntax diagnostics and compare actual cells with expected coordinates. Syntax checking does not prove visual placement, data freshness, or trading performance.
Where Pineify fits

Pine Script AI Coding Agent

Ask Pineify to draft or revise a Pine Script table from your layout and update rules. Review the generated source and syntax diagnostics, then verify the cells and values in TradingView.

Draft a table with AI

Frequently asked questions

These examples explain display and calculation behavior. A table is not an order execution interface or proof of a profitable strategy. Check values, realtime updates, and layout in TradingView before relying on the output.

Sources and verification