✨ panel-mosaic
Interactive, DuckDB-powered Mosaic visualizations for Panel.
Build linked, browser-interactive charts without embedding an entire dataset in the page. Mosaic sends SQL to DuckDB and returns only the results each view needs.
Why panel-mosaic?
- Declarative charts: Render Mosaic and vgplot specifications directly in a Panel app.
- DuckDB pushdown: Keep large tables in DuckDB; only query results travel to the browser.
- Linked exploration: Coordinate multiple charts with selections and cross-filtering.
Installation
The PyPI distribution is named panel-mosaic-viz:
pip install panel-mosaic-viz
Quick start
Create app.py with a small DuckDB table and a stacked bar chart:
import duckdb
import panel as pn
from panel_mosaic import Mosaic
pn.extension(sizing_mode="stretch_width")
con = duckdb.connect()
con.execute("""
CREATE TABLE monthly_revenue AS
SELECT * FROM (
VALUES
('Jan', 'North', 48), ('Jan', 'Central', 39), ('Jan', 'South', 42),
('Feb', 'North', 55), ('Feb', 'Central', 45), ('Feb', 'South', 49),
('Mar', 'North', 46), ('Mar', 'Central', 40), ('Mar', 'South', 44),
('Apr', 'North', 61), ('Apr', 'Central', 48), ('Apr', 'South', 52),
('May', 'North', 65), ('May', 'Central', 52), ('May', 'South', 56),
('Jun', 'North', 58), ('Jun', 'Central', 47), ('Jun', 'South', 50),
('Jul', 'North', 72), ('Jul', 'Central', 55), ('Jul', 'South', 58),
('Aug', 'North', 66), ('Aug', 'Central', 52), ('Aug', 'South', 54),
('Sep', 'North', 79), ('Sep', 'Central', 60), ('Sep', 'South', 64),
('Oct', 'North', 89), ('Oct', 'Central', 69), ('Oct', 'South', 70),
('Nov', 'North', 74), ('Nov', 'Central', 58), ('Nov', 'South', 60),
('Dec', 'North', 85), ('Dec', 'Central', 66), ('Dec', 'South', 69)
) AS t(month, region, revenue)
""")
spec = {
"width": 900,
"height": 480,
"marginLeft": 72,
"marginBottom": 48,
"xLabel": "Month",
"yLabel": "Revenue (USD thousands)",
"yGrid": "#e5e7eb",
"colorScheme": "Tableau10",
"plot": [{
"mark": "barY",
"data": {"from": "monthly_revenue"},
"x": "month",
"y": "revenue",
"fill": "region",
"stroke": "white",
"strokeWidth": 1,
}],
}
pn.Column(
"# Monthly revenue dashboard",
"Explore regional revenue with a Mosaic chart backed by DuckDB.",
Mosaic(spec, con=con),
).servable()
Run the app:
panel serve app.py --show
How it works
Mosaic is a Panel JSComponent. It renders the declarative chart specification in the browser and services Mosaic's SQL requests through its DuckDB connection. You can either pass an existing DuckDB connection with con= or register in-memory frames with data={"table_name": dataframe}.
See the documentation for API details and more examples.
Development
git clone https://github.com/panel-extensions/panel-mosaic
cd panel-mosaic
For a simple setup use uv:
uv venv
source .venv/bin/activate # on linux. Similar commands for windows and osx
uv pip install -e .[dev]
pre-commit run install
pytest tests
For the full Github Actions setup use pixi:
pixi run pre-commit-install
pixi run postinstall
pixi run test
This repository is based on copier-template-panel-extension (you can create your own Panel extension with it)!
To update to the latest template version run:
pixi exec --spec copier --spec ruamel.yaml -- copier update --defaults --trust
Note: copier will show Conflict for files with manual changes during an update. This is normal. As long as there are no merge conflict markers, all patches applied cleanly.
❤️ Contributing
Contributions are welcome! Please follow these steps to contribute:
- Fork the repository.
- Create a new branch:
git checkout -b feature/YourFeature. - Make your changes and commit them:
git commit -m 'Add some feature'. - Push to the branch:
git push origin feature/YourFeature. - Open a pull request.
Please ensure your code adheres to the project's coding standards and passes all tests.
Metadata
Release files for panel-mosaic-viz 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| panel_mosaic_viz-0.1.3.tar.gz | 217.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| panel_mosaic_viz-0.1.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 227.3 kB
Release files / panel_mosaic_viz-0.1.3.tar.gz
| Download URL | panel_mosaic_viz-0.1.3.tar.gz |
|---|---|
| Size | 217.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0357691062508de3d1ac0535ef6f29eda9dd79016257ce48e5a7244c51e5f79f
|
|
BLAKE2b-256 checksum How to use checksums |
8016815319a95ca218d2b8d4f96ccd49a32e6adad9439896f87dc0a4ca2a0e2c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 18, 2026.
Transparency logRelease files / panel_mosaic_viz-0.1.3-py3-none-any.whl
| Download URL | panel_mosaic_viz-0.1.3-py3-none-any.whl |
|---|---|
| Size | 9.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0c6b35cc05c71b40bffc9f9906ea394686db02cd51c35c7bba774713bb27a325
|
|
BLAKE2b-256 checksum How to use checksums |
61ff69466a9f3b5274249da653463c938caa05061e53c10d41cd82f6d77fab43
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 18, 2026.
Transparency log