ChartOut - Python package
Print Your Insights, Anytime, Anywhere
With every purchase, ChartOut donates to NumFOCUS to support the open-source ecosystem behind your charts.
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
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.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| chartout-1.0.0.tar.gz | 10.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| chartout-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 23.8 kB
Release files / chartout-1.0.0.tar.gz
| Download URL | chartout-1.0.0.tar.gz |
|---|---|
| Size | 10.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cf681b7fcf2fa78313503533d4fb8f0c392afbd2c80381cfbbc18d209c035fea
|
|
BLAKE2b-256 checksum How to use checksums |
8930a7c35226b0d68bc519ebe491546b9fac7f4a3716d202d6733966dc790c9f
|
| 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 9, 2026.
Transparency logRelease files / chartout-1.0.0-py3-none-any.whl
| Download URL | chartout-1.0.0-py3-none-any.whl |
|---|---|
| Size | 12.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
943e4b7b5e73cde9832d3e03a8dc11aa24d5e84c0af955017f2847a3618bde59
|
|
BLAKE2b-256 checksum How to use checksums |
6ba8e33006aa6f40da8b51694ff6b65decaade4ad5139d2bd24f2a86fb9a5f94
|
| 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 9, 2026.
Transparency log