iplotx 1.2.1__tar.gz → 1.3.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 (272) hide show
  1. {iplotx-1.2.1 → iplotx-1.3.0}/PKG-INFO +11 -4
  2. {iplotx-1.2.1 → iplotx-1.3.0}/README.md +10 -3
  3. {iplotx-1.2.1 → iplotx-1.3.0}/docs/source/code_of_conduct.rst +1 -1
  4. {iplotx-1.2.1 → iplotx-1.3.0}/docs/source/sg_execution_times.rst +6 -3
  5. iplotx-1.3.0/gallery/tree/plot_equalangle.py +35 -0
  6. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/ingest/providers/tree/biopython.py +2 -1
  7. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/ingest/providers/tree/cogent3.py +4 -1
  8. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/ingest/providers/tree/dendropy.py +10 -1
  9. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/ingest/providers/tree/ete4.py +2 -1
  10. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/ingest/providers/tree/simple.py +11 -1
  11. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/ingest/providers/tree/skbio.py +4 -1
  12. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/ingest/typing.py +49 -7
  13. iplotx-1.3.0/iplotx/layout/__init__.py +9 -0
  14. iplotx-1.3.0/iplotx/layout/tree/__init__.py +72 -0
  15. iplotx-1.2.1/iplotx/layout.py → iplotx-1.3.0/iplotx/layout/tree/rooted.py +3 -45
  16. iplotx-1.3.0/iplotx/layout/tree/unrooted.py +383 -0
  17. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/tree/__init__.py +5 -2
  18. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/version.py +1 -1
  19. iplotx-1.3.0/tests/baseline_images/test_biopython/leafedges.png +0 -0
  20. iplotx-1.3.0/tests/baseline_images/test_biopython/tree_radial.png +0 -0
  21. iplotx-1.3.0/tests/baseline_images/test_cogent3/tree_radial.png +0 -0
  22. iplotx-1.3.0/tests/baseline_images/test_ete4/equalangle_layout.png +0 -0
  23. iplotx-1.3.0/tests/baseline_images/test_ete4/tree_radial.png +0 -0
  24. iplotx-1.3.0/tests/baseline_images/test_skbio/tree_radial.png +0 -0
  25. {iplotx-1.2.1 → iplotx-1.3.0}/tests/test_ete4.py +22 -4
  26. iplotx-1.2.1/tests/baseline_images/test_biopython/leafedges.png +0 -0
  27. iplotx-1.2.1/tests/baseline_images/test_biopython/tree_radial.png +0 -0
  28. iplotx-1.2.1/tests/baseline_images/test_cogent3/tree_radial.png +0 -0
  29. iplotx-1.2.1/tests/baseline_images/test_ete4/tree_radial.png +0 -0
  30. iplotx-1.2.1/tests/baseline_images/test_skbio/tree_radial.png +0 -0
  31. {iplotx-1.2.1 → iplotx-1.3.0}/.github/workflows/publish.yml +0 -0
  32. {iplotx-1.2.1 → iplotx-1.3.0}/.github/workflows/test.yml +0 -0
  33. {iplotx-1.2.1 → iplotx-1.3.0}/.gitignore +0 -0
  34. {iplotx-1.2.1 → iplotx-1.3.0}/.pre-commit-config.yaml +0 -0
  35. {iplotx-1.2.1 → iplotx-1.3.0}/.readthedocs.yaml +0 -0
  36. {iplotx-1.2.1 → iplotx-1.3.0}/LICENSE +0 -0
  37. {iplotx-1.2.1 → iplotx-1.3.0}/MANIFEST.in +0 -0
  38. {iplotx-1.2.1 → iplotx-1.3.0}/assets/pylint.svg +0 -0
  39. {iplotx-1.2.1 → iplotx-1.3.0}/docs/Makefile +0 -0
  40. {iplotx-1.2.1 → iplotx-1.3.0}/docs/make.bat +0 -0
  41. {iplotx-1.2.1 → iplotx-1.3.0}/docs/source/_static/banner.png +0 -0
  42. {iplotx-1.2.1 → iplotx-1.3.0}/docs/source/_static/custom-icons.js +0 -0
  43. {iplotx-1.2.1 → iplotx-1.3.0}/docs/source/_static/custom.css +0 -0
  44. {iplotx-1.2.1 → iplotx-1.3.0}/docs/source/_static/graph_basic.png +0 -0
  45. {iplotx-1.2.1 → iplotx-1.3.0}/docs/source/_templates/layout.html +0 -0
  46. {iplotx-1.2.1 → iplotx-1.3.0}/docs/source/api/artists.md +0 -0
  47. {iplotx-1.2.1 → iplotx-1.3.0}/docs/source/api/complete_style_specification.md +0 -0
  48. {iplotx-1.2.1 → iplotx-1.3.0}/docs/source/api/plotting.md +0 -0
  49. {iplotx-1.2.1 → iplotx-1.3.0}/docs/source/api/providers.md +0 -0
  50. {iplotx-1.2.1 → iplotx-1.3.0}/docs/source/api/style.md +0 -0
  51. {iplotx-1.2.1 → iplotx-1.3.0}/docs/source/api.md +0 -0
  52. {iplotx-1.2.1 → iplotx-1.3.0}/docs/source/conf.py +0 -0
  53. {iplotx-1.2.1 → iplotx-1.3.0}/docs/source/images/sphx_glr_plot_basic_001.png +0 -0
  54. {iplotx-1.2.1 → iplotx-1.3.0}/docs/source/images/thumb/sphx_glr_plot_basic_thumb.png +0 -0
  55. {iplotx-1.2.1 → iplotx-1.3.0}/docs/source/index.md +0 -0
  56. {iplotx-1.2.1 → iplotx-1.3.0}/docs/source/installing.md +0 -0
  57. {iplotx-1.2.1 → iplotx-1.3.0}/docs/source/providers.md +0 -0
  58. {iplotx-1.2.1 → iplotx-1.3.0}/docs/source/style.md +0 -0
  59. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/GALLERY_HEADER.rst +0 -0
  60. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/basic/GALLERY_HEADER.rst +0 -0
  61. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/basic/plot_3d.py +0 -0
  62. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/basic/plot_basic.py +0 -0
  63. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/basic/plot_big_curves.py +0 -0
  64. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/basic/plot_dag.py +0 -0
  65. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/basic/plot_directed.py +0 -0
  66. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/basic/plot_grouping.py +0 -0
  67. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/basic/plot_house.py +0 -0
  68. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/basic/plot_loops.py +0 -0
  69. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/basic/plot_simple_path.py +0 -0
  70. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/biology/GALLERY_HEADER.rst +0 -0
  71. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/biology/data/80201010000000001.mst +0 -0
  72. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/biology/data/GN-tree.json +0 -0
  73. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/biology/data/breast_cancer_string_interactions_short.tsv +0 -0
  74. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/biology/data/breast_cancer_string_network_coordinates.tsv +0 -0
  75. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/biology/data/cell_cycle_arrest_string_interactions_short.tsv +0 -0
  76. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/biology/data/cell_cycle_arrest_string_network_coordinates.tsv +0 -0
  77. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/biology/data/fevo-08-588430_DataSheet1_S1.csv +0 -0
  78. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/biology/plot_animal_phylogeny.py +0 -0
  79. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/biology/plot_antibody_clone.py +0 -0
  80. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/biology/plot_breast_cancer_ppi.py +0 -0
  81. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/biology/plot_cell_cycle_arrest.py +0 -0
  82. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/biology/plot_food_network.py +0 -0
  83. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/biology/plot_foraging_table.py +0 -0
  84. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/biology/plot_pollinators.py +0 -0
  85. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/biology/plot_ppi.py +0 -0
  86. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/biology/plot_tca_cycle.py +0 -0
  87. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/network_science/GALLERY_HEADER.rst +0 -0
  88. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/network_science/data/chess_masters_WCC.pgn.bz2 +0 -0
  89. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/network_science/data/knuth_miles.txt.gz +0 -0
  90. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/network_science/plot_arrowlawn.py +0 -0
  91. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/network_science/plot_chess_masters.py +0 -0
  92. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/network_science/plot_cliques.py +0 -0
  93. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/network_science/plot_cluster_layout.py +0 -0
  94. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/network_science/plot_company_structure.py +0 -0
  95. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/network_science/plot_complex.py +0 -0
  96. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/network_science/plot_financial_network.py +0 -0
  97. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/network_science/plot_knuth_miles.py +0 -0
  98. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/network_science/plot_labels_and_colors.py +0 -0
  99. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/network_science/plot_max_bipartite_matching.py +0 -0
  100. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/network_science/plot_minimum_spanning_trees.py +0 -0
  101. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/network_science/plot_multipartite_layout.py +0 -0
  102. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/network_science/plot_parallel_igraph_networkx.py +0 -0
  103. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/network_science/plot_redblack.py +0 -0
  104. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/network_science/plot_shortest_path.py +0 -0
  105. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/network_science/plot_simple_networkx.py +0 -0
  106. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/network_science/plot_social_network_circles.py +0 -0
  107. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/network_science/plot_traveling_salesman.py +0 -0
  108. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/network_science/plot_with_colorbar.py +0 -0
  109. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/other/GALLERY_HEADER.rst +0 -0
  110. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/other/plot_animation.py +0 -0
  111. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/other/plot_edit_artists.py +0 -0
  112. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/other/plot_feedbacks.py +0 -0
  113. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/other/plot_graph.py +0 -0
  114. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/other/plot_mouse_hover.py +0 -0
  115. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/other/plot_train.py +0 -0
  116. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/style/GALLERY_HEADER.rst +0 -0
  117. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/style/plot_arrows.py +0 -0
  118. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/style/plot_depthshade.py +0 -0
  119. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/style/plot_edgepadding.py +0 -0
  120. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/style/plot_elements.py +0 -0
  121. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/style/plot_four_grids.py +0 -0
  122. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/style/plot_halfarrows.py +0 -0
  123. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/style/plot_multistyle.py +0 -0
  124. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/style/plot_ports.py +0 -0
  125. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/style/plot_style.py +0 -0
  126. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/style/plot_tension.py +0 -0
  127. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/style/plot_vertexmarkers.py +0 -0
  128. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/style/plot_voronoi.py +0 -0
  129. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/style/plot_waypoints.py +0 -0
  130. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/tree/GALLERY_HEADER.rst +0 -0
  131. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/tree/data/tree-with-support.json +0 -0
  132. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/tree/plot_angular_waypoints.py +0 -0
  133. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/tree/plot_biopython_tree.py +0 -0
  134. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/tree/plot_cladeedges.py +0 -0
  135. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/tree/plot_cogent3_layouts.py +0 -0
  136. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/tree/plot_cogent3_tree.py +0 -0
  137. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/tree/plot_dendropy.py +0 -0
  138. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/tree/plot_double_tree.py +0 -0
  139. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/tree/plot_elements_tree.py +0 -0
  140. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/tree/plot_ete4.py +0 -0
  141. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/tree/plot_leafedges.py +0 -0
  142. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/tree/plot_leafedges_and_cascades.py +0 -0
  143. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/tree/plot_scalebar.py +0 -0
  144. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/tree/plot_skbio_tree.py +0 -0
  145. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/tree/plot_split_edges.py +0 -0
  146. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/tree/plot_style_tree.py +0 -0
  147. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/tree/plot_support.py +0 -0
  148. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/tree/plot_tree_node_background.py +0 -0
  149. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/tree/plot_tree_style_clades.py +0 -0
  150. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/tree/plot_trees_of_trees.py +0 -0
  151. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/zero_dependency/GALLERY_HEADER.rst +0 -0
  152. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/zero_dependency/plot_simplenetworkdataprovider.py +0 -0
  153. {iplotx-1.2.1 → iplotx-1.3.0}/gallery/zero_dependency/plot_simpletreedataprovider.py +0 -0
  154. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/__init__.py +0 -0
  155. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/art3d/edge/__init__.py +0 -0
  156. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/art3d/edge/arrow.py +0 -0
  157. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/art3d/edge/geometry.py +0 -0
  158. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/art3d/vertex.py +0 -0
  159. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/artists.py +0 -0
  160. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/edge/__init__.py +0 -0
  161. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/edge/arrow.py +0 -0
  162. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/edge/geometry.py +0 -0
  163. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/edge/leaf.py +0 -0
  164. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/edge/ports.py +0 -0
  165. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/ingest/__init__.py +0 -0
  166. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/ingest/heuristics.py +0 -0
  167. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/ingest/providers/network/graph_tool.py +0 -0
  168. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/ingest/providers/network/igraph.py +0 -0
  169. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/ingest/providers/network/networkx.py +0 -0
  170. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/ingest/providers/network/simple.py +0 -0
  171. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/label.py +0 -0
  172. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/network/__init__.py +0 -0
  173. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/network/groups.py +0 -0
  174. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/plotting.py +0 -0
  175. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/style/__init__.py +0 -0
  176. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/style/leaf_info.py +0 -0
  177. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/style/library.py +0 -0
  178. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/tree/cascades.py +0 -0
  179. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/tree/scalebar.py +0 -0
  180. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/typing.py +0 -0
  181. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/utils/geometry.py +0 -0
  182. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/utils/internal.py +0 -0
  183. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/utils/matplotlib.py +0 -0
  184. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/utils/style.py +0 -0
  185. {iplotx-1.2.1 → iplotx-1.3.0}/iplotx/vertex.py +0 -0
  186. {iplotx-1.2.1 → iplotx-1.3.0}/pyproject.toml +0 -0
  187. {iplotx-1.2.1 → iplotx-1.3.0}/scripts/copy_github_release_into_version.sh +0 -0
  188. {iplotx-1.2.1 → iplotx-1.3.0}/scripts/make_banner.py +0 -0
  189. {iplotx-1.2.1 → iplotx-1.3.0}/scripts/update_pylint_badge.sh +0 -0
  190. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_biopython/cascades.png +0 -0
  191. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_biopython/directed_child.png +0 -0
  192. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_biopython/leaf_labels.png +0 -0
  193. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_biopython/leaf_labels_hmargin.png +0 -0
  194. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_biopython/show_support.png +0 -0
  195. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_biopython/tree_basic.png +0 -0
  196. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_cogent3/leaf_labels.png +0 -0
  197. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_cogent3/leaf_labels_hmargin.png +0 -0
  198. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_cogent3/tree_basic.png +0 -0
  199. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_dendropy/cascades.png +0 -0
  200. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_dendropy/directed_child.png +0 -0
  201. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_dendropy/leaf_labels.png +0 -0
  202. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_dendropy/leaf_labels_hmargin.png +0 -0
  203. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_dendropy/leafedges.png +0 -0
  204. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_dendropy/tree_basic.png +0 -0
  205. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_dendropy/tree_radial.png +0 -0
  206. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_doubletree/tree_gap.png +0 -0
  207. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_doubletree/tree_nogap.png +0 -0
  208. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_ete4/leaf_labels.png +0 -0
  209. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_ete4/leaf_labels_hmargin.png +0 -0
  210. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_ete4/split_edges.png +0 -0
  211. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_ete4/tree_basic.png +0 -0
  212. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_graph_tool/graph_basic.png +0 -0
  213. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_graph_tool/graph_directed.png +0 -0
  214. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_igraph/clustering_directed.png +0 -0
  215. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_igraph/clustering_directed_large.png +0 -0
  216. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_igraph/graph_basic.png +0 -0
  217. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_igraph/graph_directed.png +0 -0
  218. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_igraph/graph_directed_curved_loops.png +0 -0
  219. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_igraph/graph_edit_children.png +0 -0
  220. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_igraph/graph_labels.png +0 -0
  221. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_igraph/graph_layout_attribute.png +0 -0
  222. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_igraph/graph_null.png +0 -0
  223. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_igraph/graph_squares_directed.png +0 -0
  224. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_igraph/graph_vertexsize.png +0 -0
  225. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_igraph/graph_with_curved_edges.png +0 -0
  226. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_igraph/igraph_layout_object.png +0 -0
  227. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_igraph/multigraph_with_curved_edges_undirected.png +0 -0
  228. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_igraph_3d/directed.png +0 -0
  229. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_igraph_3d/undirected.png +0 -0
  230. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_igraph_3d/vertex_labels.png +0 -0
  231. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_networkx/cluster-layout.png +0 -0
  232. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_networkx/complex.png +0 -0
  233. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_networkx/complex_rotatelabels.png +0 -0
  234. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_networkx/directed_graph.png +0 -0
  235. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_networkx/directed_graph_with_colorbar.png +0 -0
  236. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_networkx/empty_graph.png +0 -0
  237. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_networkx/flat_style.png +0 -0
  238. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_networkx/house_with_colors.png +0 -0
  239. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_networkx/labels_and_colors.png +0 -0
  240. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_networkx/shortest_path.png +0 -0
  241. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_networkx/simple_graph.png +0 -0
  242. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_simple_network_provider/graph_basic.png +0 -0
  243. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_simple_network_provider/graph_directed.png +0 -0
  244. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_simple_network_provider/graph_labels.png +0 -0
  245. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_skbio/leaf_labels.png +0 -0
  246. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_skbio/leaf_labels_hmargin.png +0 -0
  247. {iplotx-1.2.1 → iplotx-1.3.0}/tests/baseline_images/test_skbio/tree_basic.png +0 -0
  248. {iplotx-1.2.1 → iplotx-1.3.0}/tests/test_arrows.py +0 -0
  249. {iplotx-1.2.1 → iplotx-1.3.0}/tests/test_biopython.py +0 -0
  250. {iplotx-1.2.1 → iplotx-1.3.0}/tests/test_cascades.py +0 -0
  251. {iplotx-1.2.1 → iplotx-1.3.0}/tests/test_cogent3.py +0 -0
  252. {iplotx-1.2.1 → iplotx-1.3.0}/tests/test_dendropy.py +0 -0
  253. {iplotx-1.2.1 → iplotx-1.3.0}/tests/test_doubletree.py +0 -0
  254. {iplotx-1.2.1 → iplotx-1.3.0}/tests/test_edge.py +0 -0
  255. {iplotx-1.2.1 → iplotx-1.3.0}/tests/test_edge_geometry.py +0 -0
  256. {iplotx-1.2.1 → iplotx-1.3.0}/tests/test_geometry.py +0 -0
  257. {iplotx-1.2.1 → iplotx-1.3.0}/tests/test_graph_tool.py +0 -0
  258. {iplotx-1.2.1 → iplotx-1.3.0}/tests/test_heuristics.py +0 -0
  259. {iplotx-1.2.1 → iplotx-1.3.0}/tests/test_igraph.py +0 -0
  260. {iplotx-1.2.1 → iplotx-1.3.0}/tests/test_igraph_3d.py +0 -0
  261. {iplotx-1.2.1 → iplotx-1.3.0}/tests/test_ingest_protocols.py +0 -0
  262. {iplotx-1.2.1 → iplotx-1.3.0}/tests/test_matplotlib_utils.py +0 -0
  263. {iplotx-1.2.1 → iplotx-1.3.0}/tests/test_network_hotload.py +0 -0
  264. {iplotx-1.2.1 → iplotx-1.3.0}/tests/test_networkx.py +0 -0
  265. {iplotx-1.2.1 → iplotx-1.3.0}/tests/test_ports.py +0 -0
  266. {iplotx-1.2.1 → iplotx-1.3.0}/tests/test_simple_network_provider.py +0 -0
  267. {iplotx-1.2.1 → iplotx-1.3.0}/tests/test_simple_tree_provider.py +0 -0
  268. {iplotx-1.2.1 → iplotx-1.3.0}/tests/test_skbio.py +0 -0
  269. {iplotx-1.2.1 → iplotx-1.3.0}/tests/test_style.py +0 -0
  270. {iplotx-1.2.1 → iplotx-1.3.0}/tests/test_vertex.py +0 -0
  271. {iplotx-1.2.1 → iplotx-1.3.0}/tests/utils.py +0 -0
  272. {iplotx-1.2.1 → iplotx-1.3.0}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iplotx
