iplotx 0.3.1__py3-none-any.whl → 0.5.0__py3-none-any.whl

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.
@@ -74,13 +74,24 @@ def _additional_set_methods(attributes, cls=None):
74
74
  return cls
75
75
 
76
76
 
77
- # FIXME: this method appears quite inconsistent, would be better to improve.
78
- # The issue is that to really know the size of a label on screen, we need to
79
- # render it first. Therefore, we should render the labels, then render the
80
- # vertices. Leaving for now, since this can be styled manually which covers
81
- # many use cases.
82
- def _get_label_width_height(text, hpadding=18, vpadding=12, **kwargs):
83
- """Get the bounding box size for a text with certain properties."""
77
+ def _get_label_width_height(text, hpadding=18, vpadding=12, dpi=72.0, **kwargs):
78
+ """Get the bounding box size for a text with certain properties.
79
+
80
+ Parameters:
81
+ text: The text to measure.
82
+ hpadding: Horizontal padding to add to the width.
83
+ vpadding: Vertical padding to add to the height.
84
+ **kwargs: Additional keyword arguments for text properties. "fontsize" is accepted,
85
+ as is "size". Many other properties are not used and will raise and exception.
86
+
87
+ Returns:
88
+ A tuple (width, height) representing the size of the text bounding box. Because
89
+ some text properties such as weight are not taken into account, ths function is not
90
+ very accurate. Yet, it is often good enough and easier to implement than a careful
91
+ orchestration of Figure.draw_without_rendering.
92
+ """
93
+ if "fontsize" in kwargs:
94
+ kwargs["size"] = kwargs.pop("fontsize")
84
95
  forbidden_props = [
85
96
  "horizontalalignment",
86
97
  "verticalalignment",
@@ -99,47 +110,56 @@ def _get_label_width_height(text, hpadding=18, vpadding=12, **kwargs):
99
110
  width = boundingbox.width
100
111
  height = boundingbox.height
101
112
 
102
- # Scaling with font size appears broken... try to patch it up linearly here, even though we know it don't work well
113
+ # Scaling with font size appears broken... try to patch it up linearly here, even though we
114
+ # know it does not work terribly accurately
103
115
  width *= kwargs.get("size", 12) / 12.0
104
116
  height *= kwargs.get("size", 12) / 12.0
105
117
 
106
118
  width += hpadding
107
119
  height += vpadding
120
+
121
+ # Scale by dpi
122
+ width *= dpi / 72.0
123
+ height *= dpi / 72.0
124
+
108
125
  return (width, height)
109
126
 
110
127
 
111
128
  def _compute_mid_coord_and_rot(path, trans):
112
129
  """Compute mid point of an edge, straight or curved."""
113
- # Distinguish between straight and curved paths
130
+ # Straight path
114
131
  if path.codes[-1] == mpl.path.Path.LINETO:
115
132
  coord = path.vertices.mean(axis=0)
116
- vtr = trans(path.vertices)
117
- rot = atan2(
118
- vtr[-1, 1] - vtr[0, 1],
119
- vtr[-1, 0] - vtr[0, 0],
120
- )
133
+ v1 = path.vertices[0]
134
+ v2 = path.vertices[-1]
121
135
 
122
136
  # Cubic Bezier
123
137
  elif path.codes[-1] == mpl.path.Path.CURVE4:
124
138
  coord = _evaluate_cubic_bezier(path.vertices, 0.5)
125
- # TODO:
126
- rot = 0
139
+ v1 = _evaluate_cubic_bezier(path.vertices, 0.475)
140
+ v2 = _evaluate_cubic_bezier(path.vertices, 0.525)
127
141
 
128
142
  # Square Bezier
129
143
  elif path.codes[-1] == mpl.path.Path.CURVE3:
130
144
  coord = _evaluate_squared_bezier(path.vertices, 0.5)
131
- # TODO:
132
- rot = 0
145
+ v1 = _evaluate_squared_bezier(path.vertices, 0.475)
146
+ v2 = _evaluate_squared_bezier(path.vertices, 0.525)
133
147
 
134
148
  else:
135
149
  raise ValueError(
136
150
  "Curve type not straight and not squared/cubic Bezier, cannot compute mid point."
137
151
  )
138
152
 
153
+ v1 = trans(v1)
154
+ v2 = trans(v2)
155
+ rot = atan2(
156
+ v2[1] - v1[1],
157
+ v2[0] - v1[0],
158
+ )
139
159
  return coord, rot
140
160
 
141
161
 
142
- def _build_cmap_fun(values, cmap):
162
+ def _build_cmap_fun(values, cmap, norm=None):
143
163
  """Map colormap on top of numerical values."""
144
164
  cmap = mpl.cm._ensure_cmap(cmap)
145
165
 
@@ -149,8 +169,9 @@ def _build_cmap_fun(values, cmap):
149
169
  if isinstance(values, dict):
150
170
  values = np.array(list(values.values()))
151
171
 
152
- vmin = np.nanmin(values)
153
- vmax = np.nanmax(values)
154
- norm = mpl.colors.Normalize(vmin=vmin, vmax=vmax)
172
+ if norm is None:
173
+ vmin = np.nanmin(values)
174
+ vmax = np.nanmax(values)
175
+ norm = mpl.colors.Normalize(vmin=vmin, vmax=vmax)
155
176
 
156
177
  return lambda x: cmap(norm(x))
iplotx/utils/style.py CHANGED
@@ -1 +1,17 @@
1
- from copy import copy
1
+ import copy
2
+ from collections import defaultdict
3
+
4
+
5
+ def copy_with_deep_values(style):
6
+ """Make a deep copy of the style dict but do not create copies of the keys."""
7
+ # Defaultdict should be respected
8
+ if hasattr(style, "default_factory"):
9
+ newdict = defaultdict(lambda: style.default_factory())
10
+ else:
11
+ newdict = {}
12
+ for key, value in style.items():
13
+ if isinstance(value, dict):
14
+ newdict[key] = copy_with_deep_values(value)
15
+ else:
16
+ newdict[key] = copy.copy(value)
17
+ return newdict
iplotx/version.py CHANGED
@@ -2,4 +2,4 @@
2
2
  iplotx version information module.
3
3
  """
4
4
 
5
- __version__ = "0.3.1"
5
+ __version__ = "0.5.0"
iplotx/vertex.py CHANGED
@@ -14,6 +14,7 @@ import matplotlib as mpl
14
14
  from matplotlib.collections import PatchCollection
15
15
  from matplotlib.patches import (
16
16
  Patch,
17
+ Polygon,
17
18
  Ellipse,
18
19
  Circle,
19
20
  RegularPolygon,
@@ -54,7 +55,7 @@ class VertexCollection(PatchCollection):
54
55
  *args,
55
56
  layout_coordinate_system: str = "cartesian",
56
57
  style: Optional[dict[str, Any]] = None,
57
- labels: Optional[Sequence[str]] = None,
58
+ labels: Optional[Sequence[str] | pd.Series] = None,
58
59
  **kwargs,
59
60
  ):
60
61
  """Initialise the VertexCollection.
@@ -68,10 +69,13 @@ class VertexCollection(PatchCollection):
68
69
 
69
70
  self._index = layout.index
70
71
  self._style = style
71
- self._labels = labels
72
72
  self._layout = layout
73
73
  self._layout_coordinate_system = layout_coordinate_system
74
74
 
75
+ if (labels is not None) and (not isinstance(labels, pd.Series)):
76
+ labels = pd.Series(labels, index=self._layout.index)
77
+ self._labels = labels
78
+
75
79
  # Create patches from structured data
76
80
  patches, sizes, kwargs2 = self._init_vertex_patches()
77
81
 
@@ -90,6 +94,10 @@ class VertexCollection(PatchCollection):
90
94
  if self._labels is not None:
91
95
  self._compute_label_collection()
92
96
 
97
+ def __len__(self):
98
+ """Return the number of vertices in the collection."""
99
+ return len(self.get_paths())
100
+
93
101
  def get_children(self) -> tuple[mpl.artist.Artist]:
94
102
  """Get the children artists.
95
103
 
@@ -226,9 +234,7 @@ class VertexCollection(PatchCollection):
226
234
 
227
235
  if style.get("size", 20) == "label":
228
236
  if self._labels is None:
229
- warnings.warn(
230
- "No labels found, cannot resize vertices based on labels."
231
- )
237
+ warnings.warn("No labels found, cannot resize vertices based on labels.")
232
238
  style["size"] = get_style("default.vertex")["size"]
233
239
 
234
240
  if "cmap" in style:
@@ -264,9 +270,7 @@ class VertexCollection(PatchCollection):
264
270
  transform = self.get_offset_transform()
265
271
 
266
272
  style = (
267
- copy_with_deep_values(self._style.get("label", None))
268
- if self._style is not None
269
- else {}
273
+ copy_with_deep_values(self._style.get("label", None)) if self._style is not None else {}
270
274
  )
271
275
  forbidden_props = ["hpadding", "vpadding"]
272
276
  for prop in forbidden_props:
@@ -355,7 +359,7 @@ def make_patch(
355
359
  **kwargs,
356
360
  ) -> tuple[Patch, float]:
357
361
  """Make a patch of the given marker shape and size."""
358
- forbidden_props = ["label", "cmap", "norm", "cascade"]
362
+ forbidden_props = ["label", "cmap", "norm", "cascade", "deep"]
359
363
  for prop in forbidden_props:
360
364
  if prop in kwargs:
361
365
  kwargs.pop(prop)
@@ -363,12 +367,12 @@ def make_patch(
363
367
  if np.isscalar(size):
364
368
  size = float(size)
365
369
  size = (size, size)
370
+ size = np.asarray(size, dtype=float)
366
371
 
367
372
  # Size of vertices is determined in self._transforms, which scales with dpi, rather than here,
368
373
  # so normalise by the average dimension (btw x and y) to keep the ratio of the marker.
369
374
  # If you check in get_sizes, you will see that rescaling also happens with the max of width
370
375
  # and height.
371
- size = np.asarray(size, dtype=float)
372
376
  size_max = size.max()
373
377
  if size_max > 0:
374
378
  size /= size_max
@@ -379,15 +383,59 @@ def make_patch(
379
383
  elif marker in ("s", "square", "r", "rectangle"):
380
384
  art = Rectangle((-size[0] / 2, -size[1] / 2), size[0], size[1], **kwargs)
381
385
  elif marker in ("^", "triangle"):
382
- art = RegularPolygon((0, 0), numVertices=3, radius=size[0] / 2, **kwargs)
383
- elif marker in ("d", "diamond"):
384
- art, _ = make_patch("s", size[0], angle=45, **kwargs)
386
+ art = RegularPolygon((0, 0), numVertices=3, radius=size[0] / np.sqrt(2), **kwargs)
385
387
  elif marker in ("v", "triangle_down"):
386
388
  art = RegularPolygon(
387
- (0, 0), numVertices=3, radius=size[0] / 2, orientation=np.pi, **kwargs
389
+ (0, 0),
390
+ numVertices=3,
391
+ radius=size[0] / np.sqrt(2),
392
+ orientation=np.pi,
393
+ **kwargs,
394
+ )
395
+ elif marker in ("<", "triangle_left"):
396
+ art = RegularPolygon(
397
+ (0, 0),
398
+ numVertices=3,
399
+ radius=size[0] / np.sqrt(2),
400
+ orientation=np.pi / 2,
401
+ **kwargs,
388
402
  )
403
+ elif marker in (">", "triangle_right"):
404
+ art = RegularPolygon(
405
+ (0, 0),
406
+ numVertices=3,
407
+ radius=size[0] / np.sqrt(2),
408
+ orientation=-np.pi / 2,
409
+ **kwargs,
410
+ )
411
+ elif marker in ("d", "diamond"):
412
+ art = RegularPolygon((0, 0), numVertices=4, radius=size[0] / np.sqrt(2), **kwargs)
413
+ elif marker in ("p", "pentagon"):
414
+ art = RegularPolygon((0, 0), numVertices=5, radius=size[0] / np.sqrt(2), **kwargs)
415
+ elif marker in ("h", "hexagon"):
416
+ art = RegularPolygon((0, 0), numVertices=6, radius=size[0] / np.sqrt(2), **kwargs)
417
+ elif marker in ("8", "octagon"):
418
+ art = RegularPolygon((0, 0), numVertices=8, radius=size[0] / np.sqrt(2), **kwargs)
389
419
  elif marker in ("e", "ellipse"):
390
- art = Ellipse((0, 0), size[0] / 2, size[1] / 2, **kwargs)
420
+ art = Ellipse((0, 0), size[0], size[1], **kwargs)
421
+ elif marker in ("*", "star"):
422
+ size *= np.sqrt(2)
423
+ art = Polygon(
424
+ [
425
+ (0, size[1] / 2),
426
+ (size[0] / 7, size[1] / 7),
427
+ (size[0] / 2, size[1] / 7),
428
+ (size[0] / 4, -size[1] / 8),
429
+ (size[0] / 3, -size[1] / 2),
430
+ (0, -0.27 * size[1]),
431
+ (-size[0] / 3, -size[1] / 2),
432
+ (-size[0] / 4, -size[1] / 8),
433
+ (-size[0] / 2, size[1] / 7),
434
+ (-size[0] / 7, size[1] / 7),
435
+ (0, size[1] / 2),
436
+ ][::-1],
437
+ **kwargs,
438
+ )
391
439
  else:
392
440
  raise KeyError(f"Unknown marker: {marker}")
393
441
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iplotx
3
- Version: 0.3.1
3
+ Version: 0.5.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
@@ -39,6 +39,7 @@ Description-Content-Type: text/markdown
39
39
  ![Github Actions](https://github.com/fabilab/iplotx/actions/workflows/test.yml/badge.svg)
40
40
  ![PyPI - Version](https://img.shields.io/pypi/v/iplotx)
41
41
  ![RTD](https://readthedocs.org/projects/iplotx/badge/?version=latest)
42
+ [![Coverage Status](https://coveralls.io/repos/github/fabilab/iplotx/badge.svg?branch=main)](https://coveralls.io/github/fabilab/iplotx?branch=main)
42
43
  ![pylint](assets/pylint.svg)
43
44
 
44
45
  # iplotx
@@ -0,0 +1,38 @@
1
+ iplotx/__init__.py,sha256=MKb9UCXKgDHHkeATuJWxYdM-AotfBo2fbWy-Rkbn9Is,509
2
+ iplotx/artists.py,sha256=Bpn6NS8S_B_E4OW88JYW6aEu2bIuIQJmbs2paTmBAoY,522
3
+ iplotx/cascades.py,sha256=OPqF7Huls-HFmDA5MCF6DEZlUeRVaXsbQcHBoKAgNJs,8182
4
+ iplotx/groups.py,sha256=_9KdIiTAi1kXtd2mDywgBJCbqoRq2z-5fzOPf76Wgb8,6287
5
+ iplotx/label.py,sha256=i107wE-9kC_MVWsgWeYG6sRy_ZmyvITNm2laIij9SR0,8761
6
+ iplotx/layout.py,sha256=KxmRLqjo8AYCBAmXez8rIiLU2sM34qhb6ox9AHYwRyE,4839
7
+ iplotx/network.py,sha256=SlmDgc4tbCfvO08QWk-jUXrUfaz6S3xoXQVg6rP1910,11345
8
+ iplotx/plotting.py,sha256=RZj-E_2R8AbXoJmxr_qAC-g_nOudqep-TDSIV4QB9BM,7408
9
+ iplotx/tree.py,sha256=iILQRKUZzcDKIiwI1LheSuixi5y_3PAQrz61vdwi6DU,27448
10
+ iplotx/typing.py,sha256=QLdzV358IiD1CFe88MVp0D77FSx5sSAVUmM_2WPPE8I,1463
11
+ iplotx/version.py,sha256=jzr3_UVrKVs0fo73K5UioUFwKYv5i4rA--sHkaSaQkw,66
12
+ iplotx/vertex.py,sha256=OjDIkJCNU-IhZUVeZTSzGwTlHLrxu27lUThiUuEb6Qs,14497
13
+ iplotx/edge/__init__.py,sha256=0w-BDZpVyR4qM908PM5DzlNVXwwfxAeDNyHNXPWPgcc,26237
14
+ iplotx/edge/arrow.py,sha256=y8xMZY1eR5BXBmkX0_aDIn-3CeqaL6jwGGLw-ndUf50,12867
15
+ iplotx/edge/geometry.py,sha256=-WLdI-BVB12-Zcq1Jc4LqDFoViuOfljTax-YHI1N7cc,13359
16
+ iplotx/edge/leaf.py,sha256=SyGMv2PIOoH0pey8-aMVaZheK3hNe1Qz_okcyWbc4E4,4268
17
+ iplotx/edge/ports.py,sha256=BpkbiEhX4mPBBAhOv4jcKFG4Y8hxXz5GRtVLCC0jbtI,1235
18
+ iplotx/ingest/__init__.py,sha256=tsXDoa7Rs6Y1ulWtjCcUsO4tQIigeQ6ZMiU2PQDyhwQ,4751
19
+ iplotx/ingest/heuristics.py,sha256=715VqgfKek5LOJnu1vTo7RqPgCl-Bb8Cf6o7_Tt57fA,5797
20
+ iplotx/ingest/typing.py,sha256=pi-mn4ULkFjTo_fFdJPUjTHrWzbny4MNgoMylN4mNKM,13940
21
+ iplotx/ingest/providers/network/igraph.py,sha256=8dWeaQ_ZNdltC098V2YeLXsGdJHQnBa6shF1GAfl0Zg,2973
22
+ iplotx/ingest/providers/network/networkx.py,sha256=FIXMI3hXU1WtAzPVlQZcz47b-4V2omeHttnNTgS2gQw,4328
23
+ iplotx/ingest/providers/network/simple.py,sha256=yKILiE3-ZhBUGSs7eYuhV8tQDyueCosbbgovZZYpSPQ,3664
24
+ iplotx/ingest/providers/tree/biopython.py,sha256=4N_54cVyHHPcASJZGr6pHKE2p5R3i8Cm307SLlSLHLA,1480
25
+ iplotx/ingest/providers/tree/cogent3.py,sha256=JmELbDK7LyybiJzFNbmeqZ4ySJoDajvFfJebpNfFKWo,1073
26
+ iplotx/ingest/providers/tree/ete4.py,sha256=D7usSq0MOjzrk3EoLi834IlaDGwv7_qG6Qt0ptfKqfI,928
27
+ iplotx/ingest/providers/tree/simple.py,sha256=vOAlQbkm2HdlBTQab6s7mjAnLibVmeNOfc6y6UpBqzw,2533
28
+ iplotx/ingest/providers/tree/skbio.py,sha256=O1KUr8tYi28pZ3VVjapgO4Uj-YpMuix3GhOH5je8Lv4,822
29
+ iplotx/style/__init__.py,sha256=4K6EtAKOFth3zS_jdaDCvOEMeZxIgnMM_rtpH_G74io,12253
30
+ iplotx/style/leaf_info.py,sha256=2XckYhvE3FvNYUaQj_CY2HwtYfZA8FUQ7uBXe_ukaWU,938
31
+ iplotx/style/library.py,sha256=yryxQUSHMIwGgeS0Iq1BediVRRaFguJcjhXMj_vsHo8,8007
32
+ iplotx/utils/geometry.py,sha256=UH2gAcM5rYW7ADnJEm7HIJTpPF4UOm8P3vjSVCOGjqM,9192
33
+ iplotx/utils/internal.py,sha256=WWfcZDGK8Ut1y_tOHRGg9wSqY1bwSeLQO7dHM_8Tvwo,107
34
+ iplotx/utils/matplotlib.py,sha256=KpkuwXuSqpYbPVKbrlP8u_1Ry5gy5q60ZBrFiR-do_Q,5284
35
+ iplotx/utils/style.py,sha256=wMWxJykxBD-JmcN8-rSKlWcV6pMfwKgR4EzSpk_NX8k,547
36
+ iplotx-0.5.0.dist-info/METADATA,sha256=QPPJUkwVArD550-tLmUpq11Qaczb7M9xgma8bDHijVc,3958
37
+ iplotx-0.5.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
38
+ iplotx-0.5.0.dist-info/RECORD,,
@@ -1,32 +0,0 @@
1
- iplotx/__init__.py,sha256=DIOWUaEo9vgmz8B6hBlurV95BEYmjmUe5BU-jRWrtG4,418
2
- iplotx/cascades.py,sha256=_J8kxCHJrZmPKaN10e0uROAPsdcLrw41hzozZu1hQcg,8405
3
- iplotx/groups.py,sha256=H3zIaqlILQaC6Iqgxrf3zSuRVgynQTLLEuuGy6lYgLI,6388
4
- iplotx/label.py,sha256=m2ryXMh29QFLwdstRphnOPocW_Wnqir9WQscxWN1Z2E,7347
5
- iplotx/layout.py,sha256=0Mqrs0odQ8Jk4nITvAYgayR6KDm3e-Lq1BY_DKeU3ok,4664
6
- iplotx/network.py,sha256=rLVfC52PBiTR0I-CCvFPE0dj7t-KCLZwXSSJrpPVzh8,9719
7
- iplotx/plotting.py,sha256=VU1LYp9peqLa1CmvHjF98BYxezkWUrcCWvd2MPB9n_8,7381
8
- iplotx/style.py,sha256=NtrKYhTIkf7GPpepsROUbXxbodIc8gu066CdLNAsMQM,12009
9
- iplotx/tree.py,sha256=YU3UoGV_Zxf_KkP4iIsi09WsL1vBvS3URkG-Uqzqyp4,18393
10
- iplotx/typing.py,sha256=17TS-EJshNNOdeUC9mmJALiJ3gwI1nRq6AGlVdQRp1E,1384
11
- iplotx/version.py,sha256=rahYe2_qX2OYwONUMb_Iwaqu5jYjPE7Kl2oak8C_GFc,66
12
- iplotx/vertex.py,sha256=JCXv-l934jDGdS2fOigOdDKDZ-5Az-7MUqHcQk8Jl18,12715
13
- iplotx/edge/__init__.py,sha256=W68WienFUneWQ0iVTFGNm8KIBQGvkfXlYq2Kx1lDzU8,23076
14
- iplotx/edge/arrow.py,sha256=2mF_HwhHkXir3lOYOTp8HW__PQgWRxaHXZN9mvk3hLQ,11452
15
- iplotx/edge/geometry.py,sha256=7RwtIUOjz6pd1QTUaNwtIivnaM4ZfxVgMjTg1bIqqQA,12827
16
- iplotx/edge/ports.py,sha256=pno3A7QdQyZGyQJOHVLYszBBeQAh-q2-jkd-lOe31TM,1183
17
- iplotx/ingest/__init__.py,sha256=dEbdb3LP3QnPKpwA7y6fJl9spCWkCYYtXCQPCGA9oVk,4971
18
- iplotx/ingest/heuristics.py,sha256=_ZSC9EiCr-eURmhGdufdZdyERpzPrPvRj01nv0rXkiE,6579
19
- iplotx/ingest/typing.py,sha256=cPEvOT5yjDiXj6Y9E3ShH2uDmepn7YtPtBIZ_cOEp6g,10345
20
- iplotx/ingest/providers/network/igraph.py,sha256=lCWIlKd2VwxJLoc2W4nivwkrvFjhmXhG9r_sJkFXWh0,2794
21
- iplotx/ingest/providers/network/networkx.py,sha256=-lb_8jpq7DvoM9lWn43qL6jTqS-VqtpJEgcSJeFz7yQ,4261
22
- iplotx/ingest/providers/tree/biopython.py,sha256=JFuD7NWV7j-fWt-6q29ApvlKf7Mqrnr_6wSkzSK-e38,1080
23
- iplotx/ingest/providers/tree/cogent3.py,sha256=LHAFLronzlrlLWl79abXWOoFP-agIdzoQqj6O15xwLE,873
24
- iplotx/ingest/providers/tree/ete4.py,sha256=vHwfYRazruR7eZfUgEJiSyeUA7UVBsTtR998uoL5bDQ,971
25
- iplotx/ingest/providers/tree/skbio.py,sha256=fwlITpl71gIKDDoJKB6nmlC-J6A2fXoplX6ul5qXsYc,869
26
- iplotx/utils/geometry.py,sha256=K5ZBYPmz4-KNm64pDh2p0L6PF5-u57SCVaEd2eWeRv0,8956
27
- iplotx/utils/internal.py,sha256=WWfcZDGK8Ut1y_tOHRGg9wSqY1bwSeLQO7dHM_8Tvwo,107
28
- iplotx/utils/matplotlib.py,sha256=T37SMwKNSA-dRKgNkVw5H4fGr5NACtxvBPebDJGdhjk,4516
29
- iplotx/utils/style.py,sha256=fEi14nc37HQqHxZTPeQaTnFFwbSneY1oDCyv2UbWfKk,22
30
- iplotx-0.3.1.dist-info/METADATA,sha256=AS5QTNoONMtRiEfOBF2E6iZ_c8RpOQvnHbb6RD79Fgw,3809
31
- iplotx-0.3.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
32
- iplotx-0.3.1.dist-info/RECORD,,
File without changes