MatplotLibAPI 3.1.2__tar.gz → 3.2.1__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 (20) hide show
  1. {matplotlibapi-3.1.2 → matplotlibapi-3.2.1}/MatplotLibAPI/Bubble.py +1 -1
  2. {matplotlibapi-3.1.2 → matplotlibapi-3.2.1}/MatplotLibAPI/Composite.py +1 -1
  3. {matplotlibapi-3.1.2 → matplotlibapi-3.2.1}/MatplotLibAPI/Network.py +1 -1
  4. matplotlibapi-3.2.1/MatplotLibAPI/StyleTemplate.py +169 -0
  5. {matplotlibapi-3.1.2 → matplotlibapi-3.2.1}/MatplotLibAPI/Table.py +1 -1
  6. {matplotlibapi-3.1.2 → matplotlibapi-3.2.1}/MatplotLibAPI/Timeserie.py +1 -1
  7. {matplotlibapi-3.1.2 → matplotlibapi-3.2.1}/MatplotLibAPI/Treemap.py +1 -1
  8. matplotlibapi-3.2.1/MatplotLibAPI/__init__.py +181 -0
  9. {matplotlibapi-3.1.2 → matplotlibapi-3.2.1/MatplotLibAPI.egg-info}/PKG-INFO +1 -1
  10. {matplotlibapi-3.1.2 → matplotlibapi-3.2.1}/MatplotLibAPI.egg-info/SOURCES.txt +1 -0
  11. {matplotlibapi-3.1.2/MatplotLibAPI.egg-info → matplotlibapi-3.2.1}/PKG-INFO +1 -1
  12. {matplotlibapi-3.1.2 → matplotlibapi-3.2.1}/pyproject.toml +1 -1
  13. matplotlibapi-3.1.2/MatplotLibAPI/__init__.py +0 -310
  14. {matplotlibapi-3.1.2 → matplotlibapi-3.2.1}/LICENSE +0 -0
  15. {matplotlibapi-3.1.2 → matplotlibapi-3.2.1}/MatplotLibAPI/Pivot.py +0 -0
  16. {matplotlibapi-3.1.2 → matplotlibapi-3.2.1}/MatplotLibAPI.egg-info/dependency_links.txt +0 -0
  17. {matplotlibapi-3.1.2 → matplotlibapi-3.2.1}/MatplotLibAPI.egg-info/requires.txt +0 -0
  18. {matplotlibapi-3.1.2 → matplotlibapi-3.2.1}/MatplotLibAPI.egg-info/top_level.txt +0 -0
  19. {matplotlibapi-3.1.2 → matplotlibapi-3.2.1}/README.md +0 -0
  20. {matplotlibapi-3.1.2 → matplotlibapi-3.2.1}/setup.cfg +0 -0
@@ -6,7 +6,7 @@ import matplotlib.pyplot as plt
6
6
  from matplotlib.axes import Axes
7
7
  import seaborn as sns
8
8
 
9
- from . import DynamicFuncFormatter, StyleTemplate, generate_ticks, string_formatter, bmk_formatter, percent_formatter, format_func,validate_dataframe
9
+ from .StyleTemplate import DynamicFuncFormatter, StyleTemplate, generate_ticks, string_formatter, bmk_formatter, percent_formatter, format_func,validate_dataframe
10
10
 
