Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

ChartOut - Python package

Print Your Insights, Anytime, Anywhere

With every purchase, we donate 10% to NumFOCUS to support open-source scientific software.

ChartOut turns data visualizations into beautiful, printed products. You create a chart, pick a product, and chartout handles everything from 3D preview to order fulfilment.

Install

pip install chartout

Quick start

import altair as alt
import chartout

chart = alt.Chart(data).mark_point().encode(x='x', y='y')

store = chartout.Store(chart)
store  # renders the interactive widget in Jupyter

ChartOut store widget

Discover products

chartout.products()  # returns a list of available product dicts with id, name, and placements
[{'name': 'Mouse Pad (White / 8.7″x7.1″)',
  'id': 'mousepad_white_8x7',
  'placements': [{'id': 'default', 'print_ratio': '6:5'}]},
 {'name': 'Canvas (10″x10″)',
  'id': 'canvas_10x10',
  'placements': [{'id': 'default', 'print_ratio': '1:1'}]},
 {'name': 'Canvas (16″x32″) Vertical',
  'id': 'canvas_16x32_vertical',
  'placements': [{'id': 'default', 'print_ratio': '27:50'}]},
 {'name': 'Canvas (16″x32″) Horizontal',
  'id': 'canvas_16x32_horizontal',
  'placements': [{'id': 'default', 'print_ratio': '50:27'}]},
 {'name': 'Ceramic Mug with Color Inside (Black / 11 oz)',
  'id': 'mug_black_11oz',
  'placements': [{'id': 'default', 'print_ratio': '18:7'}]},
 {'name': 'Ceramic Mug with Color Inside (Green / 11 oz)',
  'id': 'mug_green_11oz',
  'placements': [{'id': 'default', 'print_ratio': '18:7'}]}]

Use the id values (e.g. 'mug_black_11oz', 'canvas_16x32_horizontal') as the first argument to chartout.item().

Create an item

chartout.item() wraps a chart and a product into a CartItem:

item = chartout.item('mug_green_11oz', chart)
item
CartItem(id='mug_green_11oz', name='Green Mug with my Viz', placements=[default], quantity=1)

The product id is validated against the API by default. Pass validate=False to skip the check when the id is already known.

Positioning

Control where the chart lands on the product via shorthand kwargs or an explicit PlacementPosition:

# shorthand — forwarded directly to PlacementPosition
item = chartout.item('mug_black_11oz', chart, horizontal='left', vertical='middle', scale=0.9)

# explicit
pos = chartout.PlacementPosition(
    horizontal='left',   # 'left' | 'center' | 'right'  (default: 'center')
    vertical='middle',   # 'top'  | 'middle' | 'bottom' (default: 'middle')
    scale=0.9,           # relative scale, optional
    dx=0.05,             # horizontal offset, optional
    dy=-0.02,            # vertical offset, optional
)
item = chartout.item('mug_black_11oz', chart, position=pos)
Parameter Values Default
horizontal 'left', 'center', 'right' 'center'
vertical 'top', 'middle', 'bottom' 'middle'
scale float
dx float
dy float

Build a cart

Group multiple items before opening the store:

cart = chartout.Cart([
    chartout.item('mug_black_11oz',          chart, horizontal='left',  quantity=2),
    chartout.item('canvas_16x32_horizontal', chart, horizontal='right', quantity=3),
    chartout.item('mousepad_white_8x7',      chart, horizontal='right', quantity=3),
])
cart  # prints a summary of all items
Cart:
  - ID: mug_black_11oz
    Name: mug_black_11oz
    Quantity: 2
    Placements: [default (middle, left)]
  - ID: canvas_16x32_horizontal
    Name: canvas_16x32_horizontal
    Quantity: 3
    Placements: [default (middle, right)]
  - ID: mousepad_white_8x7
    Name: mousepad_white_8x7
    Quantity: 3
    Placements: [default (middle, right)]

Add or remove items after creation:

cart.add(another_item)   # append a CartItem
cart.remove(index=0)     # remove by position

Open the store widget

Pass a single CartItem, a Cart, or a raw chart:

store = chartout.Store(item)   # single item
store = chartout.Store(cart)   # full cart
store = chartout.Store(chart)  # raw chart (no product selected yet)
store
Parameter Values Default Description
view 'cart', 'checkout' 'cart' Starting view
shipping_location {'country': 'NL'} Pre-fills country/state in checkout
store = chartout.Store(item, view='checkout', shipping_location={'country': 'NL'})
store

Add items to an open store without reopening it:

store.add_item(another_item)  # syncs to the widget immediately
store.cart                    # current cart state as a list of dicts

Supported chart types

Library Type Status
Altair alt.Chart and all chart types supported
matplotlib Figure (including seaborn) supported
Plotly go.Figure coming soon
pyobsplot ObsplotWidget coming soon
raw image bytes or bytearray supported

Release files for chartout 1.0.0b1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for chartout 1.0.0b1
File Size Uploaded
chartout-1.0.0b1.tar.gz 10.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for chartout 1.0.0b1
File Interpreter ABI Platform
chartout-1.0.0b1-py3-none-any.whl Python 3 none any Details

Total release size: 23.8 kB

Release files / chartout-1.0.0b1.tar.gz

Download URL chartout-1.0.0b1.tar.gz
Size 10.9 kB
Tags Source
SHA-256 checksum
How to use checksums
9591756a4a0e84d5b41accdaa184b253b4c50461990f06a5df2c56af38395839
BLAKE2b-256 checksum
How to use checksums
5d87122eba1f18d618b5cf1330d9e6866b7ab4cecf60a3432b397f905afc3efc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 2, 2026.

Transparency log

Release files / chartout-1.0.0b1-py3-none-any.whl

Download URL chartout-1.0.0b1-py3-none-any.whl
Size 12.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a951300b437edbed56325a7f1e850689a6c20956b7cd4e3aa4cba9a29ab65e5a
BLAKE2b-256 checksum
How to use checksums
c78638935cc749f5b81e0316b11bafead9263949003e034ca0954d836f0f3c91
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 2, 2026.

Transparency log
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page