Plot Lines with Text in Pine Script: Complete Guide
To put text beside a Pine Script line, create a line and a label at matching price coordinates. They remain separate objects: moving one does not automatically move the other. Use setters to keep a current-price annotation synchronized, or create and delete paired objects when preserving historical signals.

Choose the right drawing tool
plot() displays a series over bars; conditional values, na, and plot styles control its visible segments. line.new() creates a segment between chosen coordinates and can extend it. label.new() supports dynamic text such as a formatted price. A line object itself does not have a text property.
For a fixed caption on every qualifying bar, plotshape() may be sufficient. For text that changes with each bar's values, use labels. Pine drawings are separate from manually drawn chart objects; a script cannot read a trend line you placed with the mouse.
A reusable current-price line and label
This complete indicator creates one pair of objects, then updates their coordinates and text on the last bar. Paste it into a new indicator, save, and add it to a chart:
//@version=6
indicator("Current Price Annotation", overlay=true, max_lines_count=1, max_labels_count=1)
var line priceLine = line.new(na, na, na, na, extend=extend.right, color=color.blue, width=2)
var label priceLabel = label.new(na, na, "", style=label.style_label_left, color=color.blue, textcolor=color.white)
if barstate.islast
line.set_xy1(priceLine, math.max(0, bar_index - 50), close)
line.set_xy2(priceLine, bar_index, close)
label.set_xy(priceLabel, bar_index, close)
label.set_text(priceLabel, "Price: " + str.tostring(close, format.mintick))
var preserves the IDs across bars. barstate.islast is true on the chart's final bar, including its realtime updates. Indicators normally execute on those updates; this example is not restricted to bar close. Strategies have different default execution timing. See TradingView's bar-state documentation.
Verify the result by changing symbols, zooming, and watching an open market. The label should match the latest available close at the symbol's tick precision. Its value can move while the realtime bar develops; that is intentional for a current-price display.
Position text without changing the measured price
The label's coordinates are its anchor. Its style controls the shape and where the text sits relative to that anchor. A label pointing upward typically places its body below the anchor; a downward-pointing label places it above. Preview the result rather than interpreting the style name as the text's absolute position.
Keep the line and label at the same y value when they describe the same price. Moving text a few bars sideways can reduce overlap without changing that value. Use format.mintick for prices instead of assuming every instrument has two decimal places.
Keep a bounded history of annotations
For historical support or crossover markers, create a pair only when the event qualifies. Store their IDs together and explicitly delete the oldest pair when your chosen retention count is exceeded. Merely storing IDs in an array does not delete anything.
TradingView defaults to displaying roughly the most recent 50 drawing objects of each relevant type, and allows up to 500 line IDs and 500 label IDs. Garbage collection removes older drawings when the configured limit is exceeded; it does not mean new labels silently stop appearing. Setting coordinates to na also does not remove the ID. Use line.delete() and label.delete() when an object is no longer needed. These limits are documented under lines and boxes and text and shapes.
A pivot confirmed several bars later can be drawn at its earlier pivot location, but the annotation was not available there in realtime. State the confirmation delay when using such drawings to explain a trading decision.
Use generated code as a starting point
Pineify can help draft an annotation script from a description of its anchors, labels, and retention rules. Inspect the generated conditions and test them on the chart. A compiling annotation does not establish that its marked level predicts future price movement.
Can a line object contain text?
Use a separate label at the same price coordinate. Update both objects when the price or location changes.
Does barstate.islast keep only one line automatically?
No. It identifies the final chart bar. Reuse persistent IDs with setters, or explicitly delete old objects; repeated creation can still accumulate objects across bars.
Why do old annotations disappear?
Check explicit deletion and the configured drawing limits. TradingView's garbage collector removes older objects once those limits are exceeded.


