tree-annotated-plot 0.0.1__tar.gz → 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/.github/workflows/release.yml +31 -1
  2. tree_annotated_plot-0.0.1/.github/workflows/ci.yml → tree_annotated_plot-0.1.0/.github/workflows/tests.yml +7 -1
  3. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/CLAUDE.md +8 -6
  4. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/PKG-INFO +28 -5
  5. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/README.md +27 -4
  6. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/docs/index.md +25 -0
  7. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/pyproject.toml +1 -1
  8. tree_annotated_plot-0.0.1/NEXT_STEPS.md +0 -94
  9. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/.github/workflows/docs.yml +0 -0
  10. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/.gitignore +0 -0
  11. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/LICENSE +0 -0
  12. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/docs/cli.md +0 -0
  13. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/docs/examples.md +0 -0
  14. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/docs/python-api.md +0 -0
  15. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/examples/fetch_auspice_data.py +0 -0
  16. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/examples/flu-seqneut-2025to2026_titer_charts.py +0 -0
  17. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/examples/synthetic_example.py +0 -0
  18. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/mkdocs.yml +0 -0
  19. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/scripts/build_docs.sh +0 -0
  20. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/scripts/check.sh +0 -0
  21. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/scripts/generate_docs_assets.py +0 -0
  22. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/src/tree_annotated_plot/__init__.py +0 -0
  23. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/src/tree_annotated_plot/_config.py +0 -0
  24. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/src/tree_annotated_plot/_plot.py +0 -0
  25. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/src/tree_annotated_plot/_tree.py +0 -0
  26. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/src/tree_annotated_plot/cli.py +0 -0
  27. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/tests/test_branch_length.py +0 -0
  28. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/tests/test_chart_loader.py +0 -0
  29. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/tests/test_cli.py +0 -0
  30. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/tests/test_examples_run.py +0 -0
  31. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/tests/test_introspection.py +0 -0
  32. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/tests/test_plot.py +0 -0
  33. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/tests/test_plot_config.py +0 -0
  34. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/tests/test_real_data.py +0 -0
  35. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/tests/test_reconciliation.py +0 -0
  36. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/tests/test_scale_bar.py +0 -0
  37. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/tests/test_style.py +0 -0
  38. {tree_annotated_plot-0.0.1 → tree_annotated_plot-0.1.0}/tests/test_tree_location.py +0 -0
@@ -1,4 +1,6 @@
1
- # Build wheel + sdist and publish to PyPI when a `v*` tag is pushed.
1
+ # When a `v*` tag is pushed: build wheel + sdist, publish to PyPI,
2
+ # then create a GitHub Release with auto-generated notes and the
3
+ # wheel + sdist attached as downloadable assets.
2
4
  #
3
5
  # Uses PyPI trusted publishing (OIDC) — no API token / password is
4
6
  # stored in the repo. The trusted-publisher relationship must be
@@ -80,3 +82,31 @@ jobs:
80
82
  path: dist/
81
83
 
82
84
  - uses: pypa/gh-action-pypi-publish@release/v1
