iplotx 1.0.0__tar.gz → 1.1.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 (259) hide show
  1. iplotx-1.1.0/.github/workflows/test.yml +86 -0
  2. {iplotx-1.0.0 → iplotx-1.1.0}/PKG-INFO +7 -6
  3. {iplotx-1.0.0 → iplotx-1.1.0}/README.md +6 -5
  4. {iplotx-1.0.0 → iplotx-1.1.0}/docs/source/index.md +1 -1
  5. {iplotx-1.0.0 → iplotx-1.1.0}/docs/source/sg_execution_times.rst +6 -3
  6. iplotx-1.1.0/gallery/tree/plot_double_tree.py +56 -0
  7. iplotx-1.1.0/iplotx/ingest/providers/network/graph_tool.py +100 -0
  8. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/layout.py +30 -1
  9. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/tree/__init__.py +3 -0
  10. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/tree/scalebar.py +4 -3
  11. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/version.py +1 -1
  12. iplotx-1.1.0/tests/baseline_images/test_graph_tool/graph_basic.png +1 -0
  13. iplotx-1.1.0/tests/baseline_images/test_graph_tool/graph_directed.png +1 -0
  14. iplotx-1.1.0/tests/test_graph_tool.py +44 -0
  15. iplotx-1.0.0/.github/workflows/test.yml +0 -43
  16. {iplotx-1.0.0 → iplotx-1.1.0}/.github/workflows/publish.yml +0 -0
  17. {iplotx-1.0.0 → iplotx-1.1.0}/.gitignore +0 -0
  18. {iplotx-1.0.0 → iplotx-1.1.0}/.pre-commit-config.yaml +0 -0
  19. {iplotx-1.0.0 → iplotx-1.1.0}/.readthedocs.yaml +0 -0
  20. {iplotx-1.0.0 → iplotx-1.1.0}/LICENSE +0 -0
  21. {iplotx-1.0.0 → iplotx-1.1.0}/MANIFEST.in +0 -0
  22. {iplotx-1.0.0 → iplotx-1.1.0}/assets/pylint.svg +0 -0
  23. {iplotx-1.0.0 → iplotx-1.1.0}/docs/Makefile +0 -0
  24. {iplotx-1.0.0 → iplotx-1.1.0}/docs/make.bat +0 -0
  25. {iplotx-1.0.0 → iplotx-1.1.0}/docs/source/_static/banner.png +0 -0
  26. {iplotx-1.0.0 → iplotx-1.1.0}/docs/source/_static/custom-icons.js +0 -0
  27. {iplotx-1.0.0 → iplotx-1.1.0}/docs/source/_static/custom.css +0 -0
  28. {iplotx-1.0.0 → iplotx-1.1.0}/docs/source/_static/graph_basic.png +0 -0
  29. {iplotx-1.0.0 → iplotx-1.1.0}/docs/source/_templates/layout.html +0 -0
  30. {iplotx-1.0.0 → iplotx-1.1.0}/docs/source/api/artists.md +0 -0
  31. {iplotx-1.0.0 → iplotx-1.1.0}/docs/source/api/complete_style_specification.md +0 -0
  32. {iplotx-1.0.0 → iplotx-1.1.0}/docs/source/api/plotting.md +0 -0
  33. {iplotx-1.0.0 → iplotx-1.1.0}/docs/source/api/providers.md +0 -0
  34. {iplotx-1.0.0 → iplotx-1.1.0}/docs/source/api/style.md +0 -0
  35. {iplotx-1.0.0 → iplotx-1.1.0}/docs/source/api.md +0 -0
  36. {iplotx-1.0.0 → iplotx-1.1.0}/docs/source/conf.py +0 -0
  37. {iplotx-1.0.0 → iplotx-1.1.0}/docs/source/images/sphx_glr_plot_basic_001.png +0 -0
  38. {iplotx-1.0.0 → iplotx-1.1.0}/docs/source/images/thumb/sphx_glr_plot_basic_thumb.png +0 -0
  39. {iplotx-1.0.0 → iplotx-1.1.0}/docs/source/installing.md +0 -0
  40. {iplotx-1.0.0 → iplotx-1.1.0}/docs/source/providers.md +0 -0
  41. {iplotx-1.0.0 → iplotx-1.1.0}/docs/source/style.md +0 -0
  42. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/GALLERY_HEADER.rst +0 -0
  43. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/basic/GALLERY_HEADER.rst +0 -0
  44. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/basic/plot_3d.py +0 -0
  45. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/basic/plot_basic.py +0 -0
  46. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/basic/plot_big_curves.py +0 -0
  47. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/basic/plot_dag.py +0 -0
  48. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/basic/plot_directed.py +0 -0
  49. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/basic/plot_grouping.py +0 -0
  50. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/basic/plot_house.py +0 -0
  51. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/basic/plot_loops.py +0 -0
  52. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/basic/plot_simple_path.py +0 -0
  53. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/biology/GALLERY_HEADER.rst +0 -0
  54. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/biology/data/80201010000000001.mst +0 -0
  55. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/biology/data/GN-tree.json +0 -0
  56. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/biology/data/breast_cancer_string_interactions_short.tsv +0 -0
  57. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/biology/data/breast_cancer_string_network_coordinates.tsv +0 -0
  58. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/biology/data/cell_cycle_arrest_string_interactions_short.tsv +0 -0
  59. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/biology/data/cell_cycle_arrest_string_network_coordinates.tsv +0 -0
  60. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/biology/data/fevo-08-588430_DataSheet1_S1.csv +0 -0
  61. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/biology/plot_animal_phylogeny.py +0 -0
  62. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/biology/plot_antibody_clone.py +0 -0
  63. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/biology/plot_breast_cancer_ppi.py +0 -0
  64. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/biology/plot_cell_cycle_arrest.py +0 -0
  65. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/biology/plot_food_network.py +0 -0
  66. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/biology/plot_foraging_table.py +0 -0
  67. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/biology/plot_pollinators.py +0 -0
  68. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/biology/plot_ppi.py +0 -0
  69. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/biology/plot_tca_cycle.py +0 -0
  70. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/network_science/GALLERY_HEADER.rst +0 -0
  71. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/network_science/data/chess_masters_WCC.pgn.bz2 +0 -0
  72. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/network_science/data/knuth_miles.txt.gz +0 -0
  73. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/network_science/plot_arrowlawn.py +0 -0
  74. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/network_science/plot_chess_masters.py +0 -0
  75. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/network_science/plot_cliques.py +0 -0
  76. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/network_science/plot_cluster_layout.py +0 -0
  77. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/network_science/plot_company_structure.py +0 -0
  78. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/network_science/plot_complex.py +0 -0
  79. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/network_science/plot_financial_network.py +0 -0
  80. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/network_science/plot_knuth_miles.py +0 -0
  81. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/network_science/plot_labels_and_colors.py +0 -0
  82. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/network_science/plot_max_bipartite_matching.py +0 -0
  83. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/network_science/plot_minimum_spanning_trees.py +0 -0
  84. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/network_science/plot_multipartite_layout.py +0 -0
  85. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/network_science/plot_parallel_igraph_networkx.py +0 -0
  86. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/network_science/plot_redblack.py +0 -0
  87. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/network_science/plot_shortest_path.py +0 -0
  88. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/network_science/plot_simple_networkx.py +0 -0
  89. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/network_science/plot_social_network_circles.py +0 -0
  90. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/network_science/plot_traveling_salesman.py +0 -0
  91. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/network_science/plot_with_colorbar.py +0 -0
  92. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/other/GALLERY_HEADER.rst +0 -0
  93. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/other/plot_animation.py +0 -0
  94. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/other/plot_edit_artists.py +0 -0
  95. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/other/plot_feedbacks.py +0 -0
  96. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/other/plot_graph.py +0 -0
  97. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/other/plot_mouse_hover.py +0 -0
  98. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/other/plot_train.py +0 -0
  99. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/style/GALLERY_HEADER.rst +0 -0
  100. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/style/plot_arrows.py +0 -0
  101. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/style/plot_depthshade.py +0 -0
  102. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/style/plot_edgepadding.py +0 -0
  103. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/style/plot_elements.py +0 -0
  104. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/style/plot_four_grids.py +0 -0
  105. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/style/plot_halfarrows.py +0 -0
  106. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/style/plot_multistyle.py +0 -0
  107. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/style/plot_ports.py +0 -0
  108. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/style/plot_style.py +0 -0
  109. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/style/plot_tension.py +0 -0
  110. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/style/plot_vertexmarkers.py +0 -0
  111. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/style/plot_voronoi.py +0 -0
  112. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/style/plot_waypoints.py +0 -0
  113. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/tree/GALLERY_HEADER.rst +0 -0
  114. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/tree/data/tree-with-support.json +0 -0
  115. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/tree/plot_angular_waypoints.py +0 -0
  116. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/tree/plot_biopython_tree.py +0 -0
  117. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/tree/plot_cladeedges.py +0 -0
  118. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/tree/plot_cogent3_layouts.py +0 -0
  119. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/tree/plot_cogent3_tree.py +0 -0
  120. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/tree/plot_dendropy.py +0 -0
  121. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/tree/plot_elements_tree.py +0 -0
  122. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/tree/plot_ete4.py +0 -0
  123. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/tree/plot_leafedges.py +0 -0
  124. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/tree/plot_leafedges_and_cascades.py +0 -0
  125. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/tree/plot_scalebar.py +0 -0
  126. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/tree/plot_skbio_tree.py +0 -0
  127. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/tree/plot_split_edges.py +0 -0
  128. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/tree/plot_style_tree.py +0 -0
  129. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/tree/plot_support.py +0 -0
  130. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/tree/plot_tree_node_background.py +0 -0
  131. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/tree/plot_tree_style_clades.py +0 -0
  132. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/tree/plot_trees_of_trees.py +0 -0
  133. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/zero_dependency/GALLERY_HEADER.rst +0 -0
  134. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/zero_dependency/plot_simplenetworkdataprovider.py +0 -0
  135. {iplotx-1.0.0 → iplotx-1.1.0}/gallery/zero_dependency/plot_simpletreedataprovider.py +0 -0
  136. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/__init__.py +0 -0
  137. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/art3d/edge/__init__.py +0 -0
  138. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/art3d/edge/arrow.py +0 -0
  139. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/art3d/edge/geometry.py +0 -0
  140. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/art3d/vertex.py +0 -0
  141. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/artists.py +0 -0
  142. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/edge/__init__.py +0 -0
  143. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/edge/arrow.py +0 -0
  144. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/edge/geometry.py +0 -0
  145. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/edge/leaf.py +0 -0
  146. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/edge/ports.py +0 -0
  147. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/ingest/__init__.py +0 -0
  148. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/ingest/heuristics.py +0 -0
  149. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/ingest/providers/network/igraph.py +0 -0
  150. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/ingest/providers/network/networkx.py +0 -0
  151. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/ingest/providers/network/simple.py +0 -0
  152. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/ingest/providers/tree/biopython.py +0 -0
  153. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/ingest/providers/tree/cogent3.py +0 -0
  154. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/ingest/providers/tree/dendropy.py +0 -0
  155. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/ingest/providers/tree/ete4.py +0 -0
  156. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/ingest/providers/tree/simple.py +0 -0
  157. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/ingest/providers/tree/skbio.py +0 -0
  158. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/ingest/typing.py +0 -0
  159. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/label.py +0 -0
  160. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/network/__init__.py +0 -0
  161. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/network/groups.py +0 -0
  162. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/plotting.py +0 -0
  163. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/style/__init__.py +0 -0
  164. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/style/leaf_info.py +0 -0
  165. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/style/library.py +0 -0
  166. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/tree/cascades.py +0 -0
  167. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/typing.py +0 -0
  168. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/utils/geometry.py +0 -0
  169. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/utils/internal.py +0 -0
  170. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/utils/matplotlib.py +0 -0
  171. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/utils/style.py +0 -0
  172. {iplotx-1.0.0 → iplotx-1.1.0}/iplotx/vertex.py +0 -0
  173. {iplotx-1.0.0 → iplotx-1.1.0}/pyproject.toml +0 -0
  174. {iplotx-1.0.0 → iplotx-1.1.0}/scripts/copy_github_release_into_version.sh +0 -0
  175. {iplotx-1.0.0 → iplotx-1.1.0}/scripts/make_banner.py +0 -0
  176. {iplotx-1.0.0 → iplotx-1.1.0}/scripts/update_pylint_badge.sh +0 -0
  177. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_biopython/cascades.png +0 -0
  178. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_biopython/directed_child.png +0 -0
  179. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_biopython/leaf_labels.png +0 -0
  180. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_biopython/leaf_labels_hmargin.png +0 -0
  181. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_biopython/leafedges.png +0 -0
  182. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_biopython/show_support.png +0 -0
  183. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_biopython/tree_basic.png +0 -0
  184. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_biopython/tree_radial.png +0 -0
  185. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_cogent3/leaf_labels.png +0 -0
  186. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_cogent3/leaf_labels_hmargin.png +0 -0
  187. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_cogent3/tree_basic.png +0 -0
  188. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_cogent3/tree_radial.png +0 -0
  189. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_dendropy/cascades.png +0 -0
  190. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_dendropy/directed_child.png +0 -0
  191. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_dendropy/leaf_labels.png +0 -0
  192. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_dendropy/leaf_labels_hmargin.png +0 -0
  193. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_dendropy/leafedges.png +0 -0
  194. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_dendropy/tree_basic.png +0 -0
  195. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_dendropy/tree_radial.png +0 -0
  196. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_ete4/leaf_labels.png +0 -0
  197. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_ete4/leaf_labels_hmargin.png +0 -0
  198. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_ete4/split_edges.png +0 -0
  199. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_ete4/tree_basic.png +0 -0
  200. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_ete4/tree_radial.png +0 -0
  201. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_igraph/clustering_directed.png +0 -0
  202. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_igraph/clustering_directed_large.png +0 -0
  203. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_igraph/graph_basic.png +0 -0
  204. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_igraph/graph_directed.png +0 -0
  205. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_igraph/graph_directed_curved_loops.png +0 -0
  206. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_igraph/graph_edit_children.png +0 -0
  207. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_igraph/graph_labels.png +0 -0
  208. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_igraph/graph_layout_attribute.png +0 -0
  209. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_igraph/graph_null.png +0 -0
  210. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_igraph/graph_squares_directed.png +0 -0
  211. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_igraph/graph_vertexsize.png +0 -0
  212. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_igraph/graph_with_curved_edges.png +0 -0
  213. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_igraph/igraph_layout_object.png +0 -0
  214. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_igraph/multigraph_with_curved_edges_undirected.png +0 -0
  215. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_igraph_3d/directed.png +0 -0
  216. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_igraph_3d/undirected.png +0 -0
  217. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_igraph_3d/vertex_labels.png +0 -0
  218. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_networkx/cluster-layout.png +0 -0
  219. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_networkx/complex.png +0 -0
  220. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_networkx/complex_rotatelabels.png +0 -0
  221. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_networkx/directed_graph.png +0 -0
  222. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_networkx/directed_graph_with_colorbar.png +0 -0
  223. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_networkx/empty_graph.png +0 -0
  224. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_networkx/flat_style.png +0 -0
  225. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_networkx/house_with_colors.png +0 -0
  226. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_networkx/labels_and_colors.png +0 -0
  227. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_networkx/shortest_path.png +0 -0
  228. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_networkx/simple_graph.png +0 -0
  229. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_simple_network_provider/graph_basic.png +0 -0
  230. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_simple_network_provider/graph_directed.png +0 -0
  231. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_simple_network_provider/graph_labels.png +0 -0
  232. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_skbio/leaf_labels.png +0 -0
  233. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_skbio/leaf_labels_hmargin.png +0 -0
  234. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_skbio/tree_basic.png +0 -0
  235. {iplotx-1.0.0 → iplotx-1.1.0}/tests/baseline_images/test_skbio/tree_radial.png +0 -0
  236. {iplotx-1.0.0 → iplotx-1.1.0}/tests/test_arrows.py +0 -0
  237. {iplotx-1.0.0 → iplotx-1.1.0}/tests/test_biopython.py +0 -0
  238. {iplotx-1.0.0 → iplotx-1.1.0}/tests/test_cascades.py +0 -0
  239. {iplotx-1.0.0 → iplotx-1.1.0}/tests/test_cogent3.py +0 -0
  240. {iplotx-1.0.0 → iplotx-1.1.0}/tests/test_dendropy.py +0 -0
  241. {iplotx-1.0.0 → iplotx-1.1.0}/tests/test_edge.py +0 -0
  242. {iplotx-1.0.0 → iplotx-1.1.0}/tests/test_edge_geometry.py +0 -0
  243. {iplotx-1.0.0 → iplotx-1.1.0}/tests/test_ete4.py +0 -0
  244. {iplotx-1.0.0 → iplotx-1.1.0}/tests/test_geometry.py +0 -0
  245. {iplotx-1.0.0 → iplotx-1.1.0}/tests/test_heuristics.py +0 -0
  246. {iplotx-1.0.0 → iplotx-1.1.0}/tests/test_igraph.py +0 -0
  247. {iplotx-1.0.0 → iplotx-1.1.0}/tests/test_igraph_3d.py +0 -0
  248. {iplotx-1.0.0 → iplotx-1.1.0}/tests/test_ingest_protocols.py +0 -0
  249. {iplotx-1.0.0 → iplotx-1.1.0}/tests/test_matplotlib_utils.py +0 -0
  250. {iplotx-1.0.0 → iplotx-1.1.0}/tests/test_network_hotload.py +0 -0
  251. {iplotx-1.0.0 → iplotx-1.1.0}/tests/test_networkx.py +0 -0
  252. {iplotx-1.0.0 → iplotx-1.1.0}/tests/test_ports.py +0 -0
  253. {iplotx-1.0.0 → iplotx-1.1.0}/tests/test_simple_network_provider.py +0 -0
  254. {iplotx-1.0.0 → iplotx-1.1.0}/tests/test_simple_tree_provider.py +0 -0
  255. {iplotx-1.0.0 → iplotx-1.1.0}/tests/test_skbio.py +0 -0
  256. {iplotx-1.0.0 → iplotx-1.1.0}/tests/test_style.py +0 -0
  257. {iplotx-1.0.0 → iplotx-1.1.0}/tests/test_vertex.py +0 -0
  258. {iplotx-1.0.0 → iplotx-1.1.0}/tests/utils.py +0 -0
  259. {iplotx-1.0.0 → iplotx-1.1.0}/uv.lock +0 -0
