Any CSV, stitched into a year of squares. Quilt turns a spreadsheet of dated events into the GitHub contribution grid you already know how to read. One command, one image, no account and no server.
habit-heatmap workouts.csv -o heatmap.svg --value-col minutesMM/DD/YYYY,
and full ISO 8601 timestamps parse with no configuration. Add --tz America/Chicago
and UTC timestamps land in the right day.--value-col minutes to sum a number per day so a long session reads
darker than a short one..png and Quilt rasterizes
it through the optional extra.github, blue,
purple, mono for print, and dark for a dark page. A theme
is just a five-color tuple.1. Install (Python 3.9 or newer)
# from GitHub; add the [png] extra for PNG output pip install "git+https://github.com/ctkrug/habit-heatmap.git"
2. Point it at a CSV with a date column
habit-heatmap workouts.csv -o heatmap.svg \
--value-col minutes \
--theme blue \
--label "Workouts"
3. Or use it as a library
from habit_heatmap import load_events, render_svg counts = load_events("events.csv", value_col="minutes") svg = render_svg(counts, theme="blue", label="Workouts")
Quilt is a small Python tool that reads a CSV of dated events and draws a contribution heatmap: a calendar grid where each square is one day and darker squares mean a busier day. It is the GitHub contribution graph, no longer tied to commits and pointed at whatever you track. If your data has a date column, Quilt can chart it.
The input is any CSV with a date column. Each row counts as one event on its date, so a
plain list of dates already becomes a streak grid. When a numeric column matters, name it with
--value-col and Quilt sums that column per day instead of counting rows, so thirty
minutes of exercise reads darker than five. Dates can be bare (2024-03-01),
slash-separated, or full ISO 8601 timestamps, and the --tz option rebuckets
timestamps into your own timezone before it counts them, which matters when an app logs
everything in UTC.
The default output is an SVG string with no runtime dependencies, which is why the core
installs as pure Python. SVG embeds directly in Markdown, a README, or a web page and scales
without going fuzzy. When you need a raster file instead, name an output ending in
.png and Quilt renders one through the optional cairosvg extra. Both
paths share the same grid: month labels across the top, weekday labels down the side, a legend
below, and a tooltip on every day.
Because the command line is a thin wrapper over two functions, load_events and
render_svg, you can skip files entirely. load_events_from_rows takes
an iterable of dictionaries straight from a database query or an API response, so Quilt fits
into a script or a dashboard as easily as it runs at a terminal.
A CSV with a header row and at least a date column. The date column defaults to
date; use --date-col if yours is named something else. A numeric
value column is optional.
Yes. Export commit dates with git log --pretty=format:'%ad' --date=short, add a
date header, and run Quilt on the result. The cookbook in the repo has the exact
commands.
Only for PNG. The SVG path is pure Python with no dependencies. PNG export pulls in
cairosvg through the [png] extra, which needs the system cairo
library.
No. Quilt is a local command line tool. It reads your CSV and writes an image file. There is no account, no server, and no network call.
Pick one of five built-in themes with --theme, or register your own five-color
tuple in habit_heatmap.colors.THEMES and pass its name.