MatplotLibAPI 3.2.20__tar.gz → 3.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 (57) hide show
  1. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/AGENTS.md +1 -1
  2. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/MatplotLibAPI/Bubble.py +9 -6
  3. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/MatplotLibAPI/Composite.py +133 -6
  4. matplotlibapi-3.3.0/MatplotLibAPI/Network.py +1823 -0
  5. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/MatplotLibAPI/StyleTemplate.py +19 -18
  6. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/MatplotLibAPI/Table.py +14 -4
  7. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/MatplotLibAPI/Timeserie.py +3 -2
  8. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/MatplotLibAPI/Wordcloud.py +61 -47
  9. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/MatplotLibAPI/__init__.py +10 -5
  10. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/MatplotLibAPI/accessor.py +333 -106
  11. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/PKG-INFO +1 -1
  12. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/pyproject.toml +1 -1
  13. matplotlibapi-3.3.0/tests/test_composite.py +78 -0
  14. matplotlibapi-3.3.0/tests/test_network.py +188 -0
  15. matplotlibapi-3.3.0/tests/test_style_template.py +27 -0
  16. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/tests/test_wordcloud.py +36 -18
  17. matplotlibapi-3.2.20/MatplotLibAPI/Network.py +0 -956
  18. matplotlibapi-3.2.20/tests/test_network.py +0 -29
  19. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/.github/workflows/ci.yml +0 -0
  20. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/.github/workflows/python-publish.yml +0 -0
  21. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/.gitignore +0 -0
  22. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/LICENSE +0 -0
  23. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/MatplotLibAPI/Area.py +0 -0
  24. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/MatplotLibAPI/Bar.py +0 -0
  25. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/MatplotLibAPI/BoxViolin.py +0 -0
  26. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/MatplotLibAPI/Heatmap.py +0 -0
  27. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/MatplotLibAPI/Histogram.py +0 -0
  28. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/MatplotLibAPI/Pie.py +0 -0
  29. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/MatplotLibAPI/Pivot.py +0 -0
  30. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/MatplotLibAPI/Sankey.py +0 -0
  31. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/MatplotLibAPI/Sunburst.py +0 -0
  32. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/MatplotLibAPI/Treemap.py +0 -0
  33. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/MatplotLibAPI/Waffle.py +0 -0
  34. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/MatplotLibAPI/_typing.py +0 -0
  35. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/MatplotLibAPI/_visualization_utils.py +0 -0
  36. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/README.md +0 -0
  37. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/SECURITY.md +0 -0
  38. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/SUGGESTIONS.md +0 -0
  39. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/scripts/generate_sample_data.py +0 -0
  40. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/tests/__init__.py +0 -0
  41. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/tests/conftest.py +0 -0
  42. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/tests/test_area.py +0 -0
  43. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/tests/test_bar.py +0 -0
  44. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/tests/test_box_violin.py +0 -0
  45. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/tests/test_bubble.py +0 -0
  46. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/tests/test_dependencies.py +0 -0
  47. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/tests/test_heatmap.py +0 -0
  48. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/tests/test_histogram.py +0 -0
  49. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/tests/test_pie.py +0 -0
  50. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/tests/test_pivot.py +0 -0
  51. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/tests/test_sankey.py +0 -0
  52. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/tests/test_smoke.py +0 -0
  53. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/tests/test_sunburst.py +0 -0
  54. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/tests/test_table.py +0 -0
  55. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/tests/test_timeseries.py +0 -0
  56. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/tests/test_treemap.py +0 -0
  57. {matplotlibapi-3.2.20 → matplotlibapi-3.3.0}/tests/test_waffle.py +0 -0
@@ -60,7 +60,7 @@ pytest -q --cov=MatplotLibAPI --cov-report=term-missing --cov-fail-under=70
60
60
 
61
61
  Each pull request should include:
62
62
 
63
- 1. **Summary** – brief description of the change.
63
+ 1. **Summary** – brief description of the change. Mention breaking changes.
64
64
  2. **Testing** – commands run and confirmation that the tests passed.
65
65
 
66
66
  Example PR body:
@@ -15,13 +15,12 @@ from matplotlib.ticker import NullLocator
15
15
 
