Skip to main content

Graphs and Plots

VisiData renders graphs directly in your terminal using Unicode Braille characters — no GUI, no matplotlib, no external tools required. Graphs are interactive: you can zoom, pan, and drill into data points.

Learning Focus

Learn the two-step graph setup: mark key column (x-axis or category) → move to numeric columnpress . (dot). Then use canvas navigation to zoom and explore.

Creating a Graph

Single Numeric Column vs Key

# Step 1: Set the x-axis or category column
# Move to 'timestamp' or 'date' column
! # mark as key column

# Step 2: Move to the numeric column to plot
# Move to 'response_time' column

# Step 3: Plot
. # plot current numeric column vs key column(s)

The graph opens as a canvas sheet using Unicode Braille characters:

response_time vs timestamp

2000│ · ··
1500│ ·· · ·
1000│ ·· · · ··
500│
└─────────────────────────
2025-01-01 2025-01-31

All Numeric Columns

g. # plot ALL visible numeric columns vs key column(s)

Canvas Navigation

Inside the graph (canvas sheet):

KeyAction
+ / -Zoom in / out (centered on cursor)
_Zoom to fit all data
z_Set aspect ratio
h j k lPan the canvas
sSelect source rows under canvas cursor
tToggle selection
EnterOpen sheet of source rows in canvas cursor area
gEnterOpen source rows visible on screen
dDelete source rows in canvas cursor area
vToggle graph labels (legend/axes)
19Toggle display of individual plot layers
Ctrl+LRedraw all pixels
Mouse scrollZoom in/out

Coordinate Axis Control

# Set x-axis range
x
# Enter: xmin xmax (e.g., 0 100)

# Set y-axis range
y
# Enter: ymin ymax (e.g., 0 5000)

Graph Types by Data Shape

DataSetupResult
Time serieskey=timestamp, value=metricLine-like scatter
Category countskey=category, value=countBar-like distribution
Two numeric columnskey=x_col, value=y_colScatterplot
Frequency histogramOpen Frequency Table, then . on countHistogram bars

Practical Use Cases

Response Time Over Time (Nginx Log)

vd /var/log/nginx/access.log

# Move to 'time' column, cast to date: @
# Mark as key: !
# Move to 'response_time' column, cast to int: #
.
# Line-like scatter of response times over dates

Salary Distribution by Role

vd /tmp/employees.csv

# Open frequency table on 'role': Shift+F
# Inside frequency table:
# Move to 'count' column
.
# Bar chart: each role's count plotted

Server Load Over Time

vd /var/log/system_metrics.csv

# Mark 'timestamp' as key: !
# Move to 'cpu_percent' column: #
.
# Plot CPU load over time
# Then g. to overlay all numeric metrics

Histogram from Frequency Table

vd /var/log/nginx/access.log

# Move to 'status' column
Shift+F # frequency table with histogram column

# The histogram column is auto-rendered with █ characters
# Press . to get a canvas-based graph of the counts

Terminal Requirements

For best graph rendering:

  • Terminal supporting UTF-8 and 256 colors
  • Recommended: TERM=xterm-256color
  • Wide terminal (80+ columns, 40+ rows)
# Set terminal for best rendering
export TERM=xterm-256color
export LANG=en_US.UTF-8

Troubleshooting Matrix

ProblemCauseFix
Graph is empty / blankNo key column setPress ! on x-axis column first
Braille blocks look garbledTerminal doesn't support UTF-8export LANG=en_US.UTF-8
All points in one lineColumn type is stringCast numeric column to # or %
Graph too dense to readToo many data pointsFilter rows first, then plot
Colors missingTerminal not 256-colorexport TERM=xterm-256color

Best Practices

  • Use . (single column) for focused exploration; use g. for multi-column overlay comparisons.
  • Zoom into anomalies: use + to zoom in on a spike, then Enter to open the source rows causing it.
  • For time series, always cast the timestamp column to date type (@) before plotting for correct x-axis ordering.

Hands-On Practice

cat > /tmp/metrics.csv << 'EOF'
day,requests,errors,response_ms
2025-01-01,1200,5,230
2025-01-02,1350,8,245
2025-01-03,980,2,210
2025-01-04,1500,15,280
2025-01-05,1100,3,220
EOF

vd /tmp/metrics.csv

# 1. Move to 'day' column, press @ (date), press ! (key)
# 2. Move to 'requests' column, press # (int)
# 3. Press . → line graph of requests over time
# 4. Press + to zoom in
# 5. Press _ to fit all data
# 6. Press q → return to sheet
# 7. Press g. → overlay requests, errors, response_ms

What's Next