MatplotLibAPI 3.1.2__tar.gz → 3.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
 
@@ -1,182 +1,21 @@
1
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
2
+ from .StyleTemplate import StyleTemplate
7
3
  from .Bubble import plot_bubble, BUBBLE_STYLE_TEMPLATE
8
- from typing import List, Optional, Dict, Callable, Union
9
- from dataclasses import dataclass
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 Graph
8
+ from .Treemap import plot_treemap, TREEMAP_STYLE_TEMPLATE
9
+ from typing import List, Optional
10
10
  import pandas as pd
11
11
  from pandas.api.extensions import register_dataframe_accessor
12
- import numpy as np
13
12
 
14
13
  from matplotlib.axes import Axes
15
14
  from matplotlib.figure import Figure
16
- from matplotlib.dates import num2date
17
- from matplotlib.ticker import FuncFormatter
18
15
  import plotly.graph_objects as go
19
16
 
20
17
 
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
18
 
179
- # endregion
180
19
 
181
20
 
182
21
  @register_dataframe_accessor("mpl")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: MatplotLibAPI
3
- Version: 3.1.2
3
+ Version: 3.2.0
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.0
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.0"
7
7
  readme = "README.md"
8
8
  requires-python=">=3.7"
9
9
  dependencies = ["pandas","matplotlib","networkx","plotly","seaborn","scikit-learn","kaleido","nbformat"]
File without changes
File without changes
File without changes