Charts functions in the Textplot DuckDB extension
Function category
Charts
3 functionsRender 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.
Signature
Arguments
| Argument | Type | Mode | Description |
|---|---|---|---|
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
Render a horizontal bar showing a numeric value as a fraction of a min/max range. Configurable width, shape (square/circle/heart), foreground/background colors, custom characters, and threshold-based coloring. Returns a VARCHAR you can drop into any SELECT.
SELECT tp_bar(0.5);
Output
| tp_bar(0.5) |
|---|
| 🟥🟥🟥🟥🟥⬜⬜⬜⬜⬜ |
SELECT tp_bar(75, min := 0, max := 100, width := 20);
Output
| tp_bar(75, min := 0, max := 100, width := 20) |
|---|
| 🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥⬜⬜⬜⬜⬜ |
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') |
|---|
| 🟢🟢🟢🟢🟢🟢🟢🟢⚪⚪ |
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'))) |
|---|
| 🟨🟨🟨🟨🟨🟨🟨🟨🟨⬜ |
SELECT tp_bar(0.7, "on" := '█', "off" := '░', width := 15);
Output
| tp_bar(0.7, "on" := '█', "off" := '░', width := 15) |
|---|
| ███████████░░░░ |
SELECT tp_bar(0.6, shape := 'heart', on_color := 'red');
Output
| tp_bar(0.6, shape := 'heart', on_color := 'red') |
|---|
| ❤️❤️❤️❤️❤️❤️🤍🤍🤍🤍 |
Related functions
- tp_density() — Render an array of numeric values as a density plot — a compact distribution visualization where the character intensity at each x-position reflects how many input values fall in that bin
- tp_sparkline() — Render an array of numeric values as a sparkline — a compact one-line trend chart
Signature
Arguments
| Argument | Type | Mode | Description |
|---|---|---|---|
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
Render an array of numeric values as a density plot — a compact distribution visualization where the character intensity at each x-position reflects how many input values fall in that bin. Multiple character-set styles, including ASCII for terminal compat and emoji for visual punch.
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)) |
|---|
| █ █ █ █ ▒ |
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') |
|---|
| █ █ ▄ |
SELECT tp_density([1, 5, 3, 8, 2], style := 'ascii');
Output
| tp_density(main.list_value(1, 5, 3, 8, 2), style := 'ascii') |
|---|
| @ @ @ @ @ |
SELECT tp_density([1, 5, 3, 8, 2], style := 'dots');
Output
| tp_density(main.list_value(1, 5, 3, 8, 2), style := 'dots') |
|---|
| ● ● ● ● ● |
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') |
|---|
| ⚪⚫⚪⚫⚫⚪⚫⚫⚫⚫⚫⚪⚫⚫⚫⚫⚫⚫⚫⚪ |
Signature
Arguments
| Argument | Type | Mode | Description |
|---|---|---|---|
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
Render an array of numeric values as a sparkline — a compact one-line trend chart. Three modes: absolute (height ∝ value), delta (direction of change), trend (direction with magnitude). Each mode has multiple themes: arrows, faces, slopes, hearts, and more.
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)) |
|---|
| ▃▃▂▂▂▆▆▅▅▅██▂▂▂ |
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') |
|---|
| ▂▂▂▂▂▂▅▅▅▅███▄▄▄ |
SELECT tp_sparkline([100, 105, 102, 108, 95], mode := 'delta');
Output
| tp_sparkline(main.list_value(100, 105, 102, 108, 95), "mode" := 'delta') |
|---|
| ↑↑↑↑↑↓↓↓↓↓↑↑↑↑↑↓↓↓↓↓ |
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') |
|---|
| 😊😊😊😊😊😐😐😐😐😐😊😊😊😊😊😞😞😞😞😞 |
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') |
|---|
| /////\\\\\/////\\\\\\\\\\ |
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') |
|---|
| +++++-----+++++---------- |