chart.point Methods
ctx object namespaces for chart points — ctx.line, ctx.label, ctx.box, ctx.polyline when the visual is an object with endpoints or bounds.
ctx Object Namespaces: When the Visual Is an Object#
Choose object namespaces when you need endpoints, bounds, labels, or shapes that are not naturally
represented as one value per row. The object still has to come from prepared data; only the object
assembly happens inside build_visuals.
Available ctx object namespaces#
| Namespace | Use for |
|---|---|
ctx.line.new(...) | Line segment between two chart points (x1/y1 → x2/y2). |
ctx.label.new(...) | Text label anchored to a chart point with configurable style. |
ctx.box.new(...) | Rectangle defined by top-left and bottom-right chart points. |
ctx.polyline.new(...) | Multi-segment path through an array of chart points. |
ctx.table.new(...) | Managed table widget with rows, columns, and cell text. |
chart.point coordinate convention#
All ctx.* objects accept x as a bar index (integer from the index column) and y as a price float.
Always cast coordinates explicitly:
ctx.label.new(
key="signal_label",
x=int(last["index"]),
y=float(last["low"]),
text="BUY",
color="#2962ff",
style="label_down",
)Rule: prepare coordinates in the frame, assemble objects in build_visuals#
# build_indicator_frame — prepare anchor columns
frame["signal_low"] = np.where(frame["buy_signal"], frame["low"], np.nan)
# build_visuals — assemble object from prepared data only
def build_visuals(frame, params=None, ctx=None):
last = frame.iloc[-1]
if not np.isnan(last.get("signal_low", float("nan"))):
return ctx.label.new(
key="buy_label",
x=int(last["index"]),
y=float(last["signal_low"]),
text="BUY",
)
return None