MatplotLibAPI 4.0.1__py3-none-any.whl → 4.0.3__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.
- MatplotLibAPI/__init__.py +3 -4
- MatplotLibAPI/accessor.py +146 -545
- MatplotLibAPI/area.py +7 -38
- MatplotLibAPI/bar.py +3 -38
- MatplotLibAPI/base_plot.py +102 -21
- MatplotLibAPI/box_violin.py +5 -41
- MatplotLibAPI/bubble.py +31 -109
- MatplotLibAPI/composite.py +237 -17
- MatplotLibAPI/heatmap.py +72 -60
- MatplotLibAPI/histogram.py +2 -26
- MatplotLibAPI/network/__init__.py +2 -0
- MatplotLibAPI/network/constants.py +1 -0
- MatplotLibAPI/network/core.py +45 -56
- MatplotLibAPI/network/plot.py +95 -6
- MatplotLibAPI/pie.py +2 -39
- MatplotLibAPI/pivot.py +9 -34
- MatplotLibAPI/table.py +1 -29
- MatplotLibAPI/timeserie.py +2 -30
- MatplotLibAPI/treemap.py +3 -1
- MatplotLibAPI/types.py +6 -0
- MatplotLibAPI/waffle.py +1 -43
- MatplotLibAPI/word_cloud.py +5 -57
- {matplotlibapi-4.0.1.dist-info → matplotlibapi-4.0.3.dist-info}/METADATA +5 -5
- matplotlibapi-4.0.3.dist-info/RECORD +35 -0
- MatplotLibAPI/typing.py +0 -12
- MatplotLibAPI/utils.py +0 -85
- matplotlibapi-4.0.1.dist-info/RECORD +0 -36
- {matplotlibapi-4.0.1.dist-info → matplotlibapi-4.0.3.dist-info}/WHEEL +0 -0
- {matplotlibapi-4.0.1.dist-info → matplotlibapi-4.0.3.dist-info}/entry_points.txt +0 -0
- {matplotlibapi-4.0.1.dist-info → matplotlibapi-4.0.3.dist-info}/licenses/LICENSE +0 -0
MatplotLibAPI/network/core.py
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
from collections import defaultdict
|
|
4
4
|
from typing import Any, Dict, Iterable, List, Optional, Tuple, Union, cast
|
|
5
|
-
from pandas.api.extensions import register_dataframe_accessor
|
|
6
5
|
import matplotlib.pyplot as plt
|
|
7
6
|
import networkx as nx
|
|
8
7
|
import numpy as np
|
|
@@ -29,6 +28,14 @@ __all__ = [
|
|
|
29
28
|
]
|
|
30
29
|
|
|
31
30
|
|
|
31
|
+
def _compute_deciles(weights: Iterable[float]) -> Optional[np.ndarray]:
|
|
32
|
+
"""Return deciles for ``weights`` or ``None`` when empty."""
|
|
33
|
+
weights_arr = np.asarray(list(weights), dtype=float)
|
|
34
|
+
if weights_arr.size == 0:
|
|
35
|
+
return None
|
|
36
|
+
return np.percentile(weights_arr, _WEIGHT_PERCENTILES)
|
|
37
|
+
|
|
38
|
+
|
|
32
39
|
class NodeView(nx.classes.reportviews.NodeView):
|
|
33
40
|
"""Extended node view with convenience helpers."""
|
|
34
41
|
|
|
@@ -235,7 +242,6 @@ class EdgeView(nx.classes.reportviews.EdgeView):
|
|
|
235
242
|
return pd.DataFrame(data)
|
|
236
243
|
|
|
237
244
|
|
|
238
|
-
@register_dataframe_accessor("network")
|
|
239
245
|
class NetworkGraph(BasePlot):
|
|
240
246
|
"""Custom graph class based on NetworkX's ``Graph``.
|
|
241
247
|
|
|
@@ -520,6 +526,9 @@ class NetworkGraph(BasePlot):
|
|
|
520
526
|
max_font_size: int = _DEFAULT["MAX_FONT_SIZE"],
|
|
521
527
|
min_font_size: int = _DEFAULT["MIN_FONT_SIZE"],
|
|
522
528
|
edge_weight_col: str = "weight",
|
|
529
|
+
*,
|
|
530
|
+
node_deciles: Optional[np.ndarray],
|
|
531
|
+
edge_deciles: Optional[np.ndarray],
|
|
523
532
|
) -> Tuple[List[float], List[float], Dict[int, List[str]]]:
|
|
524
533
|
"""Calculate node, edge and font sizes based on weights.
|
|
525
534
|
|
|
@@ -536,7 +545,11 @@ class NetworkGraph(BasePlot):
|
|
|
536
545
|
min_font_size : int, optional
|
|
537
546
|
Lower bound for font size. The default is `_DEFAULT["MIN_FONT_SIZE"]`.
|
|
538
547
|
edge_weight_col : str, optional
|
|
539
|
-
|
|
548
|
+
Edge attribute used for weighting. The default is "weight".
|
|
549
|
+
node_deciles : np.ndarray, optional
|
|
550
|
+
Node-weight deciles used to scale node and font sizes.
|
|
551
|
+
edge_deciles : np.ndarray, optional
|
|
552
|
+
Edge-weight deciles used to scale edge widths.
|
|
540
553
|
|
|
541
554
|
Returns
|
|
542
555
|
-------
|
|
@@ -547,11 +560,6 @@ class NetworkGraph(BasePlot):
|
|
|
547
560
|
node_weights = [
|
|
548
561
|
data.get(edge_weight_col, 1) for node, data in self.node_view(data=True)
|
|
549
562
|
]
|
|
550
|
-
node_deciles = (
|
|
551
|
-
np.percentile(np.array(node_weights), _WEIGHT_PERCENTILES)
|
|
552
|
-
if node_weights
|
|
553
|
-
else None
|
|
554
|
-
)
|
|
555
563
|
node_size = _scale_weights(
|
|
556
564
|
weights=node_weights,
|
|
557
565
|
scale_max=max_node_size,
|
|
@@ -563,7 +571,11 @@ class NetworkGraph(BasePlot):
|
|
|
563
571
|
edge_weights = [
|
|
564
572
|
data.get(edge_weight_col, 1) for _, _, data in self.edge_view(data=True)
|
|
565
573
|
]
|
|
566
|
-
edges_width = _scale_weights(
|
|
574
|
+
edges_width = _scale_weights(
|
|
575
|
+
weights=edge_weights,
|
|
576
|
+
scale_max=max_edge_width,
|
|
577
|
+
deciles=edge_deciles,
|
|
578
|
+
)
|
|
567
579
|
|
|
568
580
|
# Scale the normalized node weights within the desired range of font sizes
|
|
569
581
|
node_size_dict = dict(
|
|
@@ -683,7 +695,7 @@ class NetworkGraph(BasePlot):
|
|
|
683
695
|
def aplot(
|
|
684
696
|
self,
|
|
685
697
|
title: Optional[str] = None,
|
|
686
|
-
style: StyleTemplate =
|
|
698
|
+
style: Optional[StyleTemplate] = None,
|
|
687
699
|
edge_weight_col: str = "weight",
|
|
688
700
|
layout_seed: Optional[int] = _DEFAULT["SPRING_LAYOUT_SEED"],
|
|
689
701
|
ax: Optional[Axes] = None,
|
|
@@ -709,6 +721,8 @@ class NetworkGraph(BasePlot):
|
|
|
709
721
|
Axes
|
|
710
722
|
Matplotlib axes with the plotted network.
|
|
711
723
|
"""
|
|
724
|
+
if not style:
|
|
725
|
+
style = NETWORK_STYLE_TEMPLATE
|
|
712
726
|
sns.set_palette(style.palette)
|
|
713
727
|
if ax is None:
|
|
714
728
|
ax = cast(Axes, plt.gca())
|
|
@@ -716,6 +730,7 @@ class NetworkGraph(BasePlot):
|
|
|
716
730
|
isolated_nodes = list(nx.isolates(self._nx_graph))
|
|
717
731
|
graph_nx = self._nx_graph
|
|
718
732
|
if isolated_nodes:
|
|
733
|
+
|
|
719
734
|
graph_nx = graph_nx.copy()
|
|
720
735
|
graph_nx.remove_nodes_from(isolated_nodes)
|
|
721
736
|
|
|
@@ -733,6 +748,14 @@ class NetworkGraph(BasePlot):
|
|
|
733
748
|
|
|
734
749
|
mapped_min_font_size = style.font_mapping.get(0)
|
|
735
750
|
mapped_max_font_size = style.font_mapping.get(4)
|
|
751
|
+
node_weights = [
|
|
752
|
+
data.get(edge_weight_col, 1) for _, data in graph.node_view(data=True)
|
|
753
|
+
]
|
|
754
|
+
edge_weights = [
|
|
755
|
+
data.get(edge_weight_col, 1) for _, _, data in graph.edge_view(data=True)
|
|
756
|
+
]
|
|
757
|
+
node_deciles = _compute_deciles(node_weights)
|
|
758
|
+
edge_deciles = _compute_deciles(edge_weights)
|
|
736
759
|
|
|
737
760
|
node_sizes, edge_widths, font_sizes = graph.layout(
|
|
738
761
|
min_node_size=_DEFAULT["MIN_NODE_SIZE"],
|
|
@@ -749,6 +772,8 @@ class NetworkGraph(BasePlot):
|
|
|
749
772
|
else _DEFAULT["MAX_FONT_SIZE"]
|
|
750
773
|
),
|
|
751
774
|
edge_weight_col=edge_weight_col,
|
|
775
|
+
node_deciles=node_deciles,
|
|
776
|
+
edge_deciles=edge_deciles,
|
|
752
777
|
)
|
|
753
778
|
pos = graph.compute_positions(seed=layout_seed)
|
|
754
779
|
# nodes
|
|
@@ -791,51 +816,10 @@ class NetworkGraph(BasePlot):
|
|
|
791
816
|
|
|
792
817
|
return ax
|
|
793
818
|
|
|
794
|
-
def fplot(
|
|
795
|
-
self,
|
|
796
|
-
title: Optional[str] = None,
|
|
797
|
-
style: StyleTemplate = NETWORK_STYLE_TEMPLATE,
|
|
798
|
-
layout_seed: Optional[int] = _DEFAULT["SPRING_LAYOUT_SEED"],
|
|
799
|
-
figsize: Tuple[float, float] = FIG_SIZE,
|
|
800
|
-
) -> Figure:
|
|
801
|
-
"""Plot the graph using node and edge weights.
|
|
802
|
-
|
|
803
|
-
Parameters
|
|
804
|
-
----------
|
|
805
|
-
title : str, optional
|
|
806
|
-
Plot title.
|
|
807
|
-
style : StyleTemplate, optional
|
|
808
|
-
Style configuration. The default is `NETWORK_STYLE_TEMPLATE`.
|
|
809
|
-
edge_weight_col : str, optional
|
|
810
|
-
Edge attribute used for weighting. The default is "weight".
|
|
811
|
-
layout_seed : int, optional
|
|
812
|
-
Seed for the spring layout used to place nodes. The default is ``_DEFAULT["SPRING_LAYOUT_SEED"]``.
|
|
813
|
-
|
|
814
|
-
Returns
|
|
815
|
-
-------
|
|
816
|
-
Figure
|
|
817
|
-
Matplotlib figure with the plotted network.
|
|
818
|
-
"""
|
|
819
|
-
fig = Figure(
|
|
820
|
-
figsize=figsize,
|
|
821
|
-
facecolor=style.background_color,
|
|
822
|
-
edgecolor=style.background_color,
|
|
823
|
-
)
|
|
824
|
-
ax = fig.add_subplot(111)
|
|
825
|
-
ax.set_facecolor(style.background_color)
|
|
826
|
-
self.aplot(
|
|
827
|
-
title=title,
|
|
828
|
-
style=style,
|
|
829
|
-
edge_weight_col="",
|
|
830
|
-
layout_seed=layout_seed,
|
|
831
|
-
ax=ax,
|
|
832
|
-
)
|
|
833
|
-
return fig
|
|
834
|
-
|
|
835
819
|
def aplot_connected_components(
|
|
836
820
|
self,
|
|
837
821
|
title: Optional[str] = None,
|
|
838
|
-
style: StyleTemplate =
|
|
822
|
+
style: Optional[StyleTemplate] = None,
|
|
839
823
|
edge_weight_col: str = "weight",
|
|
840
824
|
layout_seed: Optional[int] = _DEFAULT["SPRING_LAYOUT_SEED"],
|
|
841
825
|
axes: Optional[np.ndarray] = None,
|
|
@@ -864,6 +848,8 @@ class NetworkGraph(BasePlot):
|
|
|
864
848
|
or created, the flattened array of axes is returned; otherwise, a
|
|
865
849
|
single Axes is returned.
|
|
866
850
|
"""
|
|
851
|
+
if not style:
|
|
852
|
+
style = NETWORK_STYLE_TEMPLATE
|
|
867
853
|
sns.set_palette(style.palette)
|
|
868
854
|
|
|
869
855
|
graph = self
|
|
@@ -912,9 +898,10 @@ class NetworkGraph(BasePlot):
|
|
|
912
898
|
def fplot_connected_components(
|
|
913
899
|
self,
|
|
914
900
|
title: Optional[str] = None,
|
|
915
|
-
style: StyleTemplate =
|
|
901
|
+
style: Optional[StyleTemplate] = None,
|
|
916
902
|
edge_weight_col: str = "weight",
|
|
917
903
|
layout_seed: Optional[int] = _DEFAULT["SPRING_LAYOUT_SEED"],
|
|
904
|
+
figsize: Tuple[float, float] = FIG_SIZE,
|
|
918
905
|
) -> Figure:
|
|
919
906
|
"""Plot all connected components of the graph.
|
|
920
907
|
|
|
@@ -934,9 +921,11 @@ class NetworkGraph(BasePlot):
|
|
|
934
921
|
Figure
|
|
935
922
|
Matplotlib figure with the plotted network.
|
|
936
923
|
"""
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
924
|
+
if not style:
|
|
925
|
+
style = NETWORK_STYLE_TEMPLATE
|
|
926
|
+
|
|
927
|
+
fig, ax = BasePlot.create_fig(figsize=figsize, style=style)
|
|
928
|
+
|
|
940
929
|
self.aplot_connected_components(
|
|
941
930
|
title=title,
|
|
942
931
|
style=style,
|
MatplotLibAPI/network/plot.py
CHANGED
|
@@ -20,6 +20,7 @@ from ..style_template import (
|
|
|
20
20
|
)
|
|
21
21
|
|
|
22
22
|
__all__ = [
|
|
23
|
+
"trim_low_degree_nodes",
|
|
23
24
|
"aplot_network",
|
|
24
25
|
"aplot_network_node",
|
|
25
26
|
"aplot_network_components",
|
|
@@ -29,6 +30,90 @@ __all__ = [
|
|
|
29
30
|
]
|
|
30
31
|
|
|
31
32
|
|
|
33
|
+
def trim_low_degree_nodes(
|
|
34
|
+
pandas_df: pd.DataFrame,
|
|
35
|
+
source: str = "source",
|
|
36
|
+
target: str = "target",
|
|
37
|
+
min_degree: int = 2,
|
|
38
|
+
recursive: bool = True,
|
|
39
|
+
) -> pd.DataFrame:
|
|
40
|
+
"""Return an edge list filtered by minimum undirected node degree.
|
|
41
|
+
|
|
42
|
+
The function preserves all original columns and only filters rows (edges).
|
|
43
|
+
Degree is computed from the edge list as an undirected multigraph:
|
|
44
|
+
duplicate edges contribute repeatedly, and self-loops contribute ``2`` to
|
|
45
|
+
the node degree (once from ``source`` and once from ``target``).
|
|
46
|
+
|
|
47
|
+
Parameters
|
|
48
|
+
----------
|
|
49
|
+
pandas_df : pd.DataFrame
|
|
50
|
+
Edge list DataFrame.
|
|
51
|
+
source : str, optional
|
|
52
|
+
Source node column name. The default is ``"source"``.
|
|
53
|
+
target : str, optional
|
|
54
|
+
Target node column name. The default is ``"target"``.
|
|
55
|
+
min_degree : int, optional
|
|
56
|
+
Minimum undirected degree required for each endpoint. The default is ``2``.
|
|
57
|
+
Use ``0`` to disable filtering.
|
|
58
|
+
recursive : bool, optional
|
|
59
|
+
Whether to recursively prune until stable. The default is ``True``.
|
|
60
|
+
If ``False``, the filter is applied in a single pass using degrees
|
|
61
|
+
from the original edge list.
|
|
62
|
+
|
|
63
|
+
Returns
|
|
64
|
+
-------
|
|
65
|
+
pd.DataFrame
|
|
66
|
+
Filtered copy of ``pandas_df``.
|
|
67
|
+
|
|
68
|
+
Raises
|
|
69
|
+
------
|
|
70
|
+
AttributeError
|
|
71
|
+
If required columns are missing.
|
|
72
|
+
ValueError
|
|
73
|
+
If ``min_degree`` is negative.
|
|
74
|
+
|
|
75
|
+
Examples
|
|
76
|
+
--------
|
|
77
|
+
>>> trim_low_degree_nodes(df, source="src", target="dst", min_degree=2)
|
|
78
|
+
"""
|
|
79
|
+
validate_dataframe(pandas_df, cols=[source, target])
|
|
80
|
+
if min_degree < 0:
|
|
81
|
+
raise ValueError("min_degree must be greater than or equal to 0.")
|
|
82
|
+
|
|
83
|
+
result = pandas_df.copy()
|
|
84
|
+
if result.empty or min_degree == 0:
|
|
85
|
+
return result
|
|
86
|
+
|
|
87
|
+
def _filter_once(edges_df: pd.DataFrame) -> pd.DataFrame:
|
|
88
|
+
valid_endpoints = edges_df[source].notna() & edges_df[target].notna()
|
|
89
|
+
valid_edges = edges_df.loc[valid_endpoints]
|
|
90
|
+
if valid_edges.empty:
|
|
91
|
+
return valid_edges.copy()
|
|
92
|
+
|
|
93
|
+
degree = cast(
|
|
94
|
+
pd.Series,
|
|
95
|
+
pd.concat(
|
|
96
|
+
[valid_edges[source], valid_edges[target]], ignore_index=True
|
|
97
|
+
).value_counts(),
|
|
98
|
+
)
|
|
99
|
+
keep_nodes = {
|
|
100
|
+
node for node, node_degree in degree.items() if node_degree >= min_degree
|
|
101
|
+
}
|
|
102
|
+
keep_mask = valid_edges[source].isin(keep_nodes) & valid_edges[target].isin(
|
|
103
|
+
keep_nodes
|
|
104
|
+
)
|
|
105
|
+
return valid_edges.loc[keep_mask].copy()
|
|
106
|
+
|
|
107
|
+
if not recursive:
|
|
108
|
+
return _filter_once(result)
|
|
109
|
+
|
|
110
|
+
while True:
|
|
111
|
+
filtered = _filter_once(result)
|
|
112
|
+
if len(filtered) == len(result):
|
|
113
|
+
return filtered
|
|
114
|
+
result = filtered
|
|
115
|
+
|
|
116
|
+
|
|
32
117
|
def _sanitize_node_dataframe(
|
|
33
118
|
node_df: Optional[pd.DataFrame],
|
|
34
119
|
edge_df: pd.DataFrame,
|
|
@@ -182,7 +267,7 @@ def aplot_network(
|
|
|
182
267
|
edge_target_col: str = "target",
|
|
183
268
|
edge_weight_col: str = "weight",
|
|
184
269
|
title: Optional[str] = None,
|
|
185
|
-
style: StyleTemplate =
|
|
270
|
+
style: Optional[StyleTemplate] = None,
|
|
186
271
|
layout_seed: Optional[int] = _DEFAULT["SPRING_LAYOUT_SEED"],
|
|
187
272
|
ax: Optional[Axes] = None,
|
|
188
273
|
) -> Axes:
|
|
@@ -233,7 +318,7 @@ def aplot_network_node(
|
|
|
233
318
|
edge_target_col: str = "target",
|
|
234
319
|
edge_weight_col: str = "weight",
|
|
235
320
|
title: Optional[str] = None,
|
|
236
|
-
style: StyleTemplate =
|
|
321
|
+
style: Optional[StyleTemplate] = None,
|
|
237
322
|
ax: Optional[Axes] = None,
|
|
238
323
|
layout_seed: Optional[int] = _DEFAULT["SPRING_LAYOUT_SEED"],
|
|
239
324
|
) -> Axes:
|
|
@@ -308,7 +393,7 @@ def aplot_network_components(
|
|
|
308
393
|
ascending: bool = False,
|
|
309
394
|
node_df: Optional[pd.DataFrame] = None,
|
|
310
395
|
title: Optional[str] = None,
|
|
311
|
-
style: StyleTemplate =
|
|
396
|
+
style: Optional[StyleTemplate] = None,
|
|
312
397
|
layout_seed: Optional[int] = _DEFAULT["SPRING_LAYOUT_SEED"],
|
|
313
398
|
axes: Optional[np.ndarray] = None,
|
|
314
399
|
) -> None:
|
|
@@ -368,7 +453,7 @@ def fplot_network(
|
|
|
368
453
|
edge_target_col: str = "target",
|
|
369
454
|
edge_weight_col: str = "weight",
|
|
370
455
|
title: Optional[str] = None,
|
|
371
|
-
style: StyleTemplate =
|
|
456
|
+
style: Optional[StyleTemplate] = None,
|
|
372
457
|
layout_seed: Optional[int] = _DEFAULT["SPRING_LAYOUT_SEED"],
|
|
373
458
|
figsize: Tuple[float, float] = FIG_SIZE,
|
|
374
459
|
) -> Figure:
|
|
@@ -427,7 +512,7 @@ def fplot_network_node(
|
|
|
427
512
|
edge_target_col: str = "target",
|
|
428
513
|
edge_weight_col: str = "weight",
|
|
429
514
|
title: Optional[str] = None,
|
|
430
|
-
style: StyleTemplate =
|
|
515
|
+
style: Optional[StyleTemplate] = None,
|
|
431
516
|
figsize: Tuple[float, float] = FIG_SIZE,
|
|
432
517
|
layout_seed: Optional[int] = _DEFAULT["SPRING_LAYOUT_SEED"],
|
|
433
518
|
) -> Figure:
|
|
@@ -478,6 +563,8 @@ def fplot_network_node(
|
|
|
478
563
|
ValueError
|
|
479
564
|
If ``node`` is not present in the prepared graph.
|
|
480
565
|
"""
|
|
566
|
+
if not style:
|
|
567
|
+
style = NETWORK_STYLE_TEMPLATE
|
|
481
568
|
fig = cast(Figure, plt.figure(figsize=figsize))
|
|
482
569
|
fig.set_facecolor(style.background_color)
|
|
483
570
|
ax = fig.add_subplot(111)
|
|
@@ -501,7 +588,7 @@ def fplot_network_components(
|
|
|
501
588
|
edge_target_col: str = "target",
|
|
502
589
|
edge_weight_col: str = "weight",
|
|
503
590
|
title: Optional[str] = None,
|
|
504
|
-
style: StyleTemplate =
|
|
591
|
+
style: Optional[StyleTemplate] = None,
|
|
505
592
|
layout_seed: Optional[int] = _DEFAULT["SPRING_LAYOUT_SEED"],
|
|
506
593
|
figsize: Tuple[float, float] = FIG_SIZE,
|
|
507
594
|
n_cols: Optional[int] = None,
|
|
@@ -554,6 +641,8 @@ def fplot_network_components(
|
|
|
554
641
|
If ``node_df`` is provided but none of its nodes appear as sources or
|
|
555
642
|
targets in ``pd_df``.
|
|
556
643
|
"""
|
|
644
|
+
if not style:
|
|
645
|
+
style = NETWORK_STYLE_TEMPLATE
|
|
557
646
|
graph = NetworkGraph(
|
|
558
647
|
pd_df=pd_df,
|
|
559
648
|
source=edge_source_col,
|
MatplotLibAPI/pie.py
CHANGED
|
@@ -11,7 +11,6 @@ from matplotlib.figure import Figure
|
|
|
11
11
|
from .base_plot import BasePlot
|
|
12
12
|
|
|
13
13
|
from .style_template import PIE_STYLE_TEMPLATE, StyleTemplate, validate_dataframe
|
|
14
|
-
from .utils import _get_axis, _merge_kwargs
|
|
15
14
|
|
|
16
15
|
__all__ = ["PIE_STYLE_TEMPLATE", "aplot_pie", "fplot_pie"]
|
|
17
16
|
|
|
@@ -63,7 +62,7 @@ class PieChart(BasePlot):
|
|
|
63
62
|
"""
|
|
64
63
|
labels = self._obj[self.category].astype(str).tolist()
|
|
65
64
|
sizes = self._obj[self.value]
|
|
66
|
-
plot_ax =
|
|
65
|
+
plot_ax = BasePlot.get_axis(ax)
|
|
67
66
|
wedgeprops: Optional[Dict[str, Any]] = None
|
|
68
67
|
if donut:
|
|
69
68
|
wedgeprops = {"width": 0.3}
|
|
@@ -74,48 +73,12 @@ class PieChart(BasePlot):
|
|
|
74
73
|
"wedgeprops": wedgeprops,
|
|
75
74
|
"textprops": {"color": style.font_color, "fontsize": style.font_size},
|
|
76
75
|
}
|
|
77
|
-
plot_ax.pie(sizes, **
|
|
76
|
+
plot_ax.pie(sizes, **BasePlot.merge_kwargs(pie_kwargs, kwargs))
|
|
78
77
|
plot_ax.axis("equal")
|
|
79
78
|
if title:
|
|
80
79
|
plot_ax.set_title(title)
|
|
81
80
|
return plot_ax
|
|
82
81
|
|
|
83
|
-
def fplot(
|
|
84
|
-
self,
|
|
85
|
-
donut: bool = False,
|
|
86
|
-
title: Optional[str] = None,
|
|
87
|
-
style: StyleTemplate = PIE_STYLE_TEMPLATE,
|
|
88
|
-
figsize: Tuple[float, float] = (8, 8),
|
|
89
|
-
) -> Figure:
|
|
90
|
-
"""Plot a pie or donut chart on a new figure.
|
|
91
|
-
|
|
92
|
-
Parameters
|
|
93
|
-
----------
|
|
94
|
-
donut : bool, optional
|
|
95
|
-
If True, render a donut chart. The default is False.
|
|
96
|
-
title : str, optional
|
|
97
|
-
Title for the plot. The default is None.
|
|
98
|
-
style : StyleTemplate, optional
|
|
99
|
-
Style template for the plot. The default is PIE_STYLE_TEMPLATE.
|
|
100
|
-
figsize : tuple[float, float], optional
|
|
101
|
-
Figure size. The default is (8, 8).
|
|
102
|
-
|
|
103
|
-
Returns
|
|
104
|
-
-------
|
|
105
|
-
Figure
|
|
106
|
-
The Matplotlib figure containing the pie or donut chart.
|
|
107
|
-
"""
|
|
108
|
-
fig = Figure(
|
|
109
|
-
figsize=figsize,
|
|
110
|
-
facecolor=style.background_color,
|
|
111
|
-
edgecolor=style.background_color,
|
|
112
|
-
)
|
|
113
|
-
ax = fig.add_subplot(111)
|
|
114
|
-
ax.set_facecolor(style.background_color)
|
|
115
|
-
fig.set_facecolor(style.background_color)
|
|
116
|
-
self.aplot(donut=donut, title=title, style=style, ax=ax)
|
|
117
|
-
return fig
|
|
118
|
-
|
|
119
82
|
|
|
120
83
|
def aplot_pie(
|
|
121
84
|
pd_df: pd.DataFrame,
|
MatplotLibAPI/pivot.py
CHANGED
|
@@ -9,7 +9,6 @@ from matplotlib.axes import Axes
|
|
|
9
9
|
from matplotlib.figure import Figure
|
|
10
10
|
|
|
11
11
|
from .base_plot import BasePlot
|
|
12
|
-
from .utils import _merge_kwargs
|
|
13
12
|
|
|
14
13
|
from .style_template import (
|
|
15
14
|
FIG_SIZE,
|
|
@@ -103,8 +102,7 @@ class PivotBarChart(BasePlot):
|
|
|
103
102
|
ascending=ascending,
|
|
104
103
|
)
|
|
105
104
|
|
|
106
|
-
|
|
107
|
-
ax = cast(Axes, plt.gca())
|
|
105
|
+
plot_ax = BasePlot.get_axis(ax)
|
|
108
106
|
|
|
109
107
|
if pd.api.types.is_datetime64_any_dtype(pivot_df[self.x]):
|
|
110
108
|
pivot_df[self.x] = pivot_df[self.x].dt.strftime("%Y-%m-%d")
|
|
@@ -113,47 +111,24 @@ class PivotBarChart(BasePlot):
|
|
|
113
111
|
"kind": "bar",
|
|
114
112
|
"x": self.x,
|
|
115
113
|
"stacked": self.stacked,
|
|
116
|
-
"ax":
|
|
114
|
+
"ax": plot_ax,
|
|
117
115
|
"alpha": 0.7,
|
|
118
116
|
}
|
|
119
|
-
pivot_df.plot(**
|
|
117
|
+
pivot_df.plot(**BasePlot.merge_kwargs(plot_kwargs, kwargs))
|
|
120
118
|
|
|
121
|
-
|
|
122
|
-
|
|
119
|
+
plot_ax.set_ylabel(string_formatter(self.y))
|
|
120
|
+
plot_ax.set_xlabel(string_formatter(self.x))
|
|
123
121
|
if title:
|
|
124
|
-
|
|
122
|
+
plot_ax.set_title(title)
|
|
125
123
|
|
|
126
|
-
|
|
124
|
+
plot_ax.legend(
|
|
127
125
|
fontsize=style.font_size - 2,
|
|
128
126
|
title_fontsize=style.font_size + 2,
|
|
129
127
|
labelcolor="linecolor",
|
|
130
128
|
facecolor=style.background_color,
|
|
131
129
|
)
|
|
132
|
-
|
|
133
|
-
return
|
|
134
|
-
|
|
135
|
-
def fplot(
|
|
136
|
-
self,
|
|
137
|
-
title: Optional[str] = None,
|
|
138
|
-
style: StyleTemplate = PIVOTBARS_STYLE_TEMPLATE,
|
|
139
|
-
sort_by: Optional[str] = None,
|
|
140
|
-
ascending: bool = False,
|
|
141
|
-
ax: Optional[Axes] = None,
|
|
142
|
-
figsize: Tuple[float, float] = FIG_SIZE,
|
|
143
|
-
**kwargs: Any,
|
|
144
|
-
) -> Figure:
|
|
145
|
-
|
|
146
|
-
fig = Figure(
|
|
147
|
-
figsize=figsize,
|
|
148
|
-
facecolor=style.background_color,
|
|
149
|
-
edgecolor=style.background_color,
|
|
150
|
-
)
|
|
151
|
-
ax = fig.add_subplot(111)
|
|
152
|
-
ax.set_facecolor(style.background_color)
|
|
153
|
-
self.aplot(
|
|
154
|
-
title=title, style=style, sort_by=sort_by, ascending=ascending, ax=ax
|
|
155
|
-
)
|
|
156
|
-
return fig
|
|
130
|
+
plot_ax.tick_params(axis="x", rotation=90)
|
|
131
|
+
return plot_ax
|
|
157
132
|
|
|
158
133
|
|
|
159
134
|
def aplot_pivoted_bars(
|
MatplotLibAPI/table.py
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
from typing import Any, List, Optional, Tuple
|
|
4
4
|
import pandas as pd
|
|
5
|
-
import matplotlib.pyplot as plt
|
|
6
5
|
from matplotlib.axes import Axes
|
|
7
6
|
from matplotlib.figure import Figure
|
|
8
7
|
from matplotlib.transforms import Bbox
|
|
@@ -10,7 +9,6 @@ from matplotlib.table import Table
|
|
|
10
9
|
|
|
11
10
|
from .base_plot import BasePlot
|
|
12
11
|
|
|
13
|
-
from .utils import _get_axis
|
|
14
12
|
|
|
15
13
|
from .style_template import (
|
|
16
14
|
FIG_SIZE,
|
|
@@ -62,7 +60,7 @@ class TablePlot(BasePlot):
|
|
|
62
60
|
ax: Optional[Axes] = None,
|
|
63
61
|
**kwargs: Any,
|
|
64
62
|
) -> Axes:
|
|
65
|
-
plot_ax =
|
|
63
|
+
plot_ax = BasePlot.get_axis(ax)
|
|
66
64
|
|
|
67
65
|
if sort_by is None:
|
|
68
66
|
sort_by = self.cols[0]
|
|
@@ -101,32 +99,6 @@ class TablePlot(BasePlot):
|
|
|
101
99
|
plot_ax.title.set_position((0.5, 1.05))
|
|
102
100
|
return plot_ax
|
|
103
101
|
|
|
104
|
-
def fplot(
|
|
105
|
-
self,
|
|
106
|
-
title: Optional[str] = None,
|
|
107
|
-
style: StyleTemplate = TABLE_STYLE_TEMPLATE,
|
|
108
|
-
sort_by: Optional[str] = None,
|
|
109
|
-
ascending: bool = False,
|
|
110
|
-
max_values: int = 20,
|
|
111
|
-
figsize: Tuple[float, float] = FIG_SIZE,
|
|
112
|
-
) -> Figure:
|
|
113
|
-
fig = Figure(
|
|
114
|
-
figsize=figsize,
|
|
115
|
-
facecolor=style.background_color,
|
|
116
|
-
edgecolor=style.background_color,
|
|
117
|
-
)
|
|
118
|
-
ax = fig.add_subplot(111)
|
|
119
|
-
ax.set_facecolor(style.background_color)
|
|
120
|
-
self.aplot(
|
|
121
|
-
title=title,
|
|
122
|
-
style=style,
|
|
123
|
-
sort_by=sort_by,
|
|
124
|
-
ascending=ascending,
|
|
125
|
-
max_values=max_values,
|
|
126
|
-
ax=ax,
|
|
127
|
-
)
|
|
128
|
-
return fig
|
|
129
|
-
|
|
130
102
|
|
|
131
103
|
def aplot_table(
|
|
132
104
|
pd_df: pd.DataFrame,
|
MatplotLibAPI/timeserie.py
CHANGED
|
@@ -9,7 +9,7 @@ from matplotlib.axes import Axes
|
|
|
9
9
|
from matplotlib.figure import Figure
|
|
10
10
|
|
|
11
11
|
from .base_plot import BasePlot
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
from .style_template import (
|
|
14
14
|
TIMESERIE_STYLE_TEMPLATE,
|
|
15
15
|
FIG_SIZE,
|
|
@@ -210,7 +210,7 @@ class TimeSeriePlot(BasePlot):
|
|
|
210
210
|
format_funcs = format_func(
|
|
211
211
|
style.format_funcs, label=self.label, x=self.x, y=self.y
|
|
212
212
|
)
|
|
213
|
-
plot_ax =
|
|
213
|
+
plot_ax = BasePlot.get_axis(ax)
|
|
214
214
|
_plot_timeserie_lines(
|
|
215
215
|
plot_ax, df, self.label, self.x, self.y, std, style, format_funcs
|
|
216
216
|
)
|
|
@@ -222,34 +222,6 @@ class TimeSeriePlot(BasePlot):
|
|
|
222
222
|
)
|
|
223
223
|
return plot_ax
|
|
224
224
|
|
|
225
|
-
def fplot(
|
|
226
|
-
self,
|
|
227
|
-
title: Optional[str] = None,
|
|
228
|
-
style: StyleTemplate = TIMESERIE_STYLE_TEMPLATE,
|
|
229
|
-
max_values: int = 100,
|
|
230
|
-
sort_by: Optional[str] = None,
|
|
231
|
-
ascending: bool = False,
|
|
232
|
-
std: bool = False,
|
|
233
|
-
figsize: Tuple[float, float] = FIG_SIZE,
|
|
234
|
-
) -> Figure:
|
|
235
|
-
fig = Figure(
|
|
236
|
-
figsize=figsize,
|
|
237
|
-
facecolor=style.background_color,
|
|
238
|
-
edgecolor=style.background_color,
|
|
239
|
-
)
|
|
240
|
-
ax = fig.add_subplot(111)
|
|
241
|
-
ax.set_facecolor(style.background_color)
|
|
242
|
-
self.aplot(
|
|
243
|
-
title=title,
|
|
244
|
-
style=style,
|
|
245
|
-
max_values=max_values,
|
|
246
|
-
sort_by=sort_by,
|
|
247
|
-
ascending=ascending,
|
|
248
|
-
std=std,
|
|
249
|
-
ax=ax,
|
|
250
|
-
)
|
|
251
|
-
return fig
|
|
252
|
-
|
|
253
225
|
|
|
254
226
|
def aplot_timeserie(
|
|
255
227
|
pd_df: pd.DataFrame,
|
MatplotLibAPI/treemap.py
CHANGED
|
@@ -19,7 +19,7 @@ def aplot_treemap(
|
|
|
19
19
|
pd_df: pd.DataFrame,
|
|
20
20
|
path: str,
|
|
21
21
|
values: str,
|
|
22
|
-
style: StyleTemplate =
|
|
22
|
+
style: Optional[StyleTemplate] = None,
|
|
23
23
|
title: Optional[str] = None,
|
|
24
24
|
color: Optional[str] = None,
|
|
25
25
|
sort_by: Optional[str] = None,
|
|
@@ -62,6 +62,8 @@ def aplot_treemap(
|
|
|
62
62
|
|
|
63
63
|
sort_col = sort_by or values
|
|
64
64
|
df = pd_df.sort_values(by=sort_col, ascending=ascending)[cols].head(max_values)
|
|
65
|
+
if not style:
|
|
66
|
+
style = TREEMAP_STYLE_TEMPLATE
|
|
65
67
|
data: Dict[str, Any] = {
|
|
66
68
|
"labels": df[path],
|
|
67
69
|
"parents": [""] * len(df),
|