Charts¶
rs_rich.chart is rich_ext::chart from Python: charts drawn with text.
Rich has no counterpart. Every chart is a renderable, so it prints, sits in a
Table cell or a Panel, and updates in a Live display. None writes a line
wider than the width it gets: at small widths it drops labels, values and
axes before it drops data. None needs colour to be read: lengths and heights
carry the values, numbers are written out, and series have their own
markers.
| Class | Draws |
|---|---|
Sparkline |
one line, one cell per value (two in Braille) |
BarChart, ChartBar |
a label, a bar and a value per row, or columns side by side |
Histogram |
raw values counted into bins, drawn as bars |
LineChart, Series |
one or more series as lines or points, with axes and a legend |
Gauge, Band, BulletChart |
a value against a range, with a target and threshold bands; several aligned |
Heatmap |
a labelled grid of values as shades, with a legend |
StatusMatrix, ChartState |
rows and columns of states (pass, fail, skip, flaky, your own) |
KpiCard |
a label, a value, a delta, a sparkline and a status |
Timeline, TimelineSpan |
labelled ranges on a scale, overlaps stacked, milestones |
Settings are keyword arguments. Three are shared:
charset:"auto"(the chart's natural glyphs: blocks, or Braille for line charts),"blocks","braille"or"ascii". A console that is not UTF-8 always gets ASCII.format: how values are written:"compact"(1.2k,3.4M; the default) or a number of decimals from 0 to 17 (another number raisesValueError).chart_format(value, format)writes one.Nonein a list of values is a gap: it is skipped, never drawn as zero.- Arguments that take several items (
gauges,bands,columns,states,milestones, a matrix row's state names) take any iterable, such as a list, a tuple or a generator, but not a string.
ChartBar, ChartState and TimelineSpan are also exported as Bar,
State and Span, their Rust names. Styles come from the theme keys in
chart.STYLES (chart.bar, chart.series.1, ...).
From the shell, rich chart draws the same charts from CSV, JSON or stdin
(rich chart).
The Rust charts guide
has a screenshot of each chart.
Sparklines, bars and histograms¶
Sparkline(values, *, range=None, min=None, max=None, charset="auto", style=None,
min_max=False, threshold=None, format=None)
BarChart(bars=None, *, range=None, max=None, charset="auto", orientation="horizontal",
bar_width=None, show_values=True, format=None, style=None)
Histogram(values, *, bins=None, range=None, charset="auto", orientation="horizontal",
bar_width=None, show_values=True, style=None)
bars is (label, value) pairs, a {label: value} mapping, or ChartBars
(ChartBar(label, value, *, style=None), to style one bar). min_max names
a sparkline's extremes after it, and threshold counts the values above
it. Histogram.counts() and Histogram.edges() give the bins.
from rs_rich.console import Console
from rs_rich import chart
console = Console(width=40, color_system=None)
console.print(chart.Sparkline([12, 15, 14, 18, 25, 31, 28, 22, 35, 41]))
console.print(chart.Sparkline([12, 15, 14, 18, 25, 31, 28, 22, 35, 41], min_max=True, threshold=30))
console.print(chart.BarChart({"api": 412, "web": 268.5, "worker": 97}, bar_width=20))
console.print(chart.Histogram([12, 14, 15, 21, 22, 23, 24, 38], bins=3, range=(10, 40), bar_width=8))
▁▂▁▂▄▆▅▃▇█
▁▂▁▂▄▆▅▃▇█ min 12 max 41 3 > 30
api ████████████████████ 412
web █████████████ 268.5
worker ████▊ 97
[10, 20) ██████ 3
[20, 30) ████████ 4
[30, 40] ██ 1
Line and scatter charts¶
Series(name, points, *, kind="line", style=None, marker=None)
LineChart(series=None, *, height=None, width=None, x_range=None, y_range=None,
charset="auto", legend=True, x_format=None, y_format=None)
points is (x, y) pairs (tuples, lists or any other sequence of two), or
plain numbers at x = 0, 1, 2, ... kind is
"line" or "scatter". In Braille each cell holds 2×4 points; in ASCII the
chart plots with markers at cell resolution.
load = chart.Series("load", [1, 3, 2, 5, 4])
console.print(chart.LineChart([load], height=6, charset="ascii"), width=24)
Gauges and bullet charts¶
Band(upto, label, *, style=None)
Gauge(label, value, *, range=None, target=None, bands=None, charset="auto",
bar_width=None, full_width=False, format=None, unit=None, style=None)
BulletChart(gauges=None, *, bar_width=None, full_width=False, charset="auto")
A band covers the values up to upto; the gauge names the one its value is
in (Gauge.band).
bands = [chart.Band(60, "ok"), chart.Band(85, "high"), chart.Band(100, "critical")]
cpu = chart.Gauge("cpu", 72, range=(0, 100), target=80, bands=bands, unit="%", bar_width=20)
console.print(cpu)
print(cpu.band)
console.print(chart.BulletChart([
chart.Gauge("revenue", 270, range=(0, 300), target=250),
chart.Gauge("profit", 22.5, range=(0, 30), target=26),
], bar_width=12))
Heatmaps and status matrices¶
Heatmap(rows=None, *, columns=None, range=None, charset="auto", cell_width=None,
legend=True, format=None)
ChartState(name, symbol, ascii, style)
StatusMatrix(rows=None, *, columns=None, states=None, legend=True, charset="auto")
Rows are (label, values) pairs or a {label: values} mapping. A matrix's
values are state names: pass, fail, skip, flaky, or a ChartState
you add with states=. StatusMatrix.counts() counts each state.
console.print(chart.Heatmap(
{"api": [1, 4, 9, 2], "web": [0, 6, 8, None]},
columns=["mon", "tue", "wed", "thu"],
cell_width=4,
charset="ascii",
))
blocked = chart.ChartState("blocked", "⊘", "#", "bold magenta")
console.print(chart.StatusMatrix(
{"unit": ["pass", "pass", "fail"], "e2e": ["pass", "blocked", "skip"]},
columns=["linux", "macos", "win"],
states=[blocked],
))
mon tue wed thu
api ....====@@@@::::
web ****%%%%????
0 [ .:-=+*#%@] 9 ? no data
linux macos win
unit ✓ ✓ ✗
e2e ✓ ⊘ ○
✓ pass 3 ✗ fail 1 ○ skip 1
⊘ blocked 1
KPI cards¶
KpiCard(label, value, *, format=None, unit=None, delta=None, delta_percent=None,
previous=None, caption=None, higher_is_better=True, trend=None, status=None,
width=None, expand=False, border=True, charset="auto")
Give at most one of delta, delta_percent and previous (the delta is
then worked out). trend is the card's sparkline; status is "ok",
"warning", "critical" or "unknown", drawn as a symbol and a word.
console.print(chart.KpiCard("Requests", 1234, delta_percent=4.2, trend=[1, 2, 3, 2, 5], status="ok", width=24))
Timelines¶
TimelineSpan(row, start, end, *, style=None)
Timeline(spans=None, *, milestones=None, range=None, charset="auto", format=None,
unit=None, compress=True, durations=True, width=None)
Spans are TimelineSpans or (row, start, end) triples; spans on one row
that overlap stack. Milestones are (label, at) pairs. None as a start,
an end or a milestone's at is a gap, as in a list of values: the span's
row is kept, but nothing is drawn for it.