3
- Version: 1.2.1
3
+ Version: 1.3.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
@@ -36,9 +36,9 @@ Provides-Extra: networkx
36
36
  Requires-Dist: networkx>=2.0.0; extra == 'networkx'
37
37
  Description-Content-Type: text/markdown
38
38
 
39
- ![Github Actions](https://github.com/fabilab/iplotx/actions/workflows/test.yml/badge.svg)
40
- ![PyPI - Version](https://img.shields.io/pypi/v/iplotx)
41
- ![RTD](https://readthedocs.org/projects/iplotx/badge/?version=latest)
39
+ [![Github Actions](https://github.com/fabilab/iplotx/actions/workflows/test.yml/badge.svg)](https://github.com/fabilab/iplotx/actions/workflows/test.yml)
40
+ [![PyPI - Version](https://img.shields.io/pypi/v/iplotx)](https://pypi.org/project/iplotx/)
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
44
  [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.16599333.svg)](https://doi.org/10.5281/zenodo.16599333)
@@ -89,6 +89,13 @@ See [readthedocs](https://iplotx.readthedocs.io/en/latest/) for the full documen
89
89
  ## Gallery
90
90
  See [gallery](https://iplotx.readthedocs.io/en/latest/gallery/index.html).
91
91
 
92
+ ## Citation
93
+ If you use `iplotx` for publication figures, please cite the [zenodo preprint](https://doi.org/10.5281/zenodo.16599333):
94
+
95
+ ```
96
+ F. Zanini. (2025). Unified network visualisation in Python. Zenodo [PREPRINT]. https://doi.org/10.5281/zenodo.16599333
97
+ ```
98
+
92
99
  ## Features
93
100
  - Plot networks from multiple libraries including networkx, igraph and graph-tool, using Matplotlib. ✅
94
101
  - Plot trees from multiple libraries such as cogent3, ETE4, skbio, biopython, and dendropy. ✅
@@ -1,6 +1,6 @@
1
- ![Github Actions](https://github.com/fabilab/iplotx/actions/workflows/test.yml/badge.svg)
2
- ![PyPI - Version](https://img.shields.io/pypi/v/iplotx)
3
- ![RTD](https://readthedocs.org/projects/iplotx/badge/?version=latest)
1
+ [![Github Actions](https://github.com/fabilab/iplotx/actions/workflows/test.yml/badge.svg)](https://github.com/fabilab/iplotx/actions/workflows/test.yml)
2
+ [![PyPI - Version](https://img.shields.io/pypi/v/iplotx)](https://pypi.org/project/iplotx/)
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
6
  [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.16599333.svg)](https://doi.org/10.5281/zenodo.16599333)
@@ -51,6 +51,13 @@ See [readthedocs](https://iplotx.readthedocs.io/en/latest/) for the full documen
51
51
  ## Gallery
52
52
  See [gallery](https://iplotx.readthedocs.io/en/latest/gallery/index.html).
53
53
 
54
+ ## Citation
55
+ If you use `iplotx` for publication figures, please cite the [zenodo preprint](https://doi.org/10.5281/zenodo.16599333):
56
+
57
+ ```
58
+ F. Zanini. (2025). Unified network visualisation in Python. Zenodo [PREPRINT]. https://doi.org/10.5281/zenodo.16599333
59
+ ```
60
+
54
61
  ## Features
55
62
  - Plot networks from multiple libraries including networkx, igraph and graph-tool, using Matplotlib. ✅
56
63
  - Plot trees from multiple libraries such as cogent3, ETE4, skbio, biopython, and dendropy. ✅
@@ -1,6 +1,6 @@
1
1
  .. _scipy-coc:
2
2
 
3
- ilpotx Code of Conduct
3
+ iplotx Code of Conduct
4
4
  ======================
5
5
 
6
6
 
@@ -6,7 +6,7 @@
6
6
 
7
7
  Computation times
8
8
  =================
9
- **00:00.565** total execution time for 77 files **from all galleries**:
9
+ **00:00.514** total execution time for 78 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_double_tree.py` (``../../gallery/tree/plot_double_tree.py``)
36
- - 00:00.565
35
+ * - :ref:`sphx_glr_gallery_tree_plot_equalangle.py` (``../../gallery/tree/plot_equalangle.py``)
36
+ - 00:00.514
37
37
  - 0.0
38
38
  * - :ref:`sphx_glr_gallery_basic_plot_3d.py` (``../../gallery/basic/plot_3d.py``)
39
39
  - 00:00.000
@@ -221,6 +221,9 @@ Computation times
221
221
  * - :ref:`sphx_glr_gallery_tree_plot_dendropy.py` (``../../gallery/tree/plot_dendropy.py``)
222
222
  - 00:00.000
223
223
  - 0.0
224
+ * - :ref:`sphx_glr_gallery_tree_plot_double_tree.py` (``../../gallery/tree/plot_double_tree.py``)
225
+ - 00:00.000
226
+ - 0.0
224
227
  * - :ref:`sphx_glr_gallery_tree_plot_elements_tree.py` (``../../gallery/tree/plot_elements_tree.py``)
225
228
  - 00:00.000
226
229
  - 0.0
@@ -0,0 +1,35 @@
1
+ """
2
+ Equal angle layout
3
+ ==================
4
+
5
+ This example showcases the "equal angle" layout. This layout is inspired by the `ggtree <https://yulab-smu.top/treedata-book/chapter4.html>`_ layout with the same name, which originally comes from Joseph Felsenstein's book "Inferring Phylogenies".
6
+ """
7
+
8
+ from cogent3.phylo import nj
9
+ import numpy as np
10
+ import iplotx as ipx
11
+ import matplotlib.pyplot as plt
12
+
13
+ nleaves = 14
14
+ distance_dict = {}
15
+ for i in range(nleaves):
16
+ for j in range(i):
17
+ distance_dict[(str(i), str(j))] = np.random.rand()
18
+ tree = nj.nj(distance_dict)
19
+
20
+ ipx.plotting.tree(
21
+ tree,
22
+ layout="equalangle",
23
+ )
24
+
25
+
26
+ # %%
27
+ # The "equal daylight" layout is an adjustment of the equal angle layout that attempts to spread out leaves more evenly
28
+ # for imbalanced trees. ``iplotx`` has an experimental implementation of this layout.
29
+ #
30
+ # .. warning:: "Experimental" means you can use it but the API and resulting layout may change in future releases.
31
+
32
+ ipx.plotting.tree(
33
+ tree,
34
+ layout="daylight",
35
+ )
@@ -21,8 +21,9 @@ class BiopythonDataProvider(TreeDataProvider):
21
21
 
22
22
  preorder = partialmethod(_traverse, order="preorder")
23
23
  postorder = partialmethod(_traverse, order="postorder")
24
+ levelorder = partialmethod(_traverse, order="level")
24
25
 
25
- def get_leaves(self) -> Sequence[Any]:
26
+ def _get_leaves(self) -> Sequence[Any]:
26
27
  return self.tree.get_terminals()
27
28
 
28
29
  @staticmethod
@@ -16,7 +16,10 @@ class Cogent3DataProvider(TreeDataProvider):
16
16
  def postorder(self) -> Sequence[Any]:
17
17
  return self.tree.postorder()
18
18
 
19
- def get_leaves(self) -> Sequence[Any]:
19
+ def levelorder(self) -> Sequence[Any]:
20
+ return self.tree.levelorder()
21
+
22
+ def _get_leaves(self) -> Sequence[Any]:
20
23
  return self.tree.tips()
21
24
 
22
25
  @staticmethod
@@ -36,7 +36,16 @@ class DendropyDataProvider(TreeDataProvider):
36
36
  return self.tree.postorder_node_iter()
37
37
  return self.tree.postorder_iter()
38
38
 
39
- def get_leaves(self) -> Sequence[Any]:
39
+ def levelorder(self) -> Any:
40
+ """Levelorder traversal of the tree.
41
+
42
+ NOTE: This will work on both entire Trees and Nodes (which means a subtree including self).
43
+ """
44
+ if hasattr(self.tree, "levelorder_node_iter"):
45
+ return self.tree.levelorder_node_iter()
46
+ return self.tree.levelorder_iter()
47
+
48
+ def _get_leaves(self) -> Sequence[Any]:
40
49
  """Get a list of leaves."""
41
50
  return self.tree.leaf_nodes()
42
51
 
@@ -18,8 +18,9 @@ class Ete4DataProvider(TreeDataProvider):
18
18
 
19
19
  preorder = partialmethod(_traverse, order="preorder")
20
20
  postorder = partialmethod(_traverse, order="postorder")
21
+ levelorder = partialmethod(_traverse, order="levelorder")
21
22
 
22
- def get_leaves(self) -> Sequence[Any]:
23
+ def _get_leaves(self) -> Sequence[Any]:
23
24
  return self.tree.leaves()
24
25
 
25
26
  @staticmethod
@@ -64,7 +64,17 @@ class SimpleTreeDataProvider(TreeDataProvider):
64
64
 
65
65
  yield from _recur(self.tree)
66
66
 
67
- def get_leaves(self) -> Sequence[Any]:
67
+ def levelorder(self) -> Iterable[dict[dict | str, Any]]:
68
+ from collections import deque
69
+
70
+ queue = deque([self.get_root()])
71
+ while queue:
72
+ node = queue.popleft()
73
+ for child in self.get_children(node):
74
+ queue.append(child)
75
+ yield node
76
+
77
+ def _get_leaves(self) -> Sequence[Any]:
68
78
  def _recur(node):
69
79
  if len(node.children) == 0:
70
80
  yield node
@@ -16,7 +16,10 @@ class SkbioDataProvider(TreeDataProvider):
16
16
  def postorder(self) -> Sequence[Any]:
17
17
  return self.tree.postorder()
18
18
 
19
- def get_leaves(self) -> Sequence[Any]:
19
+ def levelorder(self) -> Sequence[Any]:
20
+ return self.tree.levelorder()
21
+
22
+ def _get_leaves(self) -> Sequence[Any]:
20
23
  return self.tree.tips()
21
24
 
22
25
  @staticmethod
@@ -12,6 +12,7 @@ from typing import (
12
12
  Any,
13
13
  Iterable,
14
14
  )
15
+
15
16
  # NOTE: __init__ in Protocols has had a difficult gestation
16
17
  # https://github.com/python/cpython/issues/88970
17
18
  if sys.version_info < (3, 11):
@@ -156,8 +157,32 @@ class TreeDataProvider(Protocol):
156
157
  return root_attr
157
158
  return self.tree.get_root()
158
159
 
159
- def get_leaves(self) -> Sequence[Any]:
160
- """Get the tree leaves/tips in a provider-specific data structure.
160
+ def get_subtree(self, node: TreeType):
161
+ """Get the subtree rooted at the given node.
162
+
163
+ Parameters:
164
+ node: The node to get the subtree from.
165
+ Returns:
166
+ The subtree rooted at the given node.
167
+ """
168
+ return self.__class__(node)
169
+
170
+ def get_leaves(self, node: Optional[TreeType] = None) -> Sequence[Any]:
171
+ """Get the leaves of the entire tree or a subtree.
172
+
173
+ Parameters:
174
+ node: The node to get the leaves from. If None, get from the entire
175
+ tree.
176
+ Returns:
177
+ The leaves or tips of the tree or node-anchored subtree.
178
+ """
179
+ if node is None:
180
+ return self._get_leaves()
181
+ else:
182
+ return self.get_subtree(node)._get_leaves()
183
+
184
+ def _get_leaves(self) -> Sequence[Any]:
185
+ """Get the whole tree leaves/tips in a provider-specific data structure.
161
186
 
162
187
  Returns:
163
188
  The leaves or tips of the tree.
@@ -235,8 +260,6 @@ class TreeDataProvider(Protocol):
235
260
  NOTE: individual providers may implement more efficient versions of
236
261
  this function if desired.
237
262
  """
238
- provider = self.__class__
239
-
240
263
  # Find leaves of the selected nodes
241
264
  leaves = set()
242
265
  for node in nodes:
@@ -244,7 +267,7 @@ class TreeDataProvider(Protocol):
244
267
  if len(self.get_children(node)) == 0:
245
268
  leaves.add(node)
246
269
  else:
247
- leaves |= set(provider(node).get_leaves())
270
+ leaves |= set(self.get_leaves(node))
248
271
 
249
272
  # Look for nodes with the same set of leaves, starting from the bottom
250
273
  # and stopping at the first (i.e. lowest) hit.
@@ -253,7 +276,7 @@ class TreeDataProvider(Protocol):
253
276
  if len(self.get_children(node)) == 0:
254
277
  leaves_node = {node}
255
278
  else:
256
- leaves_node = set(provider(node).get_leaves())
279
+ leaves_node = set(self.get_leaves(node))
257
280
  if leaves <= leaves_node:
258
281
  root = node
259
282
  break
@@ -285,9 +308,26 @@ class TreeDataProvider(Protocol):
285
308
  orientation = "right"
286
309
  elif layout == "vertical":
287
310
  orientation = "descending"
288
- elif layout == "radial":
311
+ elif layout in ("radial", "equalangle", "daylight"):
289
312
  orientation = "clockwise"
290
313
 
314
+ # Validate orientation
315
+ valid = (layout == "horizontal") and (orientation in ("right", "left"))
316
+ valid |= (layout == "vertical") and (orientation in ("ascending", "descending"))
317
+ valid |= (layout == "radial") and (
318
+ orientation in ("clockwise", "counterclockwise", "left", "right")
319
+ )
320
+ valid |= (layout == "equalangle") and (
321
+ orientation in ("clockwise", "counterclockwise", "left", "right")
322
+ )
323
+ valid |= (layout == "daylight") and (
324
+ orientation in ("clockwise", "counterclockwise", "left", "right")
325
+ )
326
+ if not valid:
327
+ raise ValueError(
328
+ f"Orientation '{orientation}' is not valid for layout '{layout}'.",
329
+ )
330
+
291
331
  tree_data = {
292
332
  "root": self.get_root(),
293
333
  "rooted": self.is_rooted(),
@@ -304,8 +344,10 @@ class TreeDataProvider(Protocol):
304
344
  root=tree_data["root"],
305
345
  preorder_fun=self.preorder,
306
346
  postorder_fun=self.postorder,
347
+ levelorder_fun=self.levelorder,
307
348
  children_fun=self.get_children,
308
349
  branch_length_fun=self.get_branch_length_default_to_one,
350
+ leaves_fun=self.get_leaves,
309
351
  **layout_style,
310
352
  )
311
353
  if layout in ("radial",):
@@ -0,0 +1,9 @@
1
+ """
2
+ Layout functions.
3
+ """
4
+
5
+ from .tree import compute_tree_layout
6
+
7
+ __all__ = [
8
+ "compute_tree_layout",
9
+ ]
@@ -0,0 +1,72 @@
1
+ """
2
+ Tree layout algorithms.
3
+ """
4
+
5
+ from typing import (
6
+ Any,
7
+ )
8
+ from collections.abc import (
9
+ Hashable,
10
+ Callable,
11
+ )
12
+
13
+ from .rooted import (
14
+ _horizontal_tree_layout,
15
+ _vertical_tree_layout,
16
+ _radial_tree_layout,
17
+ )
18
+ from .unrooted import (
19
+ _equalangle_tree_layout,
20
+ _daylight_tree_layout,
21
+ )
22
+
23
+
24
+ def compute_tree_layout(
25
+ layout: str,
26
+ orientation: str,
27
+ root: Any,
28
+ preorder_fun: Callable,
29
+ postorder_fun: Callable,
30
+ levelorder_fun: Callable,
31
+ children_fun: Callable,
32
+ branch_length_fun: Callable,
33
+ leaves_fun: Callable,
34
+ **kwargs,
35
+ ) -> dict[Hashable, list[float]]:
36
+ """Compute the layout for a tree.
37
+
38
+ Parameters:
39
+ layout: The name of the layout, e.g. "horizontal", "vertical", or "radial".
40
+ orientation: The orientation of the layout, e.g. "right", "left", "descending",
41
+ "ascending", "clockwise", "anticlockwise".
42
+
43
+ Returns:
44
+ A layout dictionary with node positions.
45
+ """
46
+ kwargs["root"] = root
47
+ kwargs["preorder_fun"] = preorder_fun
48
+ kwargs["postorder_fun"] = postorder_fun
49
+ kwargs["levelorder_fun"] = levelorder_fun
50
+ kwargs["children_fun"] = children_fun
51
+ kwargs["orientation"] = orientation
52
+ kwargs["branch_length_fun"] = branch_length_fun
53
+ kwargs["leaves_fun"] = leaves_fun
54
+
55
+ # Angular or not, the vertex layout is unchanged. Since we do not
56
+ # currently compute an edge layout here, we can ignore the option.
57
+ kwargs.pop("angular", None)
58
+
59
+ if layout == "radial":
60
+ layout_dict = _radial_tree_layout(**kwargs)
61
+ elif layout == "horizontal":
62
+ layout_dict = _horizontal_tree_layout(**kwargs)
63
+ elif layout == "vertical":
64
+ layout_dict = _vertical_tree_layout(**kwargs)
65
+ elif layout == "equalangle":
66
+ layout_dict = _equalangle_tree_layout(**kwargs)
67
+ elif layout == "daylight":
68
+ layout_dict = _daylight_tree_layout(**kwargs)
69
+ else:
70
+ raise ValueError(f"Tree layout not available: {layout}")
71
+
72
+ return layout_dict
@@ -1,5 +1,5 @@
1
1
  """
2
- Layout functions, currently limited to trees.
2
+ Rooted tree layout for iplotx library.
3
3
  """
4
4
 
5
5
  from typing import (
@@ -14,55 +14,13 @@ from collections.abc import (
14
14
  import numpy as np
15
15
 
16
16
 
17
- def compute_tree_layout(
18
- layout: str,
19
- orientation: str,
20
- root: Any,
21
- preorder_fun: Callable,
22
- postorder_fun: Callable,
23
- children_fun: Callable,
24
- branch_length_fun: Callable,
25
- **kwargs,
26
- ) -> dict[Hashable, list[float]]:
27
- """Compute the layout for a tree.
28
-
29
- Parameters:
30
- layout: The name of the layout, e.g. "horizontal", "vertical", or "radial".
31
- orientation: The orientation of the layout, e.g. "right", "left", "descending",
32
- "ascending", "clockwise", "anticlockwise".
33
-
34
- Returns:
35
- A layout dictionary with node positions.
36
- """
37
- kwargs["root"] = root
38
- kwargs["preorder_fun"] = preorder_fun
39
- kwargs["postorder_fun"] = postorder_fun
40
- kwargs["children_fun"] = children_fun
41
- kwargs["branch_length_fun"] = branch_length_fun
42
- kwargs["orientation"] = orientation
43
-
44
- # Angular or not, the vertex layout is unchanged. Since we do not
45
- # currently compute an edge layout here, we can ignore the option.
46
- kwargs.pop("angular", None)
47
-
48
- if layout == "radial":
49
- layout_dict = _radial_tree_layout(**kwargs)
50
- elif layout == "horizontal":
51
- layout_dict = _horizontal_tree_layout(**kwargs)
52
- elif layout == "vertical":
53
- layout_dict = _vertical_tree_layout(**kwargs)
54
- else:
55
- raise ValueError(f"Tree layout not available: {layout}")
56
-
57
- return layout_dict
58
-
59
-
60
17
  def _horizontal_tree_layout_right(
61
18
  root: Any,
62
19
  preorder_fun: Callable,
63
20
  postorder_fun: Callable,
64
21
  children_fun: Callable,
65
22
  branch_length_fun: Callable,
23
+ **kwargs,
66
24
  ) -> dict[Hashable, list[float]]:
67
25
  """Build a tree layout horizontally, left to right.
68
26
 
@@ -173,7 +131,7 @@ def _radial_tree_layout(
173
131
  360, it leaves a small gap at the end to ensure the first and last leaf
174
132
  are not overlapping.
175
133
  Returns:
176
- A dictionary with the radial layout.
134
+ A dictionary with the layout.
177
135
  """
178
136
  # Short form
179
137
  th = start * np.pi / 180