Textplot DuckDB Extension
The Textplot extension, brings text-based data visualization directly to your SQL queries in DuckDB. Create stunning ASCII/Unicode charts, bar graphs, and density plots without leaving your database environment.
Use Cases
The Textplot extension is perfect for:
- Quick data exploration: Visualize distributions and trends directly in your terminal
- Dashboard creation: Add visual elements to text-based reports and dashboards
- Monitoring and alerting: Create visual indicators for system metrics and KPIs
- Data quality checks: Spot outliers and patterns in your data instantly
- Command-line analytics: Build beautiful charts for CLI tools and scripts
- Documentation: Include visual data summaries in README files and documentation
- Embedded analytics: Add lightweight visualizations to applications without heavy charting libraries
Installation
textplot
is a DuckDB Community Extension.
You can now use this by using this SQL:
from community;
install textplot load textplot
Functions
tp_bar(value, ...options)
Creates horizontal bar charts with customizable styling and colors.
Basic Usage:
-- Simple progress bar (50% filled)
SELECT tp_bar(0.5);
ββββββββββββββββββββββββ0.5) β
β tp_bar(varchar β
β
ββββββββββββββββββββββββ€
β π₯π₯π₯π₯π₯β¬β¬β¬β¬β¬ β
ββββββββββββββββββββββββ
-- Custom width and range
SELECT tp_bar(75, min := 0, max := 100, width := 20);
βββββββββββββββββββββββββββββββββββββββββββββββββ75, min := 0, max := 100, width := 20) β
β tp_bar(varchar β
β
βββββββββββββββββββββββββββββββββββββββββββββββββ€
β π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯π₯β¬β¬β¬β¬β¬ β βββββββββββββββββββββββββββββββββββββββββββββββββ
Advanced Options:
-- Custom colors and shapes
SELECT tp_bar(0.8, shape := 'circle', on_color := 'green', off_color := 'white') as bar;
ββββββββββββββββββββββββ
β bar βvarchar β
β
ββββββββββββββββββββββββ€
β π’π’π’π’π’π’π’π’βͺβͺ β
ββββββββββββββββββββββββ
-- Threshold-based coloring
SELECT tp_bar(85,
min := 0, max := 100,
:= [
thresholds 'threshold': 90, 'color': 'red'},
{'threshold': 70, 'color': 'yellow'},
{'threshold': 0, 'color': 'green'}
{
]as bar;
)
ββββββββββββββββββββββββ
β bar βvarchar β
β
ββββββββββββββββββββββββ€
β π¨π¨π¨π¨π¨π¨π¨π¨π¨β¬ β
ββββββββββββββββββββββββ
-- Custom characters
SELECT tp_bar(0.7, on := 'β', off := 'β', width := 15) as bar;
βββββββββββββββββββ
β bar βvarchar β
β
βββββββββββββββββββ€
β βββββββββββββββ β
βββββββββββββββββββ
SELECT round(n,4),
tp_bar(n,:= 14,
width := 'circle',
shape :='black',
off_color := false,
filled := [
thresholds 0.8, 'red'),
(0.7, 'orange'),
(0.6, 'yellow'),
(0.0, 'green')
(as bar
]) FROM (select random() as n from generate_series(10));
βββββββββββββββ¬βββββββββββββββββββββββββββββββround(n, 4) β bar β
β double β varchar β
β
βββββββββββββββΌβββββββββββββββββββββββββββββββ€0.9889 β β«β«β«β«β«β«β«β«β«β«β«β«β«π΄ β
β 0.6242 β β«β«β«β«β«β«β«β«π‘β«β«β«β«β« β
β 0.6013 β β«β«β«β«β«β«β«π‘β«β«β«β«β«β« β
β 0.669 β β«β«β«β«β«β«β«β«π‘β«β«β«β«β« β
β 0.8363 β β«β«β«β«β«β«β«β«β«β«β«π΄β«β« β
β 0.9193 β β«β«β«β«β«β«β«β«β«β«β«β«π΄β« β
β 0.8629 β β«β«β«β«β«β«β«β«β«β«β«π΄β«β« β
β 0.8296 β β«β«β«β«β«β«β«β«β«β«β«π΄β«β« β
β 0.0824 β π’β«β«β«β«β«β«β«β«β«β«β«β«β« β
β 0.0281 β β«β«β«β«β«β«β«β«β«β«β«β«β«β« β
β 0.2682 β β«β«β«π’β«β«β«β«β«β«β«β«β«β« β
β
βββββββββββββββ΄βββββββββββββββββββββββββββββββ€11 rows 2 columns β
β
ββββββββββββββββββββββββββββββββββββββββββββββ
SELECT round(n,4),
tp_bar(n,:= 14,
width := 'circle',
shape :='black',
off_color := true,
filled := [
thresholds 0.8, 'red'),
(0.7, 'orange'),
(0.6, 'yellow'),
(0.0, 'green')
(as bar
]) FROM (select random() as n from generate_series(10));
βββββββββββββββ¬βββββββββββββββββββββββββββββββround(n, 4) β bar β
β double β varchar β
β
βββββββββββββββΌβββββββββββββββββββββββββββββββ€0.3818 β π’π’π’π’π’β«β«β«β«β«β«β«β«β« β
β 0.1919 β π’π’π’β«β«β«β«β«β«β«β«β«β«β« β
β 0.5885 β π’π’π’π’π’π’π’π’β«β«β«β«β«β« β
β 0.9558 β π΄π΄π΄π΄π΄π΄π΄π΄π΄π΄π΄π΄π΄β« β
β 0.4463 β π’π’π’π’π’π’β«β«β«β«β«β«β«β« β
β 0.6024 β π‘π‘π‘π‘π‘π‘π‘π‘β«β«β«β«β«β« β
β 0.0114 β β«β«β«β«β«β«β«β«β«β«β«β«β«β« β
β 0.4993 β π’π’π’π’π’π’π’β«β«β«β«β«β«β« β
β 0.6884 β π‘π‘π‘π‘π‘π‘π‘π‘π‘π‘β«β«β«β« β
β 0.7929 β π π π π π π π π π π π β«β«β« β
β 0.3507 β π’π’π’π’π’β«β«β«β«β«β«β«β«β« β
β
βββββββββββββββ΄βββββββββββββββββββββββββββββββ€11 rows 2 columns β
β ββββββββββββββββββββββββββββββββββββββββββββββ
Parameters:
value
: Numeric value to visualizemin
: Minimum value (default: 0)max
: Maximum value (default: 1.0)width
: Bar width in characters (default: 10)shape
: βsquareβ, βcircleβ, or βheartβ (default: βsquareβ)on_color
/off_color
: Color names (red, green, blue, yellow, etc.)on
/off
: Custom characters for filled/empty portionsfilled
: Boolean, fill all blocks or just the endpoint (default: true)thresholds
: List of threshold objects for conditional coloring
tp_density(values, ...options)
Creates density plots and histograms from arrays of numeric data.
Basic Usage:
-- Simple density plot
SELECT tp_density([1, 2, 3, 4, 5, 4, 3, 2, 1]) as density;
ββββββββββββββββββββββββ
β density βvarchar β
β
ββββββββββββββββββββββββ€
β β β β β β β
ββββββββββββββββββββββββ
-- Custom width and style
SELECT tp_density([1, 2, 3, 2, 1], width := 30, style := 'height') as density;
ββββββββββββββββββββββββββββββββββ
β density βvarchar β
β
ββββββββββββββββββββββββββββββββββ€
β β β β β ββββββββββββββββββββββββββββββββββ
Style Options:
-- ASCII style for compatibility
SELECT tp_density([1, 5, 3, 8, 2], style := 'ascii') as density;
ββββββββββββββββββββββββ
β density βvarchar β
β
ββββββββββββββββββββββββ€
β @ @ @ @ @ β
ββββββββββββββββββββββββ
-- Dot style for subtle visualization
SELECT tp_density([1, 5, 3, 8, 2], style := 'dots') as density;
ββββββββββββββββββββββββ
β density βvarchar β
β
ββββββββββββββββββββββββ€
β β β β β β β
ββββββββββββββββββββββββ
-- Colorful emoji styles
SELECT tp_density([1, 5, 3, 8, 2], style := 'rainbow_circle') as density;
ββββββββββββββββββββββββββββββββββββββββββββ
β density βvarchar β
β
ββββββββββββββββββββββββββββββββββββββββββββ€
β βͺβ«βͺβ«β«βͺβ«β«β«β«β«βͺβ«β«β«β«β«β«β«βͺ β ββββββββββββββββββββββββββββββββββββββββββββ
Parameters:
values
: Array of numeric valueswidth
: Plot width in characters (default: 20)style
: Character set style (βshadedβ, βasciiβ, βdotsβ, βheightβ, βcirclesβ, βsafetyβ, βrainbow_circleβ, βrainbow_squareβ, βmoonβ, βsparseβ, βwhiteβ)graph_chars
: Custom array of characters for density levelsmarker
: Character to highlight specific values
Available Styles:
shaded
:ββββ
(default)ascii
:.:+#@
dots
:.β’β
height
:βββββ βββ
circles
:β«βͺπ‘π π΄
rainbow_circle
:β«π€π£π΅π’π‘π π΄βͺ
tp_sparkline(values, ...options)
Creates compact sparkline charts perfect for showing trends in time series data and small multiples.
Basic Usage:
-- Simple absolute value sparkline
SELECT tp_sparkline([1, 3, 2, 5, 4, 6, 2, 1]) as sparkline;
ββββββββββββββββββββββββ
β sparkline βvarchar β
β
ββββββββββββββββββββββββ€==---##***@@--- β
β
ββββββββββββββββββββββββ
-- Delta mode showing change direction
SELECT tp_sparkline([100, 105, 102, 108, 95], mode := 'delta') as sparkline;
ββββββββββββββββββββββββ
β sparkline βvarchar β
β
ββββββββββββββββββββββββ€
β ββββββββββββββββββββ β
ββββββββββββββββββββββββ
-- Trend mode with magnitude
SELECT tp_sparkline([10, 12, 11, 15, 8], mode := 'trend', theme := 'slopes') as sparkline;
βββββββββββββββββββββββββββββ
β sparkline βvarchar β
β
βββββββββββββββββββββββββββββ€/////\\\\\/////\\\\\\\\\\ β
β βββββββββββββββββββββββββββββ
Visualization Modes:
1. Absolute Mode (default) - Shows actual values as heights:
-- Stock prices over time
SELECT tp_sparkline([45.2, 47.1, 46.8, 49.3, 52.1, 48.7], width := 20, theme := 'utf8_blocks') as sparkline;
ββββββββββββββββββββββββ
β sparkline βvarchar β
β
ββββββββββββββββββββββββ€
β βββββββ
β
β
β
ββββββ β
ββββββββββββββββββββββββ
-- System CPU usage
SELECT tp_sparkline([25, 45, 78, 92, 67, 34], theme := 'ascii_basic', width := 15) as sparkline;
βββββββββββββββββββ
β sparkline βvarchar β
β
βββββββββββββββββββ€--###@@***.. β
β βββββββββββββββββββ
2. Delta Mode - Shows direction of change (up/same/down):
-- Sales trend directions
SELECT tp_sparkline([1000, 1200, 1150, 1300, 980], mode := 'delta', theme := 'arrows') as sparkline;
ββββββββββββββββββββββββ
β sparkline βvarchar β
β
ββββββββββββββββββββββββ€
β ββββββββββββββββββββ β
ββββββββββββββββββββββββ
-- Temperature changes
SELECT tp_sparkline([72, 75, 75, 78, 71], mode := 'delta', theme := 'faces') as sparkline;
ββββββββββββββββββββββββββββββββββββββββββββ
β sparkline βvarchar β
β
ββββββββββββββββββββββββββββββββββββββββββββ€
β ππππππππππππππππππππ β ββββββββββββββββββββββββββββββββββββββββββββ
3. Trend Mode - Shows change direction with magnitude:
-- Market volatility
SELECT tp_sparkline([100, 110, 105, 125, 90], mode := 'trend', theme := 'intensity') as sparkline;
βββββββββββββββββββββββββββββ
β sparkline βvarchar β
β
βββββββββββββββββββββββββββββ€+++++-----+++++---------- β
β
βββββββββββββββββββββββββββββ
-- Server response times
SELECT tp_sparkline([150, 145, 147, 180, 120], mode := 'trend', theme := 'arrows') as sparkline;
ββββββββββββββββββββββββ
β sparkline βvarchar β
β
ββββββββββββββββββββββββ€
β ββββββββββββββββ©β©β©β©β© β ββββββββββββββββββββββββ
Available Themes by Mode:
Absolute Mode Themes:
utf8_blocks
:βββββ βββ
(default)ascii_basic
:.-=+*#%@
hearts
:π€π€β€οΈπππππ€
faces
:πππππππ€©π€―
Delta Mode Themes:
arrows
:βββ
(default)triangles
:βΌββ²
ascii_arrows
:v-^
math
:-=+
faces
:πππ
thumbs
:πππ
trends
:πβ‘οΈπ
simple
:\\_/
Trend Mode Themes:
arrows
:β©ββββ§
(default)ascii
:Vv-^A
slopes
:\\\\ \\ _ / //
intensity
:-- - = + ++
faces
:πππππ€©
chart
:ππβ‘οΈππ
Parameters:
values
: Array of numeric valuesmode
: βabsoluteβ, βdeltaβ, or βtrendβ (default: βabsoluteβ)theme
: Theme name (varies by mode, see lists above)width
: Sparkline width in characters (default: 20)
Tips and Best Practices
- Choose appropriate widths: Longer bars (width 20-30) work well for dashboards, shorter bars (width 10-15) for compact reports
- Use thresholds for status indicators: Perfect for showing health, performance, or risk levels
- Combine with regular metrics: Text plots complement, donβt replace, numeric values
- Consider your audience: ASCII styles work everywhere, emoji styles are more visually appealing but require Unicode support
- Leverage density plots for distributions: Great for showing data patterns, outliers, and distributions
Contributing
The Textplot extension is open source and developed by Query.Farm. Contributions are welcome!
License
Love β€οΈ this DuckDB extension? Youβll Love This.
Get the best from Query.Farm β smart tips, powerful tools, and project updates sent directly to your inbox, but only when weβve got something great to share.