11
11
  BUBBLE_STYLE_TEMPLATE = StyleTemplate(
12
12
  format_funcs={"label": string_formatter,
@@ -8,7 +8,7 @@ from matplotlib.figure import Figure
8
8
  from .Network import plot_network, plot_network_components, DEFAULT
9
9
  from .Bubble import plot_bubble, BUBBLE_STYLE_TEMPLATE
10
10
  from .Table import plot_table
11
- from . import StyleTemplate, format_func, validate_dataframe
11
+ from .StyleTemplate import StyleTemplate, format_func, validate_dataframe
12
12
 
13
13
 
14
14
  def plot_composite_bubble(
@@ -13,7 +13,7 @@ from networkx import Graph
13
13
  from networkx.classes.graph import Graph
14
14
 
15
15
 
16
- from . import StyleTemplate, string_formatter, format_func,validate_dataframe
16
+ from .StyleTemplate import StyleTemplate, string_formatter, format_func,validate_dataframe
17
17
 
18
18
  NETWORK_STYLE_TEMPLATE = StyleTemplate(
19
19
  )
@@ -0,0 +1,169 @@
1
+
2
+
3
+ from typing import List, Optional, Dict, Callable, Union
4
+ from dataclasses import dataclass
5
+ import pandas as pd
6
+ import numpy as np
7
+
8
+ from matplotlib.dates import num2date
9
+ from matplotlib.ticker import FuncFormatter
10
+
11
+ # region Utils
12
+
13
+ def validate_dataframe(pd_df: pd.DataFrame,
14
+ cols: List[str],
15
+ sort_by: Optional[str] = None):
16
+ _columns = cols.copy()
17
+ if sort_by and sort_by not in _columns:
18
+ _columns.append(sort_by)
19
+ for col in _columns:
20
+ if col not in pd_df.columns:
21
+ raise AttributeError(f"{col} is not a DataFrame's column")
22
+
23
+
24
+ def format_func(
25
+ format_funcs: Optional[Dict[str, Optional[Callable[[Union[int, float, str]], str]]]],
26
+ label: Optional[str] = None,
27
+ x: Optional[str] = None,
28
+ y: Optional[str] = None,
29
+ z: Optional[str] = None):
30
+
31
+ if label and "label" in format_funcs:
32
+ format_funcs[label] = format_funcs["label"]
33
+ if x and "x" in format_funcs:
34
+ format_funcs[x] = format_funcs["x"]
35
+ if y and "y" in format_funcs:
36
+ format_funcs[y] = format_funcs["y"]
37
+ if z and "z" in format_funcs:
38
+ format_funcs[z] = format_funcs["z"]
39
+ return format_funcs
40
+
41
+ # endregion
42
+
43
+ # region Style
44
+
45
+
46
+ MAX_RESULTS = 50
47
+ X_COL = "index"
48
+ Y_COL = "overlap"
49
+ Z_COL = "users"
50
+ FIG_SIZE = (19.2, 10.8)
51
+ BACKGROUND_COLOR = 'black'
52
+ TEXT_COLOR = 'white'
53
+ PALETTE = "Greys_r"
54
+ FONT_SIZE = 14
55
+
56
+
57
+ @dataclass
58
+ class StyleTemplate:
59
+ background_color: str = BACKGROUND_COLOR
60
+ fig_border: str = BACKGROUND_COLOR
61
+ font_name: str = 'Arial'
62
+ font_size: int = FONT_SIZE
63
+ font_color: str = TEXT_COLOR
64
+ palette: str = PALETTE
65
+ legend: bool = True
66
+ xscale: Optional[str] = None
67
+ x_ticks: int = 10
68
+ yscale: Optional[str] = None
69
+ y_ticks: int = 5
70
+ format_funcs: Optional[Dict[str, Optional[Callable[[
71
+ Union[int, float, str]], str]]]] = None
72
+ col_widths: Optional[List[float]] = None
73
+
74
+ @property
75
+ def font_mapping(self):
76
+ return {0: self.font_size-3,
77
+ 1: self.font_size-1,
78
+ 2: self.font_size,
79
+ 3: self.font_size+1,
80
+ 4: self.font_size+3}
81
+
82
+
83
+ class DynamicFuncFormatter(FuncFormatter):
84
+ def __init__(self, func_name):
85
+ super().__init__(func_name)
86
+
87
+
88
+ def percent_formatter(val, pos: Optional[int] = None):
89
+ if val*100 <= 0.1: # For 0.1%
90
+ return f"{val*100:.2f}%"
91
+ elif val*100 <= 1: # For 1%
92
+ return f"{val*100:.1f}%"
93
+ else:
94
+ return f"{val*100:.0f}%"
95
+
96
+
97
+ def bmk_formatter(val, pos: Optional[int] = None):
98
+ if val >= 1_000_000_000: # Billions
99
+ return f"{val / 1_000_000_000:.2f}B"
100
+ elif val >= 1_000_000: # Millions
101
+ return f"{val / 1_000_000:.1f}M"
102
+ elif val >= 1_000: # Thousands
103
+ return f"{val / 1_000:.1f}K"
104
+ else:
105
+ return f"{int(val)}"
106
+
107
+
108
+ def integer_formatter(value, pos: Optional[int] = None):
109
+ return f"{int(value)}"
110
+
111
+
112
+ def string_formatter(value, pos: Optional[int] = None):
113
+ return str(value).replace("-", " ").replace("_", " ").title()
114
+
115
+
116
+ def yy_mm__formatter(x, pos: Optional[int] = None):
117
+ return num2date(x).strftime('%Y-%m')
118
+
119
+
120
+ def yy_mm_dd__formatter(x, pos: Optional[int] = None):
121
+ return num2date(x).strftime('%Y-%m-%D')
122
+
123
+
124
+ def percent_formatter(x, pos: Optional[int] = None):
125
+ return f"{x * 100:.0f}%"
126
+
127
+
128
+ def generate_ticks(min_val, max_val, num_ticks="10"):
129
+ # Identify the type of the input
130
+ try:
131
+ min_val = float(min_val)
132
+ max_val = float(max_val)
133
+ is_date = False
134
+ except ValueError:
135
+ is_date = True
136
+
137
+ # Convert string inputs to appropriate numerical or date types
138
+ num_ticks = int(num_ticks)
139
+
140
+ if is_date:
141
+ min_val = pd.Timestamp(min_val).to_datetime64()
142
+ max_val = pd.Timestamp(max_val).to_datetime64()
143
+ data_range = (max_val - min_val).astype('timedelta64[D]').astype(int)
144
+ else:
145
+ data_range = max_val - min_val
146
+
147
+ # Calculate a nice step size
148
+ step_size = data_range / (num_ticks - 1)
149
+
150
+ # If date, convert back to datetime
151
+ if is_date:
152
+ ticks = pd.date_range(
153
+ start=min_val, periods=num_ticks, freq=f"{step_size}D")
154
+ else:
155
+ # Round the step size to a "nice" number
156
+ exponent = np.floor(np.log10(step_size))
157
+ fraction = step_size / 10**exponent
158
+ nice_fraction = round(fraction)
159
+
160
+ # Create nice step size
161
+ nice_step = nice_fraction * 10**exponent
162
+
163
+ # Generate the tick marks based on the nice step size
164
+ ticks = np.arange(min_val, max_val + nice_step, nice_step)
165
+
166
+ return ticks
167
+
168
+
169
+ # endregion
@@ -3,7 +3,7 @@ import pandas as pd
3
3
  import matplotlib.pyplot as plt
4
4
  from matplotlib.axes import Axes
5
5
 
6
- from . import StyleTemplate, string_formatter,validate_dataframe
6
+ from .StyleTemplate import StyleTemplate, string_formatter,validate_dataframe
7
7
 
8
8
  TABLE_STYLE_TEMPLATE = StyleTemplate(
9
9
  background_color='black',
@@ -6,7 +6,7 @@ import matplotlib.pyplot as plt
6
6
  from matplotlib.axes import Axes
7
7
  import seaborn as sns
8
8
 
9
- from . import DynamicFuncFormatter, StyleTemplate, string_formatter, bmk_formatter, format_func,validate_dataframe
9
+ from .StyleTemplate import DynamicFuncFormatter, StyleTemplate, string_formatter, bmk_formatter, format_func,validate_dataframe
10
10
 
11
11
 
12
12
  TIMESERIE_STYLE_TEMPLATE = StyleTemplate(
@@ -5,7 +5,7 @@ import pandas as pd
5
5
  from pandas import CategoricalDtype,BooleanDtype
6
6
  import plotly.graph_objects as go
7
7
 
8
- from . import StyleTemplate, string_formatter, percent_formatter,validate_dataframe
8
+ from .StyleTemplate import StyleTemplate, string_formatter, percent_formatter,validate_dataframe
9
9
 
10
10
 
11
11
 
@@ -0,0 +1,181 @@
1
+
2
+ from .StyleTemplate import StyleTemplate
3
+ from .Bubble import plot_bubble, BUBBLE_STYLE_TEMPLATE
4
+ from .Composite import plot_composite_bubble
5
+ from .Timeserie import plot_timeserie, TIMESERIE_STYLE_TEMPLATE
6
+ from .Table import plot_table, TABLE_STYLE_TEMPLATE
7
+ from .Network import plot_network, plot_network_components, NETWORK_STYLE_TEMPLATE
8
+ from .Treemap import plot_treemap, TREEMAP_STYLE_TEMPLATE
9
+ from typing import List, Optional
10
+ import pandas as pd
11
+ from pandas.api.extensions import register_dataframe_accessor
12
+
13
+ from matplotlib.axes import Axes
14
+ from matplotlib.figure import Figure
15
+ import plotly.graph_objects as go
16
+
17
+
18
+ @register_dataframe_accessor("mpl")
19
+ class DataFrameAccessor:
20
+
21
+ def __init__(self, pd_df: pd.DataFrame):
22
+ self._obj = pd_df
23
+
24
+ def plot_bubble(self,
25
+ label: str,
26
+ x: str,
27
+ y: str,
28
+ z: str,
29
+ title: Optional[str] = None,
30
+ style: StyleTemplate = BUBBLE_STYLE_TEMPLATE,
31
+ max_values: int = 50,
32
+ center_to_mean: bool = False,
33
+ sort_by: Optional[str] = None,
34
+ ascending: bool = False,
35
+ ax: Optional[Axes] = None) -> Axes:
36
+
37
+ return plot_bubble(pd_df=self._obj,
38
+ label=label,
39
+ x=x,
40
+ y=y,
41
+ z=z,
42
+ title=title,
43
+ style=style,
44
+ max_values=max_values,
45
+ center_to_mean=center_to_mean,
46
+ sort_by=sort_by,
47
+ ascending=ascending,
48
+ ax=ax)
49
+
50
+ def plot_composite_bubble(self,
51
+ label: str,
52
+ x: str,
53
+ y: str,
54
+ z: str,
55
+ title: Optional[str] = None,
56
+ style: StyleTemplate = BUBBLE_STYLE_TEMPLATE,
57
+ max_values: int = 100,
58
+ center_to_mean: bool = False,
59
+ sort_by: Optional[str] = None,
60
+ ascending: bool = False,
61
+ ax: Optional[Axes] = None) -> Figure:
62
+
63
+ return plot_composite_bubble(pd_df=self._obj,
64
+ label=label,
65
+ x=x,
66
+ y=y,
67
+ z=z,
68
+ title=title,
69
+ style=style,
70
+ max_values=max_values,
71
+ center_to_mean=center_to_mean,
72
+ sort_by=sort_by,
73
+ ascending=ascending,
74
+ ax=ax)
75
+
76
+ def plot_table(self,
77
+ cols: List[str],
78
+ title: Optional[str] = None,
79
+ style: StyleTemplate = TABLE_STYLE_TEMPLATE,
80
+ max_values: int = 20,
81
+ sort_by: Optional[str] = None,
82
+ ascending: bool = False,
83
+ ax: Optional[Axes] = None) -> Axes:
84
+
85
+ return plot_table(pd_df=self._obj,
86
+ cols=cols,
87
+ title=title,
88
+ style=style,
89
+ max_values=max_values,
90
+ sort_by=sort_by,
91
+ ascending=ascending,
92
+ ax=ax)
93
+
94
+ def plot_timeserie(self,
95
+ label: str,
96
+ x: str,
97
+ y: str,
98
+ title: Optional[str] = None,
99
+ style: StyleTemplate = TIMESERIE_STYLE_TEMPLATE,
100
+ max_values: int = 100,
101
+ sort_by: Optional[str] = None,
102
+ ascending: bool = False,
103
+ ax: Optional[Axes] = None) -> Axes:
104
+
105
+ return plot_timeserie(pd_df=self._obj,
106
+ label=label,
107
+ x=x,
108
+ y=y,
109
+ title=title,
110
+ style=style,
111
+ max_values=max_values,
112
+ sort_by=sort_by,
113
+ ascending=ascending,
114
+ ax=ax)
115
+
116
+ def plot_network(self,
117
+ source: str = "source",
118
+ target: str = "target",
119
+ weight: str = "weight",
120
+ title: Optional[str] = None,
121
+ style: StyleTemplate = NETWORK_STYLE_TEMPLATE,
122
+ sort_by: Optional[str] = None,
123
+ ascending: bool = False,
124
+ node_list: Optional[List] = None,
125
+ ax: Optional[Axes] = None) -> Axes:
126
+
127
+ return plot_network(df=self._obj,
128
+ source=source,
129
+ target=target,
130
+ weight=weight,
131
+ title=title,
132
+ style=style,
133
+ sort_by=sort_by,
134
+ ascending=ascending,
135
+ node_list=node_list,
136
+ ax=ax)
137
+
138
+ def plot_network_components(self,
139
+ source: str = "source",
140
+ target: str = "target",
141
+ weight: str = "weight",
142
+ title: Optional[str] = None,
143
+ style: StyleTemplate = NETWORK_STYLE_TEMPLATE,
144
+ sort_by: Optional[str] = None,
145
+ ascending: bool = False,
146
+ node_list: Optional[List] = None,
147
+ ax: Optional[Axes] = None) -> Axes:
148
+
149
+ return plot_network_components(df=self._obj,
150
+ source=source,
151
+ target=target,
152
+ weight=weight,
153
+ title=title,
154
+ style=style,
155
+ sort_by=sort_by,
156
+ ascending=ascending,
157
+ node_list=node_list,
158
+ ax=ax)
159
+
160
+ def plot_treemap(self,
161
+ path: str,
162
+ values: str,
163
+ style: StyleTemplate = TREEMAP_STYLE_TEMPLATE,
164
+ title: Optional[str] = None,
165
+ color: Optional[str] = None,
166
+ max_values: int = 100,
167
+ sort_by: Optional[str] = None,
168
+ ascending: bool = False) -> go.Figure:
169
+ return plot_treemap(pd_df=self._obj,
170
+ path=path,
171
+ values=values,
172
+ title=title,
173
+ style=style,
174
+ color=color,
175
+ max_values=max_values,
176
+ sort_by=sort_by,
177
+ ascending=ascending)
178
+
179
+
180
+ __all__ = ["validate_dataframe", "plot_bubble", "plot_timeserie", "plot_table", "plot_network", "plot_network_components",
181
+ "plot_pivotbar", "plot_treemap", "plot_composite_bubble", "StyleTemplate", "DataFrameAccessor"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: MatplotLibAPI
3
- Version: 3.1.2
3
+ Version: 3.2.1
4
4
  Requires-Python: >=3.7
5
5
  Description-Content-Type: text/markdown
6
6
  License-File: LICENSE
@@ -5,6 +5,7 @@ MatplotLibAPI/Bubble.py
5
5
  MatplotLibAPI/Composite.py
6
6
  MatplotLibAPI/Network.py
7
7
  MatplotLibAPI/Pivot.py
8
+ MatplotLibAPI/StyleTemplate.py
8
9
  MatplotLibAPI/Table.py
9
10
  MatplotLibAPI/Timeserie.py
10
11
  MatplotLibAPI/Treemap.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: MatplotLibAPI
3
- Version: 3.1.2
3
+ Version: 3.2.1
4
4
  Requires-Python: >=3.7
5
5
  Description-Content-Type: text/markdown
6
6
  License-File: LICENSE
@@ -3,7 +3,7 @@ requires = ["setuptools", "wheel"]
3
3
  build-backend = "setuptools.build_meta"
4
4
  [project]
5
5
  name = "MatplotLibAPI"
6
- version="v3.1.2"
6
+ version="v3.2.1"
7
7
  readme = "README.md"
8
8
  requires-python=">=3.7"
9
9
  dependencies = ["pandas","matplotlib","networkx","plotly","seaborn","scikit-learn","kaleido","nbformat"]
@@ -1,310 +0,0 @@
1
-
2
- from .Treemap import plot_treemap, TREEMAP_STYLE_TEMPLATE
3
- from .Network import Graph
4
- from .Table import plot_table, TABLE_STYLE_TEMPLATE
5
- from .Timeserie import plot_timeserie, TIMESERIE_STYLE_TEMPLATE
6
- from .Composite import plot_composite_bubble
7
- from .Bubble import plot_bubble, BUBBLE_STYLE_TEMPLATE
8
- from typing import List, Optional, Dict, Callable, Union
9
- from dataclasses import dataclass
10
- import pandas as pd
11
- from pandas.api.extensions import register_dataframe_accessor
12
- import numpy as np
13
-
14
- from matplotlib.axes import Axes
15
- from matplotlib.figure import Figure
16
- from matplotlib.dates import num2date
17
- from matplotlib.ticker import FuncFormatter
18
- import plotly.graph_objects as go
19
-
20
-
21
- # region Utils
22
-
23
- def validate_dataframe(pd_df: pd.DataFrame,
24
- cols: List[str],
25
- sort_by: Optional[str] = None):
26
- _columns = cols.copy()
27
- if sort_by and sort_by not in _columns:
28
- _columns.append(sort_by)
29
- for col in _columns:
30
- if col not in pd_df.columns:
31
- raise AttributeError(f"{col} is not a DataFrame's column")
32
-
33
-
34
- def format_func(
35
- format_funcs: Optional[Dict[str, Optional[Callable[[Union[int, float, str]], str]]]],
36
- label: Optional[str] = None,
37
- x: Optional[str] = None,
38
- y: Optional[str] = None,
39
- z: Optional[str] = None):
40
-
41
- if label and "label" in format_funcs:
42
- format_funcs[label] = format_funcs["label"]
43
- if x and "x" in format_funcs:
44
- format_funcs[x] = format_funcs["x"]
45
- if y and "y" in format_funcs:
46
- format_funcs[y] = format_funcs["y"]
47
- if z and "z" in format_funcs:
48
- format_funcs[z] = format_funcs["z"]
49
- return format_funcs
50
-
51
- # endregion
52
-
53
- # region Style
54
-
55
-
56
- MAX_RESULTS = 50
57
- X_COL = "index"
58
- Y_COL = "overlap"
59
- Z_COL = "users"
60
- FIG_SIZE = (19.2, 10.8)
61
- BACKGROUND_COLOR = 'black'
62
- TEXT_COLOR = 'white'
63
- PALETTE = "Greys_r"
64
- FONT_SIZE = 14
65
-
66
-
67
- @dataclass
68
- class StyleTemplate:
69
- background_color: str = BACKGROUND_COLOR
70
- fig_border: str = BACKGROUND_COLOR
71
- font_name: str = 'Arial'
72
- font_size: int = FONT_SIZE
73
- font_color: str = TEXT_COLOR
74
- palette: str = PALETTE
75
- legend: bool = True
76
- xscale: Optional[str] = None
77
- x_ticks: int = 10
78
- yscale: Optional[str] = None
79
- y_ticks: int = 5
80
- format_funcs: Optional[Dict[str, Optional[Callable[[
81
- Union[int, float, str]], str]]]] = None
82
- col_widths: Optional[List[float]] = None
83
-
84
- @property
85
- def font_mapping(self):
86
- return {0: self.font_size-3,
87
- 1: self.font_size-1,
88
- 2: self.font_size,
89
- 3: self.font_size+1,
90
- 4: self.font_size+3}
91
-
92
-
93
- class DynamicFuncFormatter(FuncFormatter):
94
- def __init__(self, func_name):
95
- super().__init__(func_name)
96
-
97
-
98
- def percent_formatter(val, pos: Optional[int] = None):
99
- if val*100 <= 0.1: # For 0.1%
100
- return f"{val*100:.2f}%"
101
- elif val*100 <= 1: # For 1%
102
- return f"{val*100:.1f}%"
103
- else:
104
- return f"{val*100:.0f}%"
105
-
106
-
107
- def bmk_formatter(val, pos: Optional[int] = None):
108
- if val >= 1_000_000_000: # Billions
109
- return f"{val / 1_000_000_000:.2f}B"
110
- elif val >= 1_000_000: # Millions
111
- return f"{val / 1_000_000:.1f}M"
112
- elif val >= 1_000: # Thousands
113
- return f"{val / 1_000:.1f}K"
114
- else:
115
- return f"{int(val)}"
116
-
117
-
118
- def integer_formatter(value, pos: Optional[int] = None):
119
- return f"{int(value)}"
120
-
121
-
122
- def string_formatter(value, pos: Optional[int] = None):
123
- return str(value).replace("-", " ").replace("_", " ").title()
124
-
125
-
126
- def yy_mm__formatter(x, pos: Optional[int] = None):
127
- return num2date(x).strftime('%Y-%m')
128
-
129
-
130
- def yy_mm_dd__formatter(x, pos: Optional[int] = None):
131
- return num2date(x).strftime('%Y-%m-%D')
132
-
133
-
134
- def percent_formatter(x, pos: Optional[int] = None):
135
- return f"{x * 100:.0f}%"
136
-
137
-
138
- def generate_ticks(min_val, max_val, num_ticks="10"):
139
- # Identify the type of the input
140
- try:
141
- min_val = float(min_val)
142
- max_val = float(max_val)
143
- is_date = False
144
- except ValueError:
145
- is_date = True
146
-
147
- # Convert string inputs to appropriate numerical or date types
148
- num_ticks = int(num_ticks)
149
-
150
- if is_date:
151
- min_val = pd.Timestamp(min_val).to_datetime64()
152
- max_val = pd.Timestamp(max_val).to_datetime64()
153
- data_range = (max_val - min_val).astype('timedelta64[D]').astype(int)
154
- else:
155
- data_range = max_val - min_val
156
-
157
- # Calculate a nice step size
158
- step_size = data_range / (num_ticks - 1)
159
-
160
- # If date, convert back to datetime
161
- if is_date:
162
- ticks = pd.date_range(
163
- start=min_val, periods=num_ticks, freq=f"{step_size}D")
164
- else:
165
- # Round the step size to a "nice" number
166
- exponent = np.floor(np.log10(step_size))
167
- fraction = step_size / 10**exponent
168
- nice_fraction = round(fraction)
169
-
170
- # Create nice step size
171
- nice_step = nice_fraction * 10**exponent
172
-
173
- # Generate the tick marks based on the nice step size
174
- ticks = np.arange(min_val, max_val + nice_step, nice_step)
175
-
176
- return ticks
177
-
178
-
179
- # endregion
180
-
181
-
182
- @register_dataframe_accessor("mpl")
183
- class DataFrameAccessor:
184
-
185
- def __init__(self, pd_df: pd.DataFrame):
186
- self._obj = pd_df
187
-
188
- def plot_bubble(self,
189
- label: str,
190
- x: str,
191
- y: str,
192
- z: str,
193
- title: Optional[str] = None,
194
- style: StyleTemplate = BUBBLE_STYLE_TEMPLATE,
195
- max_values: int = 50,
196
- center_to_mean: bool = False,
197
- sort_by: Optional[str] = None,
198
- ascending: bool = False) -> Axes:
199
-
200
- return plot_bubble(pd_df=self._obj,
201
- label=label,
202
- x=x,
203
- y=y,
204
- z=z,
205
- title=title,
206
- style=style,
207
- max_values=max_values,
208
- center_to_mean=center_to_mean,
209
- sort_by=sort_by,
210
- ascending=ascending)
211
-
212
- def plot_composite_bubble(self,
213
- label: str,
214
- x: str,
215
- y: str,
216
- z: str,
217
- title: Optional[str] = None,
218
- style: StyleTemplate = BUBBLE_STYLE_TEMPLATE,
219
- max_values: int = 100,
220
- center_to_mean: bool = False,
221
- sort_by: Optional[str] = None,
222
- ascending: bool = False) -> Figure:
223
-
224
- return plot_composite_bubble(pd_df=self._obj,
225
- label=label,
226
- x=x,
227
- y=y,
228
- z=z,
229
- title=title,
230
- style=style,
231
- max_values=max_values,
232
- center_to_mean=center_to_mean,
233
- sort_by=sort_by,
234
- ascending=ascending)
235
-
236
- def plot_table(self,
237
- cols: List[str],
238
- title: Optional[str] = None,
239
- style: StyleTemplate = TABLE_STYLE_TEMPLATE,
240
- max_values: int = 20,
241
- sort_by: Optional[str] = None,
242
- ascending: bool = False) -> Axes:
243
-
244
- return plot_table(pd_df=self._obj,
245
- cols=cols,
246
- title=title,
247
- style=style,
248
- max_values=max_values,
249
- sort_by=sort_by,
250
- ascending=ascending)
251
-
252
- def plot_timeserie(self,
253
- label: str,
254
- x: str,
255
- y: str,
256
- title: Optional[str] = None,
257
- style: StyleTemplate = TIMESERIE_STYLE_TEMPLATE,
258
- max_values: int = 100,
259
- sort_by: Optional[str] = None,
260
- ascending: bool = False) -> Axes:
261
-
262
- return plot_timeserie(pd_df=self._obj,
263
- label=label,
264
- x=x,
265
- y=y,
266
- title=title,
267
- style=style,
268
- max_values=max_values,
269
- sort_by=sort_by,
270
- ascending=ascending)
271
-
272
- def plot_network(self,
273
- source: str = "source",
274
- target: str = "target",
275
- weight: str = "weight",
276
- title: Optional[str] = None,
277
- style: StyleTemplate = TIMESERIE_STYLE_TEMPLATE,
278
- max_values: int = 20,
279
- sort_by: Optional[str] = None,
280
- ascending: bool = False) -> Axes:
281
-
282
- graph = Graph.from_pandas_edgelist(df=self._obj,
283
- source=source,
284
- target=target,
285
- weight=weight)
286
-
287
- return graph.plotX(title, style)
288
-
289
- def plot_treemap(self,
290
- path: str,
291
- values: str,
292
- style: StyleTemplate = TREEMAP_STYLE_TEMPLATE,
293
- title: Optional[str] = None,
294
- color: Optional[str] = None,
295
- max_values: int = 100,
296
- sort_by: Optional[str] = None,
297
- ascending: bool = False) -> go.Figure:
298
- return plot_treemap(pd_df=self._obj,
299
- path=path,
300
- values=values,
301
- title=title,
302
- style=style,
303
- color=color,
304
- max_values=max_values,
305
- sort_by=sort_by,
306
- ascending=ascending)
307
-
308
-
309
- __all__ = ["validate_dataframe", "plot_bubble", "plot_timeserie", "plot_table", "plot_network", "plot_network_components",
310
- "plot_pivotbar", "plot_treemap", "plot_composite_bubble", "StyleTemplate", "DataFrameAccessor"]
File without changes
File without changes
File without changes