iplotx 0.3.1__tar.gz → 0.4.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 (165) hide show
  1. {iplotx-0.3.1 → iplotx-0.4.0}/PKG-INFO +1 -1
  2. iplotx-0.3.1/docs/source/api.md → iplotx-0.4.0/docs/source/api/artists.md +2 -37
  3. iplotx-0.4.0/docs/source/api/complete_style_specification.md +254 -0
  4. iplotx-0.4.0/docs/source/api/plotting.md +13 -0
  5. iplotx-0.4.0/docs/source/api/providers.md +17 -0
  6. iplotx-0.4.0/docs/source/api/style.md +23 -0
  7. iplotx-0.4.0/docs/source/api.md +7 -0
  8. {iplotx-0.3.1 → iplotx-0.4.0}/docs/source/index.md +6 -0
  9. iplotx-0.4.0/docs/source/providers.md +72 -0
  10. {iplotx-0.3.1 → iplotx-0.4.0}/docs/source/sg_execution_times.rst +46 -13
  11. {iplotx-0.3.1 → iplotx-0.4.0}/gallery/GALLERY_HEADER.rst +3 -0
  12. iplotx-0.4.0/gallery/plot_arrows.py +31 -0
  13. {iplotx-0.3.1 → iplotx-0.4.0}/gallery/plot_chess_masters.py +1 -1
  14. iplotx-0.4.0/gallery/plot_halfarrows.py +65 -0
  15. {iplotx-0.3.1 → iplotx-0.4.0}/gallery/plot_knuth_miles.py +1 -1
  16. iplotx-0.4.0/gallery/plot_multistyle.py +59 -0
  17. iplotx-0.4.0/gallery/plot_simpledataprovider.py +28 -0
  18. iplotx-0.4.0/gallery/plot_style.py +49 -0
  19. iplotx-0.4.0/gallery/plot_tension.py +79 -0
  20. iplotx-0.4.0/gallery/plot_vertexmarkers.py +51 -0
  21. iplotx-0.4.0/gallery/tree/GALLERY_HEADER.rst +6 -0
  22. iplotx-0.4.0/gallery/tree/data/tree-with-support.json +1 -0
  23. {iplotx-0.3.1/gallery → iplotx-0.4.0/gallery/tree}/plot_biopython_tree.py +4 -3
  24. iplotx-0.4.0/gallery/tree/plot_cogent3_layouts.py +72 -0
  25. {iplotx-0.3.1/gallery → iplotx-0.4.0/gallery/tree}/plot_ete4.py +8 -3
  26. iplotx-0.4.0/gallery/tree/plot_leafedges.py +49 -0
  27. iplotx-0.4.0/gallery/tree/plot_leafedges_and_cascades.py +37 -0
  28. iplotx-0.4.0/gallery/tree/plot_support.py +54 -0
  29. iplotx-0.4.0/gallery/tree/plot_tree_node_background.py +111 -0
  30. iplotx-0.4.0/gallery/tree/plot_tree_style_clades.py +35 -0
  31. {iplotx-0.3.1/gallery → iplotx-0.4.0/gallery/tree}/plot_trees_of_trees.py +1 -1
  32. {iplotx-0.3.1 → iplotx-0.4.0}/iplotx/__init__.py +5 -0
  33. iplotx-0.4.0/iplotx/artists.py +24 -0
  34. {iplotx-0.3.1 → iplotx-0.4.0}/iplotx/cascades.py +3 -3
  35. {iplotx-0.3.1 → iplotx-0.4.0}/iplotx/edge/__init__.py +48 -43
  36. {iplotx-0.3.1 → iplotx-0.4.0}/iplotx/edge/arrow.py +34 -0
  37. {iplotx-0.3.1 → iplotx-0.4.0}/iplotx/edge/geometry.py +23 -4
  38. iplotx-0.4.0/iplotx/edge/leaf.py +117 -0
  39. {iplotx-0.3.1 → iplotx-0.4.0}/iplotx/ingest/__init__.py +1 -6
  40. {iplotx-0.3.1 → iplotx-0.4.0}/iplotx/ingest/heuristics.py +3 -32
  41. {iplotx-0.3.1 → iplotx-0.4.0}/iplotx/ingest/providers/network/igraph.py +16 -6
  42. {iplotx-0.3.1 → iplotx-0.4.0}/iplotx/ingest/providers/network/networkx.py +14 -4
  43. iplotx-0.4.0/iplotx/ingest/providers/network/simple.py +121 -0
  44. {iplotx-0.3.1 → iplotx-0.4.0}/iplotx/ingest/providers/tree/biopython.py +13 -0
  45. {iplotx-0.3.1 → iplotx-0.4.0}/iplotx/ingest/providers/tree/cogent3.py +7 -0
  46. {iplotx-0.3.1 → iplotx-0.4.0}/iplotx/ingest/typing.py +110 -11
  47. {iplotx-0.3.1 → iplotx-0.4.0}/iplotx/label.py +42 -12
  48. {iplotx-0.3.1 → iplotx-0.4.0}/iplotx/layout.py +5 -1
  49. {iplotx-0.3.1 → iplotx-0.4.0}/iplotx/network.py +66 -12
  50. {iplotx-0.3.1 → iplotx-0.4.0}/iplotx/plotting.py +8 -8
  51. iplotx-0.3.1/iplotx/style.py → iplotx-0.4.0/iplotx/style/__init__.py +23 -85
  52. iplotx-0.4.0/iplotx/style/leaf_info.py +41 -0
  53. iplotx-0.4.0/iplotx/style/library.py +230 -0
  54. {iplotx-0.3.1 → iplotx-0.4.0}/iplotx/tree.py +244 -29
  55. {iplotx-0.3.1 → iplotx-0.4.0}/iplotx/utils/matplotlib.py +30 -12
  56. iplotx-0.4.0/iplotx/utils/style.py +12 -0
  57. {iplotx-0.3.1 → iplotx-0.4.0}/iplotx/version.py +1 -1
  58. {iplotx-0.3.1 → iplotx-0.4.0}/iplotx/vertex.py +62 -7
  59. iplotx-0.3.1/gallery/plot_style.py +0 -29
  60. iplotx-0.3.1/gallery/plot_tree_node_background.py +0 -55
  61. iplotx-0.3.1/iplotx/utils/style.py +0 -1
  62. {iplotx-0.3.1 → iplotx-0.4.0}/.github/workflows/publish.yml +0 -0
  63. {iplotx-0.3.1 → iplotx-0.4.0}/.github/workflows/test.yml +0 -0
  64. {iplotx-0.3.1 → iplotx-0.4.0}/.gitignore +0 -0
  65. {iplotx-0.3.1 → iplotx-0.4.0}/.readthedocs.yaml +0 -0
  66. {iplotx-0.3.1 → iplotx-0.4.0}/LICENSE +0 -0
  67. {iplotx-0.3.1 → iplotx-0.4.0}/MANIFEST.in +0 -0
  68. {iplotx-0.3.1 → iplotx-0.4.0}/README.md +0 -0
  69. {iplotx-0.3.1 → iplotx-0.4.0}/assets/pylint.svg +0 -0
  70. {iplotx-0.3.1 → iplotx-0.4.0}/docs/Makefile +0 -0
  71. {iplotx-0.3.1 → iplotx-0.4.0}/docs/make.bat +0 -0
  72. {iplotx-0.3.1 → iplotx-0.4.0}/docs/source/_static/graph_basic.png +0 -0
  73. {iplotx-0.3.1 → iplotx-0.4.0}/docs/source/_templates/layout.html +0 -0
  74. {iplotx-0.3.1 → iplotx-0.4.0}/docs/source/conf.py +0 -0
  75. {iplotx-0.3.1 → iplotx-0.4.0}/docs/source/images/sphx_glr_plot_basic_001.png +0 -0
  76. {iplotx-0.3.1 → iplotx-0.4.0}/docs/source/images/thumb/sphx_glr_plot_basic_thumb.png +0 -0
  77. {iplotx-0.3.1 → iplotx-0.4.0}/docs/source/style.md +0 -0
  78. {iplotx-0.3.1/gallery → iplotx-0.4.0/gallery/data}/chess_masters_WCC.pgn.bz2 +0 -0
  79. {iplotx-0.3.1/gallery → iplotx-0.4.0/gallery/data}/knuth_miles.txt.gz +0 -0
  80. {iplotx-0.3.1 → iplotx-0.4.0}/gallery/plot_animation.py +0 -0
  81. {iplotx-0.3.1 → iplotx-0.4.0}/gallery/plot_basic.py +0 -0
  82. {iplotx-0.3.1 → iplotx-0.4.0}/gallery/plot_big_curves.py +0 -0
  83. {iplotx-0.3.1 → iplotx-0.4.0}/gallery/plot_cliques.py +0 -0
  84. {iplotx-0.3.1 → iplotx-0.4.0}/gallery/plot_cluster_layout.py +0 -0
  85. {iplotx-0.3.1 → iplotx-0.4.0}/gallery/plot_company_structure.py +0 -0
  86. {iplotx-0.3.1 → iplotx-0.4.0}/gallery/plot_complex.py +0 -0
  87. {iplotx-0.3.1 → iplotx-0.4.0}/gallery/plot_dag.py +0 -0
  88. {iplotx-0.3.1 → iplotx-0.4.0}/gallery/plot_directed.py +0 -0
  89. {iplotx-0.3.1 → iplotx-0.4.0}/gallery/plot_edit_artists.py +0 -0
  90. {iplotx-0.3.1 → iplotx-0.4.0}/gallery/plot_four_grids.py +0 -0
  91. {iplotx-0.3.1 → iplotx-0.4.0}/gallery/plot_grouping.py +0 -0
  92. {iplotx-0.3.1 → iplotx-0.4.0}/gallery/plot_house.py +0 -0
  93. {iplotx-0.3.1 → iplotx-0.4.0}/gallery/plot_labels_and_colors.py +0 -0
  94. {iplotx-0.3.1 → iplotx-0.4.0}/gallery/plot_loops.py +0 -0
  95. {iplotx-0.3.1 → iplotx-0.4.0}/gallery/plot_max_bipartite_matching.py +0 -0
  96. {iplotx-0.3.1 → iplotx-0.4.0}/gallery/plot_minimum_spanning_trees.py +0 -0
  97. {iplotx-0.3.1 → iplotx-0.4.0}/gallery/plot_mouse_hover.py +0 -0
  98. {iplotx-0.3.1 → iplotx-0.4.0}/gallery/plot_multipartite_layout.py +0 -0
  99. {iplotx-0.3.1 → iplotx-0.4.0}/gallery/plot_parallel_igraph_networkx.py +0 -0
  100. {iplotx-0.3.1 → iplotx-0.4.0}/gallery/plot_ports.py +0 -0
  101. {iplotx-0.3.1 → iplotx-0.4.0}/gallery/plot_shortest_path.py +0 -0
  102. {iplotx-0.3.1 → iplotx-0.4.0}/gallery/plot_simple_networkx.py +0 -0
  103. {iplotx-0.3.1 → iplotx-0.4.0}/gallery/plot_simple_path.py +0 -0
  104. {iplotx-0.3.1 → iplotx-0.4.0}/gallery/plot_traveling_salesman.py +0 -0
  105. {iplotx-0.3.1 → iplotx-0.4.0}/gallery/plot_voronoi.py +0 -0
  106. {iplotx-0.3.1 → iplotx-0.4.0}/gallery/plot_with_colorbar.py +0 -0
  107. {iplotx-0.3.1/gallery → iplotx-0.4.0/gallery/tree}/plot_cogent3_tree.py +0 -0
  108. {iplotx-0.3.1/gallery → iplotx-0.4.0/gallery/tree}/plot_skbio_tree.py +0 -0
  109. {iplotx-0.3.1 → iplotx-0.4.0}/iplotx/edge/ports.py +0 -0
  110. {iplotx-0.3.1 → iplotx-0.4.0}/iplotx/groups.py +0 -0
  111. {iplotx-0.3.1 → iplotx-0.4.0}/iplotx/ingest/providers/tree/ete4.py +0 -0
  112. {iplotx-0.3.1 → iplotx-0.4.0}/iplotx/ingest/providers/tree/skbio.py +0 -0
  113. {iplotx-0.3.1 → iplotx-0.4.0}/iplotx/typing.py +0 -0
  114. {iplotx-0.3.1 → iplotx-0.4.0}/iplotx/utils/geometry.py +0 -0
  115. {iplotx-0.3.1 → iplotx-0.4.0}/iplotx/utils/internal.py +0 -0
  116. {iplotx-0.3.1 → iplotx-0.4.0}/pyproject.toml +0 -0
  117. {iplotx-0.3.1 → iplotx-0.4.0}/scripts/copy_github_release_into_version.sh +0 -0
  118. {iplotx-0.3.1 → iplotx-0.4.0}/scripts/update_pylint_badge.sh +0 -0
  119. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_biopython/leaf_labels.png +0 -0
  120. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_biopython/leaf_labels_hmargin.png +0 -0
  121. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_biopython/tree_basic.png +0 -0
  122. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_biopython/tree_radial.png +0 -0
  123. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_cogent3/leaf_labels.png +0 -0
  124. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_cogent3/leaf_labels_hmargin.png +0 -0
  125. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_cogent3/tree_basic.png +0 -0
  126. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_cogent3/tree_radial.png +0 -0
  127. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_ete4/leaf_labels.png +0 -0
  128. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_ete4/leaf_labels_hmargin.png +0 -0
  129. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_ete4/tree_basic.png +0 -0
  130. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_ete4/tree_radial.png +0 -0
  131. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_igraph/clustering_directed.png +0 -0
  132. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_igraph/clustering_directed_large.png +0 -0
  133. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_igraph/graph_basic.png +0 -0
  134. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_igraph/graph_directed.png +0 -0
  135. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_igraph/graph_directed_curved_loops.png +0 -0
  136. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_igraph/graph_edit_children.png +0 -0
  137. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_igraph/graph_labels.png +0 -0
  138. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_igraph/graph_layout_attribute.png +0 -0
  139. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_igraph/graph_null.png +0 -0
  140. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_igraph/graph_squares_directed.png +0 -0
  141. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_igraph/igraph_layout_object.png +0 -0
  142. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_igraph/multigraph_with_curved_edges_undirected.png +0 -0
  143. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_networkx/cluster-layout.png +0 -0
  144. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_networkx/complex.png +0 -0
  145. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_networkx/directed_graph.png +0 -0
  146. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_networkx/directed_graph_with_colorbar.png +0 -0
  147. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_networkx/empty_graph.png +0 -0
  148. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_networkx/flat_style.png +0 -0
  149. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_networkx/house_with_colors.png +0 -0
  150. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_networkx/labels_and_colors.png +0 -0
  151. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_networkx/shortest_path.png +0 -0
  152. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_networkx/simple_graph.png +0 -0
  153. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_skbio/leaf_labels.png +0 -0
  154. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_skbio/leaf_labels_hmargin.png +0 -0
  155. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_skbio/tree_basic.png +0 -0
  156. {iplotx-0.3.1 → iplotx-0.4.0}/tests/baseline_images/test_skbio/tree_radial.png +0 -0
  157. {iplotx-0.3.1 → iplotx-0.4.0}/tests/test_biopython.py +0 -0
  158. {iplotx-0.3.1 → iplotx-0.4.0}/tests/test_cogent3.py +0 -0
  159. {iplotx-0.3.1 → iplotx-0.4.0}/tests/test_ete4.py +0 -0
  160. {iplotx-0.3.1 → iplotx-0.4.0}/tests/test_igraph.py +0 -0
  161. {iplotx-0.3.1 → iplotx-0.4.0}/tests/test_networkx.py +0 -0
  162. {iplotx-0.3.1 → iplotx-0.4.0}/tests/test_skbio.py +0 -0
  163. {iplotx-0.3.1 → iplotx-0.4.0}/tests/test_style.py +0 -0
  164. {iplotx-0.3.1 → iplotx-0.4.0}/tests/utils.py +0 -0
  165. {iplotx-0.3.1 → iplotx-0.4.0}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iplotx
