MatplotLibAPI 3.1.1__py3-none-any.whl → 3.2.0__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/Bubble.py CHANGED
@@ -6,8 +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
10
- from .. import validate_dataframe
9
+ from .StyleTemplate import DynamicFuncFormatter, StyleTemplate, generate_ticks, string_formatter, bmk_formatter, percent_formatter, format_func,validate_dataframe
11
10
 
12
11
  BUBBLE_STYLE_TEMPLATE = StyleTemplate(
13
12
  format_funcs={"label": string_formatter,
@@ -8,8 +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
12
- from .. import validate_dataframe
11
+ from .StyleTemplate import StyleTemplate, format_func, validate_dataframe
13
12
 
14
13
 
15
14
  def plot_composite_bubble(
MatplotLibAPI/Network.py CHANGED
@@ -13,8 +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
17
- from .. import validate_dataframe
16
+ from .StyleTemplate import StyleTemplate, string_formatter, format_func,validate_dataframe
18
17
 
19
18
  NETWORK_STYLE_TEMPLATE = StyleTemplate(
20
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
MatplotLibAPI/Table.py CHANGED
@@ -3,8 +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
7
- from .. import validate_dataframe
6
+ from .StyleTemplate import StyleTemplate, string_formatter,validate_dataframe
8
7
 
9
8
  TABLE_STYLE_TEMPLATE = StyleTemplate(
10
9
  background_color='black',
@@ -6,8 +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
10
- from .. import validate_dataframe
9
+ from .StyleTemplate import DynamicFuncFormatter, StyleTemplate, string_formatter, bmk_formatter, format_func,validate_dataframe
11
10
 
12
11
 
13
12
  TIMESERIE_STYLE_TEMPLATE = StyleTemplate(
MatplotLibAPI/Treemap.py CHANGED
@@ -2,10 +2,11 @@
2
2
  # %%
3
3
  from typing import Optional
4
4
  import pandas as pd
5
+ from pandas import CategoricalDtype,BooleanDtype
5
6
  import plotly.graph_objects as go
6
7
 
7
- from . import StyleTemplate, string_formatter, percent_formatter
8
- from .. import validate_dataframe
8
+ from .StyleTemplate import StyleTemplate, string_formatter, percent_formatter,validate_dataframe
9
+
9
10
 
10
11
 
11
12
  TREEMAP_STYLE_TEMPLATE = StyleTemplate(
@@ -49,9 +50,9 @@ def plot_treemap(pd_df: pd.DataFrame,
49
50
 
50
51
  if color and color in pd_df.columns:
51
52
  color_data = pd_df[color]
52
- if pd.api.types.is_categorical_dtype(color_data) or pd.api.types.is_object_dtype(color_data):
53
+ if isinstance(color_data, CategoricalDtype) or pd.api.types.is_object_dtype(color_data):
53
54
  color_data = color_data.astype('category').cat.codes
54
- elif pd.api.types.is_bool_dtype(color_data):
55
+ elif isinstance(color_data, BooleanDtype):
55
56
  color_data = color_data.astype(int)
56
57
  data['marker'] = dict(colorscale="Viridis",
57
58
  colors=color_data.to_list())
MatplotLibAPI/__init__.py CHANGED
@@ -1,173 +1,21 @@
1
1
 
2
- from typing import List, Optional, Dict, Callable, Union
3
- from dataclasses import dataclass
4
- import pandas as pd
5
- from pandas.api.extensions import register_dataframe_accessor
6
- import numpy as np
7
-
8
- from matplotlib.axes import Axes
9
- from matplotlib.figure import Figure
10
- from matplotlib.dates import num2date
11
- from matplotlib.ticker import FuncFormatter
12
- import plotly.graph_objects as go
13
-
14
- from . import StyleTemplate
2
+ from .StyleTemplate import StyleTemplate
15
3
  from .Bubble import plot_bubble, BUBBLE_STYLE_TEMPLATE
16
4
  from .Composite import plot_composite_bubble
17
5
  from .Timeserie import plot_timeserie, TIMESERIE_STYLE_TEMPLATE
18
6
  from .Table import plot_table, TABLE_STYLE_TEMPLATE
19
7
  from .Network import Graph
20
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
21
12
 
22
- # region Utils
23
-
24
-
25
- def format_func(
26
- format_funcs: Optional[Dict[str, Optional[Callable[[Union[int, float, str]], str]]]],
27
- label: Optional[str] = None,
28
- x: Optional[str] = None,
29
- y: Optional[str] = None,
30
- z: Optional[str] = None):
31
-
32
- if label and "label" in format_funcs:
33
- format_funcs[label] = format_funcs["label"]
34
- if x and "x" in format_funcs:
35
- format_funcs[x] = format_funcs["x"]
36
- if y and "y" in format_funcs:
37
- format_funcs[y] = format_funcs["y"]
38
- if z and "z" in format_funcs:
39
- format_funcs[z] = format_funcs["z"]
40
- return format_funcs
41
-
42
- # endregion
43
-
44
- # region Style
45
-
46
-
47
- MAX_RESULTS = 50
48
- X_COL = "index"
49
- Y_COL = "overlap"
50
- Z_COL = "users"
51
- FIG_SIZE = (19.2, 10.8)
52
- BACKGROUND_COLOR = 'black'
53
- TEXT_COLOR = 'white'
54
- PALETTE = "Greys_r"
55
- FONT_SIZE = 14
56
-
57
-
58
- @dataclass
59
- class StyleTemplate:
60
- background_color: str = BACKGROUND_COLOR
61
- fig_border: str = BACKGROUND_COLOR
62
- font_name: str = 'Arial'
63
- font_size: int = FONT_SIZE
64
- font_color: str = TEXT_COLOR
65
- palette: str = PALETTE
66
- legend: bool = True
67
- xscale: Optional[str] = None
68
- x_ticks: int = 10
69
- yscale: Optional[str] = None
70
- y_ticks: int = 5
71
- format_funcs: Optional[Dict[str, Optional[Callable[[
72
- Union[int, float, str]], str]]]] = None
73
- col_widths: Optional[List[float]] = None
74
-
75
- @property
76
- def font_mapping(self):
77
- return {0: self.font_size-3,
78
- 1: self.font_size-1,
79
- 2: self.font_size,
80
- 3: self.font_size+1,
81
- 4: self.font_size+3}
82
-
83
-
84
- class DynamicFuncFormatter(FuncFormatter):
85
- def __init__(self, func_name):
86
- super().__init__(func_name)
87
-
88
-
89
- def percent_formatter(val, pos: Optional[int] = None):
90
- if val*100 <= 0.1: # For 0.1%
91
- return f"{val*100:.2f}%"
92
- elif val*100 <= 1: # For 1%
93
- return f"{val*100:.1f}%"
94
- else:
95
- return f"{val*100:.0f}%"
96
-
97
-
98
- def bmk_formatter(val, pos: Optional[int] = None):
99
- if val >= 1_000_000_000: # Billions
100
- return f"{val / 1_000_000_000:.2f}B"
101
- elif val >= 1_000_000: # Millions
102
- return f"{val / 1_000_000:.1f}M"
103
- elif val >= 1_000: # Thousands
104
- return f"{val / 1_000:.1f}K"
105
- else:
106
- return f"{int(val)}"
107
-
108
-
109
- def integer_formatter(value, pos: Optional[int] = None):
110
- return f"{int(value)}"
111
-
112
-
113
- def string_formatter(value, pos: Optional[int] = None):
114
- return str(value).replace("-", " ").replace("_", " ").title()
115
-
116
-
117
- def yy_mm__formatter(x, pos: Optional[int] = None):
118
- return num2date(x).strftime('%Y-%m')
119
-
120
-
121
- def yy_mm_dd__formatter(x, pos: Optional[int] = None):
122
- return num2date(x).strftime('%Y-%m-%D')
123
-
124
-
125
- def percent_formatter(x, pos: Optional[int] = None):
126
- return f"{x * 100:.0f}%"
127
-
128
-
129
- def generate_ticks(min_val, max_val, num_ticks="10"):
130
- # Identify the type of the input
131
- try:
132
- min_val = float(min_val)
133
- max_val = float(max_val)
134
- is_date = False
135
- except ValueError:
136
- is_date = True
137
-
138
- # Convert string inputs to appropriate numerical or date types
139
- num_ticks = int(num_ticks)
140
-
141
- if is_date:
142
- min_val = pd.Timestamp(min_val).to_datetime64()
143
- max_val = pd.Timestamp(max_val).to_datetime64()
144
- data_range = (max_val - min_val).astype('timedelta64[D]').astype(int)
145
- else:
146
- data_range = max_val - min_val
147
-
148
- # Calculate a nice step size
149
- step_size = data_range / (num_ticks - 1)
150
-
151
- # If date, convert back to datetime
152
- if is_date:
153
- ticks = pd.date_range(
154
- start=min_val, periods=num_ticks, freq=f"{step_size}D")
155
- else:
156
- # Round the step size to a "nice" number
157
- exponent = np.floor(np.log10(step_size))
158
- fraction = step_size / 10**exponent
159
- nice_fraction = round(fraction)
160
-
161
- # Create nice step size
162
- nice_step = nice_fraction * 10**exponent
163
-
164
- # Generate the tick marks based on the nice step size
165
- ticks = np.arange(min_val, max_val + nice_step, nice_step)
13
+ from matplotlib.axes import Axes
14
+ from matplotlib.figure import Figure
15
+ import plotly.graph_objects as go
166
16
 
167
- return ticks
168
17
 
169
18
 
170
- # endregion
171
19
 
172
20
 
173
21
  @register_dataframe_accessor("mpl")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: MatplotLibAPI
3
- Version: 3.1.1
3
+ Version: 3.2.0
4
4
  Requires-Python: >=3.7
5
5
  Description-Content-Type: text/markdown
6
6
  License-File: LICENSE
@@ -0,0 +1,14 @@
1
+ MatplotLibAPI/Bubble.py,sha256=haIj43o-t9P1OsIRNgS5_XVovdjCJGarMrr1V-bQWAI,3842
2
+ MatplotLibAPI/Composite.py,sha256=-ZXJQFkBzCtMoufKZUTRdH5fbhdRkHxLkXq-vdtRLSM,2847
3
+ MatplotLibAPI/Network.py,sha256=X-x5SKjncSFcK0bFd60e-HEbW4oBm9XIQKZtboPB4Eo,14849
4
+ MatplotLibAPI/Pivot.py,sha256=Bo7ZpkxqoE75e8vpSsKIT5X2Q7lLdfAyy46ox1fARbc,7183
5
+ MatplotLibAPI/StyleTemplate.py,sha256=va8_yXaun1RnjQUOEHGvsXJrKWHdzz4BhnY0CkROLW8,4599
6
+ MatplotLibAPI/Table.py,sha256=4vgvF2pXjewd23-a7KyuLQs-Hohnv69VK1_uRPgGi_o,2005
7
+ MatplotLibAPI/Timeserie.py,sha256=cqPONNvDmJ_7UmkOBVpBbD9oEgS79SbhEVlf1qZ3kW0,3446
8
+ MatplotLibAPI/Treemap.py,sha256=ELkmcNZuWh-thd4gKwqkSQTisnBDutHHgxGuH1ZBzsg,2552
9
+ MatplotLibAPI/__init__.py,sha256=eV05b2Le25jR0goOWBdch15tvE5H_pngljzl-CRMv_s,5931
10
+ MatplotLibAPI-3.2.0.dist-info/LICENSE,sha256=hMErKLb6YZR3lRR5zr-vxeFkvY69QAaafgSpZ5-P1dQ,1067
11
+ MatplotLibAPI-3.2.0.dist-info/METADATA,sha256=l_p7icLMmoE7FLK7xRUMYYDqxrqoFMK6e7W8A5cYzUw,462
12
+ MatplotLibAPI-3.2.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
13
+ MatplotLibAPI-3.2.0.dist-info/top_level.txt,sha256=MrzbBjDEW48Vb6YhQIqpFYGOhHzQnEIM5Qy2xy2iqew,14
14
+ MatplotLibAPI-3.2.0.dist-info/RECORD,,
@@ -1,13 +0,0 @@
1
- MatplotLibAPI/Bubble.py,sha256=dYmmtYKECFcraAwfStc5Se9TmxsCUxmRyDS2q3lLxQc,3844
2
- MatplotLibAPI/Composite.py,sha256=XEW5iaXuqjB1ask_M2ZhGnj8enWcxLmt8nqQdw_HNxE,2848
3
- MatplotLibAPI/Network.py,sha256=2IHpfTolux84OhJ2xcmROcXFM7lr-ZUH6E_oX8t5AyA,14851
4
- MatplotLibAPI/Pivot.py,sha256=Bo7ZpkxqoE75e8vpSsKIT5X2Q7lLdfAyy46ox1fARbc,7183
5
- MatplotLibAPI/Table.py,sha256=RxADNGU_EghQFCxV7Tlk7mYbLRJXPJ7XNK5emjAg8e0,2007
6
- MatplotLibAPI/Timeserie.py,sha256=SJ2TgaXynbBiwNXjCIbSXlQa9vLh2weyNFW5Xeaknb4,3448
7
- MatplotLibAPI/Treemap.py,sha256=fOUMeWd8JqI3KhI2mmYg0o0pevBd_af80Im4ILm9wBo,2511
8
- MatplotLibAPI/__init__.py,sha256=YUSyPpLmu7riEv1X76OLjIhWGtZMK5x0WqaFO-_Oh-g,10081
9
- MatplotLibAPI-3.1.1.dist-info/LICENSE,sha256=hMErKLb6YZR3lRR5zr-vxeFkvY69QAaafgSpZ5-P1dQ,1067
10
- MatplotLibAPI-3.1.1.dist-info/METADATA,sha256=dkZ4xZfVEhhf7V7UY1fMXs_SCBIjvo-gIj3c3Lum_yY,462
11
- MatplotLibAPI-3.1.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
12
- MatplotLibAPI-3.1.1.dist-info/top_level.txt,sha256=MrzbBjDEW48Vb6YhQIqpFYGOhHzQnEIM5Qy2xy2iqew,14
13
- MatplotLibAPI-3.1.1.dist-info/RECORD,,