Skip to content

Charts functions in the Textplot DuckDB extension

Function category

Charts

3 functions

Render numeric values and arrays as Unicode/ASCII charts directly in your query results — bars, sparklines, and density plots that fit in a single VARCHAR cell.

tp_bar

Scalar function Charts
Signature
tp_bar( value: DOUBLE, filled := BOOLEAN = true, max := DOUBLE = 1.0, min := DOUBLE = 0, off := VARCHAR, off_color := VARCHAR, on := VARCHAR, on_color := VARCHAR, shape := VARCHAR = 'square', thresholds := STRUCT(threshold DOUBLE, color VARCHAR)[], width := INTEGER = 10 ) VARCHAR
Arguments
Argument value Type DOUBLE Mode Positional Description Numeric value to visualize.
Argument min Type DOUBLE Mode Named Description Default: 0 Minimum of the value range.
Argument max Type DOUBLE Mode Named Description Default: 1.0 Maximum of the value range.
Argument width Type INTEGER Mode Named Description Default: 10 Bar width in characters.
Argument shape Type VARCHAR Mode Named Description Default: 'square' Block shape: 'square', 'circle', or 'heart'.
Argument on_color Type VARCHAR Mode Named Description Color name for filled portion (e.g. 'red', 'green', 'blue', 'yellow').
Argument off_color Type VARCHAR Mode Named Description Color name for unfilled portion.
Argument on Type VARCHAR Mode Named Description Custom character for filled portion. Must be quoted in SQL — "on" — because on is a reserved keyword.
Argument off Type VARCHAR Mode Named Description Custom character for unfilled portion. Must be quoted as "off".
Argument filled Type BOOLEAN Mode Named Description Default: true Fill all blocks up to the value (true) or just mark the endpoint (false).
Argument thresholds Type STRUCT(threshold DOUBLE, color VARCHAR)[] Mode Named Description List of (threshold, color) pairs for value-dependent coloring; each block uses the highest threshold ≤ value.
Description
1 Simple progress bar (50% filled)
SELECT tp_bar(0.5);

Output

tp_bar(0.5)
🟥🟥🟥🟥🟥⬜⬜⬜⬜⬜
2 Custom width and range — 75 out of 100
SELECT tp_bar(75, min := 0, max := 100, width := 20);

Output

tp_bar(75, min := 0, max := 100, width := 20)
🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥⬜⬜⬜⬜⬜
3 Circle shape with explicit colors
SELECT tp_bar(0.8, shape := 'circle', on_color := 'green', off_color := 'white');

Output

tp_bar(0.8, shape := 'circle', on_color := 'green', off_color := 'white')
🟢🟢🟢🟢🟢🟢🟢🟢⚪⚪
4 Threshold-based coloring (85 out of 100 → yellow zone)
SELECT tp_bar(85, min := 0, max := 100, thresholds := [{'threshold': 90, 'color': 'red'}, {'threshold': 70, 'color': 'yellow'}, {'threshold': 0, 'color': 'green'}]);

Output

tp_bar(85, min := 0, max := 100, thresholds := main.list_value(main.struct_pack(threshold := 90, color := 'red'), main.struct_pack(threshold := 70, color := 'yellow'), main.struct_pack(threshold := 0, color := 'green')))
🟨🟨🟨🟨🟨🟨🟨🟨🟨⬜
5 Custom characters ("on" and "off" must be quoted)
SELECT tp_bar(0.7, "on" := '█', "off" := '░', width := 15);

Output

tp_bar(0.7, "on" := '█', "off" := '░', width := 15)
███████████░░░░
6 Heart shape
SELECT tp_bar(0.6, shape := 'heart', on_color := 'red');

Output

tp_bar(0.6, shape := 'heart', on_color := 'red')
❤️❤️❤️❤️❤️❤️🤍🤍🤍🤍

tp_density