3
- Version: 0.3.1
3
+ Version: 0.4.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
@@ -1,40 +1,4 @@
1
- # Reference API
2
- This is the reference documentation for `iplotx`.
3
-
4
- ## Main functions
5
- The main user-facing function is `iplotx.network`, which can be used to plot graphs and graph groupings (covers and clusterings), and `iplotx.tree` to plot trees. `iplotx.plot` is a synonym for `iplotx.network`.
6
-
7
- ```{eval-rst}
8
- .. autofunction:: iplotx.network
9
- :noindex:
10
-
11
- .. autofunction:: iplotx.tree
12
- :noindex:
13
- ```
14
-
15
- ## Styling
16
- See also the <project:style.md> for an introduction to styles in `iplotx`.
17
-
18
-
19
- ```{eval-rst}
20
- .. autofunction:: iplotx.style.context
21
-
22
- .. autofunction:: iplotx.style.use
23
-
24
- .. autofunction:: iplotx.style.reset
25
-
26
- .. autofunction:: iplotx.style.get_style
27
- ```
28
-
29
- The following functions are reported for completeness but are rarely used by users directly:
30
-
31
- ```{eval-rst}
32
- .. autofunction:: iplotx.style.unflatten_style
33
-
34
- .. autofunction:: iplotx.style.rotate_style
35
- ```
36
-
37
- ## Artist hierarchy
1
+ # Artist hierarchy
38
2
  `iplotx.plot` return a list of `matplotlib` artists (1 or 2). When a network is plotted, the first artist is an instance of `iplotx.NetworkArtist`. This class contains the visual elements representing vertices, edges, labels, arrows, etc. and can be used to further edit the plot after `iplotx.plot` returned.
