Plotting

Lines, histograms with per-bar colors, fills, hlines, and shape markers.

plot

plot(series, name, color?, linewidth?, plot_type?, opacity?, colors?, align?, width_px?)

Draw a data series on the chart.

Draws a line, histogram, area, or step line from a pandas Series. Each plot() call creates a named series visible in the chart legend.

For per-bar coloring (e.g. yellow for block trades, gray for normal), pass a colors= array the same length as series. Per-bar colors are only valid for HISTOGRAM, COLUMNS, CROSS, CIRCLES. Lines, areas, and step lines stay single-color.

align= reshapes the geometry instead of laying bars along the time axis:

  • pinned_top / pinned_bottom - horizontal strip glued to chart top/bottom (volume-pane layout). Bars time-align to candles via timeToCoordinate; height proportional to value normalized to visible range.
  • pinned_left / pinned_right - vertical strip glued to chart left/right edge (HUD layout). Anchored to the price axis.
  • left_of_range / right_of_range - anchored to the first/last visible bar.
  • over_range - stretches across the visible range.

Pair with width_px= to control the pinned strip width (left/right) or thickness (top/bottom).

Parameters

  • series (Series, default required): pandas Series of values to plot
  • name (str, default required): Legend label (must be unique per indicator)
  • color (str, default "#2962FF"): Hex color string (fallback when colors[i] is None). Accepts 6-char #rrggbb or 8-char #rrggbbaa.
  • linewidth (int, default 2): Line thickness in pixels
  • plot_type (PlotType, default LINE): LINE, HISTOGRAM, COLUMNS, CROSS, CIRCLES, AREA, or STEPLINE
  • opacity (int, default 100): Opacity 0-100 for area fills
  • colors (list[str | None], default None): Per-bar color override array. Same length as series. None entries fall back to color. HISTOGRAM/COLUMNS/CROSS/CIRCLES only.
  • align (str, default None): pinned_top, pinned_bottom, pinned_left, pinned_right, left_of_range, right_of_range, or over_range. HISTOGRAM/COLUMNS/AREA only.
  • width_px (int, default 60): CSS pixels for the pinned region. Strip width for pinned_left/pinned_right; strip thickness for pinned_top/pinned_bottom.

Returns

None

Example

sma = close.rolling(20).mean()
plot(sma, "SMA(20)", color="#2962FF", linewidth=2)

# Per-bar histogram coloring: yellow on big trades, gray otherwise
import numpy as np
big = volume > volume.rolling(50).mean() * 3
colors = np.where(big, "#e0af68", "#3a3a45").tolist()
plot(volume, "Volume", color="#3a3a45", plot_type=PlotType.HISTOGRAM, colors=colors)

Notes

  • colors= is the per-bar override. Pass a list of hex strings or None (None falls back to color).
  • Convenience helpers: plot_histogram_colored, plot_columns_colored, plot_cross_colored, plot_circles_colored.
  • Mismatched length between colors and series raises ValueError.
  • plot() has no style or linestyle parameter (this is not Pine Script). Use plot_type for line shape; linestyle exists only on hline. Passing style= or linestyle= to plot() raises a TypeError.

plot_histogram_colored

plot_histogram_colored(series, name, base_color, colors)

Histogram with per-bar color overrides.

Convenience wrapper for plot(..., plot_type=HISTOGRAM, colors=...). Same shape as the Rust plot_histogram_colored builder.

Parameters

  • series (Series, default required): Values to plot
  • name (str, default required): Legend label
  • base_color (str, default required): Fallback color for bars where colors[i] is None
  • colors (list[str | None], default required): Per-bar color overrides

Returns

None

Example

from quant_charts import plot_histogram_colored
colors = ["#e0af68" if x > thresh else None for x in trade_size]
plot_histogram_colored(trade_size, "Trade Size", "#3a3a45", colors)

hline

hline(value, name, color?, linewidth?, linestyle?)

Draw a horizontal reference line at a fixed value.

Draws a horizontal line at a constant Y-axis value. Common for overbought/oversold levels in oscillators.

Parameters

  • value (float, default required): Y-axis value
  • name (str, default required): Legend label
  • color (str, default "#787B86"): Hex color string
  • linewidth (int, default 1): Line thickness in pixels
  • linestyle (str, default "solid"): "solid", "dashed", or "dotted"

