iplotx 1.5.1__tar.gz → 1.7.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-1.5.1 → iplotx-1.7.0}/PKG-INFO +5 -5
- {iplotx-1.5.1 → iplotx-1.7.0}/README.md +3 -3
- {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/api/complete_style_specification.md +12 -2
- {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/installing.md +8 -2
- {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/sg_execution_times.rst +23 -8
- iplotx-1.7.0/gallery/GALLERY_HEADER.rst +34 -0
- iplotx-1.7.0/gallery/fun/GALLERY_HEADER.rst +2 -0
- iplotx-1.7.0/gallery/fun/plot_67.py +54 -0
- iplotx-1.7.0/gallery/other/plot_hover_neighborhood.py +83 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/other/plot_mouse_hover.py +1 -1
- iplotx-1.7.0/gallery/style/plot_curved_waypoints.py +43 -0
- iplotx-1.7.0/gallery/style/plot_edge_multicolor.py +29 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/style/plot_waypoints.py +0 -4
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/edge/__init__.py +27 -12
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/edge/geometry.py +16 -2
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/plotting.py +47 -4
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/utils/matplotlib.py +5 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/version.py +1 -1
- {iplotx-1.5.1 → iplotx-1.7.0}/pyproject.toml +1 -1
- iplotx-1.7.0/tests/baseline_images/test_networkx/triangular_lattice.png +0 -0
- iplotx-1.7.0/tests/baseline_images/test_simple_network_provider/curved_waypoints.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_edge_geometry.py +4 -0
- iplotx-1.7.0/tests/test_igraph.py +367 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_networkx.py +8 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_simple_network_provider.py +22 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/uv.lock +2 -37
- iplotx-1.5.1/gallery/GALLERY_HEADER.rst +0 -2
- iplotx-1.5.1/tests/test_igraph.py +0 -385
- {iplotx-1.5.1 → iplotx-1.7.0}/.github/workflows/publish.yml +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/.github/workflows/test.yml +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/.gitignore +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/.pre-commit-config.yaml +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/.readthedocs.yaml +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/LICENSE +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/MANIFEST.in +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/assets/pylint.svg +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/docs/Makefile +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/docs/make.bat +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/_static/banner.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/_static/custom-icons.js +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/_static/custom.css +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/_static/graph_basic.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/_templates/layout.html +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/api/artists.md +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/api/plotting.md +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/api/providers.md +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/api/style.md +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/api.md +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/code_of_conduct.rst +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/conf.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/images/sphx_glr_plot_basic_001.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/images/thumb/sphx_glr_plot_basic_thumb.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/index.md +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/providers.md +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/style.md +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/basic/GALLERY_HEADER.rst +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/basic/plot_3d.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/basic/plot_arcs.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/basic/plot_basic.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/basic/plot_big_curves.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/basic/plot_dag.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/basic/plot_directed.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/basic/plot_grouping.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/basic/plot_house.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/basic/plot_loops.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/basic/plot_simple_path.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/biology/GALLERY_HEADER.rst +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/biology/data/80201010000000001.mst +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/biology/data/GN-tree.json +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/biology/data/breast_cancer_string_interactions_short.tsv +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/biology/data/breast_cancer_string_network_coordinates.tsv +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/biology/data/cell_cycle_arrest_string_interactions_short.tsv +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/biology/data/cell_cycle_arrest_string_network_coordinates.tsv +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/biology/data/fevo-08-588430_DataSheet1_S1.csv +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/biology/plot_animal_phylogeny.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/biology/plot_antibody_clone.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/biology/plot_breast_cancer_ppi.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/biology/plot_cell_cycle_arrest.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/biology/plot_food_network.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/biology/plot_foraging_table.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/biology/plot_pollinators.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/biology/plot_ppi.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/biology/plot_tca_cycle.py +0 -0
- {iplotx-1.5.1/gallery/other → iplotx-1.7.0/gallery/fun}/plot_train.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/GALLERY_HEADER.rst +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/data/chess_masters_WCC.pgn.bz2 +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/data/knuth_miles.txt.gz +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_arrowlawn.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_chess_masters.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_cliques.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_cluster_layout.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_company_structure.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_complex.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_financial_network.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_knuth_miles.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_labels_and_colors.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_max_bipartite_matching.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_minimum_spanning_trees.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_multipartite_layout.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_parallel_igraph_networkx.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_redblack.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_shortest_path.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_simple_networkx.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_social_network_circles.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_traveling_salesman.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_with_colorbar.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/other/GALLERY_HEADER.rst +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/other/data/african_cities_coords.csv +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/other/data/draco_stars.csv +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/other/plot_animation.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/other/plot_bundles.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/other/plot_constellation.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/other/plot_edit_artists.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/other/plot_feedbacks.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/other/plot_geomap.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/other/plot_graph.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/other/plot_multiarc.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/style/GALLERY_HEADER.rst +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/style/plot_arrows.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/style/plot_custom_vertex.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/style/plot_depthshade.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/style/plot_edge_geometries.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/style/plot_edgepadding.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/style/plot_elements.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/style/plot_filled_edges.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/style/plot_four_grids.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/style/plot_halfarrows.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/style/plot_multistyle.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/style/plot_ports.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/style/plot_style.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/style/plot_tension.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/style/plot_vertexmarkers.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/style/plot_voronoi.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/GALLERY_HEADER.rst +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/data/tree-with-support.json +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_angular_waypoints.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_biopython_tree.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_cladeedges.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_cogent3_layouts.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_cogent3_tree.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_dendropy.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_double_tree.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_elements_tree.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_equalangle.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_ete4.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_leafedges.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_leafedges_and_cascades.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_scalebar.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_skbio_tree.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_split_edges.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_style_tree.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_support.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_tree_node_background.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_tree_style_clades.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_trees_of_trees.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/zero_dependency/GALLERY_HEADER.rst +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/zero_dependency/plot_simplenetworkdataprovider.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/gallery/zero_dependency/plot_simpletreedataprovider.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/__init__.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/art3d/edge/__init__.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/art3d/edge/arrow.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/art3d/edge/geometry.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/art3d/vertex.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/artists.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/edge/arrow.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/edge/leaf.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/edge/ports.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/ingest/__init__.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/ingest/heuristics.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/ingest/providers/network/graph_tool.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/ingest/providers/network/igraph.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/ingest/providers/network/networkx.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/ingest/providers/network/simple.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/ingest/providers/tree/biopython.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/ingest/providers/tree/cogent3.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/ingest/providers/tree/dendropy.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/ingest/providers/tree/ete4.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/ingest/providers/tree/simple.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/ingest/providers/tree/skbio.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/ingest/typing.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/label.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/layout/__init__.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/layout/tree/__init__.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/layout/tree/rooted.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/layout/tree/unrooted.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/network/__init__.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/network/groups.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/style/__init__.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/style/leaf_info.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/style/library.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/tree/__init__.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/tree/cascades.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/tree/scalebar.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/typing.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/utils/geometry.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/utils/internal.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/utils/style.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/vertex.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/scripts/copy_github_release_into_version.sh +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/scripts/make_banner.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/scripts/update_pylint_badge.sh +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_biopython/cascades.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_biopython/directed_child.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_biopython/leaf_labels.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_biopython/leaf_labels_hmargin.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_biopython/leafedges.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_biopython/show_support.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_biopython/tree_basic.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_biopython/tree_radial.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_cogent3/leaf_labels.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_cogent3/leaf_labels_hmargin.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_cogent3/tree_basic.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_cogent3/tree_radial.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_dendropy/cascades.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_dendropy/directed_child.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_dendropy/leaf_labels.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_dendropy/leaf_labels_hmargin.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_dendropy/leafedges.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_dendropy/tree_basic.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_dendropy/tree_radial.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_doubletree/tree_gap.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_doubletree/tree_nogap.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_ete4/equalangle_layout.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_ete4/leaf_labels.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_ete4/leaf_labels_hmargin.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_ete4/split_edges.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_ete4/tree_basic.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_ete4/tree_radial.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_graph_tool/graph_basic.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_graph_tool/graph_directed.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/arcs.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/clustering_directed.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/clustering_directed_large.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/directed_arcs.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/graph_basic.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/graph_directed.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/graph_directed_curved_loops.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/graph_edit_children.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/graph_labels.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/graph_layout_attribute.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/graph_null.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/graph_squares_directed.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/graph_vertexsize.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/graph_with_curved_edges.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/igraph_layout_object.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/large_arcs.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/multiarc45.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/multigraph_with_curved_edges_undirected.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph_3d/directed.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph_3d/undirected.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph_3d/vertex_labels.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_networkx/cluster-layout.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_networkx/complex.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_networkx/complex_rotatelabels.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_networkx/custom_marker_path.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_networkx/custom_marker_polygon.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_networkx/directed_graph.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_networkx/directed_graph_with_colorbar.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_networkx/empty_graph.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_networkx/flat_style.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_networkx/house_with_colors.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_networkx/labels_and_colors.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_networkx/shortest_path.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_networkx/simple_graph.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_simple_network_provider/graph_basic.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_simple_network_provider/graph_directed.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_simple_network_provider/graph_labels.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_skbio/leaf_labels.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_skbio/leaf_labels_hmargin.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_skbio/tree_basic.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_skbio/tree_radial.png +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_arrows.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_biopython.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_cascades.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_cogent3.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_dendropy.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_doubletree.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_edge.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_ete4.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_geometry.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_graph_tool.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_heuristics.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_igraph_3d.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_ingest_protocols.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_matplotlib_utils.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_network_hotload.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_ports.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_simple_tree_provider.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_skbio.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_style.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_vertex.py +0 -0
- {iplotx-1.5.1 → iplotx-1.7.0}/tests/utils.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: iplotx
|
|
3
|
-
Version: 1.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 1.7.0
|
|
4
|
+
Summary: Universal network and tree visualisation library.
|
|
5
5
|
Project-URL: Homepage, https://github.com/fabilab/iplotx
|
|
6
6
|
Project-URL: Documentation, https://readthedocs.org/iplotx
|
|
7
7
|
Project-URL: Repository, https://github.com/fabilab/iplotx.git
|
|
@@ -41,7 +41,7 @@ Description-Content-Type: text/markdown
|
|
|
41
41
|
[](https://iplotx.readthedocs.io/en/latest/)
|
|
42
42
|
[](https://coveralls.io/github/fabilab/iplotx?branch=main)
|
|
43
43
|

|
|
44
|
-
[
|
|
44
|
+
[DOI](https://f1000research.com/articles/14-1377)
|
|
45
45
|
|
|
46
46
|
|
|
47
47
|
# iplotx
|
|
@@ -90,10 +90,10 @@ See [readthedocs](https://iplotx.readthedocs.io/en/latest/) for the full documen
|
|
|
90
90
|
See [gallery](https://iplotx.readthedocs.io/en/latest/gallery/index.html).
|
|
91
91
|
|
|
92
92
|
## Citation
|
|
93
|
-
If you use `iplotx` for publication figures, please cite
|
|
93
|
+
If you use `iplotx` for publication figures, please cite:
|
|
94
94
|
|
|
95
95
|
```
|
|
96
|
-
F. Zanini.
|
|
96
|
+
F. Zanini. A universal tool for visualisation of networks and trees in Python. F1000Research 2025, 14:1377. https://doi.org/10.12688/f1000research.173131.1
|
|
97
97
|
```
|
|
98
98
|
|
|
99
99
|
## Features
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[](https://iplotx.readthedocs.io/en/latest/)
|
|
4
4
|
[](https://coveralls.io/github/fabilab/iplotx?branch=main)
|
|
5
5
|

|
|
6
|
-
[
|
|
6
|
+
[DOI](https://f1000research.com/articles/14-1377)
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
# iplotx
|
|
@@ -52,10 +52,10 @@ See [readthedocs](https://iplotx.readthedocs.io/en/latest/) for the full documen
|
|
|
52
52
|
See [gallery](https://iplotx.readthedocs.io/en/latest/gallery/index.html).
|
|
53
53
|
|
|
54
54
|
## Citation
|
|
55
|
-
If you use `iplotx` for publication figures, please cite
|
|
55
|
+
If you use `iplotx` for publication figures, please cite:
|
|
56
56
|
|
|
57
57
|
```
|
|
58
|
-
F. Zanini.
|
|
58
|
+
F. Zanini. A universal tool for visualisation of networks and trees in Python. F1000Research 2025, 14:1377. https://doi.org/10.12688/f1000research.173131.1
|
|
59
59
|
```
|
|
60
60
|
|
|
61
61
|
## Features
|
|
@@ -112,6 +112,7 @@
|
|
|
112
112
|
# means a semicircle, and numbers above 5 create very large arcs, almost full
|
|
113
113
|
# circles. The exact definition of tension for arcs is the tangent of a
|
|
114
114
|
# quarter of the angle spanned by the arc.
|
|
115
|
+
# Tension is not used if explicit waypoints are set for the edge.
|
|
115
116
|
"tension": float,
|
|
116
117
|
|
|
117
118
|
# Tension for self-loops (higher values create more bigger loops).
|
|
@@ -151,8 +152,17 @@
|
|
|
151
152
|
# - ymidx0,ymidx1: The xy swap of the previous option.
|
|
152
153
|
# - x0y1: One waypoint, with x of the first point and y of the second point.
|
|
153
154
|
# - x1y0: The xy swap of the previous option.
|
|
154
|
-
#
|
|
155
|
-
|
|
155
|
+
#
|
|
156
|
+
# Instead of a string you can also specify a per-edge list of waypoints.
|
|
157
|
+
# Each waypoint is a tuple of two floats (x,y) in data coordinates. Each
|
|
158
|
+
# edge can have zero, one, or multiple waypoints.
|
|
159
|
+
# If used in this way, this option will have slightly different appearances
|
|
160
|
+
# depending of whether the edges are curved or straight (edge_curved). For
|
|
161
|
+
# straight edges, the edge will always pass through all waypoints. For
|
|
162
|
+
# curved edges, the waypoints are used as cubic Bezier control points and
|
|
163
|
+
# the edge will pass through the midpoints between each pair of consecutive
|
|
164
|
+
# waypoints.
|
|
165
|
+
"waypoints": str | list[list[tuple[float, float]]],
|
|
156
166
|
|
|
157
167
|
# Edge arrow style for directed graphs
|
|
158
168
|
"arrow": {
|
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
pip install iplotx
|
|
4
4
|
```
|
|
5
5
|
|
|
6
|
+
To also install [ilayoutx](https://ilayoutx.readthedocs.io/en/main/) to compute network layouts before visualising them:
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
pip install iplotx ilayoutx
|
|
10
|
+
```
|
|
11
|
+
|
|
6
12
|
|
|
7
13
|
## Quick Start
|
|
8
14
|
::::{tab-set}
|
|
@@ -71,10 +77,10 @@ Either way, the result is the same:
|
|
|
71
77
|
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.
|
|
72
78
|
|
|
73
79
|
## Citation
|
|
74
|
-
If you use `iplotx` for publication figures, please cite
|
|
80
|
+
If you use `iplotx` for publication figures, please cite:
|
|
75
81
|
|
|
76
82
|
```
|
|
77
|
-
F. Zanini.
|
|
83
|
+
F. Zanini. A universal tool for visualisation of networks and trees in Python. F1000Research 2025, 14:1377. https://doi.org/10.12688/f1000research.173131.1
|
|
78
84
|
```
|
|
79
85
|
|
|
80
86
|
## Contributing
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
Computation times
|
|
8
8
|
=================
|
|
9
|
-
**00:00.
|
|
9
|
+
**00:00.068** total execution time for 90 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_fun_plot_67.py` (``../../gallery/fun/plot_67.py``)
|
|
36
|
+
- 00:00.068
|
|
37
37
|
- 0.0
|
|
38
38
|
* - :ref:`sphx_glr_gallery_basic_plot_3d.py` (``../../gallery/basic/plot_3d.py``)
|
|
39
39
|
- 00:00.000
|
|
@@ -92,6 +92,9 @@ Computation times
|
|
|
92
92
|
* - :ref:`sphx_glr_gallery_biology_plot_tca_cycle.py` (``../../gallery/biology/plot_tca_cycle.py``)
|
|
93
93
|
- 00:00.000
|
|
94
94
|
- 0.0
|
|
95
|
+
* - :ref:`sphx_glr_gallery_fun_plot_train.py` (``../../gallery/fun/plot_train.py``)
|
|
96
|
+
- 00:00.000
|
|
97
|
+
- 0.0
|
|
95
98
|
* - :ref:`sphx_glr_gallery_network_science_plot_arrowlawn.py` (``../../gallery/network_science/plot_arrowlawn.py``)
|
|
96
99
|
- 00:00.000
|
|
97
100
|
- 0.0
|
|
@@ -152,6 +155,9 @@ Computation times
|
|
|
152
155
|
* - :ref:`sphx_glr_gallery_other_plot_animation.py` (``../../gallery/other/plot_animation.py``)
|
|
153
156
|
- 00:00.000
|
|
154
157
|
- 0.0
|
|
158
|
+
* - :ref:`sphx_glr_gallery_other_plot_bundles.py` (``../../gallery/other/plot_bundles.py``)
|
|
159
|
+
- 00:00.000
|
|
160
|
+
- 0.0
|
|
155
161
|
* - :ref:`sphx_glr_gallery_other_plot_constellation.py` (``../../gallery/other/plot_constellation.py``)
|
|
156
162
|
- 00:00.000
|
|
157
163
|
- 0.0
|
|
@@ -161,25 +167,28 @@ Computation times
|
|
|
161
167
|
* - :ref:`sphx_glr_gallery_other_plot_feedbacks.py` (``../../gallery/other/plot_feedbacks.py``)
|
|
162
168
|
- 00:00.000
|
|
163
169
|
- 0.0
|
|
164
|
-
* - :ref:`sphx_glr_gallery_other_plot_filled_edges.py` (``../../gallery/other/plot_filled_edges.py``)
|
|
165
|
-
- 00:00.000
|
|
166
|
-
- 0.0
|
|
167
170
|
* - :ref:`sphx_glr_gallery_other_plot_geomap.py` (``../../gallery/other/plot_geomap.py``)
|
|
168
171
|
- 00:00.000
|
|
169
172
|
- 0.0
|
|
170
173
|
* - :ref:`sphx_glr_gallery_other_plot_graph.py` (``../../gallery/other/plot_graph.py``)
|
|
171
174
|
- 00:00.000
|
|
172
175
|
- 0.0
|
|
176
|
+
* - :ref:`sphx_glr_gallery_other_plot_hover_neighborhood.py` (``../../gallery/other/plot_hover_neighborhood.py``)
|
|
177
|
+
- 00:00.000
|
|
178
|
+
- 0.0
|
|
173
179
|
* - :ref:`sphx_glr_gallery_other_plot_mouse_hover.py` (``../../gallery/other/plot_mouse_hover.py``)
|
|
174
180
|
- 00:00.000
|
|
175
181
|
- 0.0
|
|
176
182
|
* - :ref:`sphx_glr_gallery_other_plot_multiarc.py` (``../../gallery/other/plot_multiarc.py``)
|
|
177
183
|
- 00:00.000
|
|
178
184
|
- 0.0
|
|
179
|
-
* - :ref:`
|
|
185
|
+
* - :ref:`sphx_glr_gallery_style_plot_arrows.py` (``../../gallery/style/plot_arrows.py``)
|
|
180
186
|
- 00:00.000
|
|
181
187
|
- 0.0
|
|
182
|
-
* - :ref:`
|
|
188
|
+
* - :ref:`sphx_glr_gallery_style_plot_curved_waypoints.py` (``../../gallery/style/plot_curved_waypoints.py``)
|
|
189
|
+
- 00:00.000
|
|
190
|
+
- 0.0
|
|
191
|
+
* - :ref:`sphx_glr_gallery_style_plot_custom_vertex.py` (``../../gallery/style/plot_custom_vertex.py``)
|
|
183
192
|
- 00:00.000
|
|
184
193
|
- 0.0
|
|
185
194
|
* - :ref:`sphx_glr_gallery_style_plot_depthshade.py` (``../../gallery/style/plot_depthshade.py``)
|
|
@@ -188,12 +197,18 @@ Computation times
|
|
|
188
197
|
* - :ref:`sphx_glr_gallery_style_plot_edge_geometries.py` (``../../gallery/style/plot_edge_geometries.py``)
|
|
189
198
|
- 00:00.000
|
|
190
199
|
- 0.0
|
|
200
|
+
* - :ref:`sphx_glr_gallery_style_plot_edge_multicolor.py` (``../../gallery/style/plot_edge_multicolor.py``)
|
|
201
|
+
- 00:00.000
|
|
202
|
+
- 0.0
|
|
191
203
|
* - :ref:`sphx_glr_gallery_style_plot_edgepadding.py` (``../../gallery/style/plot_edgepadding.py``)
|
|
192
204
|
- 00:00.000
|
|
193
205
|
- 0.0
|
|
194
206
|
* - :ref:`sphx_glr_gallery_style_plot_elements.py` (``../../gallery/style/plot_elements.py``)
|
|
195
207
|
- 00:00.000
|
|
196
208
|
- 0.0
|
|
209
|
+
* - :ref:`sphx_glr_gallery_style_plot_filled_edges.py` (``../../gallery/style/plot_filled_edges.py``)
|
|
210
|
+
- 00:00.000
|
|
211
|
+
- 0.0
|
|
197
212
|
* - :ref:`sphx_glr_gallery_style_plot_four_grids.py` (``../../gallery/style/plot_four_grids.py``)
|
|
198
213
|
- 00:00.000
|
|
199
214
|
- 0.0
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
Gallery
|
|
2
|
+
=======
|
|
3
|
+
.. warning::
|
|
4
|
+
If plots do not show on screen, try adding `show=True` to your function call:
|
|
5
|
+
|
|
6
|
+
.. code-block::
|
|
7
|
+
|
|
8
|
+
ipx.network(
|
|
9
|
+
...,
|
|
10
|
+
show=True,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
This is a peculiarity of `matplotlib`_, the plotting engine behind `iplotx`,
|
|
14
|
+
and depends on your Python environment (e.g., Jupyter notebooks, terminal,
|
|
15
|
+
interactive mode, backend, etc). You might want to enable `interactive mode`_
|
|
16
|
+
*before* plotting to ensure everything is rendered immediately:
|
|
17
|
+
|
|
18
|
+
.. code-block::
|
|
19
|
+
|
|
20
|
+
import matplotlib.pyplot as plt
|
|
21
|
+
import iplotx as ipx
|
|
22
|
+
|
|
23
|
+
...
|
|
24
|
+
|
|
25
|
+
plt.ion()
|
|
26
|
+
ipx.network(
|
|
27
|
+
...,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
If interactive mode is on, you do not need `show=True` (because plots are
|
|
31
|
+
always rendered immediately anyway).
|
|
32
|
+
|
|
33
|
+
.. _matplotlib: https://matplotlib.org/
|
|
34
|
+
.. _interactive mode: https://matplotlib.org/stable/users/explain/figure/interactive.html
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""
|
|
2
|
+
6-7
|
|
3
|
+
===
|
|
4
|
+
|
|
5
|
+
This example shows that yo 6-7.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import igraph as ig
|
|
9
|
+
import matplotlib.pyplot as plt
|
|
10
|
+
import iplotx as ipx
|
|
11
|
+
|
|
12
|
+
g6 = ig.Graph.Ring(11, directed=True)
|
|
13
|
+
g0 = ig.Graph.Ring(4, directed=True)
|
|
14
|
+
gdash = ig.Graph(edges=[(0, 1), (1, 0)], directed=True)
|
|
15
|
+
g7 = ig.Graph.Ring(6, directed=True)
|
|
16
|
+
g67 = ig.disjoint_union([g6, g0, gdash, g7])
|
|
17
|
+
|
|
18
|
+
layout = [
|
|
19
|
+
# 6
|
|
20
|
+
[0, 0],
|
|
21
|
+
[1, 0],
|
|
22
|
+
[2, 1],
|
|
23
|
+
[2, 3],
|
|
24
|
+
[1, 4],
|
|
25
|
+
[0.8, 4],
|
|
26
|
+
[2, 6],
|
|
27
|
+
[1, 6],
|
|
28
|
+
[0, 4],
|
|
29
|
+
[-1, 2],
|
|
30
|
+
[-1, 1],
|
|
31
|
+
# 0
|
|
32
|
+
[0.3, 1.5],
|
|
33
|
+
[1.0, 1.5],
|
|
34
|
+
[1.0, 2.5],
|
|
35
|
+
[0.3, 2.5],
|
|
36
|
+
# dash
|
|
37
|
+
[3, 2],
|
|
38
|
+
[5, 2],
|
|
39
|
+
# 7
|
|
40
|
+
[6, 0],
|
|
41
|
+
[7, 0],
|
|
42
|
+
[8, 6],
|
|
43
|
+
[6, 6],
|
|
44
|
+
[6, 5],
|
|
45
|
+
[7, 5],
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
with ipx.style.context("unicorn"):
|
|
49
|
+
ipx.network(
|
|
50
|
+
g67,
|
|
51
|
+
layout,
|
|
52
|
+
node_size=9,
|
|
53
|
+
edge_linewidth=4,
|
|
54
|
+
)
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Hover neighborhoods
|
|
3
|
+
===================
|
|
4
|
+
|
|
5
|
+
This example shows how to highlight a node and its neighborhood by hovering with the mouse on it.
|
|
6
|
+
|
|
7
|
+
.. warning::
|
|
8
|
+
This example will run in a Python, IPython, or Jupyter session, however the
|
|
9
|
+
interactive functionality is not visible on the HTML page. Download the code
|
|
10
|
+
at the end of this page and run it in a local Python environment to see
|
|
11
|
+
the results.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import matplotlib.pyplot as plt
|
|
15
|
+
import igraph as ig
|
|
16
|
+
import iplotx as ipx
|
|
17
|
+
|
|
18
|
+
g = ig.Graph.Erdos_Renyi(n=40, m=120)
|
|
19
|
+
layout = g.layout()
|
|
20
|
+
|
|
21
|
+
fig, axs = plt.subplots(1, 2, gridspec_kw={"width_ratios": [1, 0.2]}, figsize=(8, 6))
|
|
22
|
+
art = ipx.network(
|
|
23
|
+
g,
|
|
24
|
+
layout=layout,
|
|
25
|
+
ax=axs[0],
|
|
26
|
+
aspect=1,
|
|
27
|
+
vertex_zorder=5,
|
|
28
|
+
)[0]
|
|
29
|
+
base_nodecolors = art.get_vertices().get_facecolors()
|
|
30
|
+
nodecolors = base_nodecolors.copy()
|
|
31
|
+
edgecolors = art.get_edges().get_edgecolors()
|
|
32
|
+
edgewidths = art.get_edges().get_linewidths()
|
|
33
|
+
|
|
34
|
+
axs[1].set_axis_off()
|
|
35
|
+
txt = axs[1].text(0.5, 0.5, "", ha="center", va="center", wrap=True,
|
|
36
|
+
fontsize=40)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def hover_callback(event):
|
|
40
|
+
"""React to mouse hovering over vertices."""
|
|
41
|
+
if event.inaxes == axs[0]:
|
|
42
|
+
cont, ind = art.get_vertices().contains(event)
|
|
43
|
+
|
|
44
|
+
# Reset everyone's color
|
|
45
|
+
is_base = (nodecolors == base_nodecolors).all()
|
|
46
|
+
|
|
47
|
+
# If mouse is over a vertex, change the color around there
|
|
48
|
+
# and redraw
|
|
49
|
+
if cont:
|
|
50
|
+
i = ind["ind"][0]
|
|
51
|
+
nodecolors[:] = [0, 0, 0, 0.3]
|
|
52
|
+
nodecolors[g.neighbors(i)] = [1, 0, 0, 0.6]
|
|
53
|
+
nodecolors[i] = [1, 0, 0, 1]
|
|
54
|
+
art.get_vertices().set_facecolors(nodecolors)
|
|
55
|
+
edgecolors[:] = [0, 0, 0, 0.3]
|
|
56
|
+
edgecolors[g.incident(i)] = [0, 0, 0, 1]
|
|
57
|
+
art.get_edges().set_edgecolors(edgecolors)
|
|
58
|
+
edgewidths[:] = 1
|
|
59
|
+
edgewidths[g.incident(i)] = 2
|
|
60
|
+
art.get_edges().set_linewidths(edgewidths)
|
|
61
|
+
|
|
62
|
+
txt.set_text(str(i))
|
|
63
|
+
# Otherwise, change back to base and redraw
|
|
64
|
+
elif not is_base:
|
|
65
|
+
nodecolors[:] = base_nodecolors
|
|
66
|
+
vertex_artist.set_facecolors(nodecolors)
|
|
67
|
+
edgecolors[:] = [0, 0, 0, 1]
|
|
68
|
+
art.get_edges().set_edgecolors(edgecolors)
|
|
69
|
+
edgewidths[:] = 1
|
|
70
|
+
art.get_edges().set_linewidths(edgewidths)
|
|
71
|
+
txt.set_text("")
|
|
72
|
+
# If nothing changed, no need to redraw
|
|
73
|
+
else:
|
|
74
|
+
return
|
|
75
|
+
|
|
76
|
+
# Redraw if needed
|
|
77
|
+
fig.canvas.draw_idle()
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
fig.canvas.mpl_connect(
|
|
81
|
+
"motion_notify_event",
|
|
82
|
+
hover_callback,
|
|
83
|
+
)
|
|
@@ -43,7 +43,7 @@ def hover_callback(event):
|
|
|
43
43
|
if event.inaxes == ax:
|
|
44
44
|
vc = art.get_vertices()
|
|
45
45
|
cont, ind = vc.contains(event)
|
|
46
|
-
# If mouse is over a vertex, show the
|
|
46
|
+
# If mouse is over a vertex, show the bubble
|
|
47
47
|
if cont:
|
|
48
48
|
i = ind["ind"][0]
|
|
49
49
|
annot.xy = vc.get_offsets()[i]
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Curved waypoints
|
|
3
|
+
================
|
|
4
|
+
|
|
5
|
+
This example demonstrates the use of curved edge waypoints.
|
|
6
|
+
For straight waypoints, the edge will pass through each waypoint.
|
|
7
|
+
For curved waypoints, they are used as cubic Bezier points to
|
|
8
|
+
interpolate smoothly between.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import matplotlib.pyplot as plt
|
|
12
|
+
import numpy as np
|
|
13
|
+
import iplotx as ipx
|
|
14
|
+
|
|
15
|
+
g = {
|
|
16
|
+
"edges": [
|
|
17
|
+
("A", "B"),
|
|
18
|
+
],
|
|
19
|
+
}
|
|
20
|
+
layout = {
|
|
21
|
+
"A": (0, 0),
|
|
22
|
+
"B": (1, 2),
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
fig, axs = plt.subplots(1, 2, figsize=(8, 4))
|
|
26
|
+
for ax, curved in zip(axs, [False, True]):
|
|
27
|
+
ipx.network(
|
|
28
|
+
g,
|
|
29
|
+
layout=layout,
|
|
30
|
+
ax=ax,
|
|
31
|
+
vertex_labels=True,
|
|
32
|
+
edge_waypoints=[[[1, 1], [0, 1.5]]],
|
|
33
|
+
edge_curved=curved,
|
|
34
|
+
)
|
|
35
|
+
if not curved:
|
|
36
|
+
ax.set_title("Straight waypoints")
|
|
37
|
+
else:
|
|
38
|
+
ax.set_title("Curved waypoints")
|
|
39
|
+
fig.tight_layout()
|
|
40
|
+
|
|
41
|
+
#%%
|
|
42
|
+
# .. tip:: The edge will actually pass through the midpoints between two consecutive waypoints.
|
|
43
|
+
#
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Multicolor edges
|
|
3
|
+
================
|
|
4
|
+
|
|
5
|
+
Sometimes the need arises to color edges with multiple colors at the same time. That's what multigraphs are for.
|
|
6
|
+
This example shows the concept in action.
|
|
7
|
+
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import networkx as nx
|
|
11
|
+
import matplotlib.pyplot as plt
|
|
12
|
+
import iplotx as ipx
|
|
13
|
+
|
|
14
|
+
g = nx.MultiGraph()
|
|
15
|
+
g.add_edges_from([(0, 1), (1, 2), (0, 2), (0, 1)])
|
|
16
|
+
|
|
17
|
+
layout = [(0, 0), (1, 0), (0.5, 1)]
|
|
18
|
+
|
|
19
|
+
ipx.network(
|
|
20
|
+
g,
|
|
21
|
+
layout,
|
|
22
|
+
edge_color=["black", "gold", "tomato", "tomato"],
|
|
23
|
+
edge_paralleloffset=8,
|
|
24
|
+
edge_linewidth=4,
|
|
25
|
+
vertex_size=40,
|
|
26
|
+
vertex_facecolor="none",
|
|
27
|
+
vertex_edgecolor="black",
|
|
28
|
+
vertex_linewidth=4,
|
|
29
|
+
)
|
|
@@ -367,21 +367,13 @@ class EdgeCollection(mpl.collections.PatchCollection):
|
|
|
367
367
|
|
|
368
368
|
# Leaf rotation
|
|
369
369
|
edge_stylei = rotate_style(self._style, index=i, key=(v1, v2))
|
|
370
|
-
if edge_stylei.get("curved", False):
|
|
371
|
-
tension = edge_stylei.get("tension", 5)
|
|
372
|
-
ports = edge_stylei.get("ports", (None, None))
|
|
373
|
-
elif edge_stylei.get("arc", False):
|
|
374
|
-
tension = edge_stylei.get("tension", 1)
|
|
375
|
-
ports = None
|
|
376
|
-
else:
|
|
377
|
-
tension = 0
|
|
378
|
-
ports = None
|
|
379
370
|
|
|
380
371
|
# Scale shrink by dpi
|
|
381
372
|
dpi = self.figure.dpi if hasattr(self, "figure") else 72.0
|
|
382
373
|
shrink = dpi / 72.0 * edge_stylei.pop("shrink", 0)
|
|
383
374
|
|
|
384
|
-
#
|
|
375
|
+
# Edge geometry and waypoints
|
|
376
|
+
# waypoints: False is a synonym for "none"
|
|
385
377
|
waypoints = edge_stylei.get("waypoints", "none")
|
|
386
378
|
if waypoints is False or waypoints is np.False_:
|
|
387
379
|
waypoints = "none"
|
|
@@ -391,10 +383,32 @@ class EdgeCollection(mpl.collections.PatchCollection):
|
|
|
391
383
|
raise ValueError(
|
|
392
384
|
"Could not determine automatically type of edge waypoints.",
|
|
393
385
|
)
|
|
394
|
-
if waypoints != "none":
|
|
395
|
-
ports = edge_stylei.get("ports", (None, None))
|
|
396
386
|
|
|
387
|
+
# Waypoints, curved, and arc have a complex logic
|
|
388
|
+
# TODO: This could be simplified I suppose
|
|
389
|
+
has_waypoints = waypoints != "none"
|
|
390
|
+
curved = edge_stylei.get("curved", False)
|
|
397
391
|
arc = edge_stylei.get("arc", False)
|
|
392
|
+
ports = edge_stylei.get("ports", (None, None))
|
|
393
|
+
|
|
394
|
+
# For now, we establish a hierarchy from the most specialised to
|
|
395
|
+
# the most common cases. Each specialisation silences lower levels
|
|
396
|
+
# Tension and ports are entirely enslaved to the
|
|
397
|
+
# waypoint/arc/curved geometry settings.
|
|
398
|
+
# NOTE: The idea here is to not punish users for slight style
|
|
399
|
+
# inconsistencies that may well stem from fallback libraries
|
|
400
|
+
if has_waypoints:
|
|
401
|
+
tension = 0
|
|
402
|
+
arc = False
|
|
403
|
+
elif arc:
|
|
404
|
+
tension = edge_stylei.get("tension", 1)
|
|
405
|
+
ports = None
|
|
406
|
+
curved = False
|
|
407
|
+
elif curved:
|
|
408
|
+
tension = edge_stylei.get("tension", 5)
|
|
409
|
+
else:
|
|
410
|
+
tension = 0
|
|
411
|
+
ports = None
|
|
398
412
|
|
|
399
413
|
# Compute actual edge path
|
|
400
414
|
path, angles = _compute_edge_path(
|
|
@@ -406,6 +420,7 @@ class EdgeCollection(mpl.collections.PatchCollection):
|
|
|
406
420
|
tension=tension,
|
|
407
421
|
waypoints=waypoints,
|
|
408
422
|
ports=ports,
|
|
423
|
+
curved=curved,
|
|
409
424
|
arc=arc,
|
|
410
425
|
layout_coordinate_system=self._vertex_collection.get_layout_coordinate_system(),
|
|
411
426
|
shrink=shrink,
|
|
@@ -239,6 +239,7 @@ def _compute_edge_path_straight(
|
|
|
239
239
|
|
|
240
240
|
def _compute_edge_path_waypoints(
|
|
241
241
|
waypoints,
|
|
242
|
+
curved,
|
|
242
243
|
vcoord_data,
|
|
243
244
|
vpath_fig,
|
|
244
245
|
vsize_fig,
|
|
@@ -277,8 +278,19 @@ def _compute_edge_path_waypoints(
|
|
|
277
278
|
+ vcoord_fig[i]
|
|
278
279
|
)
|
|
279
280
|
|
|
280
|
-
|
|
281
|
-
|
|
281
|
+
if not curved:
|
|
282
|
+
points = [vshorts[0]] + list(waypoints) + [vshorts[1]]
|
|
283
|
+
codes = ["MOVETO"] + ["LINETO"] * len(waypoints) + ["LINETO"]
|
|
284
|
+
else:
|
|
285
|
+
points = [vshorts[0]]
|
|
286
|
+
for i, waypoint in enumerate(waypoints):
|
|
287
|
+
if i != 0:
|
|
288
|
+
points.append(0.5 * (points[-1] + waypoint))
|
|
289
|
+
points.append(waypoint)
|
|
290
|
+
points.append(waypoint)
|
|
291
|
+
points.append(vshorts[1])
|
|
292
|
+
codes = ["MOVETO"] + ["CURVE4"] * (len(points) - 1)
|
|
293
|
+
|
|
282
294
|
angles = tuple(thetas)
|
|
283
295
|
|
|
284
296
|
elif waypoints in ("x0y1", "y0x1"):
|
|
@@ -587,6 +599,7 @@ def _compute_edge_path(
|
|
|
587
599
|
tension: float = 0,
|
|
588
600
|
waypoints: str | tuple[float, float] | Sequence[tuple[float, float]] | np.ndarray = "none",
|
|
589
601
|
ports: Pair[Optional[str]] = (None, None),
|
|
602
|
+
curved: bool = False,
|
|
590
603
|
arc: bool = False,
|
|
591
604
|
layout_coordinate_system: str = "cartesian",
|
|
592
605
|
**kwargs,
|
|
@@ -600,6 +613,7 @@ def _compute_edge_path(
|
|
|
600
613
|
if waypoints != "none":
|
|
601
614
|
return _compute_edge_path_waypoints(
|
|
602
615
|
waypoints,
|
|
616
|
+
curved,
|
|
603
617
|
*args,
|
|
604
618
|
layout_coordinate_system=layout_coordinate_system,
|
|
605
619
|
ports=ports,
|