39
3
 
40
4
  A `NetworkArtist` instance has two notable properties: vertices and edges, which are instances of `VertexCollection` and `EdgeCollection`, respectively. These collections are `matplotlib` artists that can be used to modify the appearance of vertices and edges after the plot has been created.
@@ -58,3 +22,4 @@ In turn, a `VertexCollection` or `EdgeCollection` instance **may** contain a `La
58
22
  .. autoclass:: iplotx.edge.arrow.EdgeArrowCollection
59
23
  :members:
60
24
  ```
25
+
@@ -0,0 +1,254 @@
1
+ # Complete style specification
2
+ ```{note}
3
+ There might be additional matplotlib options not mentioned below (e.g. rotation,
4
+ font family). Any options not mentioned below are passed directly to matplotlib.
5
+ ```
6
+
7
+
8
+ ```python
9
+ {
10
+ # Vertex style
11
+ "vertex": {
12
+ # Size of the vertex in points. If a pair, it indicates width and height
13
+ # of the marker. If "label", set the size dynamically based on the vertex
14
+ # label (a label is needed in this case)
15
+ "size": float | tuple[float, float] | str,
16
+
17
+ # Marker style. Currently supported markers:
18
+ # o, c, circle: circle
19
+ f # s, square, r, rectangle: rectangle (square if only one size specified)
20
+ # ^, triangle: upward triangle
21
+ # v, triangle_down: downward triangle
22
+ # <, triangle_left: leftward triangle
23
+ # >, triangle_right: rightward triangle
24
+ # d, diamond: diamond
25
+ # e, ellipse: ellipse
26
+ # p, pentagon: pentagon
27
+ # h, hexagon: hexagon
28
+ # 8, octagon: octagon
29
+ # *, star: 5-point star, upright
30
+ "marker": str,
31
+
32
+ "facecolor": str | Any, # Color of the vertex face (e.g. 'red', '#FF0000')
33
+ "edgecolor": str | Any, # Color of the vertex edge (e.g. 'black', '#000000')
34
+ "alpha": float, # Opacity of the vertex (0.0 for fully transparent, 1.0 for fully opaque)
35
+
36
+ # Vertex label style
37
+ "label": {
38
+ "color": str | Any, # Color of the vertex label (e.g. 'white', '#FFFFFF')
39
+ "horizontalalignment": str, # Horizontal alignment of the label ('left', 'center', 'right')
40
+ "verticalalignment": str, # Vertical alignment of the label ('top', 'center', 'bottom', 'baseline', 'center_baseline')
41
+ "hpadding": float, # Horizontal padding around the label
42
+ "vpadding": float, # Vertical padding around the label
43
+
44
+ # Bounding box properties for the label
45
+ "bbox": {
46
+ "boxstyle": str, # Style of the bounding box ('round', 'square', etc.)
47
+ "facecolor": str | Any, # Color of the bounding box (e.g. 'yellow', '#FFFF00')
48
+ "edgecolor": str | Any, # Color of the bounding box edge (e.g. 'black', '#000000')
49
+ ... # Any other bounding box property
50
+
51
+ },
52
+ "hmargin": float, # Horizontal margin around (usually left of) the label
53
+ "vmargin": float, # Vertical margin around (usually below) the label. Rarely used.
54
+ },
55
+ },
56
+
57
+ # Edge style
58
+ "edge": {
59
+ "linewidth": float, # Width of the edge line in points
60
+
61
+ # Style of the edge line ('-' for solid, '--' for dashed, etc.). Matplotlib
62
+ # allows for quite flexible syntax here.
63
+ "linestyle": str | Any,
64
+
65
+ # Color of the edge line (e.g. 'blue', '#0000FF'). This can be a floating
66
+ # number (usually set on a per-edge basis) to use color mapping. In that case
67
+ # the "cmap" property needs to be set too (see next option). In that case,
68
+ # the min/max values of the floats are used as extremes for the colormap,
69
+ # unless the "norm" option is used.
70
+ "color": str | float | Any,
71
+
72
+ # Matplotlib color map used to map floating numbers into RGBA colors. Only
73
+ # used when the previous option "color" is set to floats.
74
+ "cmap": str | matplotlib.colors.Colormap,
75
+
76
+ # Matplotlib norm to connect color map and edge floating-point color values.
77
+ # This is only used when colors are mapped through a color map. In that case,
78
+ # this option lets the user finely control what floating number will be mapped
79
+ # onto what color.
80
+ "norm": tuple[float, float] | matplotlib.colors.Normalize,
81
+
82
+ # Opacity of the vertex (0.0 for fully transparent, 1.0 for fully opaque).
83
+ # If a colormap is used and this option is also set, this opacity takes
84
+ # priority and finally determines the transparency of the edges.
85
+ "alpha": float,
86
+
87
+ "curved": bool, # Whether the edge is curved (True) or straight (False)
88
+
89
+ # Tension for curved edges (0.0 for straight, higher values position the
90
+ # Bezier control points further away from the nodes, creating more wiggly lines)
91
+ # Negative values bend the curve on the other side of the straight line.
92
+ "tension": float,
93
+
94
+ # Tension for self-loops (higher values create more bigger loops).
95
+ # This is typically a strictly positive value.
96
+ "looptension": float,
97
+
98
+ # The maximum angle for self-loops (in degrees). This is typically a positive
99
+ # number quite a bit less than 180 degrees to avoid funny-looking self-loops.
100
+ "loopmaxangle": float,
101
+
102
+ # xy offset of the edge coordinate in figure points. This is usually set on a
103
+ # per-edge basis if specific edges are to be shifted laterally slightly. Large
104
+ # offsets tend to not play well with the rest of the visualisation.
105
+ "offset": tuple[float, float],
106
+
107
+ # How much (in figure points) to offset parallel straight edges (i.e. in a
108
+ # multigraph only) along the orthogonal direction to make them more visible.
109
+ # To obtain a double-headed arrow effect, set this to zero. On the flip side,
110
+ # you will not know how many parallel edges there are between those two nodes.
111
+ "paralleloffset": float,
112
+
113
+ # Edge ports a la Graphviz, which indicate the attack angle of an edge into
114
+ # its origin (first element) and target (second element) node. "w" (for
115
+ # "west") means exiting from/entering into the left side, "e" is the right
116
+ # side, "n" the top, "s" the bottom. "nw" and similar two-letter combinations
117
+ # are accepted and indicate 45 degree angles (in figure space). None means
118
+ # that edge side is free (i.e. no special instruction there). This is almost
119
+ # universally either unset or set on a per-edge basis to finely control the
120
+ # appearance of the network (e.g. in organisational charts).
121
+ "ports": tuple[str | None, str | None],
122
+
123
+ # Edge waypoints. This option is usually set together with "ports" to
124
+ # finely control the appearance of edges. For trees, this option is used
125
+ # internally to create piecewise-straight connections. This option is
126
+ # currently experimental, but you can try the following settings:
127
+ # - xmidy0,xmidy1: Two waypoints with the mid-x and the 1st and 2nd y values.
128
+ # - ymidx0,ymidx1: The xy swap of the previous option.
129
+ # - x0y1: One waypoint, with x of the first point and y of the second point.
130
+ # - x1y0: The xy swap of the previous option.
131
+ # We are looking into ways to generalise this idea.
132
+ "waypoints": str,
133
+
134
+ # Edge arrow style for directed graphs
135
+ "arrow": {
136
+ # Arrow marker style. Currently supported:
137
+ # |>
138
+ # |/
139
+ # |\\ (double slash needed to avoid character escaping)
140
+ # >
141
+ # >>
142
+ # )>
143
+ # )
144
+ # |
145
+ # s
146
+ # d
147
+ # p
148
+ # q
149
+ "marker": str,
150
+
151
+ "width": float, # Width of the arrow in points
152
+
153
+ # Height of the arrow in points. Defaults to 1.3 times the width if not
154
+ # specified. If the string "width" is used, it is set to the width of
155
+ # the arrow.
156
+ "height": float | str,
157
+
158
+ # Color of the arrow (e.g. 'black', '#000000'). This means both the
159
+ # facecolor and edgecolor for full arrows (e.g. "|>"), only the edgecolor
160
+ # for hollow arrows (e.g. ">"). This specification, like in matplotlib,
161
+ # takes higher precedence than the "edgecolor" and "facecolor" properties.
162
+ # If this property is not specified, the color of the edge to which the
163
+ # arrowhead belongs to is used.
164
+ "color": str | Any,
165
+ },
166
+
167
+ # Edge label style
168
+ "label": {
169
+
170
+ # Whether to rotate edge labels to be horizontal (True) or to leave them
171
+ # parallel to their edge (False). Some users find this boolean
172
+ # unintuitive and interpret it the other way around, so think carefully.
173
+ "rotate": bool,
174
+
175
+ "color": str | Any, # Color of the vertex label (e.g. 'white', '#FFFFFF')
176
+ "horizontalalignment": str, # Horizontal alignment of the label ('left', 'center', 'right')
177
+ "verticalalignment": str, # Vertical alignment of the label ('top', 'center', 'bottom', 'baseline', 'center_baseline')
178
+ "hpadding": float, # Horizontal padding around the label
179
+ "vpadding": float, # Vertical padding around the label
180
+ "bbox": dict, # Bounding box properties for the label (see vertex labels)
181
+
182
+ },
183
+ },
184
+
185
+ # The following entry is used by networks ONLY (not trees as plotted by `iplotx.tree`)
186
+ "grouping": {
187
+ "facecolor": str | Any, # Color of the grouping face (e.g. 'lightgray', '#D3D3D3')
188
+ "edgecolor": str | Any, # Color of the grouping edge (e.g. 'gray', '#808080')
189
+ "linewidth": float, # Width of the grouping edge in points
190
+ "vertexpadding": float, # Padding around the vertices in the grouping in points
191
+ },
192
+
193
+ ############################################################################
194
+ # The following entries are used by trees ONLY (as plotted by `iplotx.tree`)
195
+ "cascade": {
196
+ # Whether to limit the cascade to the deepest descendant (False),
197
+ # to the deepest leaf overall (True), or to include the leaf labels
198
+ # as well "leaf_labels"
199
+ "extend": bool | str,
200
+
201
+ "facecolor": str | Any, # Color of the cascade face
202
+ "edgecolor": str | Any, # Color of the cascade edge
203
+ "alpha": float, # Opacity of the cascade patch
204
+ },
205
+
206
+ # Leaf styles are currently only used for their labels
207
+ "leaf": {
208
+ # Whether leaf nodes and labels will be aligned to the deepest leaf.
209
+ # If False, each leaf label will be at the depth of its leaf.
210
+ "deep": bool,
211
+ "label": {
212
+ "color": str | Any, # Color of the label text
213
+ "hmargin": float, # Horizontal offset (before rotation) off the leaf node
214
+ }
215
+ },
216
+
217
+ # Leaf edge styles are used for the (usually dashed) lines connecting leaves
218
+ # at less-than-max depth to deep labels (if used).
219
+ "leafedge": {
220
+ "color": str | Any, # Color of the leaf edge (e.g. 'gray', '#808080')
221
+ "linewidth": float, # Width of the leaf edge in points
222
+ "linestyle": str | Any, # Style of the leaf edge line ('--' for dashed etc.)
223
+
224
+ # Leaf edge labels.
225
+ # NOTE: These lines will NOT exist for leaves that are set at the max depth
226
+ # (at least one leaf will always be skipped). Therefore, using labels here
227
+ # can be a little trickier than you might expect.
228
+ "label": {
229
+ "color": str | Any, # Color of the leaf edge label (e.g. 'black')
230
+ "hmargin": float, # Horizontal offset (before rotation) off the leaf edge
231
+ "vmargin": float, # Vertical offset (before rotation) off the leaf edge
232
+ # Whether to rotate the label to be horizontal (True) or parallel to the edge (False)
233
+ "rotate": bool,
234
+ },
235
+ },
236
+
237
+ # Layout options for trees
238
+ "layout": {
239
+ # Orientation of the tree. Accepted values depend on the tree layout:
240
+ # - "horizontal" layout: "left" or "right"
241
+ # - "vertical" layout: "ascending" or "descending"
242
+ # - "radial" layout: "clockwise" or "counterclockwise"
243
+ "orientation": str,
244
+ "angular": bool, # Whether to use an angular or waypoint-based layout
245
+ "start": float, # Starting angle for radial layouts (in degrees)
246
+ "span": float, # Angle span for radial layouts (in degrees)
247
+ },
248
+ ############################################################################
249
+ }
250
+ ```
251
+
252
+ ```{tip}
253
+ Most options can be "leaf rotated" to obtain a per-vertex, per-edge, per-label, or per-cascade look. See <project:../style.md> for more info.
254
+ ```
@@ -0,0 +1,13 @@
1
+ # Plotting API
2
+ The main user-facing function is `iplotx.network`, which can be used to plot graphs and graph groupings (covers and clusterings), and `iplotx.tree` to plot trees.
3
+
4
+ ```{tip}
5
+ `iplotx.plot` is a synonym for `iplotx.network`.
6
+ ```
7
+
8
+ ```{eval-rst}
9
+ .. autofunction:: iplotx.network
10
+ :noindex:
11
+
12
+ .. autofunction:: iplotx.tree
13
+ :noindex:
@@ -0,0 +1,17 @@
1
+ # Data provider protocols
2
+ ```{note}
3
+ The `NetworkDataProvider` protocol requires individual providers to implement `__call__` which actually processed the network, layout, and label data. We are working on simplifying this situation.
4
+
5
+ The `TreeDataProvider` protocol is simpler to implement as this function is standardised and needs not be implemented by individual providers. Only the support functions, which are very simple and small, needs to be implemented by tree providers.
6
+ ```
7
+
8
+
9
+ ```{eval-rst}
10
+ .. autoclass:: iplotx.ingest.typing.NetworkDataProvider
11
+ :members:
12
+
13
+ .. autoclass:: iplotx.ingest.typing.TreeDataProvider
14
+ :members:
15
+
16
+ ```
17
+
@@ -0,0 +1,23 @@
1
+ # Styling
2
+ See also the <project:../style.md> page for an introduction to styles in `iplotx`. See also <project:complete_style_specification.md>.
3
+
4
+ ## Functions
5
+
6
+
7
+ ```{eval-rst}
8
+ .. autofunction:: iplotx.style.context
9
+
10
+ .. autofunction:: iplotx.style.use
11
+
12
+ .. autofunction:: iplotx.style.reset
13
+
14
+ .. autofunction:: iplotx.style.get_style
15
+ ```
16
+
17
+ The following functions are reported for completeness but are rarely used by users directly:
18
+
19
+ ```{eval-rst}
20
+ .. autofunction:: iplotx.style.unflatten_style
21
+
22
+ .. autofunction:: iplotx.style.rotate_style
23
+ ```
@@ -0,0 +1,7 @@
1
+ # Reference API
2
+ This is the reference documentation for `iplotx`. This is split into separate sections:
3
+
4
+ - <project:api/plotting.md> for the plotting API
5
+ - <project:api/style.md> for the styling API
6
+ - <project:api/artists.md> for the artist hierarchy
7
+ - <project:api/providers.md> for the data providers API
@@ -116,5 +116,11 @@ We believe graph **analysis**, graph **layouting**, and graph **visualisation**
116
116
 
117
117
  gallery/index
118
118
  style
119
+ Data providers <providers>
119
120
  API <api>
121
+ Plotting API <api/plotting>
122
+ Styling API <api/style>
123
+ Complete style specification <api/complete_style_specification>
124
+ Artist hierarchy <api/artists>
125
+ Data provider protocols <api/providers>
120
126
  ```
