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.
Files changed (292) hide show
  1. {iplotx-1.5.1 → iplotx-1.7.0}/PKG-INFO +5 -5
  2. {iplotx-1.5.1 → iplotx-1.7.0}/README.md +3 -3
  3. {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/api/complete_style_specification.md +12 -2
  4. {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/installing.md +8 -2
  5. {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/sg_execution_times.rst +23 -8
  6. iplotx-1.7.0/gallery/GALLERY_HEADER.rst +34 -0
  7. iplotx-1.7.0/gallery/fun/GALLERY_HEADER.rst +2 -0
  8. iplotx-1.7.0/gallery/fun/plot_67.py +54 -0
  9. iplotx-1.7.0/gallery/other/plot_hover_neighborhood.py +83 -0
  10. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/other/plot_mouse_hover.py +1 -1
  11. iplotx-1.7.0/gallery/style/plot_curved_waypoints.py +43 -0
  12. iplotx-1.7.0/gallery/style/plot_edge_multicolor.py +29 -0
  13. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/style/plot_waypoints.py +0 -4
  14. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/edge/__init__.py +27 -12
  15. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/edge/geometry.py +16 -2
  16. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/plotting.py +47 -4
  17. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/utils/matplotlib.py +5 -0
  18. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/version.py +1 -1
  19. {iplotx-1.5.1 → iplotx-1.7.0}/pyproject.toml +1 -1
  20. iplotx-1.7.0/tests/baseline_images/test_networkx/triangular_lattice.png +0 -0
  21. iplotx-1.7.0/tests/baseline_images/test_simple_network_provider/curved_waypoints.png +0 -0
  22. {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_edge_geometry.py +4 -0
  23. iplotx-1.7.0/tests/test_igraph.py +367 -0
  24. {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_networkx.py +8 -0
  25. {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_simple_network_provider.py +22 -0
  26. {iplotx-1.5.1 → iplotx-1.7.0}/uv.lock +2 -37
  27. iplotx-1.5.1/gallery/GALLERY_HEADER.rst +0 -2
  28. iplotx-1.5.1/tests/test_igraph.py +0 -385
  29. {iplotx-1.5.1 → iplotx-1.7.0}/.github/workflows/publish.yml +0 -0
  30. {iplotx-1.5.1 → iplotx-1.7.0}/.github/workflows/test.yml +0 -0
  31. {iplotx-1.5.1 → iplotx-1.7.0}/.gitignore +0 -0
  32. {iplotx-1.5.1 → iplotx-1.7.0}/.pre-commit-config.yaml +0 -0
  33. {iplotx-1.5.1 → iplotx-1.7.0}/.readthedocs.yaml +0 -0
  34. {iplotx-1.5.1 → iplotx-1.7.0}/LICENSE +0 -0
  35. {iplotx-1.5.1 → iplotx-1.7.0}/MANIFEST.in +0 -0
  36. {iplotx-1.5.1 → iplotx-1.7.0}/assets/pylint.svg +0 -0
  37. {iplotx-1.5.1 → iplotx-1.7.0}/docs/Makefile +0 -0
  38. {iplotx-1.5.1 → iplotx-1.7.0}/docs/make.bat +0 -0
  39. {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/_static/banner.png +0 -0
  40. {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/_static/custom-icons.js +0 -0
  41. {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/_static/custom.css +0 -0
  42. {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/_static/graph_basic.png +0 -0
  43. {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/_templates/layout.html +0 -0
  44. {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/api/artists.md +0 -0
  45. {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/api/plotting.md +0 -0
  46. {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/api/providers.md +0 -0
  47. {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/api/style.md +0 -0
  48. {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/api.md +0 -0
  49. {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/code_of_conduct.rst +0 -0
  50. {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/conf.py +0 -0
  51. {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/images/sphx_glr_plot_basic_001.png +0 -0
  52. {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/images/thumb/sphx_glr_plot_basic_thumb.png +0 -0
  53. {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/index.md +0 -0
  54. {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/providers.md +0 -0
  55. {iplotx-1.5.1 → iplotx-1.7.0}/docs/source/style.md +0 -0
  56. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/basic/GALLERY_HEADER.rst +0 -0
  57. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/basic/plot_3d.py +0 -0
  58. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/basic/plot_arcs.py +0 -0
  59. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/basic/plot_basic.py +0 -0
  60. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/basic/plot_big_curves.py +0 -0
  61. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/basic/plot_dag.py +0 -0
  62. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/basic/plot_directed.py +0 -0
  63. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/basic/plot_grouping.py +0 -0
  64. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/basic/plot_house.py +0 -0
  65. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/basic/plot_loops.py +0 -0
  66. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/basic/plot_simple_path.py +0 -0
  67. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/biology/GALLERY_HEADER.rst +0 -0
  68. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/biology/data/80201010000000001.mst +0 -0
  69. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/biology/data/GN-tree.json +0 -0
  70. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/biology/data/breast_cancer_string_interactions_short.tsv +0 -0
  71. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/biology/data/breast_cancer_string_network_coordinates.tsv +0 -0
  72. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/biology/data/cell_cycle_arrest_string_interactions_short.tsv +0 -0
  73. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/biology/data/cell_cycle_arrest_string_network_coordinates.tsv +0 -0
  74. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/biology/data/fevo-08-588430_DataSheet1_S1.csv +0 -0
  75. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/biology/plot_animal_phylogeny.py +0 -0
  76. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/biology/plot_antibody_clone.py +0 -0
  77. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/biology/plot_breast_cancer_ppi.py +0 -0
  78. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/biology/plot_cell_cycle_arrest.py +0 -0
  79. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/biology/plot_food_network.py +0 -0
  80. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/biology/plot_foraging_table.py +0 -0
  81. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/biology/plot_pollinators.py +0 -0
  82. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/biology/plot_ppi.py +0 -0
  83. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/biology/plot_tca_cycle.py +0 -0
  84. {iplotx-1.5.1/gallery/other → iplotx-1.7.0/gallery/fun}/plot_train.py +0 -0
  85. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/GALLERY_HEADER.rst +0 -0
  86. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/data/chess_masters_WCC.pgn.bz2 +0 -0
  87. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/data/knuth_miles.txt.gz +0 -0
  88. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_arrowlawn.py +0 -0
  89. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_chess_masters.py +0 -0
  90. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_cliques.py +0 -0
  91. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_cluster_layout.py +0 -0
  92. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_company_structure.py +0 -0
  93. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_complex.py +0 -0
  94. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_financial_network.py +0 -0
  95. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_knuth_miles.py +0 -0
  96. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_labels_and_colors.py +0 -0
  97. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_max_bipartite_matching.py +0 -0
  98. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_minimum_spanning_trees.py +0 -0
  99. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_multipartite_layout.py +0 -0
  100. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_parallel_igraph_networkx.py +0 -0
  101. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_redblack.py +0 -0
  102. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_shortest_path.py +0 -0
  103. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_simple_networkx.py +0 -0
  104. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_social_network_circles.py +0 -0
  105. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_traveling_salesman.py +0 -0
  106. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/network_science/plot_with_colorbar.py +0 -0
  107. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/other/GALLERY_HEADER.rst +0 -0
  108. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/other/data/african_cities_coords.csv +0 -0
  109. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/other/data/draco_stars.csv +0 -0
  110. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/other/plot_animation.py +0 -0
  111. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/other/plot_bundles.py +0 -0
  112. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/other/plot_constellation.py +0 -0
  113. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/other/plot_edit_artists.py +0 -0
  114. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/other/plot_feedbacks.py +0 -0
  115. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/other/plot_geomap.py +0 -0
  116. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/other/plot_graph.py +0 -0
  117. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/other/plot_multiarc.py +0 -0
  118. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/style/GALLERY_HEADER.rst +0 -0
  119. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/style/plot_arrows.py +0 -0
  120. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/style/plot_custom_vertex.py +0 -0
  121. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/style/plot_depthshade.py +0 -0
  122. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/style/plot_edge_geometries.py +0 -0
  123. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/style/plot_edgepadding.py +0 -0
  124. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/style/plot_elements.py +0 -0
  125. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/style/plot_filled_edges.py +0 -0
  126. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/style/plot_four_grids.py +0 -0
  127. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/style/plot_halfarrows.py +0 -0
  128. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/style/plot_multistyle.py +0 -0
  129. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/style/plot_ports.py +0 -0
  130. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/style/plot_style.py +0 -0
  131. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/style/plot_tension.py +0 -0
  132. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/style/plot_vertexmarkers.py +0 -0
  133. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/style/plot_voronoi.py +0 -0
  134. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/GALLERY_HEADER.rst +0 -0
  135. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/data/tree-with-support.json +0 -0
  136. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_angular_waypoints.py +0 -0
  137. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_biopython_tree.py +0 -0
  138. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_cladeedges.py +0 -0
  139. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_cogent3_layouts.py +0 -0
  140. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_cogent3_tree.py +0 -0
  141. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_dendropy.py +0 -0
  142. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_double_tree.py +0 -0
  143. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_elements_tree.py +0 -0
  144. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_equalangle.py +0 -0
  145. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_ete4.py +0 -0
  146. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_leafedges.py +0 -0
  147. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_leafedges_and_cascades.py +0 -0
  148. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_scalebar.py +0 -0
  149. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_skbio_tree.py +0 -0
  150. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_split_edges.py +0 -0
  151. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_style_tree.py +0 -0
  152. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_support.py +0 -0
  153. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_tree_node_background.py +0 -0
  154. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_tree_style_clades.py +0 -0
  155. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/tree/plot_trees_of_trees.py +0 -0
  156. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/zero_dependency/GALLERY_HEADER.rst +0 -0
  157. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/zero_dependency/plot_simplenetworkdataprovider.py +0 -0
  158. {iplotx-1.5.1 → iplotx-1.7.0}/gallery/zero_dependency/plot_simpletreedataprovider.py +0 -0
  159. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/__init__.py +0 -0
  160. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/art3d/edge/__init__.py +0 -0
  161. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/art3d/edge/arrow.py +0 -0
  162. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/art3d/edge/geometry.py +0 -0
  163. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/art3d/vertex.py +0 -0
  164. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/artists.py +0 -0
  165. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/edge/arrow.py +0 -0
  166. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/edge/leaf.py +0 -0
  167. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/edge/ports.py +0 -0
  168. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/ingest/__init__.py +0 -0
  169. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/ingest/heuristics.py +0 -0
  170. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/ingest/providers/network/graph_tool.py +0 -0
  171. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/ingest/providers/network/igraph.py +0 -0
  172. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/ingest/providers/network/networkx.py +0 -0
  173. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/ingest/providers/network/simple.py +0 -0
  174. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/ingest/providers/tree/biopython.py +0 -0
  175. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/ingest/providers/tree/cogent3.py +0 -0
  176. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/ingest/providers/tree/dendropy.py +0 -0
  177. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/ingest/providers/tree/ete4.py +0 -0
  178. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/ingest/providers/tree/simple.py +0 -0
  179. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/ingest/providers/tree/skbio.py +0 -0
  180. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/ingest/typing.py +0 -0
  181. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/label.py +0 -0
  182. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/layout/__init__.py +0 -0
  183. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/layout/tree/__init__.py +0 -0
  184. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/layout/tree/rooted.py +0 -0
  185. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/layout/tree/unrooted.py +0 -0
  186. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/network/__init__.py +0 -0
  187. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/network/groups.py +0 -0
  188. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/style/__init__.py +0 -0
  189. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/style/leaf_info.py +0 -0
  190. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/style/library.py +0 -0
  191. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/tree/__init__.py +0 -0
  192. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/tree/cascades.py +0 -0
  193. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/tree/scalebar.py +0 -0
  194. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/typing.py +0 -0
  195. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/utils/geometry.py +0 -0
  196. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/utils/internal.py +0 -0
  197. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/utils/style.py +0 -0
  198. {iplotx-1.5.1 → iplotx-1.7.0}/iplotx/vertex.py +0 -0
  199. {iplotx-1.5.1 → iplotx-1.7.0}/scripts/copy_github_release_into_version.sh +0 -0
  200. {iplotx-1.5.1 → iplotx-1.7.0}/scripts/make_banner.py +0 -0
  201. {iplotx-1.5.1 → iplotx-1.7.0}/scripts/update_pylint_badge.sh +0 -0
  202. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_biopython/cascades.png +0 -0
  203. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_biopython/directed_child.png +0 -0
  204. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_biopython/leaf_labels.png +0 -0
  205. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_biopython/leaf_labels_hmargin.png +0 -0
  206. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_biopython/leafedges.png +0 -0
  207. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_biopython/show_support.png +0 -0
  208. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_biopython/tree_basic.png +0 -0
  209. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_biopython/tree_radial.png +0 -0
  210. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_cogent3/leaf_labels.png +0 -0
  211. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_cogent3/leaf_labels_hmargin.png +0 -0
  212. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_cogent3/tree_basic.png +0 -0
  213. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_cogent3/tree_radial.png +0 -0
  214. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_dendropy/cascades.png +0 -0
  215. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_dendropy/directed_child.png +0 -0
  216. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_dendropy/leaf_labels.png +0 -0
  217. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_dendropy/leaf_labels_hmargin.png +0 -0
  218. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_dendropy/leafedges.png +0 -0
  219. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_dendropy/tree_basic.png +0 -0
  220. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_dendropy/tree_radial.png +0 -0
  221. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_doubletree/tree_gap.png +0 -0
  222. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_doubletree/tree_nogap.png +0 -0
  223. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_ete4/equalangle_layout.png +0 -0
  224. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_ete4/leaf_labels.png +0 -0
  225. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_ete4/leaf_labels_hmargin.png +0 -0
  226. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_ete4/split_edges.png +0 -0
  227. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_ete4/tree_basic.png +0 -0
  228. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_ete4/tree_radial.png +0 -0
  229. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_graph_tool/graph_basic.png +0 -0
  230. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_graph_tool/graph_directed.png +0 -0
  231. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/arcs.png +0 -0
  232. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/clustering_directed.png +0 -0
  233. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/clustering_directed_large.png +0 -0
  234. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/directed_arcs.png +0 -0
  235. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/graph_basic.png +0 -0
  236. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/graph_directed.png +0 -0
  237. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/graph_directed_curved_loops.png +0 -0
  238. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/graph_edit_children.png +0 -0
  239. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/graph_labels.png +0 -0
  240. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/graph_layout_attribute.png +0 -0
  241. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/graph_null.png +0 -0
  242. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/graph_squares_directed.png +0 -0
  243. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/graph_vertexsize.png +0 -0
  244. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/graph_with_curved_edges.png +0 -0
  245. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/igraph_layout_object.png +0 -0
  246. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/large_arcs.png +0 -0
  247. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/multiarc45.png +0 -0
  248. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph/multigraph_with_curved_edges_undirected.png +0 -0
  249. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph_3d/directed.png +0 -0
  250. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph_3d/undirected.png +0 -0
  251. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_igraph_3d/vertex_labels.png +0 -0
  252. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_networkx/cluster-layout.png +0 -0
  253. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_networkx/complex.png +0 -0
  254. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_networkx/complex_rotatelabels.png +0 -0
  255. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_networkx/custom_marker_path.png +0 -0
  256. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_networkx/custom_marker_polygon.png +0 -0
  257. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_networkx/directed_graph.png +0 -0
  258. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_networkx/directed_graph_with_colorbar.png +0 -0
  259. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_networkx/empty_graph.png +0 -0
  260. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_networkx/flat_style.png +0 -0
  261. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_networkx/house_with_colors.png +0 -0
  262. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_networkx/labels_and_colors.png +0 -0
  263. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_networkx/shortest_path.png +0 -0
  264. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_networkx/simple_graph.png +0 -0
  265. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_simple_network_provider/graph_basic.png +0 -0
  266. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_simple_network_provider/graph_directed.png +0 -0
  267. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_simple_network_provider/graph_labels.png +0 -0
  268. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_skbio/leaf_labels.png +0 -0
  269. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_skbio/leaf_labels_hmargin.png +0 -0
  270. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_skbio/tree_basic.png +0 -0
  271. {iplotx-1.5.1 → iplotx-1.7.0}/tests/baseline_images/test_skbio/tree_radial.png +0 -0
  272. {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_arrows.py +0 -0
  273. {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_biopython.py +0 -0
  274. {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_cascades.py +0 -0
  275. {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_cogent3.py +0 -0
  276. {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_dendropy.py +0 -0
  277. {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_doubletree.py +0 -0
  278. {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_edge.py +0 -0
  279. {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_ete4.py +0 -0
  280. {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_geometry.py +0 -0
  281. {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_graph_tool.py +0 -0
  282. {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_heuristics.py +0 -0
  283. {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_igraph_3d.py +0 -0
  284. {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_ingest_protocols.py +0 -0
  285. {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_matplotlib_utils.py +0 -0
  286. {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_network_hotload.py +0 -0
  287. {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_ports.py +0 -0
  288. {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_simple_tree_provider.py +0 -0
  289. {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_skbio.py +0 -0
  290. {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_style.py +0 -0
  291. {iplotx-1.5.1 → iplotx-1.7.0}/tests/test_vertex.py +0 -0
  292. {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.5.1
4
- Summary: Plot networkx from igraph and networkx.
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
  [![RTD](https://readthedocs.org/projects/iplotx/badge/?version=latest)](https://iplotx.readthedocs.io/en/latest/)
42
42
  [![Coverage Status](https://coveralls.io/repos/github/fabilab/iplotx/badge.svg?branch=main)](https://coveralls.io/github/fabilab/iplotx?branch=main)
43
43
  ![pylint](assets/pylint.svg)
44
- [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.16599333.svg)](https://doi.org/10.5281/zenodo.16599333)
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 the [zenodo preprint](https://doi.org/10.5281/zenodo.16599333):
93
+ If you use `iplotx` for publication figures, please cite:
94
94
 
95
95
  ```
96
- F. Zanini. (2025). Unified network visualisation in Python. Zenodo [PREPRINT]. https://doi.org/10.5281/zenodo.16599333
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
  [![RTD](https://readthedocs.org/projects/iplotx/badge/?version=latest)](https://iplotx.readthedocs.io/en/latest/)
4
4
  [![Coverage Status](https://coveralls.io/repos/github/fabilab/iplotx/badge.svg?branch=main)](https://coveralls.io/github/fabilab/iplotx?branch=main)
5
5
  ![pylint](assets/pylint.svg)
6
- [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.16599333.svg)](https://doi.org/10.5281/zenodo.16599333)
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 the [zenodo preprint](https://doi.org/10.5281/zenodo.16599333):
55
+ If you use `iplotx` for publication figures, please cite:
56
56
 
57
57
  ```
58
- F. Zanini. (2025). Unified network visualisation in Python. Zenodo [PREPRINT]. https://doi.org/10.5281/zenodo.16599333
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
- # We are looking into ways to generalise this idea.
155
- "waypoints": str,
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 the [zenodo preprint](https://doi.org/10.5281/zenodo.16599333):
80
+ If you use `iplotx` for publication figures, please cite:
75
81
 
76
82
  ```
77
- F. Zanini. (2025). Unified network visualisation in Python. Zenodo [PREPRINT]. https://doi.org/10.5281/zenodo.16599333
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.069** total execution time for 85 files **from all galleries**:
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:`sphx_glr_gallery_style_plot_custom_vertex.py` (``../../gallery/style/plot_custom_vertex.py``)
36
- - 00:00.069
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:`sphx_glr_gallery_other_plot_train.py` (``../../gallery/other/plot_train.py``)
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:`sphx_glr_gallery_style_plot_arrows.py` (``../../gallery/style/plot_arrows.py``)
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,2 @@
1
+ Fun
2
+ +++
@@ -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 buble
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
+ )
@@ -34,7 +34,3 @@ ipx.network(
34
34
  edge_waypoints=["none", [(1, 1), (0.5, 1.5), (1, 1.5)], "none", "none"],
35
35
  )
36
36
  plt.ion(); plt.show()
37
-
38
- # %%
39
- # .. note::
40
- # Edge waypoints are not currently compatible with curved edges.
@@ -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
- # False is a synonym for "none"
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
- points = [vshorts[0]] + list(waypoints) + [vshorts[1]]
281
- codes = ["MOVETO"] + ["LINETO"] * len(waypoints) + ["LINETO"]
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,