iplotx 0.7.0__tar.gz → 0.9.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.7.0 → iplotx-0.9.0}/PKG-INFO +1 -1
- {iplotx-0.7.0 → iplotx-0.9.0}/iplotx/__init__.py +3 -3
- {iplotx-0.7.0 → iplotx-0.9.0}/iplotx/network.py +8 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/iplotx/plotting.py +23 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/iplotx/style/__init__.py +13 -83
- {iplotx-0.7.0 → iplotx-0.9.0}/iplotx/tree.py +14 -0
- iplotx-0.9.0/iplotx/utils/style.py +128 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/iplotx/version.py +1 -1
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/test_igraph.py +14 -14
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/test_networkx.py +12 -12
- iplotx-0.7.0/iplotx/utils/style.py +0 -17
- {iplotx-0.7.0 → iplotx-0.9.0}/.github/workflows/publish.yml +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/.github/workflows/test.yml +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/.gitignore +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/.pre-commit-config.yaml +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/.readthedocs.yaml +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/LICENSE +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/MANIFEST.in +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/README.md +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/assets/pylint.svg +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/docs/Makefile +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/docs/make.bat +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/docs/source/_static/banner.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/docs/source/_static/graph_basic.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/docs/source/_templates/layout.html +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/docs/source/api/artists.md +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/docs/source/api/complete_style_specification.md +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/docs/source/api/plotting.md +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/docs/source/api/providers.md +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/docs/source/api/style.md +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/docs/source/api.md +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/docs/source/conf.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/docs/source/images/sphx_glr_plot_basic_001.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/docs/source/images/thumb/sphx_glr_plot_basic_thumb.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/docs/source/index.md +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/docs/source/providers.md +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/docs/source/sg_execution_times.rst +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/docs/source/style.md +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/GALLERY_HEADER.rst +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/basic/GALLERY_HEADER.rst +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/basic/plot_basic.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/basic/plot_big_curves.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/basic/plot_dag.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/basic/plot_directed.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/basic/plot_grouping.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/basic/plot_house.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/basic/plot_loops.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/basic/plot_simple_path.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/biology/GALLERY_HEADER.rst +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/biology/data/80201010000000001.mst +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/biology/data/GN-tree.json +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/biology/data/breast_cancer_string_interactions_short.tsv +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/biology/data/breast_cancer_string_network_coordinates.tsv +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/biology/data/cell_cycle_arrest_string_interactions_short.tsv +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/biology/data/cell_cycle_arrest_string_network_coordinates.tsv +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/biology/data/fevo-08-588430_DataSheet1_S1.csv +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/biology/plot_animal_phylogeny.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/biology/plot_antibody_clone.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/biology/plot_breast_cancer_ppi.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/biology/plot_cell_cycle_arrest.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/biology/plot_food_network.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/biology/plot_foraging_table.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/biology/plot_pollinators.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/biology/plot_ppi.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/biology/plot_tca_cycle.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/network_science/GALLERY_HEADER.rst +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/network_science/data/chess_masters_WCC.pgn.bz2 +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/network_science/data/knuth_miles.txt.gz +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/network_science/plot_arrowlawn.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/network_science/plot_chess_masters.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/network_science/plot_cliques.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/network_science/plot_cluster_layout.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/network_science/plot_company_structure.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/network_science/plot_complex.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/network_science/plot_financial_network.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/network_science/plot_knuth_miles.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/network_science/plot_labels_and_colors.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/network_science/plot_max_bipartite_matching.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/network_science/plot_minimum_spanning_trees.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/network_science/plot_multipartite_layout.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/network_science/plot_parallel_igraph_networkx.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/network_science/plot_redblack.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/network_science/plot_shortest_path.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/network_science/plot_simple_networkx.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/network_science/plot_social_network_circles.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/network_science/plot_traveling_salesman.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/network_science/plot_with_colorbar.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/other/GALLERY_HEADER.rst +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/other/plot_animation.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/other/plot_edit_artists.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/other/plot_feedbacks.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/other/plot_graph.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/other/plot_mouse_hover.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/other/plot_train.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/style/GALLERY_HEADER.rst +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/style/plot_arrows.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/style/plot_edgepadding.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/style/plot_elements.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/style/plot_four_grids.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/style/plot_halfarrows.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/style/plot_multistyle.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/style/plot_ports.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/style/plot_style.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/style/plot_tension.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/style/plot_vertexmarkers.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/style/plot_voronoi.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/style/plot_waypoints.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/tree/GALLERY_HEADER.rst +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/tree/data/tree-with-support.json +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/tree/plot_angular_waypoints.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/tree/plot_biopython_tree.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/tree/plot_cladeedges.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/tree/plot_cogent3_layouts.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/tree/plot_cogent3_tree.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/tree/plot_elements_tree.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/tree/plot_ete4.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/tree/plot_leafedges.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/tree/plot_leafedges_and_cascades.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/tree/plot_skbio_tree.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/tree/plot_split_edges.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/tree/plot_style_tree.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/tree/plot_support.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/tree/plot_tree_node_background.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/tree/plot_tree_style_clades.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/tree/plot_trees_of_trees.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/zero_dependency/GALLERY_HEADER.rst +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/zero_dependency/plot_simplenetworkdataprovider.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/gallery/zero_dependency/plot_simpletreedataprovider.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/iplotx/artists.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/iplotx/cascades.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/iplotx/edge/__init__.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/iplotx/edge/arrow.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/iplotx/edge/geometry.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/iplotx/edge/leaf.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/iplotx/edge/ports.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/iplotx/groups.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/iplotx/ingest/__init__.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/iplotx/ingest/heuristics.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/iplotx/ingest/providers/network/igraph.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/iplotx/ingest/providers/network/networkx.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/iplotx/ingest/providers/network/simple.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/iplotx/ingest/providers/tree/biopython.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/iplotx/ingest/providers/tree/cogent3.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/iplotx/ingest/providers/tree/ete4.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/iplotx/ingest/providers/tree/simple.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/iplotx/ingest/providers/tree/skbio.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/iplotx/ingest/typing.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/iplotx/label.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/iplotx/layout.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/iplotx/style/leaf_info.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/iplotx/style/library.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/iplotx/typing.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/iplotx/utils/geometry.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/iplotx/utils/internal.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/iplotx/utils/matplotlib.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/iplotx/vertex.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/pyproject.toml +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/scripts/copy_github_release_into_version.sh +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/scripts/make_banner.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/scripts/update_pylint_badge.sh +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_biopython/cascades.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_biopython/directed_child.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_biopython/leaf_labels.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_biopython/leaf_labels_hmargin.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_biopython/leafedges.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_biopython/show_support.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_biopython/tree_basic.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_biopython/tree_radial.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_cogent3/leaf_labels.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_cogent3/leaf_labels_hmargin.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_cogent3/tree_basic.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_cogent3/tree_radial.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_ete4/leaf_labels.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_ete4/leaf_labels_hmargin.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_ete4/split_edges.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_ete4/tree_basic.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_ete4/tree_radial.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_igraph/clustering_directed.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_igraph/clustering_directed_large.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_igraph/graph_basic.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_igraph/graph_directed.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_igraph/graph_directed_curved_loops.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_igraph/graph_edit_children.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_igraph/graph_labels.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_igraph/graph_layout_attribute.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_igraph/graph_null.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_igraph/graph_squares_directed.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_igraph/graph_vertexsize.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_igraph/graph_with_curved_edges.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_igraph/igraph_layout_object.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_igraph/multigraph_with_curved_edges_undirected.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_networkx/cluster-layout.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_networkx/complex.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_networkx/complex_rotatelabels.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_networkx/directed_graph.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_networkx/directed_graph_with_colorbar.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_networkx/empty_graph.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_networkx/flat_style.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_networkx/house_with_colors.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_networkx/labels_and_colors.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_networkx/shortest_path.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_networkx/simple_graph.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_simple_network_provider/graph_basic.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_simple_network_provider/graph_directed.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_simple_network_provider/graph_labels.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_skbio/leaf_labels.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_skbio/leaf_labels_hmargin.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_skbio/tree_basic.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/baseline_images/test_skbio/tree_radial.png +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/test_arrows.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/test_biopython.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/test_cascades.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/test_cogent3.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/test_edge.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/test_edge_geometry.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/test_ete4.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/test_geometry.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/test_heuristics.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/test_ingest_protocols.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/test_matplotlib_utils.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/test_network_hotload.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/test_ports.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/test_simple_network_provider.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/test_simple_tree_provider.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/test_skbio.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/test_style.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/test_vertex.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/tests/utils.py +0 -0
- {iplotx-0.7.0 → iplotx-0.9.0}/uv.lock +0 -0
|
@@ -9,19 +9,19 @@ library was used to construct the network.
|
|
|
9
9
|
from .version import __version__
|
|
10
10
|
from .plotting import (
|
|
11
11
|
network,
|
|
12
|
+
graph,
|
|
12
13
|
tree,
|
|
14
|
+
plot,
|
|
13
15
|
)
|
|
14
16
|
import iplotx.artists as artists
|
|
15
17
|
import iplotx.style as style
|
|
16
18
|
|
|
17
19
|
|
|
18
|
-
# Shortcut to iplotx.plotting.network
|
|
19
|
-
plot = network
|
|
20
|
-
|
|
21
20
|
__all__ = [
|
|
22
21
|
"network",
|
|
23
22
|
"tree",
|
|
24
23
|
"plot",
|
|
24
|
+
"graph",
|
|
25
25
|
"artists",
|
|
26
26
|
"style",
|
|
27
27
|
"__version__",
|
|
@@ -162,6 +162,8 @@ class NetworkArtist(mpl.artist.Artist):
|
|
|
162
162
|
"""Get VertexCollection artist."""
|
|
163
163
|
return self._vertices
|
|
164
164
|
|
|
165
|
+
get_nodes = get_vertices
|
|
166
|
+
|
|
165
167
|
def get_edges(self):
|
|
166
168
|
"""Get EdgeCollection artist."""
|
|
167
169
|
return self._edges
|
|
@@ -170,6 +172,8 @@ class NetworkArtist(mpl.artist.Artist):
|
|
|
170
172
|
"""Get list of vertex label artists."""
|
|
171
173
|
return self._vertices.get_labels()
|
|
172
174
|
|
|
175
|
+
get_node_labels = get_vertex_labels
|
|
176
|
+
|
|
173
177
|
def get_edge_labels(self):
|
|
174
178
|
"""Get list of edge label artists."""
|
|
175
179
|
return self._edges.get_labels()
|
|
@@ -211,6 +215,10 @@ class NetworkArtist(mpl.artist.Artist):
|
|
|
211
215
|
return vertex_layout_df
|
|
212
216
|
|
|
213
217
|
def _get_label_series(self, kind):
|
|
218
|
+
# Equivalence vertex/node
|
|
219
|
+
if kind == "node":
|
|
220
|
+
kind = "vertex"
|
|
221
|
+
|
|
214
222
|
if "label" in self._ipx_internal_data[f"{kind}_df"].columns:
|
|
215
223
|
return self._ipx_internal_data[f"{kind}_df"]["label"]
|
|
216
224
|
else:
|
|
@@ -22,6 +22,7 @@ def network(
|
|
|
22
22
|
layout: Optional[LayoutType] = None,
|
|
23
23
|
grouping: Optional[GroupingType] = None,
|
|
24
24
|
vertex_labels: Optional[list | dict | pd.Series | bool] = None,
|
|
25
|
+
node_labels: Optional[list | dict | pd.Series | bool] = None,
|
|
25
26
|
edge_labels: Optional[Sequence] = None,
|
|
26
27
|
ax: Optional[mpl.axes.Axes] = None,
|
|
27
28
|
style: str | dict | Sequence[str | dict] = (),
|
|
@@ -42,6 +43,9 @@ def network(
|
|
|
42
43
|
will be drawn. If a list, the labels are taken from the list. If a dict, the keys
|
|
43
44
|
should be the vertex IDs and the values should be the labels. If True (a single
|
|
44
45
|
bool value), the vertex IDs will be used as labels.
|
|
46
|
+
node_labels: Same meaning as vertex_labels. This is an alias to help users who prefer
|
|
47
|
+
the word "node" over "vertex". If both vertex_labels and node_labels are specified,
|
|
48
|
+
"node_labels" overrides "vertex_labels".
|
|
45
49
|
edge_labels: The labels for the edges. If None, no edge labels will be drawn. Defaults
|
|
46
50
|
to None.
|
|
47
51
|
ax: The axis to plot on. If None, a new figure and axis will be created. Defaults to
|
|
@@ -68,6 +72,11 @@ def network(
|
|
|
68
72
|
The list can have one or two elements, depending on whether you are requesting to
|
|
69
73
|
plot a network, a grouping, or both.
|
|
70
74
|
"""
|
|
75
|
+
# Equivalence of node_labels and vertex_labels
|
|
76
|
+
if node_labels is not None:
|
|
77
|
+
vertex_labels = node_labels
|
|
78
|
+
del node_labels
|
|
79
|
+
|
|
71
80
|
stylecontext = context(style, **kwargs) if style or kwargs else nullcontext()
|
|
72
81
|
|
|
73
82
|
with stylecontext:
|
|
@@ -126,11 +135,17 @@ def network(
|
|
|
126
135
|
return artists
|
|
127
136
|
|
|
128
137
|
|
|
138
|
+
# Aliases
|
|
139
|
+
plot = network
|
|
140
|
+
graph = network
|
|
141
|
+
|
|
142
|
+
|
|
129
143
|
def tree(
|
|
130
144
|
tree: Optional[TreeType] = None,
|
|
131
145
|
layout: str | LayoutType = "horizontal",
|
|
132
146
|
directed: bool | str = False,
|
|
133
147
|
vertex_labels: Optional[list | dict | pd.Series | bool] = None,
|
|
148
|
+
node_labels: Optional[list | dict | pd.Series | bool] = None,
|
|
134
149
|
leaf_labels: Optional[list | dict | pd.Series | bool] = None,
|
|
135
150
|
show_support: bool = False,
|
|
136
151
|
ax: Optional[mpl.axes.Axes] = None,
|
|
@@ -150,6 +165,9 @@ def tree(
|
|
|
150
165
|
directed: If False, do not draw arrows.
|
|
151
166
|
vertex_labels: The labels for the vertices. If None or False, no vertex labels. Also
|
|
152
167
|
read leaf_labels for leaf nodes.
|
|
168
|
+
node_labels: Same meaning as vertex_labels. This is an alias to help users who prefer
|
|
169
|
+
the word "node" over "vertex". If both vertex_labels and node_labels are specified,
|
|
170
|
+
"node_labels" overrides "vertex_labels".
|
|
153
171
|
leaf_labels: The labels for the leaf nodes. If None or False, no leaf labels are used
|
|
154
172
|
except if vertex_labels are specified for leaf nodes. This argument and the
|
|
155
173
|
previous vertex_labels provide somewhat redundant functionality but have quite
|
|
@@ -183,6 +201,11 @@ def tree(
|
|
|
183
201
|
Returns:
|
|
184
202
|
A TreeArtist object, set as a direct child of the matplotlib Axes.
|
|
185
203
|
"""
|
|
204
|
+
# Equivalence of node_labels and vertex_labels
|
|
205
|
+
if node_labels is not None:
|
|
206
|
+
vertex_labels = node_labels
|
|
207
|
+
del node_labels
|
|
208
|
+
|
|
186
209
|
stylecontext = context(style, **kwargs) if style or kwargs else nullcontext()
|
|
187
210
|
|
|
188
211
|
with stylecontext:
|
|
@@ -1,16 +1,24 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Main style module for iplotx.
|
|
3
|
+
"""
|
|
4
|
+
|
|
1
5
|
from typing import (
|
|
2
6
|
Any,
|
|
3
7
|
Iterable,
|
|
4
8
|
Optional,
|
|
5
9
|
Sequence,
|
|
6
10
|
)
|
|
7
|
-
from collections import defaultdict
|
|
8
11
|
from collections.abc import Hashable
|
|
9
12
|
from contextlib import contextmanager
|
|
10
13
|
import numpy as np
|
|
11
14
|
import pandas as pd
|
|
12
15
|
|
|
13
|
-
from ..utils.style import
|
|
16
|
+
from ..utils.style import (
|
|
17
|
+
copy_with_deep_values,
|
|
18
|
+
sanitize_leaves,
|
|
19
|
+
update_style,
|
|
20
|
+
sanitize_ambiguous,
|
|
21
|
+
)
|
|
14
22
|
from .library import style_library
|
|
15
23
|
from .leaf_info import (
|
|
16
24
|
style_leaves,
|
|
@@ -83,94 +91,16 @@ def merge_styles(
|
|
|
83
91
|
Returns:
|
|
84
92
|
The composite style as a dict.
|
|
85
93
|
"""
|
|
86
|
-
try:
|
|
87
|
-
import networkx as nx
|
|
88
|
-
except ImportError:
|
|
89
|
-
nx = None
|
|
90
|
-
|
|
91
|
-
def _sanitize_leaves(style: dict):
|
|
92
|
-
for key, value in style.items():
|
|
93
|
-
if key in style_leaves:
|
|
94
|
-
# Networkx has a few lazy data structures
|
|
95
|
-
# TODO: move this code to provider
|
|
96
|
-
if nx is not None:
|
|
97
|
-
if isinstance(value, nx.classes.reportviews.NodeView):
|
|
98
|
-
style[key] = dict(value)
|
|
99
|
-
elif isinstance(value, nx.classes.reportviews.EdgeViewABC):
|
|
100
|
-
style[key] = [v for *e, v in value]
|
|
101
|
-
|
|
102
|
-
elif isinstance(value, dict):
|
|
103
|
-
_sanitize_leaves(value)
|
|
104
|
-
|
|
105
|
-
def _update(style: dict, current: dict):
|
|
106
|
-
for key, value in style.items():
|
|
107
|
-
if key not in current:
|
|
108
|
-
current[key] = value
|
|
109
|
-
continue
|
|
110
|
-
|
|
111
|
-
# Style non-leaves are either recurred into or deleted
|
|
112
|
-
if key not in style_leaves:
|
|
113
|
-
if isinstance(value, dict):
|
|
114
|
-
_update(value, current[key])
|
|
115
|
-
elif value is None:
|
|
116
|
-
del current[key]
|
|
117
|
-
else:
|
|
118
|
-
raise ValueError(
|
|
119
|
-
f"Setting non-leaf style value to a non-dict: {key}, {value}",
|
|
120
|
-
)
|
|
121
|
-
else:
|
|
122
|
-
# Style leaves could be incomplete, ensure a sensible default
|
|
123
|
-
if value is None:
|
|
124
|
-
del current[key]
|
|
125
|
-
continue
|
|
126
|
-
|
|
127
|
-
if not isinstance(value, dict):
|
|
128
|
-
current[key] = value
|
|
129
|
-
continue
|
|
130
|
-
|
|
131
|
-
if hasattr(value, "default_factory"):
|
|
132
|
-
current[key] = value
|
|
133
|
-
continue
|
|
134
|
-
|
|
135
|
-
if hasattr(current[key], "default_factory"):
|
|
136
|
-
default_value = current[key].default_factory()
|
|
137
|
-
else:
|
|
138
|
-
default_value = current[key]
|
|
139
|
-
current[key] = defaultdict(
|
|
140
|
-
lambda: default_value,
|
|
141
|
-
value,
|
|
142
|
-
)
|
|
143
|
-
|
|
144
|
-
def _sanitize_ambiguous(style: dict):
|
|
145
|
-
"""Fix a few ambiguous cases in the style dict."""
|
|
146
|
-
|
|
147
|
-
# Accept "node" style as "vertex" style for user flexibility
|
|
148
|
-
if "node" in style:
|
|
149
|
-
style_node = style.pop("node")
|
|
150
|
-
if "vertex" not in style:
|
|
151
|
-
style["vertex"] = style_node
|
|
152
|
-
else:
|
|
153
|
-
# "node" style applies on TOP of "vertex" style
|
|
154
|
-
_update(style_node, style["vertex"])
|
|
155
|
-
|
|
156
|
-
# NOTE: Deprecate edge_padding for edge_shrink
|
|
157
|
-
for edgekey in ["edge", "leafedge"]:
|
|
158
|
-
if "padding" in style.get(edgekey, {}):
|
|
159
|
-
# shrink takes over
|
|
160
|
-
if "shrink" in style[edgekey]:
|
|
161
|
-
del style[edgekey]["padding"]
|
|
162
|
-
else:
|
|
163
|
-
style[edgekey]["shrink"] = style[edgekey].pop("padding")
|
|
164
94
|
|
|
165
95
|
merged = {}
|
|
166
96
|
for style in styles:
|
|
167
97
|
if isinstance(style, str):
|
|
168
98
|
style = get_style(style)
|
|
169
99
|
else:
|
|
170
|
-
|
|
100
|
+
sanitize_leaves(style)
|
|
171
101
|
unflatten_style(style)
|
|
172
|
-
|
|
173
|
-
|
|
102
|
+
sanitize_ambiguous(style)
|
|
103
|
+
update_style(style, merged)
|
|
174
104
|
|
|
175
105
|
return merged
|
|
176
106
|
|
|
@@ -193,6 +193,10 @@ class TreeArtist(mpl.artist.Artist):
|
|
|
193
193
|
"""Get vertex or edge layout."""
|
|
194
194
|
layout_columns = [f"_ipx_layout_{i}" for i in range(self._ipx_internal_data["ndim"])]
|
|
195
195
|
|
|
196
|
+
# Equivalence vertex <-> node
|
|
197
|
+
if kind == "node":
|
|
198
|
+
kind = "vertex"
|
|
199
|
+
|
|
196
200
|
if kind == "vertex":
|
|
197
201
|
layout = self._ipx_internal_data["vertex_df"][layout_columns]
|
|
198
202
|
return layout
|
|
@@ -245,6 +249,10 @@ class TreeArtist(mpl.artist.Artist):
|
|
|
245
249
|
return bbox
|
|
246
250
|
|
|
247
251
|
def _get_label_series(self, kind: str) -> Optional[pd.Series]:
|
|
252
|
+
# Equivalence vertex <-> node
|
|
253
|
+
if kind == "node":
|
|
254
|
+
kind = "vertex"
|
|
255
|
+
|
|
248
256
|
if "label" in self._ipx_internal_data[f"{kind}_df"].columns:
|
|
249
257
|
return self._ipx_internal_data[f"{kind}_df"]["label"]
|
|
250
258
|
else:
|
|
@@ -254,6 +262,8 @@ class TreeArtist(mpl.artist.Artist):
|
|
|
254
262
|
"""Get VertexCollection artist."""
|
|
255
263
|
return self._vertices
|
|
256
264
|
|
|
265
|
+
get_nodes = get_vertices
|
|
266
|
+
|
|
257
267
|
def get_edges(self) -> EdgeCollection:
|
|
258
268
|
"""Get EdgeCollection artist."""
|
|
259
269
|
return self._edges
|
|
@@ -262,6 +272,8 @@ class TreeArtist(mpl.artist.Artist):
|
|
|
262
272
|
"""Get leaf VertexCollection artist."""
|
|
263
273
|
return self._leaf_vertices
|
|
264
274
|
|
|
275
|
+
get_leaf_nodes = get_leaf_vertices
|
|
276
|
+
|
|
265
277
|
def get_leaf_edges(self) -> Optional[LeafEdgeCollection]:
|
|
266
278
|
"""Get LeafEdgeCollection artist if present."""
|
|
267
279
|
if hasattr(self, "_leaf_edges"):
|
|
@@ -272,6 +284,8 @@ class TreeArtist(mpl.artist.Artist):
|
|
|
272
284
|
"""Get list of vertex label artists."""
|
|
273
285
|
return self._vertices.get_labels()
|
|
274
286
|
|
|
287
|
+
get_node_labels = get_vertex_labels
|
|
288
|
+
|
|
275
289
|
def get_edge_labels(self) -> LabelCollection:
|
|
276
290
|
"""Get list of edge label artists."""
|
|
277
291
|
return self._edges.get_labels()
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import copy
|
|
2
|
+
from collections import defaultdict
|
|
3
|
+
|
|
4
|
+
from ..style.leaf_info import (
|
|
5
|
+
style_leaves,
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
try:
|
|
9
|
+
import networkx as nx
|
|
10
|
+
except ImportError:
|
|
11
|
+
nx = None
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def copy_with_deep_values(style):
|
|
15
|
+
"""Make a deep copy of the style dict but do not create copies of the keys."""
|
|
16
|
+
# Defaultdict should be respected
|
|
17
|
+
if hasattr(style, "default_factory"):
|
|
18
|
+
newdict = defaultdict(lambda: style.default_factory())
|
|
19
|
+
else:
|
|
20
|
+
newdict = {}
|
|
21
|
+
for key, value in style.items():
|
|
22
|
+
if isinstance(value, dict):
|
|
23
|
+
newdict[key] = copy_with_deep_values(value)
|
|
24
|
+
else:
|
|
25
|
+
newdict[key] = copy.copy(value)
|
|
26
|
+
return newdict
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def sanitize_leaves(style: dict):
|
|
30
|
+
"""Sanitize the leaves of a style dictionary.
|
|
31
|
+
|
|
32
|
+
Parameters:
|
|
33
|
+
style (dict): A style dictionary.
|
|
34
|
+
Returns:
|
|
35
|
+
None: The style dictionary is modified in place.
|
|
36
|
+
"""
|
|
37
|
+
for key, value in style.items():
|
|
38
|
+
if key in style_leaves:
|
|
39
|
+
# Networkx has a few lazy data structures
|
|
40
|
+
# TODO: move this code to provider
|
|
41
|
+
if nx is not None:
|
|
42
|
+
if isinstance(value, nx.classes.reportviews.NodeView):
|
|
43
|
+
style[key] = dict(value)
|
|
44
|
+
elif isinstance(value, nx.classes.reportviews.EdgeViewABC):
|
|
45
|
+
style[key] = [v for *e, v in value]
|
|
46
|
+
|
|
47
|
+
elif isinstance(value, dict):
|
|
48
|
+
sanitize_leaves(value)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def update_style(new_style: dict, current_style: dict):
|
|
52
|
+
"""Update the current style with a new style.
|
|
53
|
+
|
|
54
|
+
Parameters:
|
|
55
|
+
new_style (dict): A new style dictionary.
|
|
56
|
+
current_style (dict): The current style dictionary.
|
|
57
|
+
Returns:
|
|
58
|
+
None: The current style dictionary is modified in place.
|
|
59
|
+
"""
|
|
60
|
+
for key, value in new_style.items():
|
|
61
|
+
if key not in current_style:
|
|
62
|
+
current_style[key] = value
|
|
63
|
+
continue
|
|
64
|
+
|
|
65
|
+
# Style non-leaves are either recurred into or deleted
|
|
66
|
+
if key not in style_leaves:
|
|
67
|
+
if isinstance(value, dict):
|
|
68
|
+
update_style(value, current_style[key])
|
|
69
|
+
elif value is None:
|
|
70
|
+
del current_style[key]
|
|
71
|
+
else:
|
|
72
|
+
raise ValueError(
|
|
73
|
+
f"Setting non-leaf style value to a non-dict: {key}, {value}",
|
|
74
|
+
)
|
|
75
|
+
else:
|
|
76
|
+
# Style leaves could be incomplete, ensure a sensible default
|
|
77
|
+
if value is None:
|
|
78
|
+
del current_style[key]
|
|
79
|
+
continue
|
|
80
|
+
|
|
81
|
+
if not isinstance(value, dict):
|
|
82
|
+
current_style[key] = value
|
|
83
|
+
continue
|
|
84
|
+
|
|
85
|
+
if hasattr(value, "default_factory"):
|
|
86
|
+
current_style[key] = value
|
|
87
|
+
continue
|
|
88
|
+
|
|
89
|
+
if hasattr(current_style[key], "default_factory"):
|
|
90
|
+
default_value = current_style[key].default_factory()
|
|
91
|
+
else:
|
|
92
|
+
default_value = current_style[key]
|
|
93
|
+
current_style[key] = defaultdict(
|
|
94
|
+
lambda: default_value,
|
|
95
|
+
value,
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def sanitize_ambiguous(style: dict):
|
|
100
|
+
"""Fix a few ambiguous cases in the style dict.
|
|
101
|
+
|
|
102
|
+
Parameters:
|
|
103
|
+
style (dict): A style dictionary. This must be unflattened beforehand.
|
|
104
|
+
Returns:
|
|
105
|
+
None: The style dictionary is modified in place.
|
|
106
|
+
|
|
107
|
+
NOTE: This function exists by design, not accident. It is useful for purposeful
|
|
108
|
+
(e.g. node vs vertex) or historical (e.g. edge_padding vs edge_shrink) reasons.
|
|
109
|
+
Either way, it softens the user experience without complicating the API.
|
|
110
|
+
"""
|
|
111
|
+
|
|
112
|
+
# Accept "node" style as "vertex" style for user flexibility
|
|
113
|
+
if "node" in style:
|
|
114
|
+
style_node = style.pop("node")
|
|
115
|
+
if "vertex" not in style:
|
|
116
|
+
style["vertex"] = style_node
|
|
117
|
+
else:
|
|
118
|
+
# "node" style applies on TOP of "vertex" style
|
|
119
|
+
update_style(style_node, style["vertex"])
|
|
120
|
+
|
|
121
|
+
# NOTE: Deprecate edge_padding for edge_shrink
|
|
122
|
+
for edgekey in ["edge", "leafedge"]:
|
|
123
|
+
if "padding" in style.get(edgekey, {}):
|
|
124
|
+
# shrink takes over
|
|
125
|
+
if "shrink" in style[edgekey]:
|
|
126
|
+
del style[edgekey]["padding"]
|
|
127
|
+
else:
|
|
128
|
+
style[edgekey]["shrink"] = style[edgekey].pop("padding")
|
|
@@ -31,19 +31,19 @@ class GraphTestRunner(unittest.TestCase):
|
|
|
31
31
|
def test_basic(self):
|
|
32
32
|
g = ig.Graph.Ring(5)
|
|
33
33
|
fig, ax = plt.subplots(figsize=(3, 3))
|
|
34
|
-
ipx.
|
|
34
|
+
ipx.graph(g, ax=ax, layout=self.layout_small_ring)
|
|
35
35
|
|
|
36
36
|
@image_comparison(baseline_images=["graph_directed"], remove_text=True)
|
|
37
37
|
def test_directed(self):
|
|
38
38
|
g = ig.Graph.Ring(5, directed=True)
|
|
39
39
|
fig, ax = plt.subplots(figsize=(3, 3))
|
|
40
|
-
ipx.
|
|
40
|
+
ipx.graph(g, ax=ax, layout=self.layout_small_ring)
|
|
41
41
|
|
|
42
42
|
@image_comparison(baseline_images=["graph_vertexsize"], remove_text=True)
|
|
43
43
|
def test_vertexsize(self):
|
|
44
44
|
g = ig.Graph.Ring(5)
|
|
45
45
|
fig, ax = plt.subplots(figsize=(3, 3))
|
|
46
|
-
ipx.
|
|
46
|
+
ipx.graph(
|
|
47
47
|
g,
|
|
48
48
|
ax=ax,
|
|
49
49
|
layout=self.layout_small_ring,
|
|
@@ -55,7 +55,7 @@ class GraphTestRunner(unittest.TestCase):
|
|
|
55
55
|
def test_labels(self):
|
|
56
56
|
g = ig.Graph.Ring(5)
|
|
57
57
|
fig, ax = plt.subplots(figsize=(3, 3))
|
|
58
|
-
ipx.
|
|
58
|
+
ipx.graph(
|
|
59
59
|
network=g,
|
|
60
60
|
ax=ax,
|
|
61
61
|
layout=self.layout_small_ring,
|
|
@@ -76,14 +76,14 @@ class GraphTestRunner(unittest.TestCase):
|
|
|
76
76
|
g = ig.Graph.Ring(5)
|
|
77
77
|
layout = g.layout("circle")
|
|
78
78
|
fig, ax = plt.subplots(figsize=(3, 3))
|
|
79
|
-
ipx.
|
|
79
|
+
ipx.graph(g, layout=layout, ax=ax)
|
|
80
80
|
|
|
81
81
|
@image_comparison(baseline_images=["graph_layout_attribute"], remove_text=True)
|
|
82
82
|
def test_layout_attribute_alt(self):
|
|
83
83
|
g = ig.Graph.Ring(5)
|
|
84
84
|
g["layout"] = ig.Layout([(x, x) for x in range(g.vcount())])
|
|
85
85
|
fig, ax = plt.subplots(figsize=(3, 3))
|
|
86
|
-
ipx.
|
|
86
|
+
ipx.graph(g, layout="layout", ax=ax)
|
|
87
87
|
|
|
88
88
|
@image_comparison(baseline_images=["graph_directed_curved_loops"], remove_text=True)
|
|
89
89
|
def test_directed_curved_loops(self):
|
|
@@ -94,7 +94,7 @@ class GraphTestRunner(unittest.TestCase):
|
|
|
94
94
|
fig, ax = plt.subplots(figsize=(4, 4))
|
|
95
95
|
# ax.set_xlim(-1.2, 1.2)
|
|
96
96
|
# ax.set_ylim(-1.2, 1.2)
|
|
97
|
-
ipx.
|
|
97
|
+
ipx.graph(
|
|
98
98
|
g,
|
|
99
99
|
ax=ax,
|
|
100
100
|
layout=self.layout_small_ring,
|
|
@@ -112,7 +112,7 @@ class GraphTestRunner(unittest.TestCase):
|
|
|
112
112
|
def test_mark_groups_squares(self):
|
|
113
113
|
g = ig.Graph.Ring(5, directed=True)
|
|
114
114
|
fig, ax = plt.subplots(figsize=(3, 3))
|
|
115
|
-
ipx.
|
|
115
|
+
ipx.graph(
|
|
116
116
|
g,
|
|
117
117
|
ax=ax,
|
|
118
118
|
layout=self.layout_small_ring,
|
|
@@ -125,7 +125,7 @@ class GraphTestRunner(unittest.TestCase):
|
|
|
125
125
|
def test_edit_children(self):
|
|
126
126
|
g = ig.Graph.Ring(5)
|
|
127
127
|
fig, ax = plt.subplots(figsize=(4, 4))
|
|
128
|
-
ipx.
|
|
128
|
+
ipx.graph(
|
|
129
129
|
g,
|
|
130
130
|
ax=ax,
|
|
131
131
|
style={"vertex": {"marker": "o"}},
|
|
@@ -148,7 +148,7 @@ class GraphTestRunner(unittest.TestCase):
|
|
|
148
148
|
fig, ax = plt.subplots()
|
|
149
149
|
lo = g.layout("circle")
|
|
150
150
|
lo.scale(3)
|
|
151
|
-
ipx.
|
|
151
|
+
ipx.graph(
|
|
152
152
|
g,
|
|
153
153
|
ax=ax,
|
|
154
154
|
layout=lo,
|
|
@@ -176,7 +176,7 @@ class GraphTestRunner(unittest.TestCase):
|
|
|
176
176
|
fig, ax = plt.subplots()
|
|
177
177
|
lo = g.layout("circle")
|
|
178
178
|
lo.scale(3)
|
|
179
|
-
ipx.
|
|
179
|
+
ipx.graph(
|
|
180
180
|
g,
|
|
181
181
|
ax=ax,
|
|
182
182
|
layout=lo,
|
|
@@ -201,7 +201,7 @@ class GraphTestRunner(unittest.TestCase):
|
|
|
201
201
|
def test_null_graph(self):
|
|
202
202
|
g = ig.Graph()
|
|
203
203
|
fig, ax = plt.subplots()
|
|
204
|
-
ipx.
|
|
204
|
+
ipx.graph(g, ax=ax)
|
|
205
205
|
ax.set_aspect(1.0)
|
|
206
206
|
|
|
207
207
|
|
|
@@ -278,14 +278,14 @@ class ClusteringTestRunner(unittest.TestCase):
|
|
|
278
278
|
g = ig.Graph.Ring(5, directed=True)
|
|
279
279
|
clu = ig.VertexClustering(g, [0] * 5)
|
|
280
280
|
fig, ax = plt.subplots()
|
|
281
|
-
ipx.
|
|
281
|
+
ipx.graph(g, grouping=clu, ax=ax, layout=self.layout_small_ring)
|
|
282
282
|
|
|
283
283
|
@image_comparison(baseline_images=["clustering_directed_large"], remove_text=True)
|
|
284
284
|
def test_clustering_directed_large(self):
|
|
285
285
|
g = ig.Graph.Ring(50, directed=True)
|
|
286
286
|
clu = ig.VertexClustering(g, [0] * 3 + [1] * 17 + [2] * 30)
|
|
287
287
|
fig, ax = plt.subplots()
|
|
288
|
-
ipx.
|
|
288
|
+
ipx.graph(
|
|
289
289
|
g,
|
|
290
290
|
grouping=clu,
|
|
291
291
|
style={
|
|
@@ -26,14 +26,14 @@ class GraphTestRunner(unittest.TestCase):
|
|
|
26
26
|
]
|
|
27
27
|
)
|
|
28
28
|
pos = {1: (0, 0), 2: (-1, 0.3), 3: (2, 0.17), 4: (4, 0.255), 5: (5, 0.03)}
|
|
29
|
-
ipx.
|
|
29
|
+
ipx.network(
|
|
30
30
|
G,
|
|
31
31
|
layout=pos,
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
node_labels=False,
|
|
33
|
+
node_size=5,
|
|
34
|
+
node_facecolor="white",
|
|
35
|
+
node_edgecolor="black",
|
|
36
|
+
node_linewidth=3,
|
|
37
37
|
edge_linewidth=3,
|
|
38
38
|
edge_color=["grey", "black"],
|
|
39
39
|
margins=0.1,
|
|
@@ -52,10 +52,10 @@ class GraphTestRunner(unittest.TestCase):
|
|
|
52
52
|
# explicitly set positions
|
|
53
53
|
pos = {1: (0, 0), 2: (-1, 0.3), 3: (2, 0.17), 4: (4, 0.255), 5: (5, 0.03)}
|
|
54
54
|
|
|
55
|
-
ipx.
|
|
55
|
+
ipx.network(
|
|
56
56
|
G,
|
|
57
57
|
layout=pos,
|
|
58
|
-
|
|
58
|
+
node_labels=True,
|
|
59
59
|
style={
|
|
60
60
|
"vertex": {
|
|
61
61
|
"size": "label",
|
|
@@ -224,11 +224,11 @@ class GraphTestRunner(unittest.TestCase):
|
|
|
224
224
|
)
|
|
225
225
|
|
|
226
226
|
fig, ax = plt.subplots()
|
|
227
|
-
ipx.
|
|
227
|
+
ipx.network(
|
|
228
228
|
G,
|
|
229
229
|
ax=ax,
|
|
230
230
|
layout="pos",
|
|
231
|
-
|
|
231
|
+
node_labels=True,
|
|
232
232
|
edge_labels=True,
|
|
233
233
|
)
|
|
234
234
|
|
|
@@ -298,11 +298,11 @@ class GraphTestRunner(unittest.TestCase):
|
|
|
298
298
|
)
|
|
299
299
|
|
|
300
300
|
fig, ax = plt.subplots(figsize=(5, 4))
|
|
301
|
-
ipx.
|
|
301
|
+
ipx.network(
|
|
302
302
|
G,
|
|
303
303
|
ax=ax,
|
|
304
304
|
layout="pos",
|
|
305
|
-
|
|
305
|
+
node_labels=True,
|
|
306
306
|
style={
|
|
307
307
|
"vertex": {
|
|
308
308
|
"facecolor": G.nodes.data("color"),
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import copy
|
|
2
|
-
from collections import defaultdict
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
def copy_with_deep_values(style):
|
|
6
|
-
"""Make a deep copy of the style dict but do not create copies of the keys."""
|
|
7
|
-
# Defaultdict should be respected
|
|
8
|
-
if hasattr(style, "default_factory"):
|
|
9
|
-
newdict = defaultdict(lambda: style.default_factory())
|
|
10
|
-
else:
|
|
11
|
-
newdict = {}
|
|
12
|
-
for key, value in style.items():
|
|
13
|
-
if isinstance(value, dict):
|
|
14
|
-
newdict[key] = copy_with_deep_values(value)
|
|
15
|
-
else:
|
|
16
|
-
newdict[key] = copy.copy(value)
|
|
17
|
-
return newdict
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|