@@ -0,0 +1,72 @@
1
+ # Data Providers
2
+ Networks and trees can be represented in different data structures. For instance, in `igraph` nodes are ordered and numbered, while in `networkx` they are neither.
3
+
4
+ `iplotx` is designed to accept data of any kinds as long as it can understand how to
5
+ process it into a visualisation. This flexibility is achieved through **data providers**.
6
+
7
+ A **network data provider** is a class that satisfies the `NetworkDataProvider` protocol, i.e. it implements a few functions that help `iplotx` understand how to ingest
8
+ data.
9
+
10
+ Similarly, a **tree data provider** is a class that satisfies the `TreeDataProvider` protocol, i.e. it implements those few functions. It is the tree-specific equivalent of the previous case.
11
+
12
+ See <project:api/providers.md> for the exact protocols.
13
+
14
+ ## An example: Simple network data provider
15
+ While `igraph`, `networkx` and the likes can be quite complicated, `iplotx` also provides a simple dict-based `NetworkDataProvider` for educational purposes. The network data structure in this case is the following:
16
+
17
+ ```python
18
+ network : dict[str, Sequence | bool] = {
19
+ "vertices": ["alice", "bob", "jago"],
20
+ "edges": [
21
+ ("alice", "bob"),
22
+ ("bob", "jago"),
23
+ ("alice", "jago"),
24
+ ],
25
+ "directed": False,
26
+ }
27
+ ```
28
+
29
+ It is a simple dictionary with a key for vertices, one for edges, and one for directedness. Only the key for edges is required. If missing, directedness is assumed to be `False`. If vertices are missing, they are inferred from the edges (singletons will be missed - there are none in the example above).
30
+
31
+
32
+ A straightforward `NetworkDataProvider` implementation for this network data structure is found in `iplotx/ingest/providers/network/simple.py`. As a result, it is possible to ingest networks in this new format for visualisation:
33
+
34
+ ```python
35
+ import iplotx as ipx
36
+ network = {
37
+ "edges": [
38
+ ("alice", "bob"),
39
+ ("bob", "jago"),
40
+ ("alice", "jago"),
41
+ ]
42
+ }
43
+ layout = {
44
+ "alice": (0, 0),
45
+ "bob": (1, 1),
46
+ "jago": (1, 0),
47
+ }
48
+ ipx.plot(
49
+ network,
50
+ layout,
51
+ )
52
+ ```
53
+
54
+ See <project:gallery/plot_simpledataprovider.md> for the full gallery example including vertex labels and styling.
55
+
56
+ ```{tip}
57
+ This example also shows how to use `iplotx` without installing any network analysis
58
+ library. You'll still need `matplotlib` for plotting and `numpy` and `pandas` for
59
+ internal number crunching.
60
+ ```
61
+
62
+
63
+ ## Creating a custom data provider
64
+ `iplotx` is able to seek new data providers at runtime, but they need to be registered in a specific way (keyword: `entry point`).
65
+
66
+ The expected entry point for a `NetworkDataProvider` is: `iplotx.network_data_providers`.
67
+
68
+ The expected entry point for a `TreeDataProvider` is: `iplotx.tree_data_providers`.
69
+
70
+ ```{note}
71
+ If you would like to make a library compatible with `iplotx` (by developing a provider), we are here to help! Just reach out on GitHub issues and we will try to help.
72
+ ```
@@ -6,7 +6,7 @@
6
6
 
