MatplotLibAPI 3.2.18__py3-none-any.whl → 3.2.19__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.
@@ -131,6 +131,40 @@ def _prepare_word_frequencies(
131
131
  return words, weights
132
132
 
133
133
 
134
+ def create_circular_mask(size: int = 300, radius: Optional[int] = None) -> np.ndarray:
135
+ """Construct a binary mask with a circular opening for a word cloud.
136
+
137
+ Parameters
138
+ ----------
139
+ size : int, optional
140
+ Width and height of the mask in pixels. Defaults to ``300``.
141
+ radius : int, optional
142
+ Radius of the circular opening in pixels. Defaults to ``size // 2``.
143
+
144
+ Returns
145
+ -------
146
+ numpy.ndarray
147
+ Two-dimensional array suitable for the ``mask`` argument of
148
+ ``wordcloud.WordCloud`` where ``0`` values define the drawable region.
149
+
150
+ Raises
151
+ ------
152
+ ValueError
153
+ If ``size`` or ``radius`` are non-positive.
154
+ """
155
+ if size <= 0:
156
+ raise ValueError("size must be a positive integer.")
157
+
158
+ resolved_radius = radius if radius is not None else size // 2
159
+ if resolved_radius <= 0:
160
+ raise ValueError("radius must be a positive integer.")
161
+
162
+ center = (size - 1) / 2
163
+ x, y = np.ogrid[:size, :size]
164
+ mask_region = (x - center) ** 2 + (y - center) ** 2 > resolved_radius**2
165
+ return 255 * mask_region.astype(np.uint8)
166
+
167
+
134
168
  def _plot_words(
135
169
  ax: Axes,
136
170
  words: Sequence[str],
@@ -138,6 +172,7 @@ def _plot_words(
138
172
  style: StyleTemplate,
139
173
  title: Optional[str],
140
174
  random_state: Optional[int],
175
+ mask: Optional[np.ndarray],
141
176
  ) -> Axes:
142
177
  """Render words on the provided axes with sizes proportional to weights.
143
178
 
@@ -179,8 +214,20 @@ def _plot_words(
179
214
 
180
215
  canvas.draw()
181
216
  ax_bbox = ax.get_window_extent()
182
- width = max(int(ax_bbox.width), 1)
183
- height = max(int(ax_bbox.height), 1)
217
+ resolved_mask = create_circular_mask() if mask is None else np.asarray(mask)
218
+ if resolved_mask is not None and resolved_mask.ndim != 2:
219
+ raise ValueError("mask must be a 2D array.")
220
+
221
+ width = (
222
+ max(int(ax_bbox.width), 1)
223
+ if resolved_mask is None
224
+ else max(int(resolved_mask.shape[1]), 1)
225
+ )
226
+ height = (
227
+ max(int(ax_bbox.height), 1)
228
+ if resolved_mask is None
229
+ else max(int(resolved_mask.shape[0]), 1)
230
+ )
184
231
 
185
232
  frequency_map = {
186
233
  string_formatter(word): weight for word, weight in zip(words, weights)
@@ -195,6 +242,7 @@ def _plot_words(
195
242
  min_font_size=int(font_sizes.min(initial=style.font_size)),
196
243
  max_font_size=int(font_sizes.max(initial=style.font_size * 4)),
197
244
  random_state=random_state,
245
+ mask=resolved_mask,
198
246
  ).generate_from_frequencies(frequency_map)
199
247
 
200
248
  ax.imshow(wc, interpolation="bilinear")
@@ -214,6 +262,7 @@ def aplot_wordcloud(
214
262
  stopwords: Optional[Iterable[str]] = None,
215
263
  random_state: Optional[int] = None,
216
264
  ax: Optional[Axes] = None,
265
+ mask: Optional[np.ndarray] = None,
217
266
  ) -> Axes:
218
267
  """Plot a word cloud on the provided axes.
219
268
 
@@ -237,6 +286,9 @@ def aplot_wordcloud(
237
286
  Seed for word placement. Defaults to ``None``.
238
287
  ax : matplotlib.axes.Axes, optional
239
288
  Axes to draw on. Defaults to ``None`` which uses the current axes.
289
+ mask : numpy.ndarray, optional
290
+ Two-dimensional mask array defining the drawable region of the word cloud.
291
+ Defaults to a circular mask generated by :func:`create_circular_mask`.
240
292
 
241
293
  Returns
242
294
  -------
@@ -259,7 +311,13 @@ def aplot_wordcloud(
259
311
  stopwords=stopwords,
260
312
  )
261
313
  return _plot_words(
262
- ax, words, weights, style=style, title=title, random_state=random_state
314
+ ax,
315
+ words,
316
+ weights,
317
+ style=style,
318
+ title=title,
319
+ random_state=random_state,
320
+ mask=mask,
263
321
  )
264
322
 
265
323
 
@@ -275,6 +333,7 @@ def fplot_wordcloud(
275
333
  figsize: Tuple[float, float] = FIG_SIZE,
276
334
  save_path: Optional[str] = None,
277
335
  savefig_kwargs: Optional[Dict[str, Any]] = None,
336
+ mask: Optional[np.ndarray] = None,
278
337
  ) -> Figure:
279
338
  """Create a new figure with a word cloud.
280
339
 
@@ -298,6 +357,9 @@ def fplot_wordcloud(
298
357
  Seed for word placement. Defaults to ``None``.
299
358
  figsize : tuple of float, optional
300
359
  Figure size. Defaults to ``FIG_SIZE``.
360
+ mask : numpy.ndarray, optional
361
+ Two-dimensional mask array defining the drawable region of the word cloud.
362
+ Defaults to a circular mask generated by :func:`create_circular_mask`.
301
363
 
302
364
  Returns
303
365
  -------
@@ -325,6 +387,7 @@ def fplot_wordcloud(
325
387
  style=style,
326
388
  title=title,
327
389
  random_state=random_state,
390
+ mask=mask,
328
391
  )
329
392
  fig.patch.set_facecolor(style.background_color)
330
393
  fig.tight_layout()
MatplotLibAPI/__init__.py CHANGED
@@ -35,7 +35,12 @@ from .Timeserie import TIMESERIE_STYLE_TEMPLATE, aplot_timeserie, fplot_timeseri
35
35
  from .Sunburst import fplot_sunburst
36
36
  from .Treemap import TREEMAP_STYLE_TEMPLATE, fplot_treemap
37
37
  from .Waffle import aplot_waffle, fplot_waffle
38
- from .Wordcloud import WORDCLOUD_STYLE_TEMPLATE, aplot_wordcloud, fplot_wordcloud
38
+ from .Wordcloud import (
39
+ WORDCLOUD_STYLE_TEMPLATE,
40
+ aplot_wordcloud,
41
+ create_circular_mask,
42
+ fplot_wordcloud,
43
+ )
39
44
  from .accessor import DataFrameAccessor
40
45
 
41
46
  __all__ = [
@@ -54,6 +59,7 @@ __all__ = [
54
59
  "aplot_correlation_matrix",
55
60
  "aplot_area",
56
61
  "aplot_pie_donut",
62
+ "create_circular_mask",
57
63
  "aplot_waffle",
58
64
  "fplot_bubble",
59
65
  "fplot_network",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: MatplotLibAPI
3
- Version: 3.2.18
3
+ Version: 3.2.19
4
4
  License-File: LICENSE
5
5
  Requires-Python: >=3.8
6
6
  Requires-Dist: kaleido
@@ -15,12 +15,12 @@ MatplotLibAPI/Table.py,sha256=jRdnQ0LNA5op65QJhXnXv_v7tBv1JEPLX7qHNd07_is,6448
15
15
  MatplotLibAPI/Timeserie.py,sha256=vN8Ed9eC6TcN02LAiSJRzbIW3ZNoBo8ip7lznnK5eG0,10198
16
16
  MatplotLibAPI/Treemap.py,sha256=VBBk6MpNXoQtnxFzR1YPhIx6Lz9b7yJNHBMbQDhvefM,4848
17
17
  MatplotLibAPI/Waffle.py,sha256=uplRhUBDWUhSwPnI_GzU1O2D_RQXW_0OJ51m01PFKLg,2517
18
- MatplotLibAPI/Wordcloud.py,sha256=sE6P8vCh8H6bQnaIr4LPW7fd3-OQootfOuM-9-htgv4,10016
19
- MatplotLibAPI/__init__.py,sha256=6Z51NTmLCoM7P-XPDGVQdtcXtz8S1zZzoByuX_nCpyw,2233
18
+ MatplotLibAPI/Wordcloud.py,sha256=lxBeB61dPbjc2WulZawCiCmjf_s7KiPib1zW70V9nH8,12123
19
+ MatplotLibAPI/__init__.py,sha256=jyMVtJq3rGJ9GmM7mX1dhJcNCCJHJ2-IwtDClRgKBFg,2304
20
20
  MatplotLibAPI/_typing.py,sha256=Or3IPNceWKdyEk3CGXJb09FZR_fvT732oF0iWrx1ex8,598
21
21
  MatplotLibAPI/_visualization_utils.py,sha256=qIv7c0Mi3qK-saGxmKngw23uWxKFSAYjiH3uYTSr5Po,2215
22
22
  MatplotLibAPI/accessor.py,sha256=Wsje4q6bNa_-WAkljqTDWfbWpKcbAy2JKaHir9qZ9Ho,53038
23
- matplotlibapi-3.2.18.dist-info/METADATA,sha256=75mgiIyrEAbZsWAhIVTl6OzJax5iW6dANKSMdV1a4yE,5888
24
- matplotlibapi-3.2.18.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
25
- matplotlibapi-3.2.18.dist-info/licenses/LICENSE,sha256=hMErKLb6YZR3lRR5zr-vxeFkvY69QAaafgSpZ5-P1dQ,1067
26
- matplotlibapi-3.2.18.dist-info/RECORD,,
23
+ matplotlibapi-3.2.19.dist-info/METADATA,sha256=0VPbE_llP391GgQWHC2DK99Gkl5E1xZQzPcPxC1WjEM,5888
24
+ matplotlibapi-3.2.19.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
25
+ matplotlibapi-3.2.19.dist-info/licenses/LICENSE,sha256=hMErKLb6YZR3lRR5zr-vxeFkvY69QAaafgSpZ5-P1dQ,1067
26
+ matplotlibapi-3.2.19.dist-info/RECORD,,