Skip to main content

Yorillow

Lightweight, zero-dependency Python chart renderer that generates PNG and SVG charts entirely in Python.

Runs offline, inside Python applications, behind APIs, in Docker, on VPS servers, or in serverless environments.

from yorillow import render

png = render({
    "type": "line",
    "x": [1, 2, 3, 4],
    "y": [[10, 20, 15, 30]],
    "title": "Sales",
})

with open("sales.png", "wb") as f:
    f.write(png)

No Pillow. No NumPy. No matplotlib. No Chromium. No Node.js. No browser. No database.


Why Yorillow?

Yorillow matplotlib Chart.js
Runtime dependencies 0 numpy, Pillow, … Node/browser
Returns bytes directly figure objects HTML/JS
Serverless native requires setup needs browser
Import time ~27 ms seconds N/A
Memory (800×600) ~1.8 MiB ~50 MiB N/A

Installation

python -m pip install yorillow

Then:

from yorillow import render

Package name: yorillow (PyPI) / Import name: yorillow (Python)


Quick Start

Render to bytes

from yorillow import render

png = render(config, format="png")   # bytes
svg = render(config, format="svg")   # str

Save to file

from yorillow import render_to_file

render_to_file(config, "chart.png")
render_to_file(config, "chart.svg")

HTTP response helper

from yorillow import render_response

resp = render_response(config, format="png")
# resp["status_code"]  → 200
# resp["content_type"] → "image/png"
# resp["body"]         → bytes

Offline Usage

After installation, rendering requires no internet, no API key, no external service.

from yorillow import render

png = render({"type": "line", "x": [1, 2, 3], "y": [[10, 20, 30]]})

Completely offline installation

On an internet-connected machine:

python -m pip download yorillow

Transfer the downloaded file to the offline machine, then:

python -m pip install --no-index --find-links . yorillow

Since yorillow has zero runtime dependencies, only the yorillow package itself needs to be transferred.


Chart Types

Line

render({
    "type": "line",
    "x": [1, 2, 3, 4, 5],
    "y": [[10, 20, 15, 25, 30], [5, 15, 10, 20, 25]],
    "labels": ["Revenue", "Profit"],
    "title": "Monthly Performance",
    "legend": True,
    "fill": True,
})

Bar

render({
    "type": "bar",
    "categories": ["Q1", "Q2", "Q3", "Q4"],
    "values": [[120, 150, 170, 200], [90, 130, 140, 180]],
    "labels": ["Product A", "Product B"],
    "stacked": False,
})

Scatter

render({
    "type": "scatter",
    "x": [1.0, 2.5, 3.7, 4.2, 5.8],
    "y": [10.0, 20.5, 15.3, 25.1, 30.0],
    "sizes": [5, 8, 6, 10, 4],
})

Pie / Donut

render({
    "type": "pie",
    "values": [35, 25, 20, 12, 8],
    "labels": ["Chrome", "Firefox", "Safari", "Edge", "Other"],
    "donut": True,
})

Area

render({
    "type": "area",
    "x": [1, 2, 3, 4, 5],
    "y": [[10, 20, 15, 25, 30], [5, 10, 8, 12, 15]],
    "labels": ["Downloads", "Installs"],
    "stacked": True,
})

Histogram

render({
    "type": "histogram",
    "data": [12.5, 14.2, 15.0, 15.8, 16.1, 17.2, 18.0, 19.1, 20.5, 22.4, 25.0],
    "bins": 6,
    "title": "Latency Distribution (ms)",
})

Heatmap

render({
    "type": "heatmap",
    "values": [
        [22.4, 25.1, 28.3, 30.2],
        [18.2, 21.0, 24.5, 27.8],
        [15.1, 17.5, 20.2, 22.9],
    ],
    "x_labels": ["Q1", "Q2", "Q3", "Q4"],
    "y_labels": ["North", "Central", "South"],
    "color_scale": "viridis",
    "show_values": True,
    "title": "Regional Temperature Matrix",
})

Box Plot

render({
    "type": "box_plot",
    "data": [
        [15, 18, 20, 22, 23, 24, 25, 27, 29, 32, 45],
        [10, 14, 16, 17, 19, 20, 21, 22, 24, 26, 28],
    ],
    "categories": ["Algorithm A", "Algorithm B"],
    "show_outliers": True,
    "title": "Execution Time (ms)",
})

Candlestick

render({
    "type": "candlestick",
    "open": [150.0, 153.2, 151.8, 156.4],
    "high": [155.0, 156.0, 158.5, 161.0],
    "low": [148.5, 150.1, 150.0, 153.8],
    "close": [153.2, 151.8, 156.4, 154.0],
    "dates": ["Mon", "Tue", "Wed", "Thu"],
    "title": "Daily Price Action",
})

Radar / Spider