7
7
  Computation times
8
8
  =================
9
- **00:01.212** total execution time for 36 files **from all galleries**:
9
+ **00:01.295** total execution time for 47 files **from all galleries**:
10
10
 
11
11
  .. container::
12
12
 
@@ -32,19 +32,19 @@ Computation times
32
32
  * - Example
33
33
  - Time
34
34
  - Mem (MB)
35
- * - :ref:`sphx_glr_gallery_plot_ete4.py` (``../../gallery/plot_ete4.py``)
36
- - 00:01.212
35
+ * - :ref:`sphx_glr_gallery_tree_plot_support.py` (``../../gallery/tree/plot_support.py``)
36
+ - 00:01.295
37
37
  - 0.0
38
38
  * - :ref:`sphx_glr_gallery_plot_animation.py` (``../../gallery/plot_animation.py``)
39
39
  - 00:00.000
40
40
  - 0.0
41
- * - :ref:`sphx_glr_gallery_plot_basic.py` (``../../gallery/plot_basic.py``)
41
+ * - :ref:`sphx_glr_gallery_plot_arrows.py` (``../../gallery/plot_arrows.py``)
42
42
  - 00:00.000
43
43
  - 0.0
44
- * - :ref:`sphx_glr_gallery_plot_big_curves.py` (``../../gallery/plot_big_curves.py``)
44
+ * - :ref:`sphx_glr_gallery_plot_basic.py` (``../../gallery/plot_basic.py``)
45
45
  - 00:00.000