@@ -0,0 +1,86 @@
1
+ # This workflow will install Python dependencies, run tests and lint with a variety of Python versions
2
+ # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
3
+
4
+ name: Python package
5
+
6
+ on:
7
+ [push, pull_request]
8
+
9
+ jobs:
10
+ build:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ fail-fast: false
14
+ matrix:
15
+ python-version: ["3.11", "3.12", "3.13"]
16
+
17
+ steps:
18
+ - uses: actions/checkout@v5
19
+
20
+ - name: Install uv
21
+ uses: astral-sh/setup-uv@v6
22
+ with:
23
+ python-version: ${{ matrix.python-version }}
24
+
25
+ - name: Set up Python ${{ matrix.python-version }}
26
+ uses: actions/setup-python@v5
27
+ with:
28
+ python-version: ${{ matrix.python-version }}
29
+
30
+ - name: Install the project
31
+ run: uv sync --all-extras --group test
32
+
33
+ - name: Run pytest
34
+ run: uv run pytest --cov-report term-missing --cov=iplotx tests
35
+
36
+ - name: Coveralls
37
+ uses: coverallsapp/github-action@v2
38
+ with:
39
+ fail-on-error: false
40
+
41
+ - name: Run flake8
42
+ run: uv run flake8 iplotx --count --exit-zero --max-complexity=20 --max-line-length=127 --statistics
43
+
44
+ build_graph_tool:
45
+ runs-on: ubuntu-latest
46
+ strategy:
47
+ fail-fast: false
48
+ matrix:
49
+ python-version: ["3.11", "3.12", "3.13"]
50
+
51
+ steps:
52
+ - uses: actions/checkout@v5
53
+
54
+ - uses: conda-incubator/setup-miniconda@v3
55
+ with:
56
+ auto-activate-base: false
57
+ auto-update-conda: true
58
+ python-version: ${{ matrix.python-version }}
59
+ activate-environment: gt
60
+ miniforge-version: latest
61
+ channels: conda-forge
62
+ conda-remove-defaults: true
63
+ - name: Conda info
64
+ shell: bash -el {0}
65
+ run: conda info
66
+ - name: Conda list
67
+ shell: bash -el {0}
68
+ run: conda list
69
+ - name: Install graph-tool
70
+ shell: bash -el {0}
71
+ run: conda install -c conda-forge graph-tool
72
+ - name: Install pip
73
+ shell: bash -el {0}
74
+ run: conda install -c conda-forge pip
75
+ - name: Upgrade pip to >= 25.1 (which has dependency groups)
76
+ shell: bash -el {0}
77
+ run: pip install --upgrade pip
78
+ - name: Install deps and package
79
+ shell: bash -el {0}
80
+ run: pip install --group test .
81
+ - name: Check pytest
82
+ shell: bash -el {0}
83
+ run: which pytest
84
+ - name: Run pytest (graph-tool)
85
+ shell: bash -el {0}
86
+ run: pytest tests/test_graph_tool.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iplotx
3
- Version: 1.0.0
3
+ Version: 1.1.0
4
4
  Summary: Plot networkx from igraph and networkx.
