iplotx 0.11.1__tar.gz → 0.12.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.
- {iplotx-0.11.1 → iplotx-0.12.0}/PKG-INFO +10 -6
- {iplotx-0.11.1 → iplotx-0.12.0}/README.md +7 -4
- iplotx-0.12.0/docs/source/_static/custom-icons.js +30 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/docs/source/api/complete_style_specification.md +6 -2
- {iplotx-0.11.1 → iplotx-0.12.0}/docs/source/conf.py +21 -1
- {iplotx-0.11.1 → iplotx-0.12.0}/docs/source/index.md +17 -14
- {iplotx-0.11.1 → iplotx-0.12.0}/docs/source/providers.md +1 -1
- {iplotx-0.11.1 → iplotx-0.12.0}/docs/source/sg_execution_times.rst +9 -3
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/basic/plot_grouping.py +5 -0
- iplotx-0.12.0/gallery/style/plot_depthshade.py +46 -0
- iplotx-0.12.0/gallery/tree/plot_dendropy.py +50 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/art3d/edge/__init__.py +120 -1
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/edge/__init__.py +1 -0
- iplotx-0.12.0/iplotx/ingest/providers/tree/dendropy.py +59 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/network.py +4 -1
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/style/leaf_info.py +1 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/utils/matplotlib.py +78 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/version.py +1 -1
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/vertex.py +1 -1
- {iplotx-0.11.1 → iplotx-0.12.0}/pyproject.toml +5 -2
- iplotx-0.12.0/tests/baseline_images/test_dendropy/cascades.png +1 -0
- iplotx-0.12.0/tests/baseline_images/test_dendropy/directed_child.png +1 -0
- iplotx-0.12.0/tests/baseline_images/test_dendropy/leaf_labels.png +1 -0
- iplotx-0.12.0/tests/baseline_images/test_dendropy/leaf_labels_hmargin.png +1 -0
- iplotx-0.12.0/tests/baseline_images/test_dendropy/leafedges.png +1 -0
- iplotx-0.12.0/tests/baseline_images/test_dendropy/tree_basic.png +1 -0
- iplotx-0.12.0/tests/baseline_images/test_dendropy/tree_radial.png +1 -0
- iplotx-0.12.0/tests/baseline_images/test_igraph_3d/directed.png +0 -0
- iplotx-0.12.0/tests/baseline_images/test_igraph_3d/undirected.png +0 -0
- iplotx-0.12.0/tests/baseline_images/test_igraph_3d/vertex_labels.png +0 -0
- iplotx-0.12.0/tests/test_dendropy.py +236 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/uv.lock +81 -28
- iplotx-0.11.1/tests/baseline_images/test_igraph_3d/directed.png +0 -0
- iplotx-0.11.1/tests/baseline_images/test_igraph_3d/undirected.png +0 -0
- iplotx-0.11.1/tests/baseline_images/test_igraph_3d/vertex_labels.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/.github/workflows/publish.yml +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/.github/workflows/test.yml +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/.gitignore +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/.pre-commit-config.yaml +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/.readthedocs.yaml +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/LICENSE +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/MANIFEST.in +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/assets/pylint.svg +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/docs/Makefile +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/docs/make.bat +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/docs/source/_static/banner.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/docs/source/_static/graph_basic.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/docs/source/_templates/layout.html +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/docs/source/api/artists.md +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/docs/source/api/plotting.md +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/docs/source/api/providers.md +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/docs/source/api/style.md +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/docs/source/api.md +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/docs/source/images/sphx_glr_plot_basic_001.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/docs/source/images/thumb/sphx_glr_plot_basic_thumb.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/docs/source/style.md +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/GALLERY_HEADER.rst +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/basic/GALLERY_HEADER.rst +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/basic/plot_3d.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/basic/plot_basic.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/basic/plot_big_curves.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/basic/plot_dag.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/basic/plot_directed.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/basic/plot_house.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/basic/plot_loops.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/basic/plot_simple_path.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/biology/GALLERY_HEADER.rst +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/biology/data/80201010000000001.mst +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/biology/data/GN-tree.json +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/biology/data/breast_cancer_string_interactions_short.tsv +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/biology/data/breast_cancer_string_network_coordinates.tsv +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/biology/data/cell_cycle_arrest_string_interactions_short.tsv +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/biology/data/cell_cycle_arrest_string_network_coordinates.tsv +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/biology/data/fevo-08-588430_DataSheet1_S1.csv +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/biology/plot_animal_phylogeny.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/biology/plot_antibody_clone.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/biology/plot_breast_cancer_ppi.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/biology/plot_cell_cycle_arrest.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/biology/plot_food_network.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/biology/plot_foraging_table.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/biology/plot_pollinators.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/biology/plot_ppi.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/biology/plot_tca_cycle.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/network_science/GALLERY_HEADER.rst +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/network_science/data/chess_masters_WCC.pgn.bz2 +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/network_science/data/knuth_miles.txt.gz +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/network_science/plot_arrowlawn.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/network_science/plot_chess_masters.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/network_science/plot_cliques.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/network_science/plot_cluster_layout.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/network_science/plot_company_structure.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/network_science/plot_complex.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/network_science/plot_financial_network.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/network_science/plot_knuth_miles.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/network_science/plot_labels_and_colors.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/network_science/plot_max_bipartite_matching.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/network_science/plot_minimum_spanning_trees.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/network_science/plot_multipartite_layout.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/network_science/plot_parallel_igraph_networkx.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/network_science/plot_redblack.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/network_science/plot_shortest_path.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/network_science/plot_simple_networkx.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/network_science/plot_social_network_circles.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/network_science/plot_traveling_salesman.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/network_science/plot_with_colorbar.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/other/GALLERY_HEADER.rst +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/other/plot_animation.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/other/plot_edit_artists.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/other/plot_feedbacks.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/other/plot_graph.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/other/plot_mouse_hover.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/other/plot_train.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/style/GALLERY_HEADER.rst +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/style/plot_arrows.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/style/plot_edgepadding.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/style/plot_elements.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/style/plot_four_grids.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/style/plot_halfarrows.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/style/plot_multistyle.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/style/plot_ports.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/style/plot_style.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/style/plot_tension.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/style/plot_vertexmarkers.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/style/plot_voronoi.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/style/plot_waypoints.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/tree/GALLERY_HEADER.rst +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/tree/data/tree-with-support.json +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/tree/plot_angular_waypoints.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/tree/plot_biopython_tree.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/tree/plot_cladeedges.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/tree/plot_cogent3_layouts.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/tree/plot_cogent3_tree.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/tree/plot_elements_tree.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/tree/plot_ete4.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/tree/plot_leafedges.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/tree/plot_leafedges_and_cascades.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/tree/plot_skbio_tree.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/tree/plot_split_edges.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/tree/plot_style_tree.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/tree/plot_support.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/tree/plot_tree_node_background.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/tree/plot_tree_style_clades.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/tree/plot_trees_of_trees.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/zero_dependency/GALLERY_HEADER.rst +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/zero_dependency/plot_simplenetworkdataprovider.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/gallery/zero_dependency/plot_simpletreedataprovider.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/__init__.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/art3d/edge/arrow.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/art3d/edge/geometry.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/art3d/vertex.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/artists.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/cascades.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/edge/arrow.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/edge/geometry.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/edge/leaf.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/edge/ports.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/groups.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/ingest/__init__.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/ingest/heuristics.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/ingest/providers/network/igraph.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/ingest/providers/network/networkx.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/ingest/providers/network/simple.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/ingest/providers/tree/biopython.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/ingest/providers/tree/cogent3.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/ingest/providers/tree/ete4.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/ingest/providers/tree/simple.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/ingest/providers/tree/skbio.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/ingest/typing.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/label.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/layout.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/plotting.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/style/__init__.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/style/library.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/tree.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/typing.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/utils/geometry.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/utils/internal.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/iplotx/utils/style.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/scripts/copy_github_release_into_version.sh +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/scripts/make_banner.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/scripts/update_pylint_badge.sh +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_biopython/cascades.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_biopython/directed_child.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_biopython/leaf_labels.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_biopython/leaf_labels_hmargin.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_biopython/leafedges.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_biopython/show_support.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_biopython/tree_basic.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_biopython/tree_radial.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_cogent3/leaf_labels.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_cogent3/leaf_labels_hmargin.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_cogent3/tree_basic.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_cogent3/tree_radial.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_ete4/leaf_labels.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_ete4/leaf_labels_hmargin.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_ete4/split_edges.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_ete4/tree_basic.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_ete4/tree_radial.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_igraph/clustering_directed.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_igraph/clustering_directed_large.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_igraph/graph_basic.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_igraph/graph_directed.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_igraph/graph_directed_curved_loops.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_igraph/graph_edit_children.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_igraph/graph_labels.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_igraph/graph_layout_attribute.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_igraph/graph_null.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_igraph/graph_squares_directed.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_igraph/graph_vertexsize.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_igraph/graph_with_curved_edges.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_igraph/igraph_layout_object.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_igraph/multigraph_with_curved_edges_undirected.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_networkx/cluster-layout.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_networkx/complex.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_networkx/complex_rotatelabels.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_networkx/directed_graph.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_networkx/directed_graph_with_colorbar.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_networkx/empty_graph.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_networkx/flat_style.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_networkx/house_with_colors.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_networkx/labels_and_colors.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_networkx/shortest_path.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_networkx/simple_graph.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_simple_network_provider/graph_basic.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_simple_network_provider/graph_directed.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_simple_network_provider/graph_labels.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_skbio/leaf_labels.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_skbio/leaf_labels_hmargin.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_skbio/tree_basic.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/baseline_images/test_skbio/tree_radial.png +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/test_arrows.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/test_biopython.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/test_cascades.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/test_cogent3.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/test_edge.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/test_edge_geometry.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/test_ete4.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/test_geometry.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/test_heuristics.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/test_igraph.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/test_igraph_3d.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/test_ingest_protocols.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/test_matplotlib_utils.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/test_network_hotload.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/test_networkx.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/test_ports.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/test_simple_network_provider.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/test_simple_tree_provider.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/test_skbio.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/test_style.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/test_vertex.py +0 -0
- {iplotx-0.11.1 → iplotx-0.12.0}/tests/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: iplotx
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.12.0
|
|
4
4
|
Summary: Plot networkx from igraph and networkx.
|
|
5
5
|
Project-URL: Homepage, https://github.com/fabilab/iplotx
|
|
6
6
|
Project-URL: Documentation, https://readthedocs.org/iplotx
|
|
@@ -10,8 +10,9 @@ Project-URL: Changelog, https://github.com/fabilab/iplotx/blob/main/CHANGELOG.md
|
|
|
10
10
|
Author-email: Fabio Zanini <fabio.zanini@unsw.edu.au>
|
|
11
11
|
Maintainer-email: Fabio Zanini <fabio.zanini@unsw.edu.au>
|
|
12
12
|
License: MIT
|
|
13
|
-
Keywords: graph,network,plotting,visualisation
|
|
13
|
+
Keywords: graph,network,phylogeny,plotting,tree,visualisation
|
|
14
14
|
Classifier: Development Status :: 5 - Production/Stable
|
|
15
|
+
Classifier: Framework :: Matplotlib
|
|
15
16
|
Classifier: Intended Audience :: Developers
|
|
16
17
|
Classifier: Intended Audience :: Education
|
|
17
18
|
Classifier: Intended Audience :: Science/Research
|
|
@@ -52,13 +53,14 @@ Supports:
|
|
|
52
53
|
- **networks**:
|
|
53
54
|
- [networkx](https://networkx.org/)
|
|
54
55
|
- [igraph](igraph.readthedocs.io/)
|
|
55
|
-
- [minimal network data structure](https://iplotx.readthedocs.io/en/latest/gallery/plot_simplenetworkdataprovider.html#sphx-glr-gallery-plot-simplenetworkdataprovider-py) (
|
|
56
|
+
- [minimal network data structure](https://iplotx.readthedocs.io/en/latest/gallery/plot_simplenetworkdataprovider.html#sphx-glr-gallery-plot-simplenetworkdataprovider-py) (zero dependency)
|
|
56
57
|
- **trees**:
|
|
57
58
|
- [ETE4](https://etetoolkit.github.io/ete/)
|
|
58
59
|
- [cogent3](https://cogent3.org/)
|
|
59
60
|
- [Biopython](https://biopython.org/)
|
|
60
61
|
- [scikit-bio](https://scikit.bio)
|
|
61
|
-
- [
|
|
62
|
+
- [dendropy](https://jeetsukumaran.github.io/DendroPy/index.html)
|
|
63
|
+
- [minimal tree data structure](https://iplotx.readthedocs.io/en/latest/gallery/tree/plot_simpletreedataprovider.html#sphx-glr-gallery-tree-plot-simpletreedataprovider-py) (zero dependency)
|
|
62
64
|
|
|
63
65
|
In addition to the above, *any* network or tree analysis library can register an [entry point](https://iplotx.readthedocs.io/en/latest/providers.html#creating-a-custom-data-provider) to gain compatibility with `iplotx` with no intervention from our side.
|
|
64
66
|
|
|
@@ -89,15 +91,17 @@ See [gallery](https://iplotx.readthedocs.io/en/latest/gallery/index.html).
|
|
|
89
91
|
|
|
90
92
|
## Features
|
|
91
93
|
- Plot networks from multiple libraries including networkx and igraph, using matplotlib as a backend. ✅
|
|
92
|
-
- Plot trees from multiple libraries such as cogent3, ETE4, skbio, and
|
|
94
|
+
- Plot trees from multiple libraries such as cogent3, ETE4, skbio, biopython, and dendropy. ✅
|
|
93
95
|
- Flexible yet easy styling, including an internal library of styles ✅
|
|
94
96
|
- Interactive plotting, e.g. zooming and panning after the plot is created. ✅
|
|
95
97
|
- Store the plot to disk thanks to the many matplotlib backends (SVG, PNG, PDF, etc.). ✅
|
|
96
|
-
-
|
|
98
|
+
- 3D network visualisation with depth shading. ✅
|
|
99
|
+
- Efficient plotting of large graphs (up to ~1 million nodes on a laptop). ✅
|
|
97
100
|
- Edit plotting elements after the plot is created, e.g. changing node colors, labels, etc. ✅
|
|
98
101
|
- Animations, e.g. showing the evolution of a network over time. ✅
|
|
99
102
|
- Mouse and keyboard interaction, e.g. hovering over nodes/edges to get information about them. ✅
|
|
100
103
|
- Node clustering and covers, e.g. showing communities in a network. ✅
|
|
104
|
+
- Edge tension, edge waypoints, and edge ports. ✅
|
|
101
105
|
- Choice of tree layouts and orientations. ✅
|
|
102
106
|
- Tree-specific options: cascades, subtree styling, split edges, etc. ✅
|
|
103
107
|
- (WIP) Support uni- and bi-directional communication between graph object and plot object.🏗️
|
|
@@ -15,13 +15,14 @@ Supports:
|
|
|
15
15
|
- **networks**:
|
|
16
16
|
- [networkx](https://networkx.org/)
|
|
17
17
|
- [igraph](igraph.readthedocs.io/)
|
|
18
|
-
- [minimal network data structure](https://iplotx.readthedocs.io/en/latest/gallery/plot_simplenetworkdataprovider.html#sphx-glr-gallery-plot-simplenetworkdataprovider-py) (
|
|
18
|
+
- [minimal network data structure](https://iplotx.readthedocs.io/en/latest/gallery/plot_simplenetworkdataprovider.html#sphx-glr-gallery-plot-simplenetworkdataprovider-py) (zero dependency)
|
|
19
19
|
- **trees**:
|
|
20
20
|
- [ETE4](https://etetoolkit.github.io/ete/)
|
|
21
21
|
- [cogent3](https://cogent3.org/)
|
|
22
22
|
- [Biopython](https://biopython.org/)
|
|
23
23
|
- [scikit-bio](https://scikit.bio)
|
|
24
|
-
- [
|
|
24
|
+
- [dendropy](https://jeetsukumaran.github.io/DendroPy/index.html)
|
|
25
|
+
- [minimal tree data structure](https://iplotx.readthedocs.io/en/latest/gallery/tree/plot_simpletreedataprovider.html#sphx-glr-gallery-tree-plot-simpletreedataprovider-py) (zero dependency)
|
|
25
26
|
|
|
26
27
|
In addition to the above, *any* network or tree analysis library can register an [entry point](https://iplotx.readthedocs.io/en/latest/providers.html#creating-a-custom-data-provider) to gain compatibility with `iplotx` with no intervention from our side.
|
|
27
28
|
|
|
@@ -52,15 +53,17 @@ See [gallery](https://iplotx.readthedocs.io/en/latest/gallery/index.html).
|
|
|
52
53
|
|
|
53
54
|
## Features
|
|
54
55
|
- Plot networks from multiple libraries including networkx and igraph, using matplotlib as a backend. ✅
|
|
55
|
-
- Plot trees from multiple libraries such as cogent3, ETE4, skbio, and
|
|
56
|
+
- Plot trees from multiple libraries such as cogent3, ETE4, skbio, biopython, and dendropy. ✅
|
|
56
57
|
- Flexible yet easy styling, including an internal library of styles ✅
|
|
57
58
|
- Interactive plotting, e.g. zooming and panning after the plot is created. ✅
|
|
58
59
|
- Store the plot to disk thanks to the many matplotlib backends (SVG, PNG, PDF, etc.). ✅
|
|
59
|
-
-
|
|
60
|
+
- 3D network visualisation with depth shading. ✅
|
|
61
|
+
- Efficient plotting of large graphs (up to ~1 million nodes on a laptop). ✅
|
|
60
62
|
- Edit plotting elements after the plot is created, e.g. changing node colors, labels, etc. ✅
|
|
61
63
|
- Animations, e.g. showing the evolution of a network over time. ✅
|
|
62
64
|
- Mouse and keyboard interaction, e.g. hovering over nodes/edges to get information about them. ✅
|
|
63
65
|
- Node clustering and covers, e.g. showing communities in a network. ✅
|
|
66
|
+
- Edge tension, edge waypoints, and edge ports. ✅
|
|
64
67
|
- Choice of tree layouts and orientations. ✅
|
|
65
68
|
- Tree-specific options: cascades, subtree styling, split edges, etc. ✅
|
|
66
69
|
- (WIP) Support uni- and bi-directional communication between graph object and plot object.🏗️
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
FontAwesome.library.add(
|
|
2
|
+
/**
|
|
3
|
+
* Custom icon definitions
|
|
4
|
+
*
|
|
5
|
+
* see https://pydata-sphinx-theme.readthedocs.io/en/latest/user_guide/header-links.html#svg-image-icons
|
|
6
|
+
*/
|
|
7
|
+
{
|
|
8
|
+
prefix: "fa-custom",
|
|
9
|
+
iconName: "pypi",
|
|
10
|
+
icon: [
|
|
11
|
+
17.313,
|
|
12
|
+
19.807,
|
|
13
|
+
[],
|
|
14
|
+
"e001",
|
|
15
|
+
// https://simpleicons.org/icons/pypi.svg
|
|
16
|
+
"m10.383 0.2-3.239 1.1769 3.1883 1.1614 3.239-1.1798zm-3.4152 1.2411-3.2362 1.1769 3.1855 1.1614 3.2369-1.1769zm6.7177 0.00281-3.2947 1.2009v3.8254l3.2947-1.1988zm-3.4145 1.2439-3.2926 1.1981v3.8254l0.17548-0.064132 3.1171-1.1347zm-6.6564 0.018325v3.8247l3.244 1.1805v-3.8254zm10.191 0.20931v2.3137l3.1777-1.1558zm3.2947 1.2425-3.2947 1.1988v3.8254l3.2947-1.1988zm-8.7058 0.45739c0.00929-1.931e-4 0.018327-2.977e-4 0.027485 0 0.25633 0.00851 0.4263 0.20713 0.42638 0.49826 1.953e-4 0.38532-0.29327 0.80469-0.65542 0.93662-0.36226 0.13215-0.65608-0.073306-0.65613-0.4588-6.28e-5 -0.38556 0.2938-0.80504 0.65613-0.93662 0.068422-0.024919 0.13655-0.038114 0.20156-0.039466zm5.2913 0.78369-3.2947 1.1988v3.8247l3.2947-1.1981zm-10.132 1.239-3.2362 1.1769 3.1883 1.1614 3.2362-1.1769zm6.7177 0.00213-3.2926 1.2016v3.8247l3.2926-1.2009zm-3.4124 1.2439-3.2947 1.1988v3.8254l3.2947-1.1988zm-6.6585 0.016195v3.8275l3.244 1.1805v-3.8254zm16.9 0.21143-3.2947 1.1988v3.8247l3.2947-1.1981zm-3.4145 1.2411-3.2926 1.2016v3.8247l3.2926-1.2009zm-3.4145 1.2411-3.2926 1.2016v3.8247l3.2926-1.2009zm-3.4124 1.2432-3.2947 1.1988v3.8254l3.2947-1.1988zm-6.6585 0.019027v3.8247l3.244 1.1805v-3.8254zm13.485 1.4497-3.2947 1.1988v3.8247l3.2947-1.1981zm-3.4145 1.2411-3.2926 1.2016v3.8247l3.2926-1.2009zm2.4018 0.38127c0.0093-1.83e-4 0.01833-3.16e-4 0.02749 0 0.25633 0.0085 0.4263 0.20713 0.42638 0.49826 1.97e-4 0.38532-0.29327 0.80469-0.65542 0.93662-0.36188 0.1316-0.65525-0.07375-0.65542-0.4588-1.95e-4 -0.38532 0.29328-0.80469 0.65542-0.93662 0.06842-0.02494 0.13655-0.03819 0.20156-0.03947zm-5.8142 0.86403-3.244 1.1805v1.4201l3.244 1.1805z",
|
|
17
|
+
],
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
prefix: "fa-custom",
|
|
21
|
+
iconName: "pydata",
|
|
22
|
+
icon: [
|
|
23
|
+
24,
|
|
24
|
+
24,
|
|
25
|
+
[],
|
|
26
|
+
"e002",
|
|
27
|
+
"M12.1,17.8v5.8l-5-2.9v-5.8L12.1,17.8z M12.1,12v5.8l-5-2.9V9.1L12.1,12z M17,9.1L12.1,12v5.8l4.9-2.9V9.1z M12.1,6.2L7,9.1l5,2.9L17,9.1L12.1,6.2z M17,9.1V3.3l-4.9-2.8v5.8L17,9.1z",
|
|
28
|
+
],
|
|
29
|
+
},
|
|
30
|
+
);
|
|
@@ -37,6 +37,8 @@
|
|
|
37
37
|
"edgecolor": str | Any, # Color of the vertex edge (e.g. 'black', '#000000')
|
|
38
38
|
"alpha": float, # Opacity of the vertex (0.0 for fully transparent, 1.0 for fully opaque)
|
|
39
39
|
|
|
40
|
+
"depthshade": bool, # Whether to shade the color based on depth (3D only)
|
|
41
|
+
|
|
40
42
|
# Vertex label style
|
|
41
43
|
"label": {
|
|
42
44
|
"color": str | Any, # Color of the vertex label (e.g. 'white', '#FFFFFF')
|
|
@@ -91,11 +93,13 @@
|
|
|
91
93
|
# onto what color.
|
|
92
94
|
"norm": tuple[float, float] | matplotlib.colors.Normalize,
|
|
93
95
|
|
|
94
|
-
# Opacity of the
|
|
96
|
+
# Opacity of the edge (0.0 for fully transparent, 1.0 for fully opaque).
|
|
95
97
|
# If a colormap is used and this option is also set, this opacity takes
|
|
96
98
|
# priority and finally determines the transparency of the edges.
|
|
97
99
|
"alpha": float,
|
|
98
100
|
|
|
101
|
+
"depthshade": bool, # Whether to shade the color based on depth (3D only)
|
|
102
|
+
|
|
99
103
|
"curved": bool, # Whether the edge is curved (True) or straight (False)
|
|
100
104
|
|
|
101
105
|
# Tension for curved edges (0.0 for straight, higher values position the
|
|
@@ -189,7 +193,7 @@
|
|
|
189
193
|
# unintuitive and interpret it the other way around, so think carefully.
|
|
190
194
|
"rotate": bool,
|
|
191
195
|
|
|
192
|
-
"color": str | Any, # Color of the
|
|
196
|
+
"color": str | Any, # Color of the edge label (e.g. 'white', '#FFFFFF')
|
|
193
197
|
"horizontalalignment": str, # Horizontal alignment of the label ('left', 'center', 'right')
|
|
194
198
|
"verticalalignment": str, # Vertical alignment of the label ('top', 'center', 'bottom', 'baseline', 'center_baseline')
|
|
195
199
|
"hpadding": float, # Horizontal padding around the label
|
|
@@ -67,8 +67,28 @@ exclude_patterns = []
|
|
|
67
67
|
# -- Options for HTML output -------------------------------------------------
|
|
68
68
|
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
|
|
69
69
|
|
|
70
|
-
html_theme = "
|
|
70
|
+
html_theme = "pydata_sphinx_theme"
|
|
71
71
|
html_static_path = ["_static"]
|
|
72
|
+
html_js_files = [
|
|
73
|
+
("custom-icons.js", {"defer": "defer"}),
|
|
74
|
+
]
|
|
75
|
+
|
|
76
|
+
html_theme_options = {
|
|
77
|
+
"header_links_before_dropdown": 4,
|
|
78
|
+
"icon_links": [
|
|
79
|
+
{
|
|
80
|
+
"name": "GitHub",
|
|
81
|
+
"url": "https://github.com/fabilab/iplotx",
|
|
82
|
+
"icon": "fa-brands fa-github",
|
|
83
|
+
"type": "fontawesome",
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"name": "PyPI",
|
|
87
|
+
"url": "https://pypi.org/project/iplotx",
|
|
88
|
+
"icon": "fa-custom fa-pypi",
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
}
|
|
72
92
|
|
|
73
93
|
# -----------------------------------------------------------------------------
|
|
74
94
|
# Source code links (credit to the matplotlib project for this part)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# iplotx documentation
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[iplotx](https://github.com/fabilab/iplotx) is a Python library to display graphs/networks and trees with [matplotlib](https://matplotlib.org/). It natively supports [networkx](https://networkx.org/) and [igraph](https://python.igraph.org/) networks and [biopython](https://biopython.org/), [scikit-bio](https://scikit.bio/), [cogent3](https://cogent3.org/), [ETE4](https://etetoolkit.github.io/ete/), and [dendropy](https://jeetsukumaran.github.io/DendroPy/index.html) trees.
|
|
4
4
|
|
|
5
5
|
`iplotx` guarantees the **exact same visual appearance** independently of what library you used to construct the network/tree.
|
|
6
6
|
|
|
@@ -54,12 +54,6 @@ Either way, the result is the same:
|
|
|
54
54
|
See <project:gallery/index.rst> for examples of plots made with `iplotx`. Feel free to suggest new examples on GitHub by opening a new issue or pull request!
|
|
55
55
|
|
|
56
56
|
## Features
|
|
57
|
-
```{important}
|
|
58
|
-
If you are the maintainer of a network/graph/tree analysis library and would like
|
|
59
|
-
to propose improvements or see support for it, please reach out with an issue/PR
|
|
60
|
-
on GitHub!
|
|
61
|
-
```
|
|
62
|
-
|
|
63
57
|
`iplotx`'s features' include:
|
|
64
58
|
- per-edge and per-vertex styling using sequences or dictionaries
|
|
65
59
|
- labels
|
|
@@ -77,12 +71,13 @@ See <project:gallery/index.rst> for examples of plots made with `iplotx`. Feel f
|
|
|
77
71
|
- correct HiDPI scaling (e.g. retina screens) including for vertex sizes, arrow sizes, and edge offsets
|
|
78
72
|
- a consistent `matplotlib` artist hierarchy
|
|
79
73
|
- post-plot editability (e.g. for animations)
|
|
80
|
-
-
|
|
74
|
+
- interoperability with other charting tools (e.g. `seaborn`)
|
|
81
75
|
- chainable style contexts
|
|
82
76
|
- vertex clusterings and covers with convex hulls and rounding
|
|
83
|
-
- a plugin mechanism for additional libraries
|
|
84
|
-
- animations (see <project:gallery/plot_animation.rst>)
|
|
85
|
-
-
|
|
77
|
+
- a plugin mechanism for additional libraries
|
|
78
|
+
- animations (see <project:gallery/other/plot_animation.rst>)
|
|
79
|
+
- 3D visualisations
|
|
80
|
+
- mouse/keyboard interaction and events (e.g. hover, click, see <project:gallery/other/plot_mouse_hover.rst>)
|
|
86
81
|
- ... and probably more by the time you read this.
|
|
87
82
|
|
|
88
83
|
## Styles
|
|
@@ -110,17 +105,25 @@ See <project:api.md> for reference documentation of all functions and classes in
|
|
|
110
105
|
## Rationale
|
|
111
106
|
We believe graph **analysis**, graph **layouting**, and graph **visualisation** to be three separate tasks. `iplotx` currently focuses on visualisation. It can also compute simple tree layouts and might expand towards network layouts in the future.
|
|
112
107
|
|
|
108
|
+
## Contributing
|
|
109
|
+
Open an [issue on GitHub](https://github.com/fabilab/iplotx/issues) to request features, report bugs, or show intention in contributing. Pull requests are very welcome.
|
|
110
|
+
|
|
111
|
+
```{important}
|
|
112
|
+
If you are the maintainer of a network/graph/tree analysis library and would like
|
|
113
|
+
to propose improvements or see support for it, please reach out with an issue/PR
|
|
114
|
+
on GitHub!
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Sitemap
|
|
113
118
|
```{toctree}
|
|
114
119
|
:maxdepth: 2
|
|
115
120
|
:caption: Contents
|
|
116
121
|
|
|
117
122
|
gallery/index
|
|
118
123
|
style
|
|
119
|
-
Data providers <providers>
|
|
120
124
|
API <api>
|
|
121
|
-
Plotting API <api/plotting>
|
|
122
|
-
Styling API <api/style>
|
|
123
125
|
Complete style specification <api/complete_style_specification>
|
|
126
|
+
Data providers <providers>
|
|
124
127
|
Artist hierarchy <api/artists>
|
|
125
128
|
Data provider protocols <api/providers>
|
|
126
129
|
```
|
|
@@ -51,7 +51,7 @@ A straightforward `NetworkDataProvider` implementation for this network data str
|
|
|
51
51
|
)
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
See <project:gallery/plot_simpledataprovider.md> for the full gallery example including vertex labels and styling.
|
|
54
|
+
See <project:gallery/zero_dependencies/plot_simpledataprovider.md> for the full gallery example including vertex labels and styling.
|
|
55
55
|
|
|
56
56
|
```{tip}
|
|
57
57
|
This example also shows how to use `iplotx` without installing any network analysis
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
Computation times
|
|
8
8
|
=================
|
|
9
|
-
**00:00.
|
|
9
|
+
**00:00.525** total execution time for 75 files **from all galleries**:
|
|
10
10
|
|
|
11
11
|
.. container::
|
|
12
12
|
|
|
@@ -32,8 +32,8 @@ Computation times
|
|
|
32
32
|
* - Example
|
|
33
33
|
- Time
|
|
34
34
|
- Mem (MB)
|
|
35
|
-
* - :ref:`
|
|
36
|
-
- 00:00.
|
|
35
|
+
* - :ref:`sphx_glr_gallery_tree_plot_dendropy.py` (``../../gallery/tree/plot_dendropy.py``)
|
|
36
|
+
- 00:00.525
|
|
37
37
|
- 0.0
|
|
38
38
|
* - :ref:`sphx_glr_gallery_basic_plot_3d.py` (``../../gallery/basic/plot_3d.py``)
|
|
39
39
|
- 00:00.000
|
|
@@ -50,6 +50,9 @@ Computation times
|
|
|
50
50
|
* - :ref:`sphx_glr_gallery_basic_plot_directed.py` (``../../gallery/basic/plot_directed.py``)
|
|
51
51
|
- 00:00.000
|
|
52
52
|
- 0.0
|
|
53
|
+
* - :ref:`sphx_glr_gallery_basic_plot_grouping.py` (``../../gallery/basic/plot_grouping.py``)
|
|
54
|
+
- 00:00.000
|
|
55
|
+
- 0.0
|
|
53
56
|
* - :ref:`sphx_glr_gallery_basic_plot_house.py` (``../../gallery/basic/plot_house.py``)
|
|
54
57
|
- 00:00.000
|
|
55
58
|
- 0.0
|
|
@@ -164,6 +167,9 @@ Computation times
|
|
|
164
167
|
* - :ref:`sphx_glr_gallery_style_plot_arrows.py` (``../../gallery/style/plot_arrows.py``)
|
|
165
168
|
- 00:00.000
|
|
166
169
|
- 0.0
|
|
170
|
+
* - :ref:`sphx_glr_gallery_style_plot_depthshade.py` (``../../gallery/style/plot_depthshade.py``)
|
|
171
|
+
- 00:00.000
|
|
172
|
+
- 0.0
|
|
167
173
|
* - :ref:`sphx_glr_gallery_style_plot_edgepadding.py` (``../../gallery/style/plot_edgepadding.py``)
|
|
168
174
|
- 00:00.000
|
|
169
175
|
- 0.0
|
|
@@ -63,6 +63,11 @@ plt.gca().set_aspect(1.0)
|
|
|
63
63
|
#
|
|
64
64
|
# This can also be achieved with two separate calls, the first one to draw the network and the second to draw the grouping.
|
|
65
65
|
|
|
66
|
+
import igraph as ig
|
|
67
|
+
import matplotlib.pyplot as plt
|
|
68
|
+
import iplotx as ipx
|
|
69
|
+
|
|
70
|
+
g = ig.Graph.Ring(8)
|
|
66
71
|
layout = g.layout("circle")
|
|
67
72
|
fig, ax = plt.subplots(figsize=(5, 5))
|
|
68
73
|
ipx.network(
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"""
|
|
2
|
+
3D depth shading
|
|
3
|
+
================
|
|
4
|
+
|
|
5
|
+
This example shows to to use depth shading in 3D plots to reduce the opacity (increase transparency) of
|
|
6
|
+
vertices and edges that are further away from the viewer. This gives a better sense of depth but can be
|
|
7
|
+
confusing in some cases, so there are style options to turn it off.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import igraph as ig
|
|
11
|
+
import iplotx as ipx
|
|
12
|
+
|
|
13
|
+
g = ig.Graph.Erdos_Renyi(15, m=20)
|
|
14
|
+
|
|
15
|
+
layout = g.layout_fruchterman_reingold_3d()
|
|
16
|
+
|
|
17
|
+
ipx.network(
|
|
18
|
+
g,
|
|
19
|
+
layout,
|
|
20
|
+
vertex_alpha=0.9,
|
|
21
|
+
figsize=(8, 8),
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
# %%
|
|
25
|
+
# Notice that depth shading is a 0-1 multiplier on top of the existing alpha value, so no vertex will have
|
|
26
|
+
# alpha (opacity) greater than 0.9 in this example, but vertices that are further back will have values
|
|
27
|
+
# below 0.9 (the minimum is usually 0.1).
|
|
28
|
+
#
|
|
29
|
+
# .. tip::
|
|
30
|
+
# To get a better sense of depth shading, use Matplotlib with an interactive backend and rotate the
|
|
31
|
+
# plot using the mouse.
|
|
32
|
+
#
|
|
33
|
+
# You can turn off depth shading by setting ``depthshade=False`` for vertices and/or edges:
|
|
34
|
+
|
|
35
|
+
ipx.network(
|
|
36
|
+
g,
|
|
37
|
+
layout,
|
|
38
|
+
vertex_alpha=0.9,
|
|
39
|
+
figsize=(8, 8),
|
|
40
|
+
vertex_depthshade=False,
|
|
41
|
+
edge_depthshade=False,
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
# %%
|
|
45
|
+
# In this case all vertices have the same opacity (0.9) regardless of their depth, and all edges have an
|
|
46
|
+
# opacity of 1.0 (no transparency).
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Dendropy tree
|
|
3
|
+
=============
|
|
4
|
+
|
|
5
|
+
This example shows how to use ``iplotx`` to plot trees from ``dendropy``.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from dendropy import Tree
|
|
9
|
+
import iplotx as ipx
|
|
10
|
+
|
|
11
|
+
tree = Tree.get(data="((,(,((,),(,)))));", schema="newick")
|
|
12
|
+
|
|
13
|
+
ipx.plotting.tree(
|
|
14
|
+
tree,
|
|
15
|
+
aspect=1,
|
|
16
|
+
edge_color="grey",
|
|
17
|
+
edge_linestyle=["--", "-"],
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
# %%
|
|
21
|
+
# `iplotx` can compute a radial tree layout as well, and usual style modifications
|
|
22
|
+
# work for trees same as networks.
|
|
23
|
+
|
|
24
|
+
# sphinx_gallery_thumbnail_number = 2
|
|
25
|
+
ipx.plotting.tree(
|
|
26
|
+
tree,
|
|
27
|
+
layout="radial",
|
|
28
|
+
layout_orientation="right",
|
|
29
|
+
style=[
|
|
30
|
+
"tree",
|
|
31
|
+
{
|
|
32
|
+
"edge": {
|
|
33
|
+
"color": "navy",
|
|
34
|
+
"linewidth": 4,
|
|
35
|
+
},
|
|
36
|
+
"leaf": {
|
|
37
|
+
"label": {
|
|
38
|
+
"hmargin": 15,
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"leafedge": {
|
|
42
|
+
"color": "steelblue",
|
|
43
|
+
"linewidth": 2,
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
leaf_labels={leaf: str(i + 1) for i, leaf in enumerate(tree.leaf_nodes())},
|
|
48
|
+
aspect=1,
|
|
49
|
+
margin=(0.3, 0.1),
|
|
50
|
+
)
|
|
@@ -2,13 +2,26 @@
|
|
|
2
2
|
Module containing code to manipulate edge visualisations in 3D, especially the Edge3DCollection class.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
import numpy as np
|
|
6
|
+
from matplotlib import (
|
|
7
|
+
colors as mcolors,
|
|
8
|
+
)
|
|
9
|
+
from matplotlib.collections import (
|
|
10
|
+
LineCollection,
|
|
11
|
+
)
|
|
12
|
+
from mpl_toolkits.mplot3d import (
|
|
13
|
+
Axes3D,
|
|
14
|
+
)
|
|
6
15
|
from mpl_toolkits.mplot3d.art3d import (
|
|
7
16
|
Line3DCollection,
|
|
17
|
+
_viewlim_mask,
|
|
8
18
|
)
|
|
9
19
|
|
|
10
20
|
from ...utils.matplotlib import (
|
|
11
21
|
_forwarder,
|
|
22
|
+
_proj_transform_vectors,
|
|
23
|
+
_zalpha,
|
|
24
|
+
_get_data_scale,
|
|
12
25
|
)
|
|
13
26
|
from ...edge import (
|
|
14
27
|
EdgeCollection,
|
|
@@ -73,11 +86,113 @@ class Edge3DCollection(Line3DCollection):
|
|
|
73
86
|
segments3d.append(segment)
|
|
74
87
|
self.set_segments(segments3d)
|
|
75
88
|
|
|
89
|
+
def do_3d_projection(self):
|
|
90
|
+
"""
|
|
91
|
+
Project the points according to renderer matrix.
|
|
92
|
+
"""
|
|
93
|
+
segments = np.asanyarray(self._segments3d)
|
|
94
|
+
|
|
95
|
+
mask = False
|
|
96
|
+
if np.ma.isMA(segments):
|
|
97
|
+
mask = segments.mask
|
|
98
|
+
|
|
99
|
+
if self._axlim_clip:
|
|
100
|
+
viewlim_mask = _viewlim_mask(
|
|
101
|
+
segments[..., 0], segments[..., 1], segments[..., 2], self.axes
|
|
102
|
+
)
|
|
103
|
+
if np.any(viewlim_mask):
|
|
104
|
+
# broadcast mask to 3D
|
|
105
|
+
viewlim_mask = np.broadcast_to(
|
|
106
|
+
viewlim_mask[..., np.newaxis], (*viewlim_mask.shape, 3)
|
|
107
|
+
)
|
|
108
|
+
mask = mask | viewlim_mask
|
|
109
|
+
xyzs = np.ma.array(_proj_transform_vectors(segments, self.axes.M), mask=mask)
|
|
110
|
+
segments_2d = xyzs[..., 0:2]
|
|
111
|
+
LineCollection.set_segments(self, segments_2d)
|
|
112
|
+
|
|
113
|
+
# Use the average projected z value of each line for depthshade
|
|
114
|
+
xyzs_mean = xyzs.mean(axis=1)
|
|
115
|
+
self._data_scale = _get_data_scale(*(xyzs_mean.T))
|
|
116
|
+
self._vzs = xyzs_mean[..., 2]
|
|
117
|
+
|
|
118
|
+
# FIXME
|
|
119
|
+
if len(xyzs) > 0:
|
|
120
|
+
minz = min(xyzs[..., 2].min(), 1e9)
|
|
121
|
+
else:
|
|
122
|
+
minz = np.nan
|
|
123
|
+
return minz
|
|
124
|
+
|
|
125
|
+
def _maybe_depth_shade_and_sort_colors(self, color_array):
|
|
126
|
+
color_array = (
|
|
127
|
+
_zalpha(
|
|
128
|
+
color_array,
|
|
129
|
+
self._vzs,
|
|
130
|
+
min_alpha=self._depthshade_minalpha,
|
|
131
|
+
_data_scale=self._data_scale,
|
|
132
|
+
)
|
|
133
|
+
if self._vzs is not None and self._depthshade
|
|
134
|
+
else color_array
|
|
135
|
+
)
|
|
136
|
+
return mcolors.to_rgba_array(color_array, self._alpha)
|
|
137
|
+
|
|
138
|
+
def set_edgecolor(self, color):
|
|
139
|
+
"""Set the edge color of the collection."""
|
|
140
|
+
self._edgecolors = mcolors.to_rgba_array(color, self._alpha)
|
|
141
|
+
self._edgecolors_noshade = self._edgecolors.copy()
|
|
142
|
+
|
|
143
|
+
def get_edgecolor(self):
|
|
144
|
+
"""Set the edge color of the collection, including depth shading."""
|
|
145
|
+
# We need this check here to make sure we do not double-apply the depth
|
|
146
|
+
# based alpha shading when the edge color is "face" which means the
|
|
147
|
+
# edge colour should be identical to the face colour.
|
|
148
|
+
if not hasattr(self, "_edgecolors_noshade"):
|
|
149
|
+
self._edgecolors_noshade = self._edgecolors.copy()
|
|
150
|
+
return self._maybe_depth_shade_and_sort_colors(self._edgecolors_noshade)
|
|
151
|
+
|
|
152
|
+
set_edgecolors = set_edgecolor
|
|
153
|
+
get_edgecolors = get_edgecolor
|
|
154
|
+
|
|
155
|
+
def get_depthshade(self):
|
|
156
|
+
"""Get whether depth shading is performed on collection members."""
|
|
157
|
+
return self._depthshade
|
|
158
|
+
|
|
159
|
+
def get_depthshade_minalpha(self):
|
|
160
|
+
"""The minimum alpha value used by depth-shading."""
|
|
161
|
+
return self._depthshade_minalpha
|
|
162
|
+
|
|
163
|
+
def set_depthshade(
|
|
164
|
+
self,
|
|
165
|
+
depthshade,
|
|
166
|
+
depthshade_minalpha=0.1,
|
|
167
|
+
):
|
|
168
|
+
"""
|
|
169
|
+
Set whether depth shading is performed on collection members.
|
|
170
|
+
|
|
171
|
+
Parameters
|
|
172
|
+
----------
|
|
173
|
+
depthshade : bool
|
|
174
|
+
Whether to shade the patches in order to give the appearance of
|
|
175
|
+
depth.
|
|
176
|
+
depthshade_minalpha : float
|
|
177
|
+
Sets the minimum alpha value used by depth-shading.
|
|
178
|
+
|
|
179
|
+
.. versionadded:: 3.11
|
|
180
|
+
"""
|
|
181
|
+
self._depthshade = depthshade
|
|
182
|
+
self._depthshade_minalpha = depthshade_minalpha
|
|
183
|
+
self.stale = True
|
|
184
|
+
|
|
76
185
|
def _update_before_draw(self) -> None:
|
|
77
186
|
"""Update the collection before drawing."""
|
|
78
187
|
if isinstance(self.axes, Axes3D) and hasattr(self, "do_3d_projection"):
|
|
79
188
|
self.do_3d_projection()
|
|
80
189
|
|
|
190
|
+
if not hasattr(self, "_edgecolors_noshade"):
|
|
191
|
+
self._edgecolors_noshade = self._edgecolors.copy()
|
|
192
|
+
self._edgecolors = self._maybe_depth_shade_and_sort_colors(
|
|
193
|
+
self._edgecolors_noshade,
|
|
194
|
+
)
|
|
195
|
+
|
|
81
196
|
# TODO: Here's where we would shorten the edges to fit the vertex
|
|
82
197
|
# projections from 3D onto 2D, if we wanted to do that. Because edges
|
|
83
198
|
# in 3D are chains of segments rathen than splines, the shortening
|
|
@@ -111,6 +226,7 @@ def edge_collection_2d_to_3d(
|
|
|
111
226
|
col: EdgeCollection,
|
|
112
227
|
zdir: str = "z",
|
|
113
228
|
axlim_clip: bool = False,
|
|
229
|
+
depthshade: bool = True,
|
|
114
230
|
):
|
|
115
231
|
"""Convert a 2D EdgeCollection to a 3D Edge3DCollection.
|
|
116
232
|
|
|
@@ -127,6 +243,9 @@ def edge_collection_2d_to_3d(
|
|
|
127
243
|
# NOTE: after this line, none of the EdgeCollection methods will work
|
|
128
244
|
# It's become a static drawer now. It uses segments instead of paths.
|
|
129
245
|
col.__class__ = Edge3DCollection
|
|
246
|
+
col._depthshade = depthshade
|
|
247
|
+
col._depthshade_minalpha = 0.1
|
|
248
|
+
|
|
130
249
|
col._compute_edge_segments()
|
|
131
250
|
|
|
132
251
|
col._axlim_clip = axlim_clip
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
from typing import (
|
|
2
|
+
Any,
|
|
3
|
+
Optional,
|
|
4
|
+
Sequence,
|
|
5
|
+
)
|
|
6
|
+
import importlib
|
|
7
|
+
|
|
8
|
+
from ...typing import (
|
|
9
|
+
TreeDataProvider,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class DendropyDataProvider(TreeDataProvider):
|
|
14
|
+
def is_rooted(self) -> bool:
|
|
15
|
+
return True
|
|
16
|
+
|
|
17
|
+
def get_root(self) -> Any:
|
|
18
|
+
"""Get the root of the tree."""
|
|
19
|
+
return next(self.preorder())
|
|
20
|
+
|
|
21
|
+
def preorder(self) -> Any:
|
|
22
|
+
"""Preorder traversal of the tree.
|
|
23
|
+
|
|
24
|
+
NOTE: This will work on both entire Trees and Nodes (which means a subtree including self).
|
|
25
|
+
"""
|
|
26
|
+
if hasattr(self.tree, "preorder_node_iter"):
|
|
27
|
+
return self.tree.preorder_node_iter()
|
|
28
|
+
return self.tree.preorder_iter()
|
|
29
|
+
|
|
30
|
+
def postorder(self) -> Any:
|
|
31
|
+
"""Preorder traversal of the tree.
|
|
32
|
+
|
|
33
|
+
NOTE: This will work on both entire Trees and Nodes (which means a subtree including self).
|
|
34
|
+
"""
|
|
35
|
+
if hasattr(self.tree, "postorder_node_iter"):
|
|
36
|
+
return self.tree.postorder_node_iter()
|
|
37
|
+
return self.tree.postorder_iter()
|
|
38
|
+
|
|
39
|
+
def get_leaves(self) -> Sequence[Any]:
|
|
40
|
+
"""Get a list of leaves."""
|
|
41
|
+
return self.tree.leaf_nodes()
|
|
42
|
+
|
|
43
|
+
@staticmethod
|
|
44
|
+
def get_children(node: Any) -> Sequence[Any]:
|
|
45
|
+
return node.child_nodes()
|
|
46
|
+
|
|
47
|
+
@staticmethod
|
|
48
|
+
def get_branch_length(node: Any) -> Optional[float]:
|
|
49
|
+
return node.edge.length
|
|
50
|
+
|
|
51
|
+
@staticmethod
|
|
52
|
+
def check_dependencies() -> bool:
|
|
53
|
+
return importlib.util.find_spec("dendropy") is not None
|
|
54
|
+
|
|
55
|
+
@staticmethod
|
|
56
|
+
def tree_type():
|
|
57
|
+
import dendropy
|
|
58
|
+
|
|
59
|
+
return dendropy.Tree
|