46
46
  - 0.0
47
- * - :ref:`sphx_glr_gallery_plot_biopython_tree.py` (``../../gallery/plot_biopython_tree.py``)
47
+ * - :ref:`sphx_glr_gallery_plot_big_curves.py` (``../../gallery/plot_big_curves.py``)
48
48
  - 00:00.000
49
49
  - 0.0
50
50
  * - :ref:`sphx_glr_gallery_plot_chess_masters.py` (``../../gallery/plot_chess_masters.py``)
@@ -56,9 +56,6 @@ Computation times
56
56
  * - :ref:`sphx_glr_gallery_plot_cluster_layout.py` (``../../gallery/plot_cluster_layout.py``)
57
57
  - 00:00.000
58
58
  - 0.0
59
- * - :ref:`sphx_glr_gallery_plot_cogent3_tree.py` (``../../gallery/plot_cogent3_tree.py``)
60
- - 00:00.000
61
- - 0.0
62
59
  * - :ref:`sphx_glr_gallery_plot_company_structure.py` (``../../gallery/plot_company_structure.py``)
63
60
  - 00:00.000
64
61
  - 0.0
@@ -80,6 +77,9 @@ Computation times
80
77
  * - :ref:`sphx_glr_gallery_plot_grouping.py` (``../../gallery/plot_grouping.py``)
