genome-spy-python 0.2.0__tar.gz → 0.3.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.
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/CHANGELOG.md +15 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/PKG-INFO +1 -1
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/THIRD_PARTY_NOTICES.md +5 -6
- genome_spy_python-0.3.0/docs/_static/gallery/p53_sequence_comparison.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/datasets.md +5 -5
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/brush_linked_genome_tracks.py +11 -5
- genome_spy_python-0.3.0/docs/examples/p53_sequence_comparison.md +41 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/p53_sequence_comparison.py +107 -52
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/notebooks/brush_linked_genome_tracks.ipynb +89 -23
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/pyproject.toml +1 -1
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/__init__.py +1 -1
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/datasets/__init__.py +1 -1
- genome_spy_python-0.3.0/src/genome_spy/datasets/data/p53_sequence_comparison_aligned.fasta.gz +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/tests/test_chart.py +1 -1
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/tests/test_combined_gallery_data.py +21 -26
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/tests/test_docs_gallery.py +65 -16
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/tools/check_notebook_rendering.py +6 -1
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/tools/prepare_combined_gallery_data.py +3 -61
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/uv.lock +1 -1
- genome_spy_python-0.2.0/docs/_static/gallery/p53_sequence_comparison.png +0 -0
- genome_spy_python-0.2.0/docs/examples/p53_sequence_comparison.md +0 -29
- genome_spy_python-0.2.0/src/genome_spy/datasets/data/p53_sequence_comparison.json.gz +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/.agents/skills/commit/SKILL.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/.agents/skills/proper-code-review/SKILL.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/.agents/skills/proper-code-review/references/correctness.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/.agents/skills/proper-code-review/references/design.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/.agents/skills/proper-code-review/references/performance.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/.claude/skills/commit/SKILL.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/.claude/skills/proper-code-review/SKILL.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/.claude/skills/proper-code-review/references/correctness.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/.claude/skills/proper-code-review/references/design.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/.claude/skills/proper-code-review/references/performance.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/.gitattributes +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/.github/workflows/ci.yml +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/.github/workflows/docs.yml +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/.github/workflows/release.yml +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/.gitignore +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/.pre-commit-config.yaml +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/.python-version +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/AGENTS.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/CLAUDE.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/CONTRIBUTING.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/LICENSE +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/LICENSES/ALTAIR-BSD-3-Clause.txt +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/LICENSES/GALLERY-DATA-MIT.txt +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/README.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_ext/genomespy_gallery.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/data/README.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/data/airway_metadata.csv +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/data/airway_scaledcounts.csv +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/data/hapmap_gwas.csv +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/data/oncoprint_dataset3.json +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/data/pik3ca_mutations.json +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/external-links.js +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/airway_ma_plot.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/airway_volcano_plot.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/ascat_copy_number.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/ascat_fitting.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/bam_read_alignments.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/bigbed_ccre_track.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/brush_linked_genome_tracks.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/clinvar_variants.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/combined_laml_oncoplot.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/composing_genome_browser.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/copy_number.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/cytobands.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/dynseq_bqtl.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/genome_tracks.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/gff3_gene_annotations.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/hcc1954_sv_cnv.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/indexed_fasta_sequence.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/link_mark.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/luad_oncoprint.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/manhattan_plot.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/multiple_sequence_alignment.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/needle_plot.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/oncoprint.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/pik3ca_tcga_brca_lollipop.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/point_mark.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/rainfall_plot.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/ranged_rule.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/rect_heatmap.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/refseq_scored_genes.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/sashimi_plot.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/scrollable_viewport.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/sequence_logo.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/six_frame_translation.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/stacked_genome_browser.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/tcga_ov_gistic.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/upset_mutations.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/vertical_concat.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/gallery/volcano_plot.png +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/genomespy.css +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_static/snaketie.svg +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_templates/autosummary/class.rst +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_templates/autosummary/class_own_members.rst +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/_templates/components/view-this-page.html +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/about.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/api.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/conf.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/airway_ma_plot.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/airway_ma_plot.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/airway_volcano_plot.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/airway_volcano_plot.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/ascat_copy_number.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/ascat_copy_number.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/ascat_fitting.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/ascat_fitting.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/bam_read_alignments.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/bam_read_alignments.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/bigbed_ccre_track.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/brush_linked_genome_tracks.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/clinvar_variants.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/clinvar_variants.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/combined_laml_oncoplot.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/combined_laml_oncoplot.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/composing_genome_browser.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/composing_genome_browser.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/copy_number.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/cytobands.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/cytobands.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/dynseq_bqtl.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/dynseq_bqtl.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/genome_tracks.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/gff3_gene_annotations.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/gff3_gene_annotations.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/hcc1954_sv_cnv.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/hcc1954_sv_cnv.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/indexed_fasta_sequence.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/link_mark.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/luad_oncoprint.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/luad_oncoprint.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/manhattan_plot.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/manhattan_plot.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/multiple_sequence_alignment.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/multiple_sequence_alignment.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/needle_plot.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/oncoprint.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/oncoprint.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/pik3ca_tcga_brca_lollipop.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/pik3ca_tcga_brca_lollipop.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/point_mark.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/rainfall_plot.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/rainfall_plot.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/ranged_rule.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/rect_heatmap.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/refseq_scored_genes.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/refseq_scored_genes.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/sashimi_plot.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/sashimi_plot.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/scrollable_viewport.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/sequence_logo.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/six_frame_translation.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/six_frame_translation.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/stacked_genome_browser.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/tcga_ov_gistic.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/tcga_ov_gistic.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/upset_mutations.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/upset_mutations.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/vertical_concat.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/volcano_plot.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/volcano_plot.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/getting-started.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/index.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/tutorials/annotations.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/tutorials/charts_and_marks.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/tutorials/composition.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/tutorials/configuration.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/tutorials/data_inputs.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/tutorials/display_controls.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/tutorials/encoding_channels.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/tutorials/genome_browser_layouts.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/tutorials/genomic_coordinates.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/tutorials/genomic_data.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/tutorials/getting_started.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/tutorials/importing_specifications.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/tutorials/interaction.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/tutorials/notebooks.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/tutorials/scales_and_guides.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/tutorials/serialization.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/tutorials/transforms.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/user-guide/annotations.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/user-guide/charts.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/user-guide/composition.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/user-guide/configuration.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/user-guide/data.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/user-guide/display-controls.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/user-guide/encodings.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/user-guide/genome-browser-layouts.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/user-guide/genomic-axes.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/user-guide/genomic-data.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/user-guide/importing-specifications.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/user-guide/index.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/user-guide/interaction.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/user-guide/notebooks.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/user-guide/scales-axes-legends.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/user-guide/serialization.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/user-guide/transforms.md +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/_chart_authoring.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/_conditions.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/_embed.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/_expressions.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/_parameters.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/_render.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/_utils.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/_widget.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/api.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/arrow.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/channels.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/chart.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/data.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/data_transformers.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/datasets/_airway.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/datasets/_annotations.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/datasets/_gistic.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/datasets/_grammar.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/datasets/_hapmap.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/datasets/_mutation.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/datasets/_oncoprint.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/datasets/data/airway_metadata.csv +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/datasets/data/airway_scaledcounts.csv +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/datasets/data/brca.maf.gz +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/datasets/data/hapmap_gwas.csv +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/datasets/data/mutation_impact_reference.json +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/datasets/data/oncoprint_dataset3.json +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/datasets/data/pik3ca_mutations.json +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/datasets/data/pik3ca_tcga_brca_lollipop.json +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/datasets/data/refseq_gene_bodies.csv.gz +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/datasets/data/tal1_alphagenome_reference.json.gz +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/datasets/data/tcga.tsv +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/datasets/data/tcga_laml.maf.gz +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/datasets/data/tcga_laml_annot.tsv +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/datasets/data/tcga_laml_combined_oncoplot.json.gz +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/datasets/data/tcga_ov_gistic_lesions.tsv.gz +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/datasets/data/tcga_ov_gistic_scores.tsv.gz +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/helpers.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/jupyter.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/py.typed +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/schema/__init__.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/schema/_kwds.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/schema/_typing.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/schema/capabilities.json +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/schema/channels.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/schema/composition.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/schema/core.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/schema/ergonomics.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/schema/expressions.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/schema/genome-spy-schema.json +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/schema/lazy.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/schema/mixins.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/schemapi.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/src/genome_spy/static/widget.js +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/tests/__init__.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/tests/test_arrow.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/tests/test_data_transformers.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/tests/test_datasets.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/tests/test_docs_api_reference.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/tests/test_docs_tutorial.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/tests/test_expressions.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/tests/test_generated_schema_package.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/tests/test_generated_transform_methods.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/tests/test_render_thumbnails.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/tests/test_schema_codegen.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/tests/test_widget.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/tests/widget.test.mjs +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/tools/docs_gallery.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/tools/generate_api_docs.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/tools/generate_schema_wrapper.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/tools/prepare_refseq_gene_annotations.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/tools/render_thumbnails.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/tools/schemapi/__init__.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/tools/schemapi/codegen.py +0 -0
- {genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/tools/schemapi/expression_codegen.py +0 -0
|
@@ -5,6 +5,20 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.3.0] - 2026-09-09
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- **Dataset format change:** `p53_sequence_comparison` now contains 34 protein
|
|
13
|
+
sequences aligned with MAFFT L-INS-i, replacing the unaligned JSON tables.
|
|
14
|
+
Load the aligned FASTA with
|
|
15
|
+
`load_dataset("p53_sequence_comparison", as_format="text")`; code expecting
|
|
16
|
+
the previous mapping of prepared tables must be updated.
|
|
17
|
+
- Updated the P53 gallery example to show the aligned sequences and calculate
|
|
18
|
+
conservation, gap-free fractions, and sequence logos in GenomeSpy.
|
|
19
|
+
- Made the brush notebook build progressively from a simple p-value chart to
|
|
20
|
+
linked tracks, and added an effect-size zero baseline in the notebook and gallery.
|
|
21
|
+
|
|
8
22
|
## [0.2.0] - 2026-09-09
|
|
9
23
|
|
|
10
24
|
### Added
|
|
@@ -45,5 +59,6 @@ First public alpha release, targeting GenomeSpy Core 0.87.0.
|
|
|
45
59
|
- Packaged example datasets, documentation, tutorials, and an interactive
|
|
46
60
|
visualization gallery.
|
|
47
61
|
|
|
62
|
+
[0.3.0]: https://github.com/genome-spy/genome-spy-python/compare/v0.2.0...v0.3.0
|
|
48
63
|
[0.2.0]: https://github.com/genome-spy/genome-spy-python/compare/v0.1.0...v0.2.0
|
|
49
64
|
[0.1.0]: https://github.com/genome-spy/genome-spy-python/releases/tag/v0.1.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: genome-spy-python
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: genome-spy-python is a declarative genomics visualization library for Python, built on top of the genome-spy JSON specification.
|
|
5
5
|
Project-URL: Homepage, https://github.com/genome-spy/genome-spy-python
|
|
6
6
|
Project-URL: Documentation, https://genomespy.app/genome-spy-python/
|
|
@@ -4,12 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
`tcga_laml_combined_oncoplot.json.gz` contains prepared TCGA LAML tables from
|
|
6
6
|
maftools revision `015a4cf8c69ba89a55a3fdcea911421509e9a198` (Anand Mayakonda,
|
|
7
|
-
MIT). `
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
`LICENSES/GALLERY-DATA-MIT.txt`.
|
|
7
|
+
MIT). `p53_sequence_comparison_aligned.fasta.gz` contains p53 sequences from
|
|
8
|
+
Plotly's datasets revision `0c447c47b757ad74edecab31f0d72f849d2e67c2`
|
|
9
|
+
(Plotly Technologies Inc., MIT), aligned with MAFFT v7.526 using L-INS-i. The
|
|
10
|
+
corresponding gallery pages describe processing. Copyright notices and terms
|
|
11
|
+
are included in `LICENSES/GALLERY-DATA-MIT.txt`.
|
|
13
12
|
|
|
14
13
|
## Code adapted from Vega-Altair
|
|
15
14
|
|
|
Binary file
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Example datasets
|
|
2
2
|
|
|
3
3
|
The combined LAML oncoplot uses `load_dataset("tcga_laml_combined_oncoplot")`;
|
|
4
|
-
the p53 sequence comparison
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
the p53 sequence comparison loads aligned FASTA text with
|
|
5
|
+
`load_dataset("p53_sequence_comparison", as_format="text")`. Their
|
|
6
|
+
MIT-licensed sources and processing are described in the
|
|
7
|
+
[combined oncoplot](gallery/combined_laml_oncoplot.md) and
|
|
8
8
|
[p53 comparison](gallery/p53_sequence_comparison.md) gallery pages.
|
|
9
9
|
|
|
10
10
|
The package ships the tables that the [gallery](gallery/index.md) examples use,
|
|
@@ -30,7 +30,7 @@ for JSON files. Pass `as_format="text"` to get the raw file contents instead.
|
|
|
30
30
|
| `tcga_laml_maf` | Somatic mutation calls for TCGA acute myeloid leukemia |
|
|
31
31
|
| `tcga_laml_annotations` | Clinical annotations for those leukemia samples |
|
|
32
32
|
| `tcga_laml_combined_oncoplot` | Prepared mutation, copy-number, clinical, pathway, VAF, and MutSig tables |
|
|
33
|
-
| `p53_sequence_comparison` | 34
|
|
33
|
+
| `p53_sequence_comparison` | 34 p53 protein sequences aligned with MAFFT L-INS-i, compressed FASTA |
|
|
34
34
|
| `pyoncoprint_tcga` | Alteration matrix for TCGA lung adenocarcinoma samples |
|
|
35
35
|
| `tcga_ov_gistic_scores` | GISTIC2 copy-number scores for TCGA ovarian tumors |
|
|
36
36
|
| `tcga_ov_gistic_lesions` | GISTIC2 peak regions for the same cohort |
|
{genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/brush_linked_genome_tracks.py
RENAMED
|
@@ -86,7 +86,7 @@ association_track = (
|
|
|
86
86
|
)
|
|
87
87
|
|
|
88
88
|
# Show effect sizes for the same range.
|
|
89
|
-
|
|
89
|
+
effect_points = (
|
|
90
90
|
gs.Chart()
|
|
91
91
|
.mark_point(filled=True, size=24, opacity=0.78, color="#f58518")
|
|
92
92
|
.encode(
|
|
@@ -96,10 +96,16 @@ effect_track = (
|
|
|
96
96
|
y=gs.Y("EFFECTSIZE:Q").scale(domain=[-3, 3]).title("Effect size"),
|
|
97
97
|
tooltip=["SNP:N", "GENE:N", "EFFECTSIZE:Q"],
|
|
98
98
|
)
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
# Put a zero line behind the points to separate positive and negative effects.
|
|
102
|
+
effect_baseline = (
|
|
103
|
+
gs.Chart([{"EFFECTSIZE": 0}])
|
|
104
|
+
.mark_rule(color="#888888", size=1, tooltip=None)
|
|
105
|
+
.encode(y=gs.Y("EFFECTSIZE:Q").scale(domain=[-3, 3]).title("Effect size"))
|
|
106
|
+
)
|
|
107
|
+
effect_track = (effect_baseline + effect_points).properties(
|
|
108
|
+
name="effect-size", height=95
|
|
103
109
|
)
|
|
104
110
|
|
|
105
111
|
# Add Z-scores as the third view of the selected range.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
## What to notice
|
|
2
|
+
|
|
3
|
+
Drag the overview at the bottom to choose the positions shown above. The
|
|
4
|
+
summary tracks, sequence logo, and residue matrix stay aligned as the view
|
|
5
|
+
moves. Move the pointer across the detail tracks to follow one position with
|
|
6
|
+
the vertical ruler. Hover a tile for its accession and position. Zoom in to
|
|
7
|
+
read letters.
|
|
8
|
+
|
|
9
|
+
**Conservation** shows the fraction of non-gap sequences that share the most
|
|
10
|
+
common amino acid at each alignment column. **Gap-free** shows
|
|
11
|
+
the fraction of sequences containing a residue there. Keeping the two measures
|
|
12
|
+
separate makes it clear whether a low score reflects disagreement or missing
|
|
13
|
+
aligned residues. The sequence logo shows the full non-gap residue mixture,
|
|
14
|
+
with larger letters for larger shares. The x-axis reports one-based alignment
|
|
15
|
+
columns, not residue numbers in any individual protein.
|
|
16
|
+
|
|
17
|
+
This adapts [Dash Bio AlignmentChart](https://dash.plotly.com/dash-bio/alignmentchart)
|
|
18
|
+
with GenomeSpy rectangles, text, bars, a sequence logo, and a shared brush.
|
|
19
|
+
|
|
20
|
+
:::{admonition} Data use and provenance
|
|
21
|
+
:class: note
|
|
22
|
+
|
|
23
|
+
The 34 UniProt-labelled p53 protein sequences come from the
|
|
24
|
+
[Plotly FASTA](https://github.com/plotly/datasets/blob/0c447c47b757ad74edecab31f0d72f849d2e67c2/Dash_Bio/Genetic/alignment_viewer_p53.fasta)
|
|
25
|
+
in Plotly's MIT-licensed datasets repository. They were aligned with MAFFT
|
|
26
|
+
v7.526 using the L-INS-i strategy:
|
|
27
|
+
`mafft-linsi p53.unaligned.fasta > p53.aligned.fasta`. The resulting alignment
|
|
28
|
+
is packaged as `p53_sequence_comparison_aligned.fasta.gz`.
|
|
29
|
+
:::
|
|
30
|
+
|
|
31
|
+
## Python and GenomeSpy processing
|
|
32
|
+
|
|
33
|
+
Python reads the packaged compressed FASTA, splits its 34 records, preserves
|
|
34
|
+
the UniProt identifiers and headers, and verifies that every aligned sequence
|
|
35
|
+
has the same length. GenomeSpy then flattens each sequence into residues in the
|
|
36
|
+
browser and declaratively calculates gap-free fractions, non-gap conservation,
|
|
37
|
+
and logo stacks. The Python API authors and serializes
|
|
38
|
+
those transforms; GenomeSpy executes them while rendering and interacting with
|
|
39
|
+
the visualization. For comparison, the
|
|
40
|
+
[multiple sequence alignment example](multiple_sequence_alignment.md) sends
|
|
41
|
+
FASTA directly to GenomeSpy and parses it in the browser-side dataflow.
|
{genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/docs/examples/p53_sequence_comparison.py
RENAMED
|
@@ -1,23 +1,52 @@
|
|
|
1
|
-
"""P53 sequence
|
|
1
|
+
"""P53 multiple-sequence alignment with an overview brush.
|
|
2
2
|
|
|
3
|
-
Explore the p53
|
|
4
|
-
position agreement,
|
|
3
|
+
Explore a MAFFT alignment of the p53 proteins used by Dash Bio, with residue
|
|
4
|
+
tiles, a sequence logo, position agreement, gap prevalence, and a linked
|
|
5
|
+
overview.
|
|
5
6
|
"""
|
|
6
7
|
|
|
7
8
|
import genome_spy as gs
|
|
8
|
-
from genome_spy.datasets import
|
|
9
|
+
from genome_spy.datasets import load_dataset
|
|
9
10
|
|
|
10
11
|
META = {
|
|
11
12
|
"category": "Reference annotation tracks",
|
|
12
13
|
"order": 29,
|
|
13
|
-
"height":
|
|
14
|
+
"height": 850,
|
|
14
15
|
"max_width": 1000,
|
|
15
16
|
}
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
|
|
19
|
+
def _parse_fasta(text: str) -> list[dict[str, str]]:
|
|
20
|
+
records = []
|
|
21
|
+
for block in text.strip().split(">")[1:]:
|
|
22
|
+
header, *lines = block.splitlines()
|
|
23
|
+
source_id = header.split(maxsplit=1)[0]
|
|
24
|
+
parts = source_id.split("|")
|
|
25
|
+
records.append(
|
|
26
|
+
{
|
|
27
|
+
"identifier": parts[-1],
|
|
28
|
+
"accession": parts[1] if len(parts) >= 3 else source_id,
|
|
29
|
+
"header": header,
|
|
30
|
+
"sequence": "".join("".join(lines).split()).upper(),
|
|
31
|
+
}
|
|
32
|
+
)
|
|
33
|
+
if not records:
|
|
34
|
+
raise ValueError("The FASTA alignment contains no sequences.")
|
|
35
|
+
lengths = {len(record["sequence"]) for record in records}
|
|
36
|
+
if len(lengths) != 1:
|
|
37
|
+
raise ValueError(f"The FASTA sequences are not aligned: lengths={lengths}.")
|
|
38
|
+
return records
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
# Python handles packaged-file access and the small amount of header parsing.
|
|
42
|
+
alignment_records = _parse_fasta(
|
|
43
|
+
load_dataset("p53_sequence_comparison", as_format="text")
|
|
44
|
+
)
|
|
45
|
+
alignment_length = len(alignment_records[0]["sequence"])
|
|
46
|
+
sequence_order = [record["identifier"] for record in alignment_records]
|
|
47
|
+
|
|
48
|
+
# GenomeSpy flattens the sequences and calculates all column-level summaries.
|
|
49
|
+
# Use soft amino-acid colors; alignment gaps are pale grey.
|
|
21
50
|
residue_colors = gs.Scale(
|
|
22
51
|
domain=list("ACDEFGHIKLMNPQRSTVWY-"),
|
|
23
52
|
range=[
|
|
@@ -79,17 +108,21 @@ detail_ruler = gs.ruler(
|
|
|
79
108
|
|
|
80
109
|
# Keep all positions visible here; drag to choose the range shown below.
|
|
81
110
|
overview = (
|
|
82
|
-
gs.Chart(
|
|
111
|
+
gs.Chart()
|
|
83
112
|
.mark_rect()
|
|
84
113
|
.encode(
|
|
85
114
|
x=gs.X("position:I")
|
|
86
|
-
.scale(domain=[1,
|
|
115
|
+
.scale(domain=[1, alignment_length + 1], zoom=False)
|
|
87
116
|
.title(None),
|
|
88
|
-
y=gs.Y("identifier:N")
|
|
89
|
-
.scale(domain=data["sequence_order"], reverse=True)
|
|
90
|
-
.axis(None),
|
|
117
|
+
y=gs.Y("identifier:N").scale(domain=sequence_order, reverse=True).axis(None),
|
|
91
118
|
color=color,
|
|
92
|
-
tooltip=[
|
|
119
|
+
tooltip=[
|
|
120
|
+
"identifier:N",
|
|
121
|
+
"accession:N",
|
|
122
|
+
"position:Q",
|
|
123
|
+
"residue:N",
|
|
124
|
+
"header:N",
|
|
125
|
+
],
|
|
93
126
|
)
|
|
94
127
|
.properties(height=100)
|
|
95
128
|
.add_params(selection)
|
|
@@ -101,28 +134,60 @@ overview_group = (
|
|
|
101
134
|
.properties(padding=gs.Paddings(top=6))
|
|
102
135
|
)
|
|
103
136
|
|
|
104
|
-
#
|
|
137
|
+
# Calculate the most common non-gap residue and its share at each alignment column.
|
|
138
|
+
column_consensus = (
|
|
139
|
+
gs.Chart()
|
|
140
|
+
.transform_filter(gs.datum.residue != "-")
|
|
141
|
+
.transform_aggregate(groupby=["position", "residue"])
|
|
142
|
+
.transform_window(
|
|
143
|
+
ops=["sum", "row_number"],
|
|
144
|
+
fields=["count", None],
|
|
145
|
+
as_=["nonGapCount", "rank"],
|
|
146
|
+
frame=[None, None],
|
|
147
|
+
groupby=["position"],
|
|
148
|
+
sort=gs.compare(
|
|
149
|
+
field=["count", "residue"],
|
|
150
|
+
order=["descending", "ascending"],
|
|
151
|
+
),
|
|
152
|
+
)
|
|
153
|
+
.transform_filter(gs.datum.rank == 1)
|
|
154
|
+
.transform_formula(
|
|
155
|
+
expr=gs.datum.count / gs.datum.nonGapCount,
|
|
156
|
+
as_="conservation",
|
|
157
|
+
)
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
# Show agreement among the non-gap amino acids at each position.
|
|
105
161
|
conservation = (
|
|
106
|
-
|
|
107
|
-
.mark_rect()
|
|
162
|
+
column_consensus.mark_rect()
|
|
108
163
|
.encode(
|
|
109
164
|
x=gs.X("position:I").title(None),
|
|
110
|
-
y=gs.Y("
|
|
111
|
-
color=gs.Color("
|
|
165
|
+
y=gs.Y("conservation:Q").scale(domain=[0, 1]).axis(tickCount=3, title=None),
|
|
166
|
+
color=gs.Color("conservation:Q")
|
|
112
167
|
.scale(domain=[0, 1], scheme="viridis")
|
|
113
168
|
.legend(title="Conservation", gradientLength=140, tickCount=3),
|
|
114
|
-
tooltip=["position:Q", "
|
|
169
|
+
tooltip=["position:Q", "conservation:Q", "residue:N", "nonGapCount:Q"],
|
|
115
170
|
)
|
|
116
171
|
.properties(height=60, title=gs.title("Conservation", style="track-title"))
|
|
117
172
|
)
|
|
118
|
-
# Show the fraction of sequences without a gap at each
|
|
173
|
+
# Show the fraction of sequences without a gap at each alignment column.
|
|
119
174
|
gap_free = (
|
|
120
|
-
gs.Chart(
|
|
175
|
+
gs.Chart()
|
|
176
|
+
.transform_formula(
|
|
177
|
+
expr=gs.expr.if_(gs.datum.residue == "-", 0, 1),
|
|
178
|
+
as_="hasResidue",
|
|
179
|
+
)
|
|
180
|
+
.transform_aggregate(
|
|
181
|
+
groupby=["position"],
|
|
182
|
+
fields=["hasResidue"],
|
|
183
|
+
ops=["mean"],
|
|
184
|
+
as_=["gapFree"],
|
|
185
|
+
)
|
|
121
186
|
.mark_rect(color="#b4bbc2")
|
|
122
187
|
.encode(
|
|
123
188
|
x=gs.X("position:I").title(None),
|
|
124
|
-
y=gs.Y("
|
|
125
|
-
tooltip=["position:Q", "
|
|
189
|
+
y=gs.Y("gapFree:Q").scale(domain=[0, 1]).axis(tickCount=3, title=None),
|
|
190
|
+
tooltip=["position:Q", "gapFree:Q"],
|
|
126
191
|
)
|
|
127
192
|
.properties(
|
|
128
193
|
height=30,
|
|
@@ -131,25 +196,9 @@ gap_free = (
|
|
|
131
196
|
)
|
|
132
197
|
)
|
|
133
198
|
|
|
134
|
-
# Show the most common amino acid as a compact consensus row.
|
|
135
|
-
consensus_tiles = (
|
|
136
|
-
gs.Chart(data["columns"])
|
|
137
|
-
.mark_rect()
|
|
138
|
-
.encode(
|
|
139
|
-
x=gs.X("position:I").title(None),
|
|
140
|
-
y=gs.Y("identifier:N").title(None),
|
|
141
|
-
color=color,
|
|
142
|
-
tooltip=["position:Q", "residue:N", "identity:Q"],
|
|
143
|
-
)
|
|
144
|
-
)
|
|
145
|
-
consensus_letters = consensus_tiles.mark_text(size=11, fitToBand=True).encode(
|
|
146
|
-
text="residue:N", color=gs.value("#202020")
|
|
147
|
-
)
|
|
148
|
-
consensus = (consensus_tiles + consensus_letters).properties(height=15)
|
|
149
|
-
|
|
150
199
|
# Summarize the residue mixture at each position as a sequence logo.
|
|
151
|
-
|
|
152
|
-
gs.Chart(
|
|
200
|
+
sequence_logo = (
|
|
201
|
+
gs.Chart()
|
|
153
202
|
.transform_filter(gs.datum.residue != "-")
|
|
154
203
|
.transform_aggregate(groupby=["position", "residue"])
|
|
155
204
|
.transform_stack(
|
|
@@ -182,15 +231,19 @@ consensus_logo = (
|
|
|
182
231
|
|
|
183
232
|
# Draw one colored tile per amino acid, with sequence details on hover.
|
|
184
233
|
tiles = (
|
|
185
|
-
gs.Chart(
|
|
234
|
+
gs.Chart()
|
|
186
235
|
.mark_rect()
|
|
187
236
|
.encode(
|
|
188
237
|
x=gs.X("position:I").title(None),
|
|
189
|
-
y=gs.Y("identifier:N")
|
|
190
|
-
.scale(domain=data["sequence_order"], reverse=True)
|
|
191
|
-
.title(None),
|
|
238
|
+
y=gs.Y("identifier:N").scale(domain=sequence_order, reverse=True).title(None),
|
|
192
239
|
color=legend_color,
|
|
193
|
-
tooltip=[
|
|
240
|
+
tooltip=[
|
|
241
|
+
"identifier:N",
|
|
242
|
+
"accession:N",
|
|
243
|
+
"position:Q",
|
|
244
|
+
"residue:N",
|
|
245
|
+
"header:N",
|
|
246
|
+
],
|
|
194
247
|
)
|
|
195
248
|
)
|
|
196
249
|
# Add letters when there is enough room to read them.
|
|
@@ -204,8 +257,7 @@ details = (
|
|
|
204
257
|
gs.vconcat(
|
|
205
258
|
gap_free,
|
|
206
259
|
conservation,
|
|
207
|
-
|
|
208
|
-
consensus_logo,
|
|
260
|
+
sequence_logo,
|
|
209
261
|
sequences,
|
|
210
262
|
spacing=6,
|
|
211
263
|
)
|
|
@@ -228,10 +280,13 @@ chart = (
|
|
|
228
280
|
gs.vconcat(details, overview_group, spacing=2)
|
|
229
281
|
.add_params(brush)
|
|
230
282
|
.properties(
|
|
283
|
+
data=alignment_records,
|
|
231
284
|
width="container",
|
|
232
|
-
title="P53
|
|
233
|
-
description="34
|
|
285
|
+
title="P53 protein alignment: overview and residue detail",
|
|
286
|
+
description="A 34-sequence p53 protein alignment generated with MAFFT L-INS-i. Drag the overview or zoom the detail tracks to compare alignment columns; grey cells are alignment gaps.",
|
|
234
287
|
)
|
|
288
|
+
.transform_flatten_sequence(as_=["position", "residue"])
|
|
289
|
+
.transform_formula(expr=gs.datum.position + 1, as_="position")
|
|
235
290
|
.resolve_scale(x="independent", y="independent")
|
|
236
291
|
.resolve_legend(color="collected")
|
|
237
292
|
.configure_legend(
|
{genome_spy_python-0.2.0 → genome_spy_python-0.3.0}/notebooks/brush_linked_genome_tracks.ipynb
RENAMED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"\n",
|
|
10
10
|
"This notebook makes an interactive genome visualization with [GenomeSpy for Python](https://genomespy.app/genome-spy-python/).\n",
|
|
11
11
|
"\n",
|
|
12
|
-
"
|
|
12
|
+
"Start with a simple plot of p-values. Then add a draggable overview and two more tracks that follow the same selected region.\n",
|
|
13
13
|
"\n",
|
|
14
14
|
"You do not need to know GenomeSpy yet. Run each cell from top to bottom using the play button on its left."
|
|
15
15
|
]
|
|
@@ -109,12 +109,44 @@
|
|
|
109
109
|
"variants[[\"SNP\", \"chrom\", \"BP\", \"P\", \"EFFECTSIZE\", \"ZSCORE\"]].head()"
|
|
110
110
|
]
|
|
111
111
|
},
|
|
112
|
+
{
|
|
113
|
+
"cell_type": "markdown",
|
|
114
|
+
"id": "first-chart-explanation",
|
|
115
|
+
"metadata": {},
|
|
116
|
+
"source": [
|
|
117
|
+
"## 4. Draw a first chart\n",
|
|
118
|
+
"\n",
|
|
119
|
+
"Each point is a variant. Its position comes from `gs.Locus(\"chrom\", \"BP\")`, which combines chromosome and position into one axis. Taller points have smaller p-values. Hover over a point to see its values."
|
|
120
|
+
]
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"cell_type": "code",
|
|
124
|
+
"execution_count": null,
|
|
125
|
+
"id": "first-chart",
|
|
126
|
+
"metadata": {},
|
|
127
|
+
"outputs": [],
|
|
128
|
+
"source": [
|
|
129
|
+
"association = (\n",
|
|
130
|
+
" gs.Chart()\n",
|
|
131
|
+
" .mark_point(filled=True, size=24, opacity=0.78, color=\"#4c78a8\")\n",
|
|
132
|
+
" .encode(\n",
|
|
133
|
+
" x=gs.Locus(\"chrom\", \"BP\"),\n",
|
|
134
|
+
" y=gs.Y(\"neglog:Q\").scale(domain=y_domain).title(\"−log10 p\"),\n",
|
|
135
|
+
" tooltip=[\"SNP:N\", \"GENE:N\", \"P:Q\"],\n",
|
|
136
|
+
" )\n",
|
|
137
|
+
" .properties(height=180)\n",
|
|
138
|
+
")\n",
|
|
139
|
+
"\n",
|
|
140
|
+
"# Give this first chart its data and genome assembly, then show it.\n",
|
|
141
|
+
"association.properties(data=variants, assembly=\"hg18\")"
|
|
142
|
+
]
|
|
143
|
+
},
|
|
112
144
|
{
|
|
113
145
|
"cell_type": "markdown",
|
|
114
146
|
"id": "brush-explanation",
|
|
115
147
|
"metadata": {},
|
|
116
148
|
"source": [
|
|
117
|
-
"##
|
|
149
|
+
"## 5. Add a brush\n",
|
|
118
150
|
"\n",
|
|
119
151
|
"A **brush** is the blue rectangle you draw with the mouse. Its only job is to remember the genomic interval you selected.\n",
|
|
120
152
|
"\n",
|
|
@@ -159,11 +191,9 @@
|
|
|
159
191
|
"id": "overview-explanation",
|
|
160
192
|
"metadata": {},
|
|
161
193
|
"source": [
|
|
162
|
-
"##
|
|
194
|
+
"## 6. Build the whole-genome overview\n",
|
|
163
195
|
"\n",
|
|
164
|
-
"
|
|
165
|
-
"\n",
|
|
166
|
-
"We turn zooming off only for this overview so it always remains our complete genome map."
|
|
196
|
+
"This smaller, gray plot will sit above our first chart. It stays zoomed out so you can always choose a different region."
|
|
167
197
|
]
|
|
168
198
|
},
|
|
169
199
|
{
|
|
@@ -206,18 +236,18 @@
|
|
|
206
236
|
},
|
|
207
237
|
{
|
|
208
238
|
"cell_type": "markdown",
|
|
209
|
-
"id": "
|
|
239
|
+
"id": "link-explanation",
|
|
210
240
|
"metadata": {},
|
|
211
241
|
"source": [
|
|
212
|
-
"##
|
|
242
|
+
"## 7. Try the brush with one detail track\n",
|
|
213
243
|
"\n",
|
|
214
|
-
"
|
|
244
|
+
"Reuse the first chart, but let the brush choose its visible range with `gs.SelectionDomainRef`. Drag across the gray overview: the blue chart below follows your selection."
|
|
215
245
|
]
|
|
216
246
|
},
|
|
217
247
|
{
|
|
218
248
|
"cell_type": "code",
|
|
219
249
|
"execution_count": null,
|
|
220
|
-
"id": "
|
|
250
|
+
"id": "link-first-track",
|
|
221
251
|
"metadata": {},
|
|
222
252
|
"outputs": [],
|
|
223
253
|
"source": [
|
|
@@ -227,18 +257,39 @@
|
|
|
227
257
|
" initial=initial_region,\n",
|
|
228
258
|
")\n",
|
|
229
259
|
"\n",
|
|
230
|
-
"association_track = (\n",
|
|
231
|
-
" gs.
|
|
232
|
-
"
|
|
233
|
-
"
|
|
234
|
-
"
|
|
235
|
-
"
|
|
236
|
-
"
|
|
237
|
-
" )\n",
|
|
238
|
-
" .
|
|
260
|
+
"association_track = association.encode(\n",
|
|
261
|
+
" x=gs.Locus(\"chrom\", \"BP\").scale(domain=selected_region)\n",
|
|
262
|
+
").properties(height=95)\n",
|
|
263
|
+
"\n",
|
|
264
|
+
"linked_chart = (\n",
|
|
265
|
+
" (overview & association_track)\n",
|
|
266
|
+
" .properties(data=variants, assembly=\"hg18\", spacing=8)\n",
|
|
267
|
+
" .add_params(brush)\n",
|
|
268
|
+
" .resolve_scale(x=\"independent\", y=\"independent\")\n",
|
|
269
|
+
" .resolve_axis(x=\"independent\", y=\"independent\")\n",
|
|
239
270
|
")\n",
|
|
240
271
|
"\n",
|
|
241
|
-
"
|
|
272
|
+
"linked_chart"
|
|
273
|
+
]
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
"cell_type": "markdown",
|
|
277
|
+
"id": "details-explanation",
|
|
278
|
+
"metadata": {},
|
|
279
|
+
"source": [
|
|
280
|
+
"## 8. Add two more measurements\n",
|
|
281
|
+
"\n",
|
|
282
|
+
"Effect size and Z-score give two more views of the same variants. Both use `selected_region`, so they follow the same brush."
|
|
283
|
+
]
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
"cell_type": "code",
|
|
287
|
+
"execution_count": null,
|
|
288
|
+
"id": "build-details",
|
|
289
|
+
"metadata": {},
|
|
290
|
+
"outputs": [],
|
|
291
|
+
"source": [
|
|
292
|
+
"effect_points = (\n",
|
|
242
293
|
" gs.Chart()\n",
|
|
243
294
|
" .mark_point(filled=True, size=24, opacity=0.78, color=\"#f58518\")\n",
|
|
244
295
|
" .encode(\n",
|
|
@@ -246,9 +297,16 @@
|
|
|
246
297
|
" y=gs.Y(\"EFFECTSIZE:Q\").scale(domain=[-3, 3]).title(\"Effect size\"),\n",
|
|
247
298
|
" tooltip=[\"SNP:N\", \"GENE:N\", \"EFFECTSIZE:Q\"],\n",
|
|
248
299
|
" )\n",
|
|
249
|
-
" .properties(height=95)\n",
|
|
250
300
|
")\n",
|
|
251
301
|
"\n",
|
|
302
|
+
"# A zero line separates positive and negative effects.\n",
|
|
303
|
+
"effect_baseline = (\n",
|
|
304
|
+
" gs.Chart([{\"EFFECTSIZE\": 0}])\n",
|
|
305
|
+
" .mark_rule(color=\"#888888\", size=1, tooltip=None)\n",
|
|
306
|
+
" .encode(y=gs.Y(\"EFFECTSIZE:Q\").scale(domain=[-3, 3]).title(\"Effect size\"))\n",
|
|
307
|
+
")\n",
|
|
308
|
+
"effect_track = (effect_baseline + effect_points).properties(height=95)\n",
|
|
309
|
+
"\n",
|
|
252
310
|
"zscore_track = (\n",
|
|
253
311
|
" gs.Chart()\n",
|
|
254
312
|
" .mark_point(filled=True, size=24, opacity=0.78, color=\"#54a24b\")\n",
|
|
@@ -266,7 +324,7 @@
|
|
|
266
324
|
"id": "display-explanation",
|
|
267
325
|
"metadata": {},
|
|
268
326
|
"source": [
|
|
269
|
-
"##
|
|
327
|
+
"## 9. Put it all together\n",
|
|
270
328
|
"\n",
|
|
271
329
|
"`vconcat` stacks charts vertically. The whole composition receives the same data, genome assembly, and brush parameter.\n",
|
|
272
330
|
"\n",
|
|
@@ -286,7 +344,15 @@
|
|
|
286
344
|
"outputs": [],
|
|
287
345
|
"source": [
|
|
288
346
|
"chart = (\n",
|
|
289
|
-
" gs.vconcat(
|
|
347
|
+
" gs.vconcat(\n",
|
|
348
|
+
" overview,\n",
|
|
349
|
+
" # Only the bottom detail track needs x-axis labels.\n",
|
|
350
|
+
" association_track.encode(\n",
|
|
351
|
+
" x=gs.Locus(\"chrom\", \"BP\").scale(domain=selected_region).axis(None)\n",
|
|
352
|
+
" ),\n",
|
|
353
|
+
" effect_track,\n",
|
|
354
|
+
" zscore_track,\n",
|
|
355
|
+
" )\n",
|
|
290
356
|
" .properties(\n",
|
|
291
357
|
" data=variants,\n",
|
|
292
358
|
" assembly=\"hg18\",\n",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "genome-spy-python"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.3.0"
|
|
4
4
|
description = "genome-spy-python is a declarative genomics visualization library for Python, built on top of the genome-spy JSON specification."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11"
|
|
@@ -21,7 +21,7 @@ _DATASETS = {
|
|
|
21
21
|
"brca_maf": "brca.maf.gz",
|
|
22
22
|
"hapmap_gwas": "hapmap_gwas.csv",
|
|
23
23
|
"mutation_impact_reference": "mutation_impact_reference.json",
|
|
24
|
-
"p53_sequence_comparison": "
|
|
24
|
+
"p53_sequence_comparison": "p53_sequence_comparison_aligned.fasta.gz",
|
|
25
25
|
"pik3ca_mutations": "pik3ca_mutations.json",
|
|
26
26
|
"pik3ca_tcga_brca_lollipop": "pik3ca_tcga_brca_lollipop.json",
|
|
27
27
|
"tal1_alphagenome_reference": "tal1_alphagenome_reference.json.gz",
|
|
Binary file
|