Scalar function Charts
Signature
tp_density( values: DOUBLE[], graph_chars := VARCHAR[], marker := VARCHAR, style := VARCHAR = 'shaded', width := INTEGER = 20 ) VARCHAR
Arguments
Argument values Type DOUBLE[] Mode Positional Description Array of numeric values to plot the distribution of.
Argument width Type INTEGER Mode Named Description Default: 20 Plot width in characters.
Argument style Type VARCHAR Mode Named Description Default: 'shaded' Character-set style: 'shaded' (default ░▒▓█), 'ascii' ( .:+#@), 'dots' ( .•●), 'height' ( ▁▂▃▄▅▆▇█), 'circles' (⚫⚪🟡🟠🔴), 'safety', 'rainbow_circle' (⚫🟤🟣🔵🟢🟡🟠🔴⚪), 'rainbow_square', 'moon', 'sparse', or 'white'.
Argument graph_chars Type VARCHAR[] Mode Named Description Custom array of characters for density levels — overrides style.
Argument marker Type VARCHAR Mode Named Description Character used to highlight specific values inside the plot.
Description
1 Default shaded style
SELECT tp_density([1, 2, 3, 4, 5, 4, 3, 2, 1]);

Output

tp_density(main.list_value(1, 2, 3, 4, 5, 4, 3, 2, 1))
█ █ █ █ ▒
2 Wide height-style plot
SELECT tp_density([1, 2, 3, 2, 1], width := 30, style := 'height');

Output

tp_density(main.list_value(1, 2, 3, 2, 1), width := 30, style := 'height')
█ █ ▄
3 ASCII style for terminals without Unicode
SELECT tp_density([1, 5, 3, 8, 2], style := 'ascii');

Output

tp_density(main.list_value(1, 5, 3, 8, 2), style := 'ascii')
@ @ @ @ @
4 Dot style for subtle visualization
SELECT tp_density([1, 5, 3, 8, 2], style := 'dots');

Output

tp_density(main.list_value(1, 5, 3, 8, 2), style := 'dots')
● ● ● ● ●
5 Rainbow emoji style
SELECT tp_density([1, 5, 3, 8, 2], style := 'rainbow_circle');

Output

tp_density(main.list_value(1, 5, 3, 8, 2), style := 'rainbow_circle')
⚪⚫⚪⚫⚫⚪⚫⚫⚫⚫⚫⚪⚫⚫⚫⚫⚫⚫⚫⚪

tp_sparkline

Scalar function Charts
Signature
tp_sparkline( values: DOUBLE[], mode := VARCHAR = 'absolute', theme := VARCHAR, width := INTEGER = 20 ) VARCHAR
Arguments
Argument values Type DOUBLE[] Mode Positional Description Array of numeric values, ordered (typically by time).
Argument mode Type VARCHAR Mode Named Description Default: 'absolute' Visualization mode: 'absolute' (height ∝ value), 'delta' (up/same/down), or 'trend' (signed magnitude).
Argument theme Type VARCHAR Mode Named Description Character-set theme. Options vary by mode — absolute: utf8_blocks, ascii_basic, hearts, faces. delta: arrows, triangles, ascii_arrows, math, faces, thumbs, trends, simple. trend: arrows, ascii, slopes, intensity, faces, chart.
Argument width Type INTEGER Mode Named Description Default: 20 Sparkline width in characters.
Description
1 Absolute mode (default)
SELECT tp_sparkline([1, 3, 2, 5, 4, 6, 2, 1]);

Output

tp_sparkline(main.list_value(1, 3, 2, 5, 4, 6, 2, 1))
▃▃▂▂▂▆▆▅▅▅██▂▂▂
2 Stock prices with explicit theme and width
SELECT tp_sparkline([45.2, 47.1, 46.8, 49.3, 52.1, 48.7], width := 20, theme := 'utf8_blocks');

Output

tp_sparkline(main.list_value(45.2, 47.1, 46.8, 49.3, 52.1, 48.7), width := 20, theme := 'utf8_blocks')
▂▂▂▂▂▂▅▅▅▅███▄▄▄
3 Delta mode with arrow theme
SELECT tp_sparkline([100, 105, 102, 108, 95], mode := 'delta');

Output

tp_sparkline(main.list_value(100, 105, 102, 108, 95), "mode" := 'delta')
↑↑↑↑↑↓↓↓↓↓↑↑↑↑↑↓↓↓↓↓
4 Delta mode with face theme
SELECT tp_sparkline([72, 75, 75, 78, 71], mode := 'delta', theme := 'faces');

Output

tp_sparkline(main.list_value(72, 75, 75, 78, 71), "mode" := 'delta', theme := 'faces')
😊😊😊😊😊😐😐😐😐😐😊😊😊😊😊😞😞😞😞😞
5 Trend mode with slope theme
SELECT tp_sparkline([10, 12, 11, 15, 8], mode := 'trend', theme := 'slopes');

Output

tp_sparkline(main.list_value(10, 12, 11, 15, 8), "mode" := 'trend', theme := 'slopes')
/////\\\\\/////\\\\\\\\\\
6 Trend mode with intensity theme
SELECT tp_sparkline([100, 110, 105, 125, 90], mode := 'trend', theme := 'intensity');

Output

tp_sparkline(main.list_value(100, 110, 105, 125, 90), "mode" := 'trend', theme := 'intensity')
+++++-----+++++----------