81
78
  - 00:00.000
82
79
  - 0.0
80
+ * - :ref:`sphx_glr_gallery_plot_halfarrows.py` (``../../gallery/plot_halfarrows.py``)
81
+ - 00:00.000
82
+ - 0.0
83
83
  * - :ref:`sphx_glr_gallery_plot_house.py` (``../../gallery/plot_house.py``)
84
84
  - 00:00.000
85
85
  - 0.0
@@ -104,6 +104,9 @@ Computation times
104
104
  * - :ref:`sphx_glr_gallery_plot_multipartite_layout.py` (``../../gallery/plot_multipartite_layout.py``)
105
105
  - 00:00.000
106
106
  - 0.0
107
+ * - :ref:`sphx_glr_gallery_plot_multistyle.py` (``../../gallery/plot_multistyle.py``)
108
+ - 00:00.000
109
+ - 0.0
107
110
  * - :ref:`sphx_glr_gallery_plot_parallel_igraph_networkx.py` (``../../gallery/plot_parallel_igraph_networkx.py``)
108
111
  - 00:00.000
109
112
  - 0.0
@@ -119,19 +122,19 @@ Computation times
119
122
  * - :ref:`sphx_glr_gallery_plot_simple_path.py` (``../../gallery/plot_simple_path.py``)
120
123
  - 00:00.000
121
124
  - 0.0
122
- * - :ref:`sphx_glr_gallery_plot_skbio_tree.py` (``../../gallery/plot_skbio_tree.py``)
125
+ * - :ref:`sphx_glr_gallery_plot_simpledataprovider.py` (``../../gallery/plot_simpledataprovider.py``)
123
126
  - 00:00.000