render({
    "type": "radar",
    "categories": ["Attack", "Defense", "Speed", "Tactics", "Stamina"],
    "values": [
        [88, 72, 94, 85, 90],
        [75, 92, 78, 88, 82],
    ],
    "labels": ["Player Alpha", "Player Beta"],
    "fill": True,
    "legend": True,
    "title": "Skill Radar",
})

Step

render({
    "type": "step",
    "x": [0, 1, 2, 3, 4, 5, 6, 7],
    "y": [[0, 1, 1, 2, 3, 5, 8, 13]],
    "step_where": "post",
    "fill": True,
    "title": "State Progression",
})

Styling & Customization

Every chart is fully customizable through the same plain-dict config — no new objects, no new dependencies. All options work identically for PNG and SVG.

render({
    "type": "line",
    "x": [1, 2, 3, 4, 5],
    "y": [[10, 20, 15, 30, 26], [5, 12, 9, 18, 14]],
    "labels": ["Revenue", "Profit"],

    "width": 860, "height": 500, "scale": 2,        # high-resolution output
    "theme": "corporate",                            # 13 built-in themes
    "background": "transparent",                     # transparent PNGs
    "colors": ["#003f5c", "#ff7c43"],                # custom palette

    "title": {"text": "Growth", "align": "left", "size": 22, "bold": True},
    "subtitle": "FY2026",
    "caption": "Source: internal",

    "margin": 12,
    "legend": {"show": True, "position": "bottom", "marker": "circle"},
    "grid": {"x": False, "dash": [3, 3], "opacity": 0.6},
    "axes": {"x": {"label": "Month"},
             "y": {"label": "USD", "min": 0, "format": "{:,.0f}"}},
    "series": [{"line_width": 3, "fill": True, "fill_opacity": 0.15},
               {"dash": [6, 3]}],
    "annotations": [{"type": "hline", "y": 25, "label": "Target"}],
})
Area Options
🎨 Themes 13 built-ins, inline dict themes, Theme objects, custom registry
🖌️ Colors Palettes by name or list, per-series colors, custom backgrounds
📐 Size width, height, scale (1–8) for high-resolution export
🔤 Text Family, size, weight, italic, letter-spacing, color, rotation
📝 Labels Title, subtitle, caption, axis titles, annotations
📏 Layout margin, padding, automatic space reservation
🧭 Legend 8 positions, orientation, markers, box styling
📊 Axes/grid Ticks, formats, prefixes, min/max, dashes, per-axis control
🖼️ Transparency "background": "transparent" (alpha-0 PNG, bare SVG)

Full reference: docs/api/styling.md · Cookbook: docs/guides/customization.md


Themes

default / light dark minimal
neon corporate mono
solarized pastel ocean
high_contrast midnight print
render({**config, "theme": "dark"})

# inline theme, no global state
render({**config, "theme": {"base": "dark", "palette": "ocean"}})

# reusable theme object
from yorillow import Theme
brand = Theme(name="brand", palette=["#003366", "#0066cc"], title_color="#003366")
render({**config, "theme": brand})

More: docs/api/themes.md


JSON Configuration

Chart configurations are plain JSON — no Python objects required.

{
    "type": "line",
    "x": [1, 2, 3, 4],
    "y": [[10, 20, 15, 30]],
    "title": "Sales"
}
import json
from yorillow import render

with open("chart.json") as f:
    config = json.load(f)

png = render(config)

This makes Yorillow useful when configuration comes from another program, a database, an API, or another language.


CLI

yorillow chart.json -o chart.png          # render PNG
yorillow chart.json -o chart.svg          # render SVG
cat chart.json | yorillow -o chart.png    # stdin
yorillow chart.json --base64              # JSON with base64 data
yorillow chart.json --validate-only       # validate only
yorillow chart.json -o out.png --bench    # show timing
yorillow chart.json -o out.png --theme midnight --scale 2 --transparent
yorillow chart.json -o out.svg --title "Q1" --width 900 --height 500
yorillow --list-themes                    # list available themes
yorillow --version
yorillow --help

PowerShell:

Get-Content chart.json -Raw | yorillow -o chart.png

Build an API

Yorillow is the renderer, not the server.

Client → JSON → HTTP Server → yorillow.render() → PNG/SVG → HTTP Response

stdlib (zero dependencies)

python examples/api/simple_http_server.py
curl -X POST http://localhost:8080/chart \
  -H "Content-Type: application/json" \
  -d '{"type":"line","x":[1,2,3],"y":[[10,20,30]]}' \
  --output chart.png

Flask

pip install flask yorillow
python examples/api/flask_app.py

FastAPI

pip install fastapi uvicorn yorillow
python -m uvicorn examples.api.fastapi_app:app

Deploy

Environment Guide Status
Local Python Offline Usage ✓ Tested
CLI CLI ✓ Tested
VPS docs/deployment/vps.md ✓ Tested
Docker docs/deployment/docker.md ✓ Tested
Flask examples/api/flask_app.py Example
FastAPI examples/api/fastapi_app.py Example
Render docs/deployment/render.md Example
Railway docs/deployment/railway.md Example
Vercel docs/deployment/vercel.md Example
Netlify docs/deployment/netlify.md Example
AWS Lambda docs/deployment/aws-lambda.md Example

