Render tabular query results as chart images. Rows in, PNG out.
query-viz does one thing: it turns a list of row dicts — exactly what a data
warehouse driver (BigQuery, Snowflake, Postgres, …) hands back — into a chart
image. No agent framework, no cloud SDK, no DataFrame requirement. That makes it
a clean building block for an LLM agent tool, a report generator, or any
pipeline that has already fetched data and wants a picture of it.
from query_viz import render_chart
png = render_chart(
rows=[
{"month": "Jan", "signups": 120},
{"month": "Feb", "signups": 155},
{"month": "Mar", "signups": 143},
],
chart_type="bar", # bar | line | pie | scatter
x="month",
y="signups",
title="Signups by month",
)
with open("signups.png", "wb") as fh:
fh.write(png)It was extracted from an ADK marketing agent's "chart this query" tool. The
rendering is pure and reusable; the agent-specific parts (running a guarded
query, uploading the image to Drive) stay in the agent as a thin wrapper. Same
split as sql-guard: the reusable
engine is a library, the framework glue is not.
render_chart(
rows, # Sequence[Mapping[str, Any]]
*,
chart_type, # "bar" | "line" | "pie" | "scatter"
x, # category / x-axis column (pie slice labels)
y=None, # numeric value column (required except... see below)
title="",
dpi=120,
figsize=(10.0, 6.0),
) -> bytes # PNG image bytesbar,line,scatterneed bothxandy.pieusesxfor slice labels andyfor slice sizes.- Non-numeric
yvalues coerce to0.0rather than erroring, so a strayNonewon't sink a whole chart. - Raises
ChartError(aValueError) for an unsupported type, empty rows, or a missing column.
- Headless. Forces matplotlib's
Aggbackend, so it renders on a server with no display. - Pure. No I/O, no globals — deterministic given its inputs, and safe to
call from a worker thread (
asyncio.to_thread). - Typed. Ships
py.typed.
pip install query-vizOnly dependency is matplotlib.
Apache-2.0.