16
16
  from .StyleTemplate import (
17
17
  BUBBLE_STYLE_TEMPLATE,
18
+ FIG_SIZE,
18
19
  MAX_RESULTS,
20
+ TITLE_SCALE_FACTOR,
19
21
  StyleTemplate,
20
- bmk_formatter,
21
22
  format_func,
22
23
  generate_ticks,
23
- percent_formatter,
24
- string_formatter,
25
24
  validate_dataframe,
26
25
  DynamicFuncFormatter,
27
26
  FormatterFunc,
@@ -354,7 +353,11 @@ def aplot_bubble(
354
353
  _draw_bubble_labels(ax, plot_df, label, x, y, style, format_funcs)
355
354
 
356
355
  if title:
357
- ax.set_title(title, color=style.font_color, fontsize=style.font_size * 2)
356
+ ax.set_title(
357
+ title,
358
+ color=style.font_color,
359
+ fontsize=style.font_size * TITLE_SCALE_FACTOR,
360
+ )
358
361
 
359
362
  return ax
360
363
 
@@ -373,7 +376,7 @@ def fplot_bubble(
373
376
  ascending: bool = False,
374
377
  hline: bool = False,
375
378
  vline: bool = False,
376
- figsize: Tuple[float, float] = (19.2, 10.8),
379
+ figsize: Tuple[float, float] = FIG_SIZE,
377
380
  save_path: Optional[str] = None,
378
381
  savefig_kwargs: Optional[Dict[str, Any]] = None,
379
382
  ) -> Figure:
@@ -408,7 +411,7 @@ def fplot_bubble(
408
411
  vline : bool, optional
409
412
  Draw vertical line at mean x. The default is `False`.
410
413
  figsize : tuple[float, float], optional
411
- Size of the figure. The default is (19.2, 10.8).
414
+ Size of the figure. The default is FIG_SIZE.
412
415
 
413
416
  Returns
414
417
  -------
@@ -1,18 +1,26 @@
1
1
  """Composite plotting routines combining multiple charts."""
2
2
 
3
- from typing import Dict, Optional, Tuple, cast
3
+ from typing import Dict, Iterable, Optional, Tuple, cast
4
4
 
5
5
  import matplotlib.pyplot as plt
6
6
  import pandas as pd
7
7
  import plotly.graph_objects as go
8
+ from matplotlib.axes import Axes
8
9
  from matplotlib.figure import Figure
9
10
  from matplotlib.gridspec import GridSpec
10
11
  from plotly.subplots import make_subplots
11
12
 
12
- from .Bubble import BUBBLE_STYLE_TEMPLATE, aplot_bubble
13
- from .StyleTemplate import StyleTemplate, validate_dataframe
13
+ from .Bubble import BUBBLE_STYLE_TEMPLATE, FIG_SIZE, aplot_bubble
14
+ from .Network import aplot_network
15
+ from .StyleTemplate import (
16
+ MAX_RESULTS,
17
+ TITLE_SCALE_FACTOR,
18
+ StyleTemplate,
19
+ validate_dataframe,
20
+ )
14
21
  from .Table import aplot_table
15
22
  from .Treemap import TREEMAP_STYLE_TEMPLATE, aplot_treemap
23
+ from .Wordcloud import WORDCLOUD_STYLE_TEMPLATE, aplot_wordcloud
16
24
 
17
25
 
18
26
  def plot_composite_bubble(
@@ -29,7 +37,7 @@ def plot_composite_bubble(
29
37
  sort_by: Optional[str] = None,
30
38
  ascending: bool = False,
31
39
  table_rows: int = 10,
32
- figsize: Tuple[float, float] = (19.2, 10.8),
40
+ figsize: Tuple[float, float] = FIG_SIZE,
33
41
  ) -> Figure:
34
42
  """Plot a composite bubble chart with summary tables.
35
43
 
@@ -62,7 +70,7 @@ def plot_composite_bubble(
62
70
  table_rows : int, optional
63
71
  Number of rows to display in the tables. The default is 10.
64
72
  figsize : tuple[float, float], optional
65
- Size of the created figure. The default is (19.2, 10.8).
73
+ Size of the created figure. The default is FIG_SIZE.
66
74
 
67
75
  Returns
68
76
  -------
@@ -120,7 +128,10 @@ def plot_composite_bubble(
120
128
  max_values=table_rows,
121
129
  style=style,
122
130
  )
123
- fig.tight_layout()
131
+ if title:
132
+ fig.tight_layout(rect=(0, 0, 1, 0.95))
133
+ else:
134
+ fig.tight_layout()
124
135
  return fig
125
136
 
126
137
 
@@ -193,3 +204,119 @@ def plot_composite_treemap(
193
204
  current_row += 1
194
205
  return fig
195
206
  return None
207
+
208
+
209
+ def plot_wordcloud_network(
210
+ nodes_df: pd.DataFrame,
211
+ edges_df: pd.DataFrame,
212
+ node_col: str = "node",
213
+ node_weight_col: str = "weight",
214
+ edge_source_col: str = "source",
215
+ edge_target_col: str = "target",
216
+ edge_weight_col: str = "weight",
217
+ max_words: int = MAX_RESULTS,
218
+ stopwords: Optional[Iterable[str]] = None,
219
+ title: Optional[str] = None,
220
+ style: StyleTemplate = WORDCLOUD_STYLE_TEMPLATE,
221
+ wordcloud_style: Optional[StyleTemplate] = None,
222
+ network_style: Optional[StyleTemplate] = None,
223
+ figsize: Tuple[float, float] = FIG_SIZE,
224
+ ) -> Figure:
225
+ """Plot a word cloud above a network graph.
226
+
227
+ Parameters
228
+ ----------
229
+ nodes_df : pd.DataFrame
230
+ DataFrame containing node labels and optional weights for the word cloud.
231
+ edges_df : pd.DataFrame
232
+ DataFrame containing edge connections for the network plot.
233
+ node_col : str, optional
234
+ Column in ``nodes_df`` containing the node labels. The default is ``"node"``.
235
+ node_weight_col : str, optional
236
+ Column in ``nodes_df`` containing weights for sizing words. The default is
237
+ ``"weight"``.
238
+ edge_source_col : str, optional
239
+ Column in ``edges_df`` containing source nodes. The default is ``"source"``.
240
+ edge_target_col : str, optional
241
+ Column in ``edges_df`` containing target nodes. The default is ``"target"``.
242
+ edge_weight_col : str, optional
243
+ Column in ``edges_df`` containing edge weights. The default is ``"weight"``.
244
+ max_words : int, optional
245
+ Maximum number of words to include in the word cloud. The default is ``50``.
246
+ stopwords : Iterable[str], optional
247
+ Stopwords to exclude from the word cloud. The default is ``None``.
248
+ title : str, optional
249
+ Title for the composite figure. The default is ``None``.
250
+ style : StyleTemplate, optional
251
+ Shared style configuration applied to the composite figure and used for
252
+ subplots when specialized styles are not provided. The default is
253
+ ``WORDCLOUD_STYLE_TEMPLATE``.
254
+ wordcloud_style : StyleTemplate, optional
255
+ Optional style configuration for the word cloud subplot. When ``None``
256
+ the shared ``style`` is used. The default is ``None``.
257
+ network_style : StyleTemplate, optional
258
+ Optional style configuration for the network subplot. When ``None`` the
259
+ shared ``style`` is used. The default is ``None``.
260
+ figsize : tuple[float, float], optional
261
+ Size of the composite figure. The default is ``FIG_SIZE``.
262
+
263
+ Returns
264
+ -------
265
+ Figure
266
+ Matplotlib figure containing the word cloud on top and network below.
267
+ """
268
+ validate_dataframe(nodes_df, cols=[node_col], sort_by=node_weight_col)
269
+ validate_dataframe(
270
+ edges_df, cols=[edge_source_col, edge_target_col, edge_weight_col], sort_by=None
271
+ )
272
+
273
+ fig_raw, axes_raw = plt.subplots(
274
+ 2,
275
+ 1,
276
+ figsize=figsize,
277
+ gridspec_kw={"height_ratios": [1, 2]},
278
+ )
279
+ fig = cast(Figure, fig_raw)
280
+ wordcloud_ax, network_ax = cast(Tuple[Axes, Axes], axes_raw)
281
+
282
+ wordcloud_style = wordcloud_style or style
283
+ network_style = network_style or style
284
+
285
+ fig.patch.set_facecolor(style.background_color)
286
+ if title:
287
+ fig.suptitle(
288
+ title,
289
+ color=style.font_color,
290
+ fontsize=style.font_size * TITLE_SCALE_FACTOR,
291
+ fontname=style.font_name,
292
+ )
293
+
294
+ aplot_wordcloud(
295
+ pd_df=nodes_df,
296
+ text_column=node_col,
297
+ weight_column=node_weight_col,
298
+ title=None,
299
+ style=wordcloud_style,
300
+ max_words=max_words,
301
+ stopwords=stopwords,
302
+ ax=wordcloud_ax,
303
+ )
304
+
305
+ aplot_network(
306
+ pd_df=edges_df,
307
+ node_df=nodes_df,
308
+ node_col=node_col,
309
+ node_weight_col=node_weight_col,
310
+ edge_source_col=edge_source_col,
311
+ edge_target_col=edge_target_col,
312
+ edge_weight_col=edge_weight_col,
313
+ title=None,
314
+ style=network_style,
315
+ ax=network_ax,
316
+ )
317
+
318
+ if title:
319
+ fig.tight_layout(rect=(0, 0, 1, 0.95))
320
+ else:
321
+ fig.tight_layout()
322
+ return fig