5
5
  Project-URL: Homepage, https://github.com/fabilab/iplotx
6
6
  Project-URL: Documentation, https://readthedocs.org/iplotx
@@ -53,14 +53,15 @@ Supports:
53
53
  - **networks**:
54
54
  - [networkx](https://networkx.org/)
55
55
  - [igraph](igraph.readthedocs.io/)
56
- - [minimal network data structure](https://iplotx.readthedocs.io/en/latest/gallery/plot_simplenetworkdataprovider.html#sphx-glr-gallery-plot-simplenetworkdataprovider-py) (zero dependency)
56
+ - [graph-tool](https://graph-tool.skewed.de/)
57
+ - [zero-dependency](https://iplotx.readthedocs.io/en/latest/gallery/plot_simplenetworkdataprovider.html#sphx-glr-gallery-plot-simplenetworkdataprovider-py)
57
58
  - **trees**:
58
59
  - [ETE4](https://etetoolkit.github.io/ete/)
59
60
  - [cogent3](https://cogent3.org/)
60
61
  - [Biopython](https://biopython.org/)
61
62
  - [scikit-bio](https://scikit.bio)
62
63
  - [dendropy](https://jeetsukumaran.github.io/DendroPy/index.html)
63
- - [minimal tree data structure](https://iplotx.readthedocs.io/en/latest/gallery/tree/plot_simpletreedataprovider.html#sphx-glr-gallery-tree-plot-simpletreedataprovider-py) (zero dependency)
64
+ - [zero-dependency](https://iplotx.readthedocs.io/en/latest/gallery/tree/plot_simpletreedataprovider.html#sphx-glr-gallery-tree-plot-simpletreedataprovider-py)
64
65
 
65
66
  In addition to the above, *any* network or tree analysis library can register an [entry point](https://iplotx.readthedocs.io/en/latest/providers.html#creating-a-custom-data-provider) to gain compatibility with `iplotx` with no intervention from our side.
66
67
 
@@ -81,7 +82,7 @@ fig, ax = plt.subplots(figsize=(3, 3))
81
82
  ipx.plot(g, ax=ax, layout=layout)
82
83
  ```
83
84
 
84
- ![Quick start image](docs/source/_static/graph_basic.png)
85
+ ![Quick start image](/docs/source/_static/graph_basic.png)
85
86
 
86
87
  ## Documentation
87
88
  See [readthedocs](https://iplotx.readthedocs.io/en/latest/) for the full documentation.
@@ -90,11 +91,11 @@ See [readthedocs](https://iplotx.readthedocs.io/en/latest/) for the full documen
90
91
  See [gallery](https://iplotx.readthedocs.io/en/latest/gallery/index.html).
91
92
 
92
93
  ## Features
93
- - Plot networks from multiple libraries including networkx and igraph, using matplotlib as a backend. ✅
94
+ - Plot networks from multiple libraries including networkx, igraph and graph-tool, using Matplotlib. ✅
94
95
  - Plot trees from multiple libraries such as cogent3, ETE4, skbio, biopython, and dendropy. ✅
95
96
  - Flexible yet easy styling, including an internal library of styles ✅
96
97
  - Interactive plotting, e.g. zooming and panning after the plot is created. ✅
97
- - Store the plot to disk thanks to the many matplotlib backends (SVG, PNG, PDF, etc.). ✅
98
+ - Store the plot to disk in many formats (SVG, PNG, PDF, GIF, etc.). ✅
98
99
  - 3D network visualisation with depth shading. ✅
99
100
  - Efficient plotting of large graphs (up to ~1 million nodes on a laptop). ✅
100
101
  - Edit plotting elements after the plot is created, e.g. changing node colors, labels, etc. ✅
@@ -15,14 +15,15 @@ Supports:
15
15
  - **networks**:
16
16
  - [networkx](https://networkx.org/)
17
17
  - [igraph](igraph.readthedocs.io/)
18
- - [minimal network data structure](https://iplotx.readthedocs.io/en/latest/gallery/plot_simplenetworkdataprovider.html#sphx-glr-gallery-plot-simplenetworkdataprovider-py) (zero dependency)
18
+ - [graph-tool](https://graph-tool.skewed.de/)
19
+ - [zero-dependency](https://iplotx.readthedocs.io/en/latest/gallery/plot_simplenetworkdataprovider.html#sphx-glr-gallery-plot-simplenetworkdataprovider-py)
19
20
  - **trees**:
20
21
  - [ETE4](https://etetoolkit.github.io/ete/)
21
22
  - [cogent3](https://cogent3.org/)
22
23
  - [Biopython](https://biopython.org/)
23
24
  - [scikit-bio](https://scikit.bio)
24
25
  - [dendropy](https://jeetsukumaran.github.io/DendroPy/index.html)
25
- - [minimal tree data structure](https://iplotx.readthedocs.io/en/latest/gallery/tree/plot_simpletreedataprovider.html#sphx-glr-gallery-tree-plot-simpletreedataprovider-py) (zero dependency)
26
+ - [zero-dependency](https://iplotx.readthedocs.io/en/latest/gallery/tree/plot_simpletreedataprovider.html#sphx-glr-gallery-tree-plot-simpletreedataprovider-py)
26
27
 
27
28
  In addition to the above, *any* network or tree analysis library can register an [entry point](https://iplotx.readthedocs.io/en/latest/providers.html#creating-a-custom-data-provider) to gain compatibility with `iplotx` with no intervention from our side.
28
29
 
@@ -43,7 +44,7 @@ fig, ax = plt.subplots(figsize=(3, 3))
43
44
  ipx.plot(g, ax=ax, layout=layout)
44
45
  ```
45
46
 
46
- ![Quick start image](docs/source/_static/graph_basic.png)
47
+ ![Quick start image](/docs/source/_static/graph_basic.png)
47
48
 
48
49
  ## Documentation
49
50
  See [readthedocs](https://iplotx.readthedocs.io/en/latest/) for the full documentation.
@@ -52,11 +53,11 @@ See [readthedocs](https://iplotx.readthedocs.io/en/latest/) for the full documen
52
53
  See [gallery](https://iplotx.readthedocs.io/en/latest/gallery/index.html).
53
54
 
54
55
  ## Features
55
- - Plot networks from multiple libraries including networkx and igraph, using matplotlib as a backend. ✅
56
+ - Plot networks from multiple libraries including networkx, igraph and graph-tool, using Matplotlib. ✅
56
57
  - Plot trees from multiple libraries such as cogent3, ETE4, skbio, biopython, and dendropy. ✅
57
58
  - Flexible yet easy styling, including an internal library of styles ✅
58
59
  - Interactive plotting, e.g. zooming and panning after the plot is created. ✅
59
- - Store the plot to disk thanks to the many matplotlib backends (SVG, PNG, PDF, etc.). ✅
60
+ - Store the plot to disk in many formats (SVG, PNG, PDF, GIF, etc.). ✅
60
61
  - 3D network visualisation with depth shading. ✅
61
62
  - Efficient plotting of large graphs (up to ~1 million nodes on a laptop). ✅
62
63
  - Edit plotting elements after the plot is created, e.g. changing node colors, labels, etc. ✅
@@ -17,7 +17,7 @@
17
17
  :::
18
18
  ```
19
19
 
20
- [iplotx](https://github.com/fabilab/iplotx) is a Python library to display graphs/networks and trees with [matplotlib](https://matplotlib.org/). It natively supports [networkx](https://networkx.org/) and [igraph](https://python.igraph.org/) networks and [biopython](https://biopython.org/), [scikit-bio](https://scikit.bio/), [cogent3](https://cogent3.org/), [ETE4](https://etetoolkit.github.io/ete/), and [dendropy](https://jeetsukumaran.github.io/DendroPy/index.html) trees. It can also plot networks and trees from simple, pure Python data structures for zero-dependency visualisation.
20
+ [iplotx](https://github.com/fabilab/iplotx) is a Python library to display graphs/networks and trees with [matplotlib](https://matplotlib.org/). It natively supports [networkx](https://networkx.org/), [igraph](https://python.igraph.org/), and [graph-tool](https://graph-tool.skewed.de/) networks and [biopython](https://biopython.org/), [scikit-bio](https://scikit.bio/), [cogent3](https://cogent3.org/), [ETE4](https://etetoolkit.github.io/ete/), and [dendropy](https://jeetsukumaran.github.io/DendroPy/index.html) trees. It can also plot networks and trees from simple Python data structures for zero-dependency visualisation.
21
21
 
22
22
  `iplotx` guarantees the **exact same visual appearance** independently of what library you used to construct the network/tree.
23
23
 
@@ -6,7 +6,7 @@
6
6
 
7
7
  Computation times
8
8
  =================
9
- **00:00.497** total execution time for 76 files **from all galleries**:
9
+ **00:00.542** total execution time for 77 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_tree_plot_scalebar.py` (``../../gallery/tree/plot_scalebar.py``)
36
- - 00:00.497
35
+ * - :ref:`sphx_glr_gallery_tree_plot_double_tree.py` (``../../gallery/tree/plot_double_tree.py``)
36
+ - 00:00.542
37
37
  - 0.0
38
38
  * - :ref:`sphx_glr_gallery_basic_plot_3d.py` (``../../gallery/basic/plot_3d.py``)
39
39
  - 00:00.000
@@ -233,6 +233,9 @@ Computation times
233
233
  * - :ref:`sphx_glr_gallery_tree_plot_leafedges_and_cascades.py` (``../../gallery/tree/plot_leafedges_and_cascades.py``)
234
234
  - 00:00.000
235
235
  - 0.0
236
+ * - :ref:`sphx_glr_gallery_tree_plot_scalebar.py` (``../../gallery/tree/plot_scalebar.py``)
237
+ - 00:00.000
238
+ - 0.0
236
239
  * - :ref:`sphx_glr_gallery_tree_plot_skbio_tree.py` (``../../gallery/tree/plot_skbio_tree.py``)
237
240
  - 00:00.000
238
241
  - 0.0
@@ -0,0 +1,56 @@
1
+ """
2
+ Double tree
3
+ ===========
4
+
5
+ This example shows how to use `iplotx` to plot two trees facing each other, which is typical in coevolutionary studies.
6
+ """
7
+
8
+ from ete4 import Tree
9
+ from matplotlib import pyplot as plt
10
+ import iplotx as ipx
11
+
12
+ tree1 = Tree(
13
+ "((),((),(((),()),((),()))));",
14
+ )
15
+
16
+
17
+ tree2 = Tree(
18
+ "((),((),(),((),())),());",
19
+ )
20
+
21
+ fig, ax = plt = plt.subplots(figsize=(9, 4))
22
+
23
+ # Plot first tree on the left
24
+ ipx.plotting.tree(
25
+ tree1,
26
+ ax=ax,
27
+ aspect=1,
28
+ edge_color="tomato",
29
+ leaf_deep=True,
30
+ )
31
+
32
+ # Plot second tree on the right, facing left
33
+ ipx.plotting.tree(
34
+ tree2,
35
+ ax=ax,
36
+ aspect=1,
37
+ edge_color="steelblue",
38
+ layout="horizontal",
39
+ layout_orientation="left",
40
+ layout_start=(11, 0),
41
+ leaf_deep=True,
42
+ )
43
+
44
+ # Add lines connecting corresponding leaves
45
+ matches = [
46
+ (0, 0),
47
+ (1, 4),
48
+ (2, 5),
49
+ (3, 2),
50
+ (4, 1),
51
+ (5, 5),
52
+ ]
53
+ for y1, y2 in matches:
54
+ ax.plot(
55
+ [5.2, 6.8], [y1, y2], color="gray", linewidth=2,
56
+ )
@@ -0,0 +1,100 @@
1
+ from typing import (
2
+ Optional,
3
+ Sequence,
4
+ )
5
+ from collections.abc import Hashable
6
+ import importlib
7
+ import numpy as np
8
+ import pandas as pd
9
+
10
+ from ....typing import (
11
+ LayoutType,
12
+ )
13
+ from ...heuristics import (
14
+ normalise_layout,
15
+ )
16
+ from ...typing import (
17
+ NetworkDataProvider,
18
+ NetworkData,
19
+ )
20
+ from ....utils.internal import (
21
+ _make_layout_columns,
22
+ )
23
+
24
+
25
+ class GraphToolDataProvider(NetworkDataProvider):
26
+ def __call__(
27
+ self,
28
+ layout: Optional[LayoutType] = None,
29
+ vertex_labels: Optional[Sequence[str] | dict[Hashable, str] | pd.Series] = None,
30
+ edge_labels: Optional[Sequence[str] | dict[str]] = None,
31
+ ) -> NetworkData:
32
+ """Create network data object for iplotx from an igraph object."""
33
+
34
+ # Get layout
35
+ vertex_df = normalise_layout(
36
+ layout,
37
+ network=self.network,
38
+ nvertices=self.number_of_vertices(),
39
+ )
40
+ ndim = vertex_df.shape[1]
41
+ vertex_df.columns = _make_layout_columns(ndim)
42
+
43
+ # Vertices are ordered integers, no gaps
44
+
45
+ # Vertex labels
46
+ # Recast vertex_labels=False as vertex_labels=None
47
+ if np.isscalar(vertex_labels) and (not vertex_labels):
48
+ vertex_labels = None
49
+ if vertex_labels is not None:
50
+ if np.isscalar(vertex_labels):
51
+ vertex_df["label"] = vertex_df.index.astype(str)
52
+ elif len(vertex_labels) != len(vertex_df):
53
+ raise ValueError("Vertex labels must be the same length as the number of vertices.")
54
+ else:
55
+ vertex_df["label"] = vertex_labels
56
+
57
+ # Edges are a list of tuples, because of multiedges
58
+ tmp = []
59
+ for edge in self.network.edges():
60
+ row = {"_ipx_source": edge.source(), "_ipx_target": edge.target()}
61
+ # TODO: add graph-tool edge attributes
62
+ # row.update(edge.attributes())
63
+ tmp.append(row)
64
+ if len(tmp):
65
+ edge_df = pd.DataFrame(tmp)
66
+ else:
67
+ edge_df = pd.DataFrame(columns=["_ipx_source", "_ipx_target"])
68
+ del tmp
69
+
70
+ # Edge labels
71
+ if edge_labels is not None:
72
+ if len(edge_labels) != len(edge_df):
73
+ raise ValueError("Edge labels must be the same length as the number of edges.")
74
+ edge_df["label"] = edge_labels
75
+
76
+ network_data = {
77
+ "vertex_df": vertex_df,
78
+ "edge_df": edge_df,
79
+ "directed": self.is_directed(),
80
+ "ndim": ndim,
81
+ }
82
+ return network_data
83
+
84
+ @staticmethod
85
+ def check_dependencies() -> bool:
86
+ return importlib.util.find_spec("graph_tool") is not None
87
+
88
+ @staticmethod
89
+ def graph_type():
90
+ import graph_tool.all as gt
91
+
92
+ return gt.Graph
93
+
94
+ def is_directed(self):
95
+ """Whether the network is directed."""
96
+ return self.network.is_directed()
97
+
98
+ def number_of_vertices(self):
99
+ """The number of vertices/nodes in the network."""
100
+ return self.network.num_vertices()
@@ -2,7 +2,10 @@
2
2
  Layout functions, currently limited to trees.
3
3
  """
4
4
 
5
- from typing import Any
5
+ from typing import (
6
+ Any,
7
+ Optional,
8
+ )
6
9
  from collections.abc import (
7
10
  Hashable,
8
11
  Callable,
@@ -99,6 +102,8 @@ def _horizontal_tree_layout_right(
99
102
 
100
103
  def _horizontal_tree_layout(
101
104
  orientation="right",
105
+ start: tuple[float, float] = (0, 0),
106
+ span: Optional[float] = None,
102
107
  **kwargs,
103
108
  ) -> dict[Hashable, list[float]]:
104
109
  """Horizontal tree layout."""
@@ -110,11 +115,24 @@ def _horizontal_tree_layout(
110
115
  if orientation == "left":
111
116
  for key in layout:
112
117
  layout[key][0] *= -1
118
+
119
+ if span is not None:
120
+ cur_span = len(layout) - 1
121
+ for key in layout:
122
+ layout[key][1] = float(layout[key][1]) * span / cur_span
123
+
124
+ if start != (0, 0):
125
+ for key in layout:
126
+ layout[key][0] += start[0]
127
+ layout[key][1] += start[1]
128
+
113
129
  return layout
114
130
 
115
131
 
116
132
  def _vertical_tree_layout(
117
133
  orientation="descending",
134
+ start: tuple[float, float] = (0, 0),
135
+ span: Optional[float] = None,
118
136
  **kwargs,
119
137
  ) -> dict[Hashable, list[float]]:
120
138
  """Vertical tree layout."""
@@ -125,6 +143,17 @@ def _vertical_tree_layout(
125
143
  layout[key] = value[::-1]
126
144
  # Orient vertically
127
145
  layout[key][1] *= sign
146
+
147
+ if span is not None:
148
+ cur_span = len(layout) - 1
149
+ for key in layout:
150
+ layout[key][0] = float(layout[key][0]) * span / cur_span
151
+
152
+ if start != (0, 0):
153
+ for key in layout:
154
+ layout[key][0] += start[0]
155
+ layout[key][1] += start[1]
156
+
128
157
  return layout
129
158
 
130
159
 
@@ -669,6 +669,7 @@ class TreeArtist(mpl.artist.Artist):
669
669
  def scalebar(
670
670
  self,
671
671
  loc: str = "upper left",
672
+ label_format: str = ".2f",
672
673
  **kwargs,
673
674
  ):
674
675
  """Create scalebar for the tree.
@@ -689,6 +690,8 @@ class TreeArtist(mpl.artist.Artist):
689
690
  self,
690
691
  layout=self.get_layout_name(),
691
692
  loc=loc,
693
+ label_format=label_format,
694
+ **kwargs,
692
695
  )
693
696
 
694
697
  # Remove previous scalebars if any
@@ -37,13 +37,15 @@ class TreeScalebarArtist(Legend):
37
37
  self,
38
38
  treeartist,
39
39
  layout: str = "horizontal",
40
- frameon=False,
40
+ frameon: bool = False,
41
+ label_format: str = ".2f",
41
42
  **kwargs,
42
43
  ):
43
44
  handles = [treeartist.get_edges()]
44
45
  labels = [""]
45
46
  self._layout = layout
46
47
  self._treeartist = treeartist
48
+ self._label_format = label_format
47
49
 
48
50
  if layout == "vertical":
49
51
  handler_kwargs = dict(xerr_size=0, yerr_size=1)
@@ -191,13 +193,12 @@ class TreeScalebarArtist(Legend):
191
193
 
192
194
  bar_trans = bar_handle.get_transform()
193
195
  data_trans = self.parent.transData
194
- # FIXME: this is off, probably because of some Packer anchor additional transform
195
196
  composite_trans = data_trans.inverted() + bar_trans
196
197
 
197
198
  p0_data = composite_trans.transform(p0)
198
199
  p1_data = composite_trans.transform(p1)
199
200
  distance = np.linalg.norm(p1_data - p0_data)
200
- label = f"{distance:.2f}"
201
+ label = format(distance, self._label_format)
201
202
  return label
202
203
 
203
204
  def draw(self, renderer):
@@ -2,4 +2,4 @@
2
2
  iplotx version information module.
3
3
  """
4
4
 
5
- __version__ = "1.0.0"
5
+ __version__ = "1.1.0"
@@ -0,0 +1 @@
1
+ ../test_igraph/graph_basic.png
@@ -0,0 +1 @@
1
+ ../test_igraph/graph_directed.png
@@ -0,0 +1,44 @@
1
+ import pytest
2
+ import matplotlib as mpl
3
+
4
+ mpl.use("agg")
5
+ import matplotlib.pyplot as plt
6
+ import iplotx as ipx
7
+
8
+ from utils import image_comparison
9
+
10
+ gt = pytest.importorskip("graph_tool")
11
+
12
+
13
+ @pytest.fixture
14
+ def layout_small_ring():
15
+ coords = [
16
+ [1.015318095035966, 0.03435580194714975],
17
+ [0.29010409851547664, 1.0184451153265959],
18
+ [-0.8699239050738742, 0.6328259400443561],
19
+ [-0.8616466426732888, -0.5895891303732176],
20
+ [0.30349699041342515, -0.9594640169691343],
21
+ ]
22
+ return coords
23
+
24
+
25
+ @image_comparison(baseline_images=["graph_basic"], remove_text=True)
26
+ def test_basic(layout_small_ring):
27
+ g = gt.Graph(directed=False)
28
+ vertices = list(g.add_vertex(5))
29
+ for i in range(5):
30
+ g.add_edge(vertices[i], vertices[(i + 1) % 5])
31
+
32
+ fig, ax = plt.subplots(figsize=(3, 3))
33
+ ipx.graph(g, ax=ax, layout=layout_small_ring)
34
+
35
+
36
+ @image_comparison(baseline_images=["graph_directed"], remove_text=True)
37
+ def test_directed(layout_small_ring):
38
+ g = gt.Graph(directed=True)
39
+ vertices = list(g.add_vertex(5))
40
+ for i in range(5):
41
+ g.add_edge(vertices[i], vertices[(i + 1) % 5])
42
+
43
+ fig, ax = plt.subplots(figsize=(3, 3))
44
+ ipx.graph(g, ax=ax, layout=layout_small_ring)
@@ -1,43 +0,0 @@
1
- # This workflow will install Python dependencies, run tests and lint with a variety of Python versions
2
- # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
3
-
4
- name: Python package
5
-
6
- on:
7
- [push, pull_request]
8
-
9
- jobs:
10
- build:
11
-
12
- runs-on: ubuntu-latest
13
- strategy:
14
- fail-fast: false
15
- matrix:
16
- python-version: ["3.11", "3.12", "3.13"]
17
-
18
- steps:
19
- - uses: actions/checkout@v4
20
-
21
- - name: Install uv
22
- uses: astral-sh/setup-uv@v5
23
- with:
24
- python-version: ${{ matrix.python-version }}
25
-
26
- - name: Set up Python ${{ matrix.python-version }}
27
- uses: actions/setup-python@v5
28
- with:
29
- python-version: ${{ matrix.python-version }}
30
-
31
- - name: Install the project
32
- run: uv sync --all-extras --group test
33
-
34
- - name: Run pytest
35
- run: uv run pytest --cov-report term-missing --cov=iplotx tests
36
-
37
- - name: Coveralls
38
- uses: coverallsapp/github-action@v2
39
- with:
40
- fail-on-error: false
41
-
42
- - name: Run flake8
43
- run: uv run flake8 iplotx --count --exit-zero --max-complexity=20 --max-line-length=127 --statistics
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