protspace 3.2.0__tar.gz → 3.3.1__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.
- {protspace-3.2.0 → protspace-3.3.1}/.gitignore +1 -0
- {protspace-3.2.0 → protspace-3.3.1}/CHANGELOG.md +84 -0
- {protspace-3.2.0 → protspace-3.3.1}/PKG-INFO +1 -1
- {protspace-3.2.0 → protspace-3.3.1}/docs/cli.md +9 -1
- protspace-3.3.1/docs/styling.md +122 -0
- {protspace-3.2.0 → protspace-3.3.1}/notebooks/ProtSpace_Preparation.ipynb +249 -130
- {protspace-3.2.0 → protspace-3.3.1}/pyproject.toml +1 -1
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/__init__.py +1 -1
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/cli/local_data.py +1 -2
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/data/annotations/manager.py +0 -1
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/data/annotations/retrievers/interpro_retriever.py +0 -1
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/data/annotations/retrievers/taxonomy_retriever.py +0 -1
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/data/annotations/retrievers/uniprot_retriever.py +0 -1
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/data/io/settings_converter.py +102 -11
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/data/processors/base_processor.py +14 -1
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/data/processors/local_processor.py +4 -2
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/data/processors/uniprot_query_processor.py +0 -1
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/utils/add_annotation_style.py +74 -12
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/utils/reducers.py +81 -3
- protspace-3.3.1/tests/test_reducers.py +274 -0
- {protspace-3.2.0 → protspace-3.3.1}/uv.lock +1 -1
- protspace-3.2.0/docs/styling.md +0 -66
- {protspace-3.2.0 → protspace-3.3.1}/.dockerignore +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/.env.example +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/.github/SEMANTIC_RELEASE_SETUP.md +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/.github/workflows/docker.yml +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/.github/workflows/jekyll-gh-pages.yml +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/.github/workflows/python.yml +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/.github/workflows/release.yml +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/.python-version +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/Dockerfile +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/LICENSE +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/README.md +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/data/3FTx/3FTx.csv +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/data/3FTx/parquetbundle/3FTx_accession.csv +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/data/3FTx/parquetbundle/3ftx_with_db_styled.parquetbundle +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/data/3FTx/parquetbundle/styles.json +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/data/Pla2g2/Pla2g2.csv +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/data/Pla2g2/Pla2g2.fasta +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/data/Pla2g2/Pla2g2_pdb.zip +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/data/Pla2g2/protspace_files/Pla2g2.json +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/data/Pla2g2/protspace_files/Pla2g2_customized.json +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/data/Pla2g2/style.json +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/data/toxins/protspace/projections_data.parquet +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/data/toxins/protspace/projections_metadata.parquet +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/data/toxins/protspace/selected_annotations.parquet +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/data/toxins/toxins.json +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/data/toxins/toxins.parquetbundle +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/docs/annotations.md +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/docs/protspace_example.png +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/Workflow.svg +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/cli/protspace_local.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/cli/protspace_query.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/image_creation.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/3FTx/PCA2_group.svg +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/3FTx/PCA2_major_group.svg +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/3FTx/PCA3_group.html +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/3FTx/PCA3_major_group.html +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/3FTx/UMAP2_group.svg +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/3FTx/UMAP2_major_group.svg +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/3FTx/UMAP3_group.html +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/3FTx/UMAP3_major_group.html +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/Pla2g2/Pla2g2_dashboard.png +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/Pla2g2/Pla2g2_group.svg +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/Pla2g2/group.svg +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/automatic_projections/PCA_2_annotation_score.png +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/automatic_projections/PCA_2_protein_existence.png +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/automatic_projections/PCA_3_annotation_score.html +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/automatic_projections/PCA_3_protein_existence.html +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/gfp/prott5_umap2_brightness_category.svg +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/gfp/prott5_umap2_nr_mutations.svg +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/gfp/seq_sim_mds2_brightness_category.svg +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/gfp/seq_sim_mds2_nr_mutations.svg +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/gfp/seq_sim_umap2_brightness_category.svg +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/gfp/seq_sim_umap2_nr_mutations.svg +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/gfp/struct_sim_mds2_brightness_category.svg +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/gfp/struct_sim_mds2_nr_mutations.svg +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/phages/function_umap.svg +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/phages/product_category_umap.svg +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/phages/sub_all_members.html +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/phages/sub_all_members.svg +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/phages/sub_clusterrep.html +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/phages/sub_clusterrep.svg +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/toxins/family_bitmap_umap.svg +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/toxins/family_evalue_umap.svg +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/toxins/order_bits_umap.svg +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/toxins/order_evalue_umap.svg +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/toxins/order_umap.png +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/toxins/order_umap.svg +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/toxins/protein_category_bits_umap.svg +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/toxins/protein_category_evalue_umap.svg +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/toxins/protein_category_umap.png +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/out/toxins/protein_category_umap.svg +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/examples/run_interactive_mode.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/notebooks/ClickThrough_GenerateEmbeddings.ipynb +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/notebooks/Explore_ProtSpace.ipynb +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/notebooks/PfamExplorer_ProtSpace.ipynb +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/notebooks/Run_ProtSpace.ipynb +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/out/images/marker_gallery.png +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/requirements-py310.txt +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/requirements-py311.txt +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/requirements-py312.txt +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/app.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/assets/__init__.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/assets/annotated_image.png +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/assets/custom.css +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/assets/help_content/__init__.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/assets/help_content/help_faq.md +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/assets/help_content/help_how_it_works.md +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/assets/help_content/help_json.md +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/assets/help_content/help_overview.md +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/assets/rostlab_logo.png +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/cli/__init__.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/cli/common_args.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/cli/uniprot_query.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/core/__init__.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/core/config.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/core/constants.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/data/__init__.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/data/annotations/__init__.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/data/annotations/configuration.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/data/annotations/merging.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/data/annotations/retrievers/__init__.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/data/annotations/retrievers/base_retriever.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/data/annotations/scores.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/data/annotations/transformers/__init__.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/data/annotations/transformers/interpro_transforms.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/data/annotations/transformers/length_binning.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/data/annotations/transformers/transformer.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/data/annotations/transformers/uniprot_transforms.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/data/io/__init__.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/data/io/bundle.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/data/io/formatters.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/data/io/readers.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/data/io/writers.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/data/parsers/__init__.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/data/parsers/uniprot_parser.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/data/processors/__init__.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/main.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/ui/__init__.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/ui/callbacks.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/ui/layout.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/ui/styles.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/utils/__init__.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/utils/analyse_json.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/utils/arrow_reader.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/utils/json_reader.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/visualization/__init__.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/visualization/molstar.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/visualization/plotting.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/src/protspace/wsgi.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/tests/README.md +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/tests/__init__.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/tests/test_annotation_manager.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/tests/test_base_data_processor.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/tests/test_config.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/tests/test_interpro_annotation_retriever.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/tests/test_local_data_processor.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/tests/test_output_combinations.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/tests/test_taxonomy_annotation_retriever.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/tests/test_transformer.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/tests/test_uniprot_annotation_retriever.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/tests/test_uniprot_query_processor.py +0 -0
- {protspace-3.2.0 → protspace-3.3.1}/update_deps.sh +0 -0
|
@@ -1,6 +1,90 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
## v3.3.1 (2026-02-27)
|
|
5
|
+
|
|
6
|
+
### Chores
|
|
7
|
+
|
|
8
|
+
* chore: remove dead code and redundant logging.basicConfig calls
|
|
9
|
+
|
|
10
|
+
- Remove 6 redundant logging.basicConfig() calls from library modules
|
|
11
|
+
(only the CLI entry point setup_logging() should configure logging)
|
|
12
|
+
- Remove duplicate logger assignment in reducers.py
|
|
13
|
+
- Replace bare print(e) with logger.error() in reducers.py
|
|
14
|
+
- Remove commented-out dead code in local_data.py
|
|
15
|
+
|
|
16
|
+
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> ([`74f04f4`](https://github.com/tsenoner/protspace/commit/74f04f4aee338db09a3abcea699b3932b51ec01a))
|
|
17
|
+
|
|
18
|
+
### Documentation
|
|
19
|
+
|
|
20
|
+
* docs(notebook): overhaul Colab UI with interactive widgets
|
|
21
|
+
|
|
22
|
+
Replace basic SelectMultiple widgets with a polished interactive UI:
|
|
23
|
+
- Annotation selection: checkboxes in 2-column CSS grids per category
|
|
24
|
+
(UniProt/InterPro/Taxonomy) with per-group and global preset buttons
|
|
25
|
+
- DR method selection: ToggleButtons with color feedback and tooltips
|
|
26
|
+
- Method parameters: bordered cards in responsive flex-wrap grid with
|
|
27
|
+
shared params merged (n_neighbors for UMAP/PaCMAP/LocalMAP, etc.)
|
|
28
|
+
- Dynamic show/hide of parameter groups based on selected methods
|
|
29
|
+
- Remove gene_name from selectable annotations (always auto-included)
|
|
30
|
+
- Add /.claude to .gitignore
|
|
31
|
+
|
|
32
|
+
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> ([`f671715`](https://github.com/tsenoner/protspace/commit/f671715ebf13eb808e7f44567b3c0407a5accb41))
|
|
33
|
+
|
|
34
|
+
### Fixes
|
|
35
|
+
|
|
36
|
+
* fix(reducers): robust float16 upcast, annoy fallback, suppress noisy warnings
|
|
37
|
+
|
|
38
|
+
- Upcast float16 → float32 at HDF5 load time (local_processor) with a
|
|
39
|
+
safety-net in base_processor, preventing overflow in all DR methods
|
|
40
|
+
- Add lazy annoy health check: on platforms where annoy segfaults or
|
|
41
|
+
returns empty results (e.g. macOS ARM64), transparently swap in an
|
|
42
|
+
sklearn NearestNeighbors drop-in so PaCMAP/LocalMAP keep working
|
|
43
|
+
- Suppress harmless sklearn RuntimeWarnings (randomized SVD overflow),
|
|
44
|
+
FutureWarnings, and umap UserWarnings during fit_transform
|
|
45
|
+
- Add LocalMAP to Colab notebook (METHODS list, parameter sliders,
|
|
46
|
+
intro text) — previously missing from the preparation UI
|
|
47
|
+
|
|
48
|
+
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> ([`7c8193e`](https://github.com/tsenoner/protspace/commit/7c8193ef0ef4c2b9df3a9031dc142f77b28d9fc6))
|
|
49
|
+
|
|
50
|
+
### Testing
|
|
51
|
+
|
|
52
|
+
* test(reducers): add comprehensive tests for all 6 DR methods
|
|
53
|
+
|
|
54
|
+
51 tests covering PCA, t-SNE, UMAP, PaCMAP, MDS, and LocalMAP:
|
|
55
|
+
- Per-method: output shape (2D/3D), NaN-free, get_params, determinism
|
|
56
|
+
- Cross-cutting (parametrized): finite output, float dtype, no Inf
|
|
57
|
+
- Float16 handling: verify upcast produces correct results
|
|
58
|
+
- Config validation: defaults, custom values, invalid inputs
|
|
59
|
+
- End-to-end: all methods through BaseProcessor.process_reduction
|
|
60
|
+
|
|
61
|
+
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> ([`85697c0`](https://github.com/tsenoner/protspace/commit/85697c00bd84885999a96bd4613eb3289bcb03bb))
|
|
62
|
+
|
|
63
|
+
### Unknown
|
|
64
|
+
|
|
65
|
+
* Merge pull request #34 from tsenoner/stage
|
|
66
|
+
|
|
67
|
+
Robust reducers, test suite, and Colab UI overhaul ([`e1e416d`](https://github.com/tsenoner/protspace/commit/e1e416d1b51e7880b65a60c60d4d489f4f58645a))
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
## v3.3.0 (2026-02-17)
|
|
71
|
+
|
|
72
|
+
### Features
|
|
73
|
+
|
|
74
|
+
* feat(styling): add pinnedValues, __REST__ marker, and value preprocessing
|
|
75
|
+
|
|
76
|
+
Add legend ordering support to protspace-annotation-colors:
|
|
77
|
+
- pinnedValues for explicit control over legend order and visible categories
|
|
78
|
+
- __REST__ auto-fill marker to expand top values by frequency
|
|
79
|
+
- zOrderSort to decouple zOrder computation from stored sortMode
|
|
80
|
+
- Value preprocessing (pipe trimming, semicolon splitting) matching the
|
|
81
|
+
ProtSpace web frontend
|
|
82
|
+
- Auto-assign Kelly's palette colors for pinned values, __NA__ key format
|
|
83
|
+
- Comprehensive docs in docs/styling.md, docs/cli.md, and CLI epilog
|
|
84
|
+
|
|
85
|
+
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> ([`530cd3c`](https://github.com/tsenoner/protspace/commit/530cd3c90cb7acbc5ea35f3974eb39d0bb74c34c))
|
|
86
|
+
|
|
87
|
+
|
|
4
88
|
## v3.2.0 (2026-02-17)
|
|
5
89
|
|
|
6
90
|
### Code Style
|
|
@@ -59,7 +59,7 @@ protspace-query -q 'organism_name:"Homo sapiens" AND reviewed:true' -m pca2,umap
|
|
|
59
59
|
|
|
60
60
|
## `protspace-annotation-colors`
|
|
61
61
|
|
|
62
|
-
Add custom colors, shapes, and display settings to existing ProtSpace files. See [Annotation Styling](styling.md) for the full styles JSON format
|
|
62
|
+
Add custom colors, shapes, legend ordering, and display settings to existing ProtSpace files. See [Annotation Styling](styling.md) for the full styles JSON format, including legend ordering with `pinnedValues`.
|
|
63
63
|
|
|
64
64
|
```bash
|
|
65
65
|
# Generate a styles template (values in frequency order, empty color placeholders)
|
|
@@ -71,6 +71,14 @@ protspace-annotation-colors input.parquetbundle output.parquetbundle --annotatio
|
|
|
71
71
|
# Apply styles from an inline JSON string
|
|
72
72
|
protspace-annotation-colors input.parquetbundle output.parquetbundle --annotation_styles '{"ann": {"colors": {"val": "#FF0000"}}}'
|
|
73
73
|
|
|
74
|
+
# Pin specific legend entries with N/A at the end
|
|
75
|
+
protspace-annotation-colors input.parquetbundle output.parquetbundle --annotation_styles \
|
|
76
|
+
'{"ann": {"sortMode": "manual", "zOrderSort": "size-desc", "pinnedValues": ["val1", "val2", ""]}}'
|
|
77
|
+
|
|
78
|
+
# Auto-fill top values by frequency, N/A at end
|
|
79
|
+
protspace-annotation-colors input.parquetbundle output.parquetbundle --annotation_styles \
|
|
80
|
+
'{"ann": {"sortMode": "manual", "zOrderSort": "size-desc", "pinnedValues": ["__REST__", ""]}}'
|
|
81
|
+
|
|
74
82
|
# Inspect stored settings
|
|
75
83
|
protspace-annotation-colors data.parquetbundle --dump-settings
|
|
76
84
|
```
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# Annotation Styling
|
|
2
|
+
|
|
3
|
+
Custom colors, shapes, and legend settings for annotation categories.
|
|
4
|
+
|
|
5
|
+
**Two approaches:**
|
|
6
|
+
|
|
7
|
+
- **Web UI** — interactive editing in [ProtSpace Web](https://protspace.app/explore), save to download the updated bundle
|
|
8
|
+
- **CLI** — programmatic via `protspace-annotation-colors` (see [CLI Reference](cli.md#protspace-annotation-colors))
|
|
9
|
+
|
|
10
|
+
## Workflow
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
# 1. Generate a styles template (values listed in frequency order)
|
|
14
|
+
protspace-annotation-colors data.parquetbundle --generate-template > styles.json
|
|
15
|
+
|
|
16
|
+
# 2. Edit styles.json — fill in colors, adjust settings
|
|
17
|
+
|
|
18
|
+
# 3. Apply styles to produce a new bundle
|
|
19
|
+
protspace-annotation-colors data.parquetbundle styled.parquetbundle --annotation_styles styles.json
|
|
20
|
+
|
|
21
|
+
# 4. Verify stored settings
|
|
22
|
+
protspace-annotation-colors styled.parquetbundle --dump-settings
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Styles JSON format
|
|
26
|
+
|
|
27
|
+
Top-level keys are annotation names. Each annotation accepts the keys below.
|
|
28
|
+
|
|
29
|
+
| Key | Type | Default | Stored | Description |
|
|
30
|
+
| ------------------- | -------- | ------------- | ------ | ------------------------------------------------------------------------------------------------ |
|
|
31
|
+
| `colors` | `{}` | — | yes | `{value: color}` — hex (`#FF0000`) or rgb (`rgb(255,0,0)`). Empty strings are ignored. |
|
|
32
|
+
| `shapes` | `{}` | — | yes | `{value: shape}` — one of `circle`, `square`, `diamond`, `triangle-up`, `triangle-down`, `plus`. |
|
|
33
|
+
| `sortMode` | string | `"size-desc"` | yes | Legend sort: `size-desc`, `size-asc`, `alpha-asc`, `alpha-desc`, `manual`. |
|
|
34
|
+
| `maxVisibleValues` | int | `10` | yes | Legend entries shown before the "Other" bucket. |
|
|
35
|
+
| `shapeSize` | int | `30` | yes | Marker size in the scatter plot. |
|
|
36
|
+
| `hiddenValues` | string[] | `[]` | yes | Categories hidden from the plot. |
|
|
37
|
+
| `selectedPaletteId` | string | `"kellys"` | yes | Color palette for categories without explicit colors. |
|
|
38
|
+
| `pinnedValues` | string[] | — | no | Ordered list of values for legend positions 0..N-1. See [Legend ordering](#legend-ordering). |
|
|
39
|
+
| `zOrderSort` | string | — | no | Sort mode for zOrder assignment only (overrides `sortMode` for zOrder computation). |
|
|
40
|
+
|
|
41
|
+
**Stored** keys are persisted in the output bundle. **Non-stored** (processing-only) keys are consumed during generation — only their effects (the resulting categories with `zOrder`, `color`, `shape`) are written.
|
|
42
|
+
|
|
43
|
+
### N/A values
|
|
44
|
+
|
|
45
|
+
Missing values (`""`, `"<NA>"`, `"NaN"`) are normalized automatically — use any form in the styles file. In the output bundle N/A is stored with the key `__NA__` (the frontend's internal format).
|
|
46
|
+
|
|
47
|
+
### Example: custom colors and shapes
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"major_group": {
|
|
52
|
+
"maxVisibleValues": 6,
|
|
53
|
+
"colors": {
|
|
54
|
+
"Short-chain": "#63CBE5",
|
|
55
|
+
"Long-chain": "#24638F",
|
|
56
|
+
"<NA>": "#C0C0C0"
|
|
57
|
+
},
|
|
58
|
+
"shapes": {
|
|
59
|
+
"Short-chain": "circle",
|
|
60
|
+
"Long-chain": "square"
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Legend ordering
|
|
67
|
+
|
|
68
|
+
By default (`sortMode: "size-desc"`), legend items are sorted by frequency with N/A sorted by its count like any other category. To control which values appear and in what order, use `pinnedValues` with `sortMode: "manual"`.
|
|
69
|
+
|
|
70
|
+
### How `pinnedValues` works
|
|
71
|
+
|
|
72
|
+
- Each value in the list receives a `zOrder` starting from 0. **Only pinned values** are written into the bundle's categories — the frontend treats everything else as "Other".
|
|
73
|
+
- `sortMode: "manual"` tells the frontend to sort legend items by `zOrder` (i.e., the order you defined).
|
|
74
|
+
- `maxVisibleValues` must match the number of pinned values. Example: 12 families + N/A = 13 entries requires `maxVisibleValues: 13`.
|
|
75
|
+
- Colors are auto-assigned from Kelly's 21 Colors of Maximum Contrast when no explicit `colors` are provided. N/A gets a lighter gray (`#DDDDDD`).
|
|
76
|
+
- Use `""` for N/A in `pinnedValues`.
|
|
77
|
+
|
|
78
|
+
### `__REST__` auto-fill marker
|
|
79
|
+
|
|
80
|
+
Instead of listing every value, use `"__REST__"` as a placeholder that expands to the top values by frequency (sorted by `zOrderSort`), filling up to `maxVisibleValues`.
|
|
81
|
+
|
|
82
|
+
**Top 9 by frequency + N/A at end** (default `maxVisibleValues=10`):
|
|
83
|
+
|
|
84
|
+
```json
|
|
85
|
+
{
|
|
86
|
+
"ec": {
|
|
87
|
+
"sortMode": "manual",
|
|
88
|
+
"zOrderSort": "size-desc",
|
|
89
|
+
"pinnedValues": ["__REST__", ""]
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Pin specific values + auto-fill + N/A:**
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"protein_families": {
|
|
99
|
+
"maxVisibleValues": 13,
|
|
100
|
+
"sortMode": "manual",
|
|
101
|
+
"zOrderSort": "size-desc",
|
|
102
|
+
"pinnedValues": ["familyA", "familyB", "__REST__", ""]
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Here `familyA` gets zOrder 0, `familyB` zOrder 1, the next 10 top-frequency values fill slots 2–11, and N/A gets slot 12.
|
|
108
|
+
|
|
109
|
+
### `zOrderSort`
|
|
110
|
+
|
|
111
|
+
Decouples zOrder assignment from the stored `sortMode`. Useful pattern: `zOrderSort: "size-desc"` computes frequency-based zOrders, while `sortMode: "manual"` tells the frontend to display in that order. Without `zOrderSort`, zOrder assignment falls back to `sortMode`.
|
|
112
|
+
|
|
113
|
+
## Value preprocessing
|
|
114
|
+
|
|
115
|
+
Raw annotation values are preprocessed to match the ProtSpace web frontend **before** settings are applied. **All settings (including `pinnedValues`) must use display names** (after preprocessing).
|
|
116
|
+
|
|
117
|
+
| Delimiter | Behavior | Example |
|
|
118
|
+
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- |
|
|
119
|
+
| Pipe `\|` | Part after `\|` is a source tag — trimmed for display. Multiple raw variants with the same display name merge into one entry with combined count. | `"familyA\|IC"` → `"familyA"` |
|
|
120
|
+
| Semicolon `;` | Multi-label split — each part becomes a separate entry. The protein counts toward all resulting categories. | `"familyA;familyB"` → `"familyA"` and `"familyB"` |
|
|
121
|
+
|
|
122
|
+
Combined: `"familyA|IC;familyB|SAM"` → split by `;` → `"familyA|IC"`, `"familyB|SAM"` → trim `|` → `"familyA"`, `"familyB"`.
|