124
127
  - 0.0
125
128
  * - :ref:`sphx_glr_gallery_plot_style.py` (``../../gallery/plot_style.py``)
126
129
  - 00:00.000
127
130
  - 0.0
128
- * - :ref:`sphx_glr_gallery_plot_traveling_salesman.py` (``../../gallery/plot_traveling_salesman.py``)
131
+ * - :ref:`sphx_glr_gallery_plot_tension.py` (``../../gallery/plot_tension.py``)
129
132
  - 00:00.000
130
133
  - 0.0
131
- * - :ref:`sphx_glr_gallery_plot_tree_node_background.py` (``../../gallery/plot_tree_node_background.py``)
134
+ * - :ref:`sphx_glr_gallery_plot_traveling_salesman.py` (``../../gallery/plot_traveling_salesman.py``)
132
135
  - 00:00.000
133
136
  - 0.0
134
- * - :ref:`sphx_glr_gallery_plot_trees_of_trees.py` (``../../gallery/plot_trees_of_trees.py``)
137
+ * - :ref:`sphx_glr_gallery_plot_vertexmarkers.py` (``../../gallery/plot_vertexmarkers.py``)
135
138
  - 00:00.000
136
139
  - 0.0
137
140
  * - :ref:`sphx_glr_gallery_plot_voronoi.py` (``../../gallery/plot_voronoi.py``)
@@ -140,3 +143,33 @@ Computation times
140
143
  * - :ref:`sphx_glr_gallery_plot_with_colorbar.py` (``../../gallery/plot_with_colorbar.py``)
141
144
  - 00:00.000
142
145
  - 0.0
146
+ * - :ref:`sphx_glr_gallery_tree_plot_biopython_tree.py` (``../../gallery/tree/plot_biopython_tree.py``)
147
+ - 00:00.000
148
+ - 0.0
149
+ * - :ref:`sphx_glr_gallery_tree_plot_cogent3_layouts.py` (``../../gallery/tree/plot_cogent3_layouts.py``)
150
+ - 00:00.000
151
+ - 0.0
152
+ * - :ref:`sphx_glr_gallery_tree_plot_cogent3_tree.py` (``../../gallery/tree/plot_cogent3_tree.py``)
153
+ - 00:00.000
154
+ - 0.0
155
+ * - :ref:`sphx_glr_gallery_tree_plot_ete4.py` (``../../gallery/tree/plot_ete4.py``)
156
+ - 00:00.000
157
+ - 0.0
158
+ * - :ref:`sphx_glr_gallery_tree_plot_leafedges.py` (``../../gallery/tree/plot_leafedges.py``)
159
+ - 00:00.000
160
+ - 0.0
161
+ * - :ref:`sphx_glr_gallery_tree_plot_leafedges_and_cascades.py` (``../../gallery/tree/plot_leafedges_and_cascades.py``)
162
+ - 00:00.000
163
+ - 0.0
164
+ * - :ref:`sphx_glr_gallery_tree_plot_skbio_tree.py` (``../../gallery/tree/plot_skbio_tree.py``)
165
+ - 00:00.000
166
+ - 0.0
167
+ * - :ref:`sphx_glr_gallery_tree_plot_tree_node_background.py` (``../../gallery/tree/plot_tree_node_background.py``)
168
+ - 00:00.000
169
+ - 0.0
170
+ * - :ref:`sphx_glr_gallery_tree_plot_tree_style_clades.py` (``../../gallery/tree/plot_tree_style_clades.py``)
171
+ - 00:00.000
172
+ - 0.0
173
+ * - :ref:`sphx_glr_gallery_tree_plot_trees_of_trees.py` (``../../gallery/tree/plot_trees_of_trees.py``)
174
+ - 00:00.000
175
+ - 0.0
@@ -1,3 +1,6 @@
1
1
  Gallery
2
2
  =======
3
3
  This is a gallery of examples that demonstrate the capabilities of the `iplotx` library.
4
+
5
+ Networks
6
+ ++++++++
@@ -0,0 +1,31 @@
1
+ """
2
+ Arrowheads
3
+ ==========
4
+
5
+ This example showcases various types of arrowheads for connected graphs.
6
+ """
7
+
8
+ import networkx as nx
9
+ import matplotlib.pyplot as plt
10
+ import iplotx as ipx
11
+
12
+ arrow_markers = ["|>", "|/", "|\\", ">", ">>", ")>", ")", "|", "s", "d", "p", "q"]
13
+ n = len(arrow_markers)
14
+ G = nx.DiGraph()
15
+ G.add_edges_from([(f"l{i}", f"r{i}") for i in range(n)])
16
+ layout = {f"l{i}": (0, -i) for i in range(n)}
17
+ layout.update({f"r{i}": (1, -i) for i in range(n)})
18
+
19
+ fig, ax = plt.subplots(figsize=(3, 7.5))
20
+ ipx.network(
21
+ G,
22
+ layout=layout,
23
+ ax=ax,
24
+ vertex_size=12,
25
+ edge_arrow_marker=arrow_markers,
26
+ edge_arrow_height="width",
27
+ edge_color="steelblue",
28
+ title="Arrow markers",
29
+ )
30
+ ax.set_yticks(list(range(-n + 1, 1))[::-1])
31
+ ax.set_yticklabels(arrow_markers)
@@ -20,7 +20,7 @@ import iplotx as ipx
20
20
  game_details = ["Event", "Date", "Result", "ECO", "Site"]
21
21
 
22
22
 
23
- def chess_pgn_graph(pgn_file="chess_masters_WCC.pgn.bz2"):
23
+ def chess_pgn_graph(pgn_file="data/chess_masters_WCC.pgn.bz2"):
24
24
  """Read chess games in pgn format in pgn_file.
25
25
 
26
26
  Filenames ending in .bz2 will be uncompressed.