Returns

None

Example

hline(70, "Overbought", color="#EF5350", linestyle="dashed")
hline(30, "Oversold", color="#26A69A", linestyle="dashed")

fill

fill(series1_name, series2_name, color?, opacity?)

Fill the area between two plotted series.

Fills the space between two previously plotted series. Both must have been drawn with plot() first, referenced by their name string.

Parameters

  • series1_name (str, default required): Name of the first plot() series
  • series2_name (str, default required): Name of the second plot() series
  • color (str, default "#2962FF"): Fill color as hex string
  • opacity (int, default 10): Fill opacity 0-100

Returns

None

Example

plot(upper, "Upper", color="#2962FF")
plot(lower, "Lower", color="#2962FF")
fill("Upper", "Lower", color="#2962FF", opacity=10)

vp_visual

vp_visual(anchor_ts, end_ts, price_min, price_step, bins, poc_price, vah, val, ...)

Emit a horizontal volume profile histogram (POC + value area).

Pure-Python parity with the Rust push_vp_visual(...) builder. The renderer draws bars at each price row, an accent line at the Point of Control, and the Value Area High / Low as a translucent zone.

anchor_ts and end_ts are Unix milliseconds (the executor converts to seconds for Lightweight Charts). bins[i] is the volume in the price row starting at price_min + i * price_step. align defaults to right_of_range; pass pinned_right to glue to the chart edge regardless of pan.

Progressive trails (poc_trail, value_area_trail) draw a moving POC/VA line across each session anchor instead of a single static profile.

Parameters

  • anchor_ts (int, default required): Anchor timestamp (Unix ms). Where the histogram baseline starts.
  • end_ts (int, default required): End timestamp (Unix ms).
  • price_min (float, default required): Lower edge of the lowest bin.
  • price_step (float, default required): Row height in price units. Must be > 0.
  • bins (list[float], default required): Volume per row, length = number of rows.
  • poc_price (float, default required): Point of Control (highest-volume row center).
  • vah (float, default required): Value Area High.
  • val (float, default required): Value Area Low.
  • color (str, default "#7aa2f7"): Bar color (overridden per-bin by bin_colors[i]).
  • poc_color (str, default "#e0af68"): POC accent line color.
  • value_area_color (str, default "#73daca"): Value-area zone color.
  • opacity (int, default 60): Bar opacity 0-100.
  • width_px (int, default 80): Histogram width in CSS pixels.
  • align (str, default "right_of_range"): right_of_range, left_of_range, over_range, pinned_right, pinned_left, pinned_top, pinned_bottom.
  • style (str, default "bars"): bars, line, or area.
  • bin_colors (list[str | None], default None): Per-row color override (same length as bins).
  • hvn_levels (list[float], default None): High-volume node prices (drawn as bright lines).
  • lvn_levels (list[float], default None): Low-volume node prices.
  • poc_trail (list[dict], default None): List of {ts: ms, price: float} for a moving POC line.
  • value_area_trail (list[dict], default None): List of {ts: ms, vah: float, val: float} for VA bands.
  • draw_level_lines (bool, default True): Draw POC/VAH/VAL horizontal lines across the range.

Returns

None

Example

from quant_charts import vp_visual
import numpy as np

# bin all session ticks into 0.25 price rows
bins = np.histogram(typical, range=(lo, hi), bins=int((hi-lo)/0.25))[0]
poc_idx = int(np.argmax(bins))
poc_price = lo + (poc_idx + 0.5) * 0.25

vp_visual(
    anchor_ts=int(ts[0]), end_ts=int(ts[-1]),
    price_min=lo, price_step=0.25,
    bins=bins.tolist(),
    poc_price=poc_price, vah=poc_price + 4.0, val=poc_price - 4.0,
    width_px=80, opacity=55,
    align="right_of_range",
)

Notes

  • Timestamps are Unix MILLISECONDS; the executor converts to seconds.
  • opacity is rejected if outside 0-100. NaN/Inf in any price field is rejected.
  • align validates against the five known values; unknown strings raise.
  • Calling vp_visual() multiple times in one calculate() emits multiple histograms (one per anchor).