MatplotLibAPI 3.2.20__tar.gz → 3.2.21__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.
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/MatplotLibAPI/Bubble.py +3 -2
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/MatplotLibAPI/Composite.py +98 -5
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/MatplotLibAPI/Network.py +43 -10
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/MatplotLibAPI/Table.py +3 -3
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/MatplotLibAPI/Timeserie.py +3 -2
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/MatplotLibAPI/Wordcloud.py +9 -12
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/MatplotLibAPI/__init__.py +6 -1
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/MatplotLibAPI/accessor.py +29 -28
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/PKG-INFO +1 -1
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/pyproject.toml +1 -1
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/tests/test_wordcloud.py +32 -14
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/.github/workflows/ci.yml +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/.github/workflows/python-publish.yml +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/.gitignore +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/AGENTS.md +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/LICENSE +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/MatplotLibAPI/Area.py +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/MatplotLibAPI/Bar.py +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/MatplotLibAPI/BoxViolin.py +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/MatplotLibAPI/Heatmap.py +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/MatplotLibAPI/Histogram.py +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/MatplotLibAPI/Pie.py +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/MatplotLibAPI/Pivot.py +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/MatplotLibAPI/Sankey.py +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/MatplotLibAPI/StyleTemplate.py +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/MatplotLibAPI/Sunburst.py +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/MatplotLibAPI/Treemap.py +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/MatplotLibAPI/Waffle.py +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/MatplotLibAPI/_typing.py +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/MatplotLibAPI/_visualization_utils.py +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/README.md +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/SECURITY.md +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/SUGGESTIONS.md +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/scripts/generate_sample_data.py +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/tests/__init__.py +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/tests/conftest.py +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/tests/test_area.py +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/tests/test_bar.py +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/tests/test_box_violin.py +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/tests/test_bubble.py +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/tests/test_dependencies.py +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/tests/test_heatmap.py +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/tests/test_histogram.py +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/tests/test_network.py +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/tests/test_pie.py +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/tests/test_pivot.py +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/tests/test_sankey.py +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/tests/test_smoke.py +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/tests/test_sunburst.py +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/tests/test_table.py +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/tests/test_timeseries.py +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/tests/test_treemap.py +0 -0
- {matplotlibapi-3.2.20 → matplotlibapi-3.2.21}/tests/test_waffle.py +0 -0
|
@@ -15,6 +15,7 @@ from matplotlib.ticker import NullLocator
|
|
|
15
15
|
|
|
16
16
|
from .StyleTemplate import (
|
|
17
17
|
BUBBLE_STYLE_TEMPLATE,
|
|
18
|
+
FIG_SIZE,
|
|
18
19
|
MAX_RESULTS,
|
|
19
20
|
StyleTemplate,
|
|
20
21
|
bmk_formatter,
|
|
@@ -373,7 +374,7 @@ def fplot_bubble(
|
|
|
373
374
|
ascending: bool = False,
|
|
374
375
|
hline: bool = False,
|
|
375
376
|
vline: bool = False,
|
|
376
|
-
figsize: Tuple[float, float] =
|
|
377
|
+
figsize: Tuple[float, float] = FIG_SIZE,
|
|
377
378
|
save_path: Optional[str] = None,
|
|
378
379
|
savefig_kwargs: Optional[Dict[str, Any]] = None,
|
|
379
380
|
) -> Figure:
|
|
@@ -408,7 +409,7 @@ def fplot_bubble(
|
|
|
408
409
|
vline : bool, optional
|
|
409
410
|
Draw vertical line at mean x. The default is `False`.
|
|
410
411
|
figsize : tuple[float, float], optional
|
|
411
|
-
Size of the figure. The default is
|
|
412
|
+
Size of the figure. The default is FIG_SIZE.
|
|
412
413
|
|
|
413
414
|
Returns
|
|
414
415
|
-------
|
|
@@ -1,6 +1,6 @@
|
|
|
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
|
|
@@ -9,10 +9,12 @@ from matplotlib.figure import Figure
|
|
|
9
9
|
from matplotlib.gridspec import GridSpec
|
|
10
10
|
from plotly.subplots import make_subplots
|
|
11
11
|
|
|
12
|
-
from .Bubble import BUBBLE_STYLE_TEMPLATE, aplot_bubble
|
|
13
|
-
from .
|
|
12
|
+
from .Bubble import BUBBLE_STYLE_TEMPLATE, FIG_SIZE, aplot_bubble
|
|
13
|
+
from .Network import NETWORK_STYLE_TEMPLATE, aplot_network
|
|
14
|
+
from .StyleTemplate import MAX_RESULTS, StyleTemplate, validate_dataframe
|
|
14
15
|
from .Table import aplot_table
|
|
15
16
|
from .Treemap import TREEMAP_STYLE_TEMPLATE, aplot_treemap
|
|
17
|
+
from .Wordcloud import WORDCLOUD_STYLE_TEMPLATE, aplot_wordcloud
|
|
16
18
|
|
|
17
19
|
|
|
18
20
|
def plot_composite_bubble(
|
|
@@ -29,7 +31,7 @@ def plot_composite_bubble(
|
|
|
29
31
|
sort_by: Optional[str] = None,
|
|
30
32
|
ascending: bool = False,
|
|
31
33
|
table_rows: int = 10,
|
|
32
|
-
figsize: Tuple[float, float] =
|
|
34
|
+
figsize: Tuple[float, float] = FIG_SIZE,
|
|
33
35
|
) -> Figure:
|
|
34
36
|
"""Plot a composite bubble chart with summary tables.
|
|
35
37
|
|
|
@@ -62,7 +64,7 @@ def plot_composite_bubble(
|
|
|
62
64
|
table_rows : int, optional
|
|
63
65
|
Number of rows to display in the tables. The default is 10.
|
|
64
66
|
figsize : tuple[float, float], optional
|
|
65
|
-
Size of the created figure. The default is
|
|
67
|
+
Size of the created figure. The default is FIG_SIZE.
|
|
66
68
|
|
|
67
69
|
Returns
|
|
68
70
|
-------
|
|
@@ -193,3 +195,94 @@ def plot_composite_treemap(
|
|
|
193
195
|
current_row += 1
|
|
194
196
|
return fig
|
|
195
197
|
return None
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def plot_wordcloud_network(
|
|
201
|
+
nodes_df: pd.DataFrame,
|
|
202
|
+
edges_df: pd.DataFrame,
|
|
203
|
+
text_column: str = "node",
|
|
204
|
+
node_weight: Optional[str] = "weight",
|
|
205
|
+
source: str = "source",
|
|
206
|
+
target: str = "target",
|
|
207
|
+
edge_weight: str = "weight",
|
|
208
|
+
wordcloud_title: Optional[str] = None,
|
|
209
|
+
network_title: Optional[str] = None,
|
|
210
|
+
wordcloud_style: StyleTemplate = WORDCLOUD_STYLE_TEMPLATE,
|
|
211
|
+
network_style: StyleTemplate = NETWORK_STYLE_TEMPLATE,
|
|
212
|
+
max_words: int = MAX_RESULTS,
|
|
213
|
+
stopwords: Optional[Iterable[str]] = None,
|
|
214
|
+
figsize: Tuple[float, float] = FIG_SIZE,
|
|
215
|
+
) -> Figure:
|
|
216
|
+
"""Plot a word cloud above a network graph.
|
|
217
|
+
|
|
218
|
+
Parameters
|
|
219
|
+
----------
|
|
220
|
+
nodes_df : pd.DataFrame
|
|
221
|
+
DataFrame containing node labels and optional weights for the word cloud.
|
|
222
|
+
edges_df : pd.DataFrame
|
|
223
|
+
DataFrame containing edge connections for the network plot.
|
|
224
|
+
text_column : str, optional
|
|
225
|
+
Column in ``nodes_df`` containing the node labels. The default is ``"node"``.
|
|
226
|
+
node_weight : str, optional
|
|
227
|
+
Column in ``nodes_df`` containing weights for sizing words. The default is
|
|
228
|
+
``"weight"``.
|
|
229
|
+
source : str, optional
|
|
230
|
+
Column in ``edges_df`` containing source nodes. The default is ``"source"``.
|
|
231
|
+
target : str, optional
|
|
232
|
+
Column in ``edges_df`` containing target nodes. The default is ``"target"``.
|
|
233
|
+
edge_weight : str, optional
|
|
234
|
+
Column in ``edges_df`` containing edge weights. The default is ``"weight"``.
|
|
235
|
+
wordcloud_title : str, optional
|
|
236
|
+
Title for the word cloud subplot. The default is ``None``.
|
|
237
|
+
network_title : str, optional
|
|
238
|
+
Title for the network subplot. The default is ``None``.
|
|
239
|
+
wordcloud_style : StyleTemplate, optional
|
|
240
|
+
Style configuration for the word cloud. The default is
|
|
241
|
+
``WORDCLOUD_STYLE_TEMPLATE``.
|
|
242
|
+
network_style : StyleTemplate, optional
|
|
243
|
+
Style configuration for the network graph. The default is
|
|
244
|
+
``NETWORK_STYLE_TEMPLATE``.
|
|
245
|
+
max_words : int, optional
|
|
246
|
+
Maximum number of words to include in the word cloud. The default is ``50``.
|
|
247
|
+
stopwords : Iterable[str], optional
|
|
248
|
+
Stopwords to exclude from the word cloud. The default is ``None``.
|
|
249
|
+
figsize : tuple[float, float], optional
|
|
250
|
+
Size of the composite figure. The default is ``FIG_SIZE``.
|
|
251
|
+
|
|
252
|
+
Returns
|
|
253
|
+
-------
|
|
254
|
+
Figure
|
|
255
|
+
Matplotlib figure containing the word cloud on top and network below.
|
|
256
|
+
"""
|
|
257
|
+
validate_dataframe(nodes_df, cols=[text_column], sort_by=node_weight)
|
|
258
|
+
validate_dataframe(edges_df, cols=[source, target, edge_weight], sort_by=None)
|
|
259
|
+
|
|
260
|
+
fig = cast(Figure, plt.figure(figsize=figsize))
|
|
261
|
+
fig.patch.set_facecolor(wordcloud_style.background_color)
|
|
262
|
+
grid = GridSpec(2, 1, height_ratios=[1, 2])
|
|
263
|
+
|
|
264
|
+
wordcloud_ax = fig.add_subplot(grid[0, 0])
|
|
265
|
+
aplot_wordcloud(
|
|
266
|
+
pd_df=nodes_df,
|
|
267
|
+
text_column=text_column,
|
|
268
|
+
weight_column=node_weight,
|
|
269
|
+
title=wordcloud_title,
|
|
270
|
+
style=wordcloud_style,
|
|
271
|
+
max_words=max_words,
|
|
272
|
+
stopwords=stopwords,
|
|
273
|
+
ax=wordcloud_ax,
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
network_ax = fig.add_subplot(grid[1, 0])
|
|
277
|
+
aplot_network(
|
|
278
|
+
pd_df=edges_df,
|
|
279
|
+
source=source,
|
|
280
|
+
target=target,
|
|
281
|
+
weight=edge_weight,
|
|
282
|
+
title=network_title,
|
|
283
|
+
style=network_style,
|
|
284
|
+
ax=network_ax,
|
|
285
|
+
)
|
|
286
|
+
|
|
287
|
+
fig.tight_layout()
|
|
288
|
+
return fig
|
|
@@ -14,6 +14,7 @@ from matplotlib.figure import Figure
|
|
|
14
14
|
|
|
15
15
|
from .StyleTemplate import (
|
|
16
16
|
NETWORK_STYLE_TEMPLATE,
|
|
17
|
+
FIG_SIZE,
|
|
17
18
|
StyleTemplate,
|
|
18
19
|
format_func,
|
|
19
20
|
string_formatter,
|
|
@@ -410,7 +411,25 @@ class NetworkGraph:
|
|
|
410
411
|
if ax is None:
|
|
411
412
|
ax = cast(Axes, plt.gca())
|
|
412
413
|
|
|
413
|
-
|
|
414
|
+
isolated_nodes = list(nx.isolates(self._nx_graph))
|
|
415
|
+
graph_nx = self._nx_graph
|
|
416
|
+
if isolated_nodes:
|
|
417
|
+
# Avoid mutating the user-provided graph when pruning display-only
|
|
418
|
+
# isolates so the underlying data remains unchanged after plotting.
|
|
419
|
+
graph_nx = graph_nx.copy()
|
|
420
|
+
graph_nx.remove_nodes_from(isolated_nodes)
|
|
421
|
+
|
|
422
|
+
graph = self if graph_nx is self._nx_graph else NetworkGraph(graph_nx)
|
|
423
|
+
|
|
424
|
+
if graph._nx_graph.number_of_nodes() == 0:
|
|
425
|
+
ax.set_axis_off()
|
|
426
|
+
if title:
|
|
427
|
+
ax.set_title(
|
|
428
|
+
title, color=style.font_color, fontsize=style.font_size * 2
|
|
429
|
+
)
|
|
430
|
+
return ax
|
|
431
|
+
|
|
432
|
+
node_sizes, edge_widths, font_sizes = graph.layout(
|
|
414
433
|
min_node_size=DEFAULT["MIN_NODE_SIZE"] // 5,
|
|
415
434
|
max_node_size=DEFAULT["MAX_NODE_SIZE"],
|
|
416
435
|
max_edge_width=DEFAULT["MAX_EDGE_WIDTH"],
|
|
@@ -418,11 +437,11 @@ class NetworkGraph:
|
|
|
418
437
|
max_font_size=style.font_mapping.get(4, DEFAULT["MAX_FONT_SIZE"]),
|
|
419
438
|
weight=weight,
|
|
420
439
|
)
|
|
421
|
-
pos = nx.spring_layout(
|
|
440
|
+
pos = nx.spring_layout(graph._nx_graph, k=1)
|
|
422
441
|
# nodes
|
|
423
442
|
node_sizes_int = [int(size) for size in node_sizes]
|
|
424
443
|
nx.draw_networkx_nodes(
|
|
425
|
-
|
|
444
|
+
graph._nx_graph,
|
|
426
445
|
pos,
|
|
427
446
|
ax=ax,
|
|
428
447
|
node_size=cast(Any, node_sizes_int),
|
|
@@ -431,7 +450,7 @@ class NetworkGraph:
|
|
|
431
450
|
)
|
|
432
451
|
# edges
|
|
433
452
|
nx.draw_networkx_edges(
|
|
434
|
-
|
|
453
|
+
graph._nx_graph,
|
|
435
454
|
pos,
|
|
436
455
|
ax=ax,
|
|
437
456
|
edge_color=style.font_color,
|
|
@@ -441,7 +460,7 @@ class NetworkGraph:
|
|
|
441
460
|
# labels
|
|
442
461
|
for font_size, nodes in font_sizes.items():
|
|
443
462
|
nx.draw_networkx_labels(
|
|
444
|
-
|
|
463
|
+
graph._nx_graph,
|
|
445
464
|
pos,
|
|
446
465
|
ax=ax,
|
|
447
466
|
font_size=font_size,
|
|
@@ -614,7 +633,7 @@ def compute_network_grid(
|
|
|
614
633
|
n_components = len(connected_components)
|
|
615
634
|
n_cols = int(np.ceil(np.sqrt(n_components)))
|
|
616
635
|
n_rows = int(np.ceil(n_components / n_cols))
|
|
617
|
-
fig, axes_grid = plt.subplots(n_rows, n_cols, figsize=
|
|
636
|
+
fig, axes_grid = plt.subplots(n_rows, n_cols, figsize=FIG_SIZE)
|
|
618
637
|
fig = cast(Figure, fig)
|
|
619
638
|
fig.patch.set_facecolor(style.background_color)
|
|
620
639
|
if not isinstance(axes_grid, np.ndarray):
|
|
@@ -767,6 +786,20 @@ def aplot_network_components(
|
|
|
767
786
|
|
|
768
787
|
connected_components = list(nx.connected_components(graph._nx_graph))
|
|
769
788
|
|
|
789
|
+
if not connected_components:
|
|
790
|
+
if axes is not None:
|
|
791
|
+
for ax in axes.flatten():
|
|
792
|
+
ax.set_axis_off()
|
|
793
|
+
return
|
|
794
|
+
|
|
795
|
+
isolated_nodes = list(nx.isolates(graph._nx_graph))
|
|
796
|
+
if isolated_nodes:
|
|
797
|
+
# Keep the caller's graph intact while dropping isolates purely for
|
|
798
|
+
# visualization.
|
|
799
|
+
graph = NetworkGraph(graph._nx_graph.copy())
|
|
800
|
+
graph._nx_graph.remove_nodes_from(isolated_nodes)
|
|
801
|
+
connected_components = list(nx.connected_components(graph._nx_graph))
|
|
802
|
+
|
|
770
803
|
if not connected_components:
|
|
771
804
|
if axes is not None:
|
|
772
805
|
for ax in axes.flatten():
|
|
@@ -806,7 +839,7 @@ def fplot_network(
|
|
|
806
839
|
sort_by: Optional[str] = None,
|
|
807
840
|
ascending: bool = False,
|
|
808
841
|
node_list: Optional[List] = None,
|
|
809
|
-
figsize: Tuple[float, float] =
|
|
842
|
+
figsize: Tuple[float, float] = FIG_SIZE,
|
|
810
843
|
save_path: Optional[str] = None,
|
|
811
844
|
savefig_kwargs: Optional[Dict[str, Any]] = None,
|
|
812
845
|
) -> Figure:
|
|
@@ -833,7 +866,7 @@ def fplot_network(
|
|
|
833
866
|
node_list : list, optional
|
|
834
867
|
Nodes to include.
|
|
835
868
|
figsize : tuple[float, float], optional
|
|
836
|
-
Size of the created figure. The default is
|
|
869
|
+
Size of the created figure. The default is FIG_SIZE.
|
|
837
870
|
|
|
838
871
|
Returns
|
|
839
872
|
-------
|
|
@@ -870,7 +903,7 @@ def fplot_network_components(
|
|
|
870
903
|
sort_by: Optional[str] = None,
|
|
871
904
|
ascending: bool = False,
|
|
872
905
|
node_list: Optional[List] = None,
|
|
873
|
-
figsize: Tuple[float, float] =
|
|
906
|
+
figsize: Tuple[float, float] = FIG_SIZE,
|
|
874
907
|
n_cols: Optional[int] = None,
|
|
875
908
|
save_path: Optional[str] = None,
|
|
876
909
|
savefig_kwargs: Optional[Dict[str, Any]] = None,
|
|
@@ -898,7 +931,7 @@ def fplot_network_components(
|
|
|
898
931
|
node_list : list, optional
|
|
899
932
|
Nodes to include.
|
|
900
933
|
figsize : tuple[float, float], optional
|
|
901
|
-
Size of the created figure. The default is
|
|
934
|
+
Size of the created figure. The default is FIG_SIZE.
|
|
902
935
|
n_cols : int, optional
|
|
903
936
|
Number of columns for subplots. If None, it's inferred.
|
|
904
937
|
|
|
@@ -8,7 +8,7 @@ from matplotlib.figure import Figure
|
|
|
8
8
|
from matplotlib.transforms import Bbox
|
|
9
9
|
from matplotlib.table import Table
|
|
10
10
|
|
|
11
|
-
from .StyleTemplate import StyleTemplate, string_formatter, validate_dataframe
|
|
11
|
+
from .StyleTemplate import StyleTemplate, string_formatter, validate_dataframe, FIG_SIZE
|
|
12
12
|
|
|
13
13
|
TABLE_STYLE_TEMPLATE = StyleTemplate(
|
|
14
14
|
background_color="black", fig_border="darkgrey", font_color="white", palette="magma"
|
|
@@ -172,7 +172,7 @@ def fplot_table(
|
|
|
172
172
|
max_values: int = 20,
|
|
173
173
|
sort_by: Optional[str] = None,
|
|
174
174
|
ascending: bool = False,
|
|
175
|
-
figsize: Tuple[float, float] =
|
|
175
|
+
figsize: Tuple[float, float] = FIG_SIZE,
|
|
176
176
|
save_path: Optional[str] = None,
|
|
177
177
|
savefig_kwargs: Optional[Dict[str, Any]] = None,
|
|
178
178
|
) -> Figure:
|
|
@@ -195,7 +195,7 @@ def fplot_table(
|
|
|
195
195
|
ascending : bool, optional
|
|
196
196
|
Sort order for the data, by default ``False``.
|
|
197
197
|
figsize : tuple of float, optional
|
|
198
|
-
Size of the created figure, by default ``
|
|
198
|
+
Size of the created figure, by default ``FIG_SIZE``.
|
|
199
199
|
|
|
200
200
|
Returns
|
|
201
201
|
-------
|
|
@@ -10,6 +10,7 @@ from matplotlib.figure import Figure
|
|
|
10
10
|
|
|
11
11
|
from .StyleTemplate import (
|
|
12
12
|
TIMESERIE_STYLE_TEMPLATE,
|
|
13
|
+
FIG_SIZE,
|
|
13
14
|
StyleTemplate,
|
|
14
15
|
bmk_formatter,
|
|
15
16
|
format_func,
|
|
@@ -269,7 +270,7 @@ def fplot_timeserie(
|
|
|
269
270
|
sort_by: Optional[str] = None,
|
|
270
271
|
ascending: bool = False,
|
|
271
272
|
std: bool = False,
|
|
272
|
-
figsize: Tuple[float, float] =
|
|
273
|
+
figsize: Tuple[float, float] = FIG_SIZE,
|
|
273
274
|
save_path: Optional[str] = None,
|
|
274
275
|
savefig_kwargs: Optional[Dict[str, Any]] = None,
|
|
275
276
|
) -> Figure:
|
|
@@ -298,7 +299,7 @@ def fplot_timeserie(
|
|
|
298
299
|
std : bool, optional
|
|
299
300
|
Whether to plot rolling standard deviation. The default is `False`.
|
|
300
301
|
figsize : tuple[float, float], optional
|
|
301
|
-
Size of the created figure. The default is
|
|
302
|
+
Size of the created figure. The default is FIG_SIZE.
|
|
302
303
|
|
|
303
304
|
Returns
|
|
304
305
|
-------
|
|
@@ -187,20 +187,17 @@ def _plot_words(
|
|
|
187
187
|
|
|
188
188
|
canvas.draw()
|
|
189
189
|
ax_bbox = ax.get_window_extent()
|
|
190
|
-
|
|
191
|
-
if
|
|
190
|
+
|
|
191
|
+
if mask is None:
|
|
192
|
+
mask_dimension = max(int(ax_bbox.width), int(ax_bbox.height), 1)
|
|
193
|
+
resolved_mask = create_circular_mask(size=mask_dimension)
|
|
194
|
+
else:
|
|
195
|
+
resolved_mask = np.asarray(mask)
|
|
196
|
+
|
|
197
|
+
if resolved_mask.ndim != 2:
|
|
192
198
|
raise ValueError("mask must be a 2D array.")
|
|
193
199
|
|
|
194
|
-
width =
|
|
195
|
-
max(int(ax_bbox.width), 1)
|
|
196
|
-
if resolved_mask is None
|
|
197
|
-
else max(int(resolved_mask.shape[1]), 1)
|
|
198
|
-
)
|
|
199
|
-
height = (
|
|
200
|
-
max(int(ax_bbox.height), 1)
|
|
201
|
-
if resolved_mask is None
|
|
202
|
-
else max(int(resolved_mask.shape[0]), 1)
|
|
203
|
-
)
|
|
200
|
+
height, width = resolved_mask.shape
|
|
204
201
|
|
|
205
202
|
frequency_map = {
|
|
206
203
|
string_formatter(word): weight for word, weight in zip(words, weights)
|
|
@@ -4,7 +4,11 @@ from .Area import aplot_area, fplot_area
|
|
|
4
4
|
from .Bar import aplot_bar, fplot_bar
|
|
5
5
|
from .BoxViolin import aplot_box_violin, fplot_box_violin
|
|
6
6
|
from .Bubble import BUBBLE_STYLE_TEMPLATE, aplot_bubble, fplot_bubble
|
|
7
|
-
from .Composite import
|
|
7
|
+
from .Composite import (
|
|
8
|
+
plot_composite_bubble,
|
|
9
|
+
plot_composite_treemap,
|
|
10
|
+
plot_wordcloud_network,
|
|
11
|
+
)
|
|
8
12
|
from .Heatmap import (
|
|
9
13
|
HEATMAP_STYLE_TEMPLATE,
|
|
10
14
|
aplot_correlation_matrix,
|
|
@@ -80,5 +84,6 @@ __all__ = [
|
|
|
80
84
|
"fplot_sankey",
|
|
81
85
|
"plot_composite_bubble",
|
|
82
86
|
"plot_composite_treemap",
|
|
87
|
+
"plot_wordcloud_network",
|
|
83
88
|
"prepare_network_graph",
|
|
84
89
|
]
|
|
@@ -32,6 +32,7 @@ from .Network import (
|
|
|
32
32
|
from .Pie import aplot_pie_donut, fplot_pie_donut
|
|
33
33
|
from .Sankey import SANKEY_STYLE_TEMPLATE, fplot_sankey
|
|
34
34
|
from .StyleTemplate import (
|
|
35
|
+
FIG_SIZE,
|
|
35
36
|
AREA_STYLE_TEMPLATE,
|
|
36
37
|
DISTRIBUTION_STYLE_TEMPLATE,
|
|
37
38
|
PIE_STYLE_TEMPLATE,
|
|
@@ -210,7 +211,7 @@ class DataFrameAccessor:
|
|
|
210
211
|
ascending: bool = False,
|
|
211
212
|
hline: bool = False,
|
|
212
213
|
vline: bool = False,
|
|
213
|
-
figsize: Tuple[float, float] =
|
|
214
|
+
figsize: Tuple[float, float] = FIG_SIZE,
|
|
214
215
|
save_path: Optional[str] = None,
|
|
215
216
|
savefig_kwargs: Optional[Dict[str, Any]] = None,
|
|
216
217
|
) -> Figure:
|
|
@@ -243,7 +244,7 @@ class DataFrameAccessor:
|
|
|
243
244
|
vline : bool, optional
|
|
244
245
|
If True, draw a vertical line at the mean of x-values. The default is `False`.
|
|
245
246
|
figsize : tuple[float, float], optional
|
|
246
|
-
Figure size. The default is
|
|
247
|
+
Figure size. The default is FIG_SIZE.
|
|
247
248
|
|
|
248
249
|
Returns
|
|
249
250
|
-------
|
|
@@ -386,7 +387,7 @@ class DataFrameAccessor:
|
|
|
386
387
|
stacked: bool = False,
|
|
387
388
|
title: Optional[str] = None,
|
|
388
389
|
style: StyleTemplate = DISTRIBUTION_STYLE_TEMPLATE,
|
|
389
|
-
figsize: Tuple[float, float] =
|
|
390
|
+
figsize: Tuple[float, float] = FIG_SIZE,
|
|
390
391
|
) -> Figure:
|
|
391
392
|
"""Plot bar or stacked bar charts on a new figure.
|
|
392
393
|
|
|
@@ -405,7 +406,7 @@ class DataFrameAccessor:
|
|
|
405
406
|
style : StyleTemplate, optional
|
|
406
407
|
Styling template. The default is ``DISTRIBUTION_STYLE_TEMPLATE``.
|
|
407
408
|
figsize : tuple[float, float], optional
|
|
408
|
-
Figure size. The default is
|
|
409
|
+
Figure size. The default is FIG_SIZE.
|
|
409
410
|
|
|
410
411
|
Returns
|
|
411
412
|
-------
|
|
@@ -471,7 +472,7 @@ class DataFrameAccessor:
|
|
|
471
472
|
kde: bool = True,
|
|
472
473
|
title: Optional[str] = None,
|
|
473
474
|
style: StyleTemplate = DISTRIBUTION_STYLE_TEMPLATE,
|
|
474
|
-
figsize: Tuple[float, float] =
|
|
475
|
+
figsize: Tuple[float, float] = FIG_SIZE,
|
|
475
476
|
) -> Figure:
|
|
476
477
|
"""Plot a histogram with an optional KDE on a new figure.
|
|
477
478
|
|
|
@@ -488,7 +489,7 @@ class DataFrameAccessor:
|
|
|
488
489
|
style : StyleTemplate, optional
|
|
489
490
|
Styling template. The default is ``DISTRIBUTION_STYLE_TEMPLATE``.
|
|
490
491
|
figsize : tuple[float, float], optional
|
|
491
|
-
Figure size. The default is
|
|
492
|
+
Figure size. The default is FIG_SIZE.
|
|
492
493
|
|
|
493
494
|
Returns
|
|
494
495
|
-------
|
|
@@ -553,7 +554,7 @@ class DataFrameAccessor:
|
|
|
553
554
|
violin: bool = False,
|
|
554
555
|
title: Optional[str] = None,
|
|
555
556
|
style: StyleTemplate = DISTRIBUTION_STYLE_TEMPLATE,
|
|
556
|
-
figsize: Tuple[float, float] =
|
|
557
|
+
figsize: Tuple[float, float] = FIG_SIZE,
|
|
557
558
|
) -> Figure:
|
|
558
559
|
"""Plot box or violin charts on a new figure.
|
|
559
560
|
|
|
@@ -570,7 +571,7 @@ class DataFrameAccessor:
|
|
|
570
571
|
style : StyleTemplate, optional
|
|
571
572
|
Styling template. The default is ``DISTRIBUTION_STYLE_TEMPLATE``.
|
|
572
573
|
figsize : tuple[float, float], optional
|
|
573
|
-
Figure size. The default is
|
|
574
|
+
Figure size. The default is FIG_SIZE.
|
|
574
575
|
|
|
575
576
|
Returns
|
|
576
577
|
-------
|
|
@@ -635,7 +636,7 @@ class DataFrameAccessor:
|
|
|
635
636
|
value: str,
|
|
636
637
|
title: Optional[str] = None,
|
|
637
638
|
style: StyleTemplate = HEATMAP_STYLE_TEMPLATE,
|
|
638
|
-
figsize: Tuple[float, float] =
|
|
639
|
+
figsize: Tuple[float, float] = FIG_SIZE,
|
|
639
640
|
) -> Figure:
|
|
640
641
|
"""Plot a heatmap on a new figure.
|
|
641
642
|
|
|
@@ -652,7 +653,7 @@ class DataFrameAccessor:
|
|
|
652
653
|
style : StyleTemplate, optional
|
|
653
654
|
Styling template. The default is ``HEATMAP_STYLE_TEMPLATE``.
|
|
654
655
|
figsize : tuple[float, float], optional
|
|
655
|
-
Figure size. The default is
|
|
656
|
+
Figure size. The default is FIG_SIZE.
|
|
656
657
|
|
|
657
658
|
Returns
|
|
658
659
|
-------
|
|
@@ -712,7 +713,7 @@ class DataFrameAccessor:
|
|
|
712
713
|
method: CorrelationMethod = "pearson",
|
|
713
714
|
title: Optional[str] = None,
|
|
714
715
|
style: StyleTemplate = HEATMAP_STYLE_TEMPLATE,
|
|
715
|
-
figsize: Tuple[float, float] =
|
|
716
|
+
figsize: Tuple[float, float] = FIG_SIZE,
|
|
716
717
|
) -> Figure:
|
|
717
718
|
"""Plot a correlation matrix heatmap on a new figure.
|
|
718
719
|
|
|
@@ -727,7 +728,7 @@ class DataFrameAccessor:
|
|
|
727
728
|
style : StyleTemplate, optional
|
|
728
729
|
Styling template. The default is ``HEATMAP_STYLE_TEMPLATE``.
|
|
729
730
|
figsize : tuple[float, float], optional
|
|
730
|
-
Figure size. The default is
|
|
731
|
+
Figure size. The default is FIG_SIZE.
|
|
731
732
|
|
|
732
733
|
Returns
|
|
733
734
|
-------
|
|
@@ -796,7 +797,7 @@ class DataFrameAccessor:
|
|
|
796
797
|
stacked: bool = True,
|
|
797
798
|
title: Optional[str] = None,
|
|
798
799
|
style: StyleTemplate = AREA_STYLE_TEMPLATE,
|
|
799
|
-
figsize: Tuple[float, float] =
|
|
800
|
+
figsize: Tuple[float, float] = FIG_SIZE,
|
|
800
801
|
) -> Figure:
|
|
801
802
|
"""Plot an area chart on a new figure.
|
|
802
803
|
|
|
@@ -815,7 +816,7 @@ class DataFrameAccessor:
|
|
|
815
816
|
style : StyleTemplate, optional
|
|
816
817
|
Styling template. The default is ``AREA_STYLE_TEMPLATE``.
|
|
817
818
|
figsize : tuple[float, float], optional
|
|
818
|
-
Figure size. The default is
|
|
819
|
+
Figure size. The default is FIG_SIZE.
|
|
819
820
|
|
|
820
821
|
Returns
|
|
821
822
|
-------
|
|
@@ -881,7 +882,7 @@ class DataFrameAccessor:
|
|
|
881
882
|
donut: bool = False,
|
|
882
883
|
title: Optional[str] = None,
|
|
883
884
|
style: StyleTemplate = PIE_STYLE_TEMPLATE,
|
|
884
|
-
figsize: Tuple[float, float] =
|
|
885
|
+
figsize: Tuple[float, float] = FIG_SIZE,
|
|
885
886
|
) -> Figure:
|
|
886
887
|
"""Plot pie or donut charts on a new figure.
|
|
887
888
|
|
|
@@ -898,7 +899,7 @@ class DataFrameAccessor:
|
|
|
898
899
|
style : StyleTemplate, optional
|
|
899
900
|
Styling template. The default is ``PIE_STYLE_TEMPLATE``.
|
|
900
901
|
figsize : tuple[float, float], optional
|
|
901
|
-
Figure size. The default is
|
|
902
|
+
Figure size. The default is FIG_SIZE.
|
|
902
903
|
|
|
903
904
|
Returns
|
|
904
905
|
-------
|
|
@@ -963,7 +964,7 @@ class DataFrameAccessor:
|
|
|
963
964
|
rows: int = 10,
|
|
964
965
|
title: Optional[str] = None,
|
|
965
966
|
style: StyleTemplate = PIE_STYLE_TEMPLATE,
|
|
966
|
-
figsize: Tuple[float, float] =
|
|
967
|
+
figsize: Tuple[float, float] = FIG_SIZE,
|
|
967
968
|
) -> Figure:
|
|
968
969
|
"""Plot waffle charts on a new figure.
|
|
969
970
|
|
|
@@ -980,7 +981,7 @@ class DataFrameAccessor:
|
|
|
980
981
|
style : StyleTemplate, optional
|
|
981
982
|
Styling template. The default is ``PIE_STYLE_TEMPLATE``.
|
|
982
983
|
figsize : tuple[float, float], optional
|
|
983
|
-
Figure size. The default is
|
|
984
|
+
Figure size. The default is FIG_SIZE.
|
|
984
985
|
|
|
985
986
|
Returns
|
|
986
987
|
-------
|
|
@@ -1087,7 +1088,7 @@ class DataFrameAccessor:
|
|
|
1087
1088
|
max_values: int = 20,
|
|
1088
1089
|
sort_by: Optional[str] = None,
|
|
1089
1090
|
ascending: bool = False,
|
|
1090
|
-
figsize: Tuple[float, float] =
|
|
1091
|
+
figsize: Tuple[float, float] = FIG_SIZE,
|
|
1091
1092
|
) -> Figure:
|
|
1092
1093
|
"""Plot a table of the DataFrame's data on a new figure.
|
|
1093
1094
|
|
|
@@ -1106,7 +1107,7 @@ class DataFrameAccessor:
|
|
|
1106
1107
|
ascending : bool, optional
|
|
1107
1108
|
Sort order. The default is `False`.
|
|
1108
1109
|
figsize : tuple[float, float], optional
|
|
1109
|
-
Figure size. The default is
|
|
1110
|
+
Figure size. The default is FIG_SIZE.
|
|
1110
1111
|
|
|
1111
1112
|
Returns
|
|
1112
1113
|
-------
|
|
@@ -1192,7 +1193,7 @@ class DataFrameAccessor:
|
|
|
1192
1193
|
sort_by: Optional[str] = None,
|
|
1193
1194
|
ascending: bool = False,
|
|
1194
1195
|
std: bool = False,
|
|
1195
|
-
figsize: Tuple[float, float] =
|
|
1196
|
+
figsize: Tuple[float, float] = FIG_SIZE,
|
|
1196
1197
|
) -> Figure:
|
|
1197
1198
|
"""Plot a time series on a new figure.
|
|
1198
1199
|
|
|
@@ -1217,7 +1218,7 @@ class DataFrameAccessor:
|
|
|
1217
1218
|
std : bool, optional
|
|
1218
1219
|
If True, plot the standard deviation. The default is `False`.
|
|
1219
1220
|
figsize : tuple[float, float], optional
|
|
1220
|
-
Figure size. The default is
|
|
1221
|
+
Figure size. The default is FIG_SIZE.
|
|
1221
1222
|
|
|
1222
1223
|
Returns
|
|
1223
1224
|
-------
|
|
@@ -1296,7 +1297,7 @@ class DataFrameAccessor:
|
|
|
1296
1297
|
max_words: int = 50,
|
|
1297
1298
|
stopwords: Optional[List[str]] = None,
|
|
1298
1299
|
random_state: Optional[int] = None,
|
|
1299
|
-
figsize: Tuple[float, float] =
|
|
1300
|
+
figsize: Tuple[float, float] = FIG_SIZE,
|
|
1300
1301
|
) -> Figure:
|
|
1301
1302
|
"""Plot a word cloud on a new figure.
|
|
1302
1303
|
|
|
@@ -1317,7 +1318,7 @@ class DataFrameAccessor:
|
|
|
1317
1318
|
random_state : int, optional
|
|
1318
1319
|
Seed for word placement. The default is ``None``.
|
|
1319
1320
|
figsize : tuple[float, float], optional
|
|
1320
|
-
Figure size. The default is
|
|
1321
|
+
Figure size. The default is FIG_SIZE.
|
|
1321
1322
|
|
|
1322
1323
|
Returns
|
|
1323
1324
|
-------
|
|
@@ -1447,7 +1448,7 @@ class DataFrameAccessor:
|
|
|
1447
1448
|
sort_by: Optional[str] = None,
|
|
1448
1449
|
ascending: bool = False,
|
|
1449
1450
|
node_list: Optional[List] = None,
|
|
1450
|
-
figsize: Tuple[float, float] =
|
|
1451
|
+
figsize: Tuple[float, float] = FIG_SIZE,
|
|
1451
1452
|
) -> Figure:
|
|
1452
1453
|
"""Plot a network graph on a new figure.
|
|
1453
1454
|
|
|
@@ -1470,7 +1471,7 @@ class DataFrameAccessor:
|
|
|
1470
1471
|
node_list : list, optional
|
|
1471
1472
|
List of nodes to include. If None, all nodes are used.
|
|
1472
1473
|
figsize : tuple[float, float], optional
|
|
1473
|
-
Figure size. The default is
|
|
1474
|
+
Figure size. The default is FIG_SIZE.
|
|
1474
1475
|
|
|
1475
1476
|
Returns
|
|
1476
1477
|
-------
|
|
@@ -1500,7 +1501,7 @@ class DataFrameAccessor:
|
|
|
1500
1501
|
sort_by: Optional[str] = None,
|
|
1501
1502
|
ascending: bool = False,
|
|
1502
1503
|
node_list: Optional[List] = None,
|
|
1503
|
-
figsize: Tuple[float, float] =
|
|
1504
|
+
figsize: Tuple[float, float] = FIG_SIZE,
|
|
1504
1505
|
n_cols: Optional[int] = None,
|
|
1505
1506
|
) -> Figure:
|
|
1506
1507
|
"""Plot network components on a new figure.
|
|
@@ -1524,7 +1525,7 @@ class DataFrameAccessor:
|
|
|
1524
1525
|
node_list : list, optional
|
|
1525
1526
|
List of nodes to include. If None, all nodes are used.
|
|
1526
1527
|
figsize : tuple[float, float], optional
|
|
1527
|
-
Figure size. The default is
|
|
1528
|
+
Figure size. The default is FIG_SIZE.
|
|
1528
1529
|
n_cols : int, optional
|
|
1529
1530
|
Number of columns for arranging component subplots.
|
|
1530
1531
|
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
"""Tests for word cloud visualizations."""
|
|
2
2
|
|
|
3
|
+
from typing import cast
|
|
4
|
+
|
|
3
5
|
import matplotlib.pyplot as plt
|
|
6
|
+
from matplotlib.axes import Axes
|
|
4
7
|
from matplotlib.figure import Figure
|
|
5
8
|
import numpy as np
|
|
6
9
|
|
|
@@ -16,15 +19,21 @@ def test_fplot_wordcloud(load_sample_df):
|
|
|
16
19
|
|
|
17
20
|
df = load_sample_df("wordcloud.csv")
|
|
18
21
|
|
|
19
|
-
fig =
|
|
20
|
-
|
|
22
|
+
fig = cast(
|
|
23
|
+
Figure,
|
|
24
|
+
fplot_wordcloud(
|
|
25
|
+
pd_df=df, text_column="country", weight_column="population", random_state=42
|
|
26
|
+
),
|
|
21
27
|
)
|
|
22
28
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
29
|
+
fig.canvas.draw()
|
|
30
|
+
ax = cast(Axes, fig.axes[0])
|
|
31
|
+
expected_size = int(
|
|
32
|
+
max(ax.get_window_extent().width, ax.get_window_extent().height)
|
|
33
|
+
)
|
|
34
|
+
image = ax.images[0].get_array()
|
|
26
35
|
assert image is not None
|
|
27
|
-
assert
|
|
36
|
+
assert image.shape[0] == image.shape[1] >= expected_size
|
|
28
37
|
|
|
29
38
|
|
|
30
39
|
def test_fplot_wordcloud_with_mask(load_sample_df):
|
|
@@ -33,15 +42,18 @@ def test_fplot_wordcloud_with_mask(load_sample_df):
|
|
|
33
42
|
df = load_sample_df("wordcloud.csv")
|
|
34
43
|
mask = create_circular_mask(size=200)
|
|
35
44
|
|
|
36
|
-
fig =
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
45
|
+
fig = cast(
|
|
46
|
+
Figure,
|
|
47
|
+
fplot_wordcloud(
|
|
48
|
+
pd_df=df,
|
|
49
|
+
text_column="country",
|
|
50
|
+
weight_column="population",
|
|
51
|
+
random_state=0,
|
|
52
|
+
mask=mask,
|
|
53
|
+
),
|
|
42
54
|
)
|
|
43
55
|
|
|
44
|
-
image = fig.axes[0].images[0].get_array()
|
|
56
|
+
image = cast(Axes, fig.axes[0]).images[0].get_array()
|
|
45
57
|
assert image is not None
|
|
46
58
|
assert tuple(image.shape[:2]) == mask.shape
|
|
47
59
|
|
|
@@ -51,6 +63,8 @@ def test_aplot_wordcloud(load_sample_df):
|
|
|
51
63
|
|
|
52
64
|
df = load_sample_df("wordcloud.csv")
|
|
53
65
|
fig, ax = plt.subplots()
|
|
66
|
+
fig = cast(Figure, fig)
|
|
67
|
+
ax = cast(Axes, ax)
|
|
54
68
|
|
|
55
69
|
result_ax = aplot_wordcloud(
|
|
56
70
|
ax=ax,
|
|
@@ -62,9 +76,13 @@ def test_aplot_wordcloud(load_sample_df):
|
|
|
62
76
|
|
|
63
77
|
assert result_ax is not None
|
|
64
78
|
assert ax is result_ax
|
|
79
|
+
fig.canvas.draw()
|
|
80
|
+
expected_size = int(
|
|
81
|
+
max(ax.get_window_extent().width, ax.get_window_extent().height)
|
|
82
|
+
)
|
|
65
83
|
image = result_ax.images[0].get_array()
|
|
66
84
|
assert image is not None
|
|
67
|
-
assert image.shape[0]
|
|
85
|
+
assert image.shape[0] == image.shape[1] >= expected_size
|
|
68
86
|
|
|
69
87
|
|
|
70
88
|
def test_create_circular_mask():
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|