85
+
86
+ github-release:
87
+ # Runs only after PyPI publish succeeds, so a transient PyPI failure
88
+ # doesn't leave a GitHub Release pointing at a version that isn't on
89
+ # PyPI. The Release page links to the tag, the wheel + sdist, and an
90
+ # auto-generated changelog (PR titles + commit list since the
91
+ # previous tag).
92
+ needs: publish
93
+ runs-on: ubuntu-latest
94
+ permissions:
95
+ # `softprops/action-gh-release` needs write access to create a
96
+ # Release on the tag and upload the dist files as assets.
97
+ contents: write
98
+ steps:
99
+ - uses: actions/download-artifact@v8
100
+ with:
101
+ name: dist
102
+ path: dist/
103
+
104
+ - uses: softprops/action-gh-release@v3
105
+ with:
106
+ # Attach the same wheel + sdist that went to PyPI so the
107
+ # Release page is a complete record of what was published.
108
+ files: dist/*
109
+ # Auto-generate notes from PR titles + commits since the
110
+ # previous tag. Maintainer can edit them after the fact in
111
+ # the Releases UI without re-running the workflow.
112
+ generate_release_notes: true
@@ -1,10 +1,16 @@
1
1
  # Run lint, format-check, and tests on every push to main and on every PR.
2
2
  #
3
+ # The workflow `name` is "tests" because that's what the README badge
4
+ # displays — readers (especially the biology audience) parse "tests
5
+ # passing" more readily than "CI passing". Behaviorally, this workflow
6
+ # also runs ruff and black (i.e. it's the project's full CI gate, not
7
+ # only tests); the slight label overload is intentional.
8
+ #
3
9
  # Local equivalent: `scripts/check.sh` (which expects a local .venv;
4
10
  # this workflow uses the runner's python directly so it doesn't depend
5
11
  # on that layout).
6
12
 
7
- name: ci
13
+ name: tests
8
14
 
9
15
  on:
10
16
  push:
@@ -57,7 +57,7 @@
57
57
  scripts/check.sh
58
58
  ```
59
59
  The same three checks run in CI via
60
- [`.github/workflows/ci.yml`](.github/workflows/ci.yml) on push to
60
+ [`.github/workflows/tests.yml`](.github/workflows/tests.yml) on push to
61
61
  `main` and on PRs (CI also fetches the upstream Kikawa Auspice JSONs
62
62
  so real-data tests run rather than skip). Local green ≈ CI green.
63
63
  - **Build docs alongside checks** when changing public API surface:
@@ -95,11 +95,13 @@
95
95
  - **Releases are tag-driven**. Push a `vX.Y.Z` tag (after bumping
96
96
  `pyproject.toml`'s `version`) and
97
97
  [`.github/workflows/release.yml`](.github/workflows/release.yml)
98
- builds wheel + sdist and publishes to PyPI via trusted publishing
99
- (OIDC — no token in the repo). The build job verifies the tag and
100
- `pyproject.toml` version match before publishing. Per-release recipe
101
- and one-time PyPI configuration steps are in `README.md` under
102
- "Releasing a new version".
98
+ builds wheel + sdist, publishes to PyPI via trusted publishing
99
+ (OIDC — no token in the repo), and creates a matching GitHub
100
+ Release with auto-generated notes + the wheel/sdist attached as
101
+ assets. The build job verifies the tag and `pyproject.toml` version
102
+ match before publishing. Per-release recipe and one-time PyPI
103
+ configuration steps are in `README.md` under "Releasing a new
104
+ version".
103
105
  - **Adding a new example** (full recipe in `README.md`):
104
106
  1. Self-contained module under `examples/` with module-level
105
107
  helpers (callable from outside).
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tree-annotated-plot
3
- Version: 0.0.1
3
+ Version: 0.1.0
4
4
  Summary: Annotate the axis of an Altair / Vega-Lite plot with a phylogenetic tree.
5
5
  Project-URL: Documentation, https://jbloomlab.github.io/tree-annotated-plot/
6
6
  Project-URL: Homepage, https://github.com/jbloomlab/tree-annotated-plot
@@ -51,6 +51,10 @@ Description-Content-Type: text/markdown
51
51
 
52
52
  # `tree-annotated-plot`: annotate the axis of an Altair / Vega-Lite plot with a phylogenetic tree
53
53
 
54
+ [![PyPI version](https://img.shields.io/pypi/v/tree-annotated-plot.svg)](https://pypi.org/project/tree-annotated-plot/)
55
+ [![Python versions](https://img.shields.io/pypi/pyversions/tree-annotated-plot.svg)](https://pypi.org/project/tree-annotated-plot/)
56
+ [![tests](https://github.com/jbloomlab/tree-annotated-plot/actions/workflows/tests.yml/badge.svg)](https://github.com/jbloomlab/tree-annotated-plot/actions/workflows/tests.yml)
57
+ [![Docs](https://img.shields.io/github/deployments/jbloomlab/tree-annotated-plot/github-pages?label=docs)](https://jbloomlab.github.io/tree-annotated-plot/)
54
58
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
55
59
  [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
56
60
  [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
@@ -60,6 +64,22 @@ See [https://jbloomlab.github.io/tree-annotated-plot/](https://jbloomlab.github.
60
64
 
61
65
  > **Note:** charts must be saved from altair 6+ (Vega-Lite v6). Older specs raise by default; pass `--no-strict-version` (CLI) or `strict_version=False` (Python) to override at your own risk. See the [docs](https://jbloomlab.github.io/tree-annotated-plot/) for details.
62
66
 
67
+ ## Installation
68
+
69
+ Released on [PyPI](https://pypi.org/project/tree-annotated-plot/). Requires Python 3.13+.
70
+
71
+ ```bash
72
+ pip install tree-annotated-plot
73
+ ```
74
+
75
+ To install the bleeding edge directly from this repository:
76
+
77
+ ```bash
78
+ pip install git+https://github.com/jbloomlab/tree-annotated-plot.git
79
+ ```
80
+
81
+ For a development checkout, see [Installation (development)](#installation-development) below.
82
+
63
83
  ## Notes for developing the package
64
84
 
65
85
  ### Installation (development)
@@ -110,9 +130,9 @@ Then open `site/examples.html` in a browser and, for each example:
110
130
  If something visibly regresses, fix it before pushing — there's no
111
131
  CI gate that will catch a visual regression for you.
112
132
 
113
- ### Continuous integration
133
+ ### Continuous integration tests
114
134
 
115
- [`.github/workflows/ci.yml`](.github/workflows/ci.yml) runs on every
135
+ [`.github/workflows/tests.yml`](.github/workflows/tests.yml) runs on every
116
136
  push to `main` and every pull request: it installs the package, fetches
117
137
  the upstream Kikawa Auspice JSONs (so the real-data tests actually
118
138
  exercise rather than skip), builds the Kikawa titer chart specs, and
@@ -129,8 +149,11 @@ merge), and additionally deploys `site/` to GitHub Pages on push to
129
149
 
130
150
  A third workflow,
131
151
  [`.github/workflows/release.yml`](.github/workflows/release.yml),
132
- builds the sdist + wheel and publishes them to PyPI when a `v*` tag
133
- is pushed (see "Releasing a new version" below).
152
+ builds the sdist + wheel when a `v*` tag is pushed, publishes them
153
+ to PyPI, and creates a matching
154
+ [GitHub Release](https://github.com/jbloomlab/tree-annotated-plot/releases)
155
+ with auto-generated notes and the wheel/sdist attached (see
156
+ "Releasing a new version" below).
134
157
 
135
158
  ### Releasing a new version
136
159
 
@@ -1,5 +1,9 @@
1
1
  # `tree-annotated-plot`: annotate the axis of an Altair / Vega-Lite plot with a phylogenetic tree
2
2
 
3
+ [![PyPI version](https://img.shields.io/pypi/v/tree-annotated-plot.svg)](https://pypi.org/project/tree-annotated-plot/)
4
+ [![Python versions](https://img.shields.io/pypi/pyversions/tree-annotated-plot.svg)](https://pypi.org/project/tree-annotated-plot/)
5
+ [![tests](https://github.com/jbloomlab/tree-annotated-plot/actions/workflows/tests.yml/badge.svg)](https://github.com/jbloomlab/tree-annotated-plot/actions/workflows/tests.yml)
6
+ [![Docs](https://img.shields.io/github/deployments/jbloomlab/tree-annotated-plot/github-pages?label=docs)](https://jbloomlab.github.io/tree-annotated-plot/)
3
7
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
4
8
  [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
5
9
  [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
@@ -9,6 +13,22 @@ See [https://jbloomlab.github.io/tree-annotated-plot/](https://jbloomlab.github.
9
13
 
10
14
  > **Note:** charts must be saved from altair 6+ (Vega-Lite v6). Older specs raise by default; pass `--no-strict-version` (CLI) or `strict_version=False` (Python) to override at your own risk. See the [docs](https://jbloomlab.github.io/tree-annotated-plot/) for details.
11
15
 
16
+ ## Installation
17
+
18
+ Released on [PyPI](https://pypi.org/project/tree-annotated-plot/). Requires Python 3.13+.
19
+
20
+ ```bash
21
+ pip install tree-annotated-plot
22
+ ```
23
+
24
+ To install the bleeding edge directly from this repository:
25
+
26
+ ```bash
27
+ pip install git+https://github.com/jbloomlab/tree-annotated-plot.git
28
+ ```
29
+
30
+ For a development checkout, see [Installation (development)](#installation-development) below.
31
+
12
32
  ## Notes for developing the package
13
33
 
14
34
  ### Installation (development)
@@ -59,9 +79,9 @@ Then open `site/examples.html` in a browser and, for each example:
59
79
  If something visibly regresses, fix it before pushing — there's no
60
80
  CI gate that will catch a visual regression for you.
61
81
 
62
- ### Continuous integration
82
+ ### Continuous integration tests
63
83
 
64
- [`.github/workflows/ci.yml`](.github/workflows/ci.yml) runs on every
84
+ [`.github/workflows/tests.yml`](.github/workflows/tests.yml) runs on every
65
85
  push to `main` and every pull request: it installs the package, fetches
66
86
  the upstream Kikawa Auspice JSONs (so the real-data tests actually
67
87
  exercise rather than skip), builds the Kikawa titer chart specs, and
@@ -78,8 +98,11 @@ merge), and additionally deploys `site/` to GitHub Pages on push to
78
98
 
79
99
  A third workflow,
80
100
  [`.github/workflows/release.yml`](.github/workflows/release.yml),
81
- builds the sdist + wheel and publishes them to PyPI when a `v*` tag
82
- is pushed (see "Releasing a new version" below).
101
+ builds the sdist + wheel when a `v*` tag is pushed, publishes them
102
+ to PyPI, and creates a matching
103
+ [GitHub Release](https://github.com/jbloomlab/tree-annotated-plot/releases)
104
+ with auto-generated notes and the wheel/sdist attached (see
105
+ "Releasing a new version" below).
83
106
 
84
107
  ### Releasing a new version
85
108
 
@@ -24,6 +24,31 @@ with `Chart` / `LayerChart` / `FacetChart` / `HConcatChart` /
24
24
  axis. The tree drops to whichever side of the chart the strain labels
25
25
  sit on by default (left for y-axis, bottom for x-axis).
26
26
 
27
+ ## Installation
28
+
29
+ Released on [PyPI](https://pypi.org/project/tree-annotated-plot/).
30
+ Requires Python 3.13+.
31
+
32
+ ```bash
33
+ pip install tree-annotated-plot
34
+ ```
35
+
36
+ To pin a specific version:
37
+
38
+ ```bash
39
+ pip install tree-annotated-plot==0.0.1
40
+ ```
41
+
42
+ To install the bleeding edge directly from the
43
+ [GitHub source](https://github.com/jbloomlab/tree-annotated-plot):
44
+
45
+ ```bash
46
+ pip install git+https://github.com/jbloomlab/tree-annotated-plot.git
47
+ ```
48
+
49
+ For a development checkout (contributors), see the README's
50
+ [development install](https://github.com/jbloomlab/tree-annotated-plot#installation-development).
51
+
27
52
  ## 30-second example
28
53
 
29
54
  Given an Auspice tree at `h3n2.auspice.json` and a Vega-Lite chart spec
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "tree-annotated-plot"
7
- version = "0.0.1"
7
+ version = "0.1.0"
8
8
  description = "Annotate the axis of an Altair / Vega-Lite plot with a phylogenetic tree."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.13"
@@ -1,94 +0,0 @@
1
- # Next steps
2
-
3
- Phase 2 is complete. This file is the to-do list for resuming —
4
- either by Jesse picking up later or by a future Claude session.
5
- Lifecycle: shrink as items get done; delete the file when only
6
- hypothetical Phase 3 work is left.
7
-
8
- ## Immediate actions (not yet done)
9
-
10
- 1. **Push to GitHub.** Local commits haven't been pushed yet.
11
- ```bash
12
- git push -u origin main
13
- ```
14
- 2. **Enable Pages.** GitHub repo → Settings → Pages → Source:
15
- "GitHub Actions". This activates the dormant
16
- `.github/workflows/docs.yml` so the next push to `main` builds
17
- and deploys the docs site to
18
- https://jbloomlab.github.io/tree-annotated-plot/.
19
- 3. **Verify the deployed site.** Click through Home / Python API /
20
- Command line / Examples. On the Examples page, each "Open the
21
- interactive chart →" link should open a working interactive
22
- Altair chart with tooltips and selection bindings. If any link
23
- 404s or any image is missing, the `Generate chart assets` step
24
- in the workflow probably failed — check the Actions tab.
25
- 4. **Bump the version + cut a tag** when you're ready for v0.1.0.
26
- `pyproject.toml`'s `version = "0.0.1"` is an alpha placeholder.
27
- ```bash
28
- # edit pyproject.toml: version = "0.1.0"
29
- git commit -am "release v0.1.0" && git tag v0.1.0
30
- git push && git push --tags
31
- ```
32
- 5. **Add a GitHub action to run the tests**: this should include running any tests, examples, linting, and code formatting
33
- 6. **Add installation instructions to the docs and README**: assume it can be installed from PyPI but have documentation also link to GitHub source
34
-
35
- ## Phase 3 candidate features (deferred from Phase 2)
36
-
37
- The Phase 2 plan's "Out of scope" section listed these explicitly
38
- and the user signed off on deferring them. Pick from this list when
39
- adding the next round of features:
40
-
41
- - **Clade coloring / tree decoration.** API shape undecided. Two
42
- options on the table:
43
- - Declarative: `clades=[{"node_attr": "subclade", "values_to_colors": {...}}]` and the package paints branches.
44
- - Lower-level: expose `tree_chart()` returning the tree panel as
45
- an editable `alt.Chart` so users layer their own decoration.
46
- - **Image-snapshot regression tests.** Render via
47
- `vl-convert-python` (already a dep) to PNG and compare with a
48
- structural diff or perceptual-similarity metric. Tool choice
49
- undecided (`pytest-mpl` is matplotlib-only; would need to find or
50
- build something for Vega-Lite output).
51
- - **Newick / Nexus tree input.** Auspice JSON v2 is the only tree
52
- format today.
53
- - **Static (matplotlib) backend.** Only altair-via-Vega-Lite today.
54
- - **HTML chart-spec extraction beyond the default altair template.**
55
- Today we parse `var spec = {...}` out of altair's standard
56
- `to_html()` output via stdlib `html.parser` +
57
- `json.JSONDecoder.raw_decode()`. Custom `chart.save(template=...)`
58
- outputs would need a real JS-AST parser (e.g. `esprima`).
59
- - **Per-clade collapsing of subtrees** (different from the
60
- topology-pruning we already do for `prune_tree_to_chart`).
61
- - **Vega-Lite v5 → v6 auto-upgrade** of stale specs. We currently
62
- detect-and-report; we don't translate.
63
-
64
- ## Smaller polish items
65
-
66
- - **Add `CHANGELOG.md`.** None today; `git log --oneline` is the
67
- de-facto record. Worth one if multiple releases pile up.
68
- - **Add a PyPI publish workflow.**
69
- `.github/workflows/release.yml` triggered on tag, building wheel +
70
- sdist, uploading via trusted publishing. None today; would
71
- complement the existing docs-deploy workflow.
72
- - **Compress the H1N1 docs PNG** (currently ~1 MB). Options:
73
- - Pass `optimize=True` to the PIL save (might need post-processing
74
- after `chart.save()`).
75
- - Lower PPI in `scripts/generate_docs_assets.py` from 96 to 72.
76
- - Crop or resize after rendering.
77
- - **Investigate the "Automatically deduplicated selection parameter"
78
- altair warning** that appears when the Kikawa chart-builder runs.
79
- Pre-existing and cosmetic, but it'd be cleaner to silence
80
- (probably needs explicit `name=` on the selection params).
81
- - **Add badges to README** Add badges for GitHub Actions test and PyPI version to the README.
82
- Is there also a badge I can add for the docs, or other badges to consider?
83
-
84
- ## State at session close
85
-
86
- - 21 commits on `main`, none pushed.
87
- - All 102 tests pass via `scripts/check.sh`.
88
- - `scripts/build_docs.sh` produces a viewable `site/` from a clean
89
- checkout.
90
- - `plan.md` is gone (disassembled per its own Lifecycle section in
91
- commit `b9beb66`).
92
- - `docs_plan.md` is gone (transient design note for the docs
93
- deployment + asset strategy; written, reviewed, and removed in
94
- commit `f1f551d`).