Serverless Architecture

The core renderer is stateless and dependency-free, making it suitable for Python-compatible serverless runtimes.

Request → render() → PNG/SVG → Response

No persistent process. No database. No filesystem. No browser.

See docs/architecture/serverless.md.


Performance

Metric Value
Import ~27 ms
PNG 800×600 ~15–60 ms
SVG 800×600 <0.4 ms
PNG 1920×1080 ~60 ms
Canvas 800×600 1.8 MiB

Run python benchmarks/bench.py to reproduce.

See docs/performance.md.


Security

Yorillow validates all inputs: max dimensions, data point limits, NaN/Infinity rejection, type checking.

When exposing publicly, add authentication, rate limiting, and request size limits at the HTTP layer.

See docs/security.md.


API Reference

Function Returns Description
render(config, format, encoding) bytes/str Stateless chart renderer
render_to_file(config, path) None Render and save to file
render_response(config, format) dict HTTP response helper
Class Description
Canvas Low-level drawing surface
Theme Colour/font bundle (get_theme, list_themes, resolve_theme)
ChartStyle Styling container for the object API
ResolvedStyle Fully-resolved appearance shared by both renderers
Layout / Rect Computed chart geometry (compute_layout)
Annotation Parsed annotation
LineChart Line chart
BarChart Bar chart
ScatterChart Scatter plot
PieChart Pie / donut chart
AreaChart Area chart
HistogramChart (Histogram) Histogram chart
HeatmapChart (Heatmap) Heatmap matrix
BoxPlotChart (BoxPlot) Box plot (whisker plot)
CandlestickChart (Candlestick) Candlestick OHLC chart
RadarChart (Radar, SpiderChart) Radar / spider chart
StepChart (Step) Step-wise line chart
Exception Description
YorillowError Base exception
ValidationError Invalid input
RenderError Internal error

Full reference: docs/api/


Examples

Example Description
examples/python/basic_png.py Basic PNG
examples/python/basic_svg.py Basic SVG
examples/python/multiple_series.py Multiple series
examples/python/histogram_example.py Histogram chart
examples/python/heatmap_example.py Heatmap matrix
examples/python/box_plot_example.py Box plot
examples/python/candlestick_example.py Candlestick OHLC
examples/python/radar_example.py Radar / spider chart
examples/python/step_example.py Step chart
examples/python/themes.py Theme demo
examples/python/custom_theme.py Custom & inline themes
examples/python/theme_gallery.py Every theme × 3 chart types
examples/python/styling_full.py Every styling option at once
examples/python/legend_positions.py Legend positions & styles
examples/python/axes_and_grid.py Axis & grid customization
examples/python/annotations.py Reference lines, bands, labels
examples/python/transparent_png.py Transparent backgrounds
examples/python/high_res_export.py High-resolution export
examples/python/png_svg_parity.py PNG/SVG consistency
examples/python/save_to_file.py Save to file
examples/python/json_config.py JSON config
examples/demo.py Full gallery generation
examples/api/simple_http_server.py stdlib HTTP API
examples/api/flask_app.py Flask API
examples/api/fastapi_app.py FastAPI API
examples/client/remote_client.py Python HTTP client
examples/serverless/ Serverless handlers
examples/docker/ Docker

Development

git clone https://github.com/harshi79/yorillow.git
cd yorillow
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
python -m pytest tests/ -v

See CONTRIBUTING.md.


License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

yorillow-1.1.0.tar.gz (143.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

yorillow-1.1.0-py3-none-any.whl (86.2 kB view details)

Uploaded Python 3

File details

Details for the file yorillow-1.1.0.tar.gz.

File metadata

  • Download URL: yorillow-1.1.0.tar.gz
  • Upload date:
  • Size: 143.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.10.11

File hashes

Hashes for yorillow-1.1.0.tar.gz
Algorithm Hash digest
SHA256 2ac84bceb0d61b9562076f89ad185b49b357de285f60aac9c32db931eec5d08e
MD5 f0fb67b657886181e3b146c0d6c1d330
BLAKE2b-256 0a3e1dc49402198f5751fb83855edcb105fc2ea36277ac34487edfd24a5f2776

See more details on using hashes here.

File details

Details for the file yorillow-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: yorillow-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 86.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.10.11

File hashes

Hashes for yorillow-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 551697fe370549cd9640bebc7258cc5db85fc26d192643da8e2feda28d42d5c0
MD5 66a1ccfe247a12a3ab54c889b0e7d394
BLAKE2b-256 97c880bb1a9aaaa6eda02d4873437cf79d495f28342c0c224b8a7b596efc7332

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

1.1.0 This release

2 files

1.0.1

2 files

1.0.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page