opengood.py-ml-plot 2.2.0__tar.gz → 2.4.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.

Potentially problematic release.


This version of opengood.py-ml-plot might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 OpenGood
3
+ Copyright (c) 2025-2026 OpenGood
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: opengood.py_ml_plot
3
- Version: 2.2.0
3
+ Version: 2.4.0
4
4
  Summary: Modules containing reusable functions for machine learning visualization plotting
5
5
  Author-email: OpenGood <ai@opengood.ai>
6
6
  License: MIT License
7
7
 
8
- Copyright (c) 2025 OpenGood
8
+ Copyright (c) 2025-2026 OpenGood
9
9
 
10
10
  Permission is hereby granted, free of charge, to any person obtaining a copy
11
11
  of this software and associated documentation files (the "Software"), to deal
@@ -25,30 +25,34 @@ License: MIT License
25
25
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
26
  SOFTWARE.
27
27
 
28
- Project-URL: Homepage, https://github.com/opengood-aio/py-ml-plot
29
- Project-URL: Documentation, https://github.com/opengood-aio/py-ml-plot
28
+ Project-URL: Homepage, https://github.com/opengood-ai/py-ml-plot
29
+ Project-URL: Documentation, https://github.com/opengood-ai/py-ml-plot
30
30
  Classifier: Programming Language :: Python :: 3
31
31
  Classifier: License :: OSI Approved :: MIT License
32
32
  Classifier: Operating System :: OS Independent
33
33
  Requires-Python: >=3.12
34
34
  Description-Content-Type: text/markdown
35
35
  License-File: LICENSE
36
- Requires-Dist: matplotlib>=3.10.3
37
- Requires-Dist: numpy>=2.3.0rc1
38
- Requires-Dist: pandas>=2.2.3
39
- Requires-Dist: scikit-learn>=1.7.0rc1
36
+ Requires-Dist: matplotlib>=3.10.8
37
+ Requires-Dist: numpy>=2.4.3
38
+ Requires-Dist: pandas>=3.0.1
39
+ Requires-Dist: scikit-learn>=1.8.0
40
+ Provides-Extra: dev
41
+ Requires-Dist: pip-tools>=7.5.3; extra == "dev"
42
+ Requires-Dist: pytest>=9.0.2; extra == "dev"
43
+ Requires-Dist: pytest-cov>=7.0.0; extra == "dev"
40
44
  Dynamic: license-file
41
45
 
42
46
  # Python Machine Learning (ML) Plot
43
47
 
44
- [![Build](https://github.com/opengood-aio/py-ml-plot/workflows/build/badge.svg)](https://github.com/opengood-aio/py-ml-plot/actions?query=workflow%3Abuild)
45
- [![Release](https://github.com/opengood-aio/py-ml-plot/workflows/release/badge.svg)](https://github.com/opengood-aio/py-ml-plot/actions?query=workflow%3Arelease)
46
- [![CodeQL](https://github.com/opengood-aio/py-ml-plot/actions/workflows/codeql.yml/badge.svg)](https://github.com/opengood-aio/py-ml-plot/actions/workflows/codeql.yml)
47
- [![Codecov](https://codecov.io/gh/opengood-aio/py-ml-plot/graph/badge.svg?token=WX6Er5S6Vj)](https://codecov.io/gh/opengood-aio/py-ml-plot)
48
- [![Release Version](https://img.shields.io/github/release/opengood-aio/py-ml-plot.svg)](https://github.com/opengood-aio/py-ml-plot/releases/latest)
48
+ [![Build](https://github.com/opengood-ai/py-ml-plot/workflows/build/badge.svg)](https://github.com/opengood-ai/py-ml-plot/actions?query=workflow%3Abuild)
49
+ [![Release](https://github.com/opengood-ai/py-ml-plot/workflows/release/badge.svg)](https://github.com/opengood-ai/py-ml-plot/actions?query=workflow%3Arelease)
50
+ [![CodeQL](https://github.com/opengood-ai/py-ml-plot/actions/workflows/codeql.yml/badge.svg)](https://github.com/opengood-ai/py-ml-plot/actions/workflows/codeql.yml)
51
+ [![Codecov](https://codecov.io/gh/opengood-ai/py-ml-plot/graph/badge.svg?token=WX6Er5S6Vj)](https://codecov.io/gh/opengood-ai/py-ml-plot)
52
+ [![Release Version](https://img.shields.io/github/release/opengood-ai/py-ml-plot.svg)](https://github.com/opengood-ai/py-ml-plot/releases/latest)
49
53
  [![PyPI](https://img.shields.io/pypi/v/opengood.py-ml-plot)](https://pypi.org/project/opengood.py-ml-plot/)
50
54
  ![Python](https://img.shields.io/pypi/pyversions/opengood.py-ml-plot)
51
- [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/opengood-aio/py-ml-plot/master/LICENSE)
55
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/opengood-ai/py-ml-plot/master/LICENSE)
52
56
 
53
57
  Modules containing reusable functions for machine learning visualization
54
58
  plotting
@@ -119,6 +123,10 @@ setup_classification_plot(
119
123
  title="Logistic Regression",
120
124
  x_label="Age",
121
125
  y_label="Estimated Salary",
126
+ meshgrid={
127
+ 0: {"min": 10, "max": 10, "step": 0.25},
128
+ 1: {"min": 1000, "max": 1000, "step": 0.25},
129
+ },
122
130
  feature_scale=lambda x_set, y_set: (
123
131
  sc.inverse_transform(x_set), y_set
124
132
  ),
@@ -135,7 +143,7 @@ plt.show()
135
143
 
136
144
  ##### Output
137
145
 
138
- ![Setup Classification Plot Visualization](https://raw.githubusercontent.com/opengood-aio/py-ml-plot/main/docs/images/setup-classification-plot-visualization.png)
146
+ ![Setup Classification Plot Visualization](https://raw.githubusercontent.com/opengood-ai/py-ml-plot/main/docs/images/setup-classification-plot-visualization.png)
139
147
 
140
148
  ---
141
149
 
@@ -146,8 +154,8 @@ plt.show()
146
154
  `feature_scale` lambda implementation logic for function
147
155
  `setup_classification_plot` is as follows:
148
156
 
149
- * Inverse feature scaling is invoked via a featuring scaling object, such as
150
- the `StandardScalar` object `sc` created earlier for feature scaling
157
+ * Inverse feature scaling is invoked via a feature scaling object, such as
158
+ the `StandardScaler` object `sc` created earlier for feature scaling
151
159
  * `x_set` and `y_set` are assigned non-feature scaled values of the matrix of
152
160
  features and the dependent variable
153
161
  * `x_set` values are inverted from their feature-scaled values in `x`
@@ -177,18 +185,22 @@ is as follows:
177
185
  Visualization implementation logic for function `setup_classification_plot` is
178
186
  as follows:
179
187
 
180
- * `ListedColormap` class from the Matplotlib library creates an object that
181
- generates a colormap visual from a list of colors
188
+ * If the `meshgrid` dict is not defined, a default set of dict attributes are
189
+ set providing min, max, and step values for each axis:
190
+ * `0` and `1` are used for the keys
191
+ * `10` and `1000` are used for `min` and `max` values
192
+ * `0.25` is used for `step` value
193
+ * If the `feature_scale` lambda is not defined, `x_set` and `y_set` are
194
+ assigned the values of `x` and `y`, respectively
182
195
  * If the `feature_scale` lambda is defined, `x_set` and `y_set` are
183
196
  assigned non-feature scaled values of the matrix of features and the dependent
184
197
  variable from the sets using a feature scaling object, such as the
185
- `StandardScalar` object created earlier for feature scaling
198
+ `StandardScaler` object created earlier for feature scaling
186
199
  * `x_set` values are inverted from their feature-scaled values in `x`
187
200
  * `y_set` values are not inverted and taken directly from `y`
188
- * If the `feature_scale` lambda is not defined, `x_set` and `y_set` are
189
- assigned the values of `x` and `y`, respectively
190
201
  * `meshgrid` function from the NumPy library returns a tuple of coordinate
191
202
  matrices from coordinate vectors
203
+ * The ranges for each axis are controlled by the `meshgrid` dict parameter
192
204
  * Two sets of matrices (`x1` and `x2`) are returned with coordinate vectors
193
205
  * `x1`
194
206
  * `arange` function is called with a defined start and stop interval
@@ -220,7 +232,7 @@ as follows:
220
232
  * `step` parameter
221
233
  * Spacing between values
222
234
  * Value of `0.25` is added for spacing
223
- * The prediction logic implemented in the `preodict` lambda is executed, and
235
+ * The prediction logic implemented in the `predict` lambda is executed, and
224
236
  the result is assigned to `y_pred`, containing the predictions
225
237
  * `contourf` function from the Matplotlib library is used for creating filled
226
238
  contour plots
@@ -297,32 +309,54 @@ as follows:
297
309
 
298
310
  ## Python Virtual Environment
299
311
 
300
- Create Python virtual environment:
312
+ Create and activate Python virtual environment:
301
313
 
302
314
  ```bash
303
- cd ~/workspace/opengood-aio/py-ml-plot/.venv
304
- python3 -m venv ~/workspace/opengood-aio/py-ml-plot/.venv
315
+ python3 -m venv .venv
305
316
  source .venv/bin/activate
306
317
  ```
307
318
 
308
- ## Install Packages
319
+ ## Install Dependencies
320
+
321
+ Install the package in editable mode with all dependencies:
322
+
323
+ ```bash
324
+ python3 -m pip install -e .
325
+ ```
326
+
327
+ Install with development dependencies (includes `pip-tools`, `pytest`, `pytest-cov`):
309
328
 
310
329
  ```bash
311
- python3 -m pip install matplotlib
312
- python3 -m pip install numpy
313
- python3 -m pip install pandas
314
- python3 -m pip install scikit-learn
330
+ python3 -m pip install -e ".[dev]"
315
331
  ```
316
332
 
317
- ## Create Requirements File
333
+ ## Generate Requirements File
334
+
335
+ Generate a pinned `requirements.txt` file from pyproject.toml:
318
336
 
319
337
  ```bash
320
- pip freeze > requirements.txt
338
+ pip-compile pyproject.toml -o requirements.txt
321
339
  ```
322
340
 
341
+ This creates a `requirements.txt` with exact versions of all dependencies and their transitive dependencies.
342
+
323
343
  ## Run Tests
324
344
 
345
+ Run all tests with coverage:
346
+
325
347
  ```bash
326
348
  python -m pytest tests/
327
349
  ```
328
350
 
351
+ Run tests with verbose output and coverage report:
352
+
353
+ ```bash
354
+ python -m pytest tests/ -v --cov=src.opengood.py_ml_plot --cov-report=term-missing
355
+ ```
356
+
357
+ Run a specific test:
358
+
359
+ ```bash
360
+ python -m pytest tests/py_ml_plot/test_classification_plot.py::TestClassificationPlot::test_logistic_regression_setup_classification_plot_with_shaded_regions
361
+ ```
362
+
@@ -1,13 +1,13 @@
1
1
  # Python Machine Learning (ML) Plot
2
2
 
3
- [![Build](https://github.com/opengood-aio/py-ml-plot/workflows/build/badge.svg)](https://github.com/opengood-aio/py-ml-plot/actions?query=workflow%3Abuild)
4
- [![Release](https://github.com/opengood-aio/py-ml-plot/workflows/release/badge.svg)](https://github.com/opengood-aio/py-ml-plot/actions?query=workflow%3Arelease)
5
- [![CodeQL](https://github.com/opengood-aio/py-ml-plot/actions/workflows/codeql.yml/badge.svg)](https://github.com/opengood-aio/py-ml-plot/actions/workflows/codeql.yml)
6
- [![Codecov](https://codecov.io/gh/opengood-aio/py-ml-plot/graph/badge.svg?token=WX6Er5S6Vj)](https://codecov.io/gh/opengood-aio/py-ml-plot)
7
- [![Release Version](https://img.shields.io/github/release/opengood-aio/py-ml-plot.svg)](https://github.com/opengood-aio/py-ml-plot/releases/latest)
3
+ [![Build](https://github.com/opengood-ai/py-ml-plot/workflows/build/badge.svg)](https://github.com/opengood-ai/py-ml-plot/actions?query=workflow%3Abuild)
4
+ [![Release](https://github.com/opengood-ai/py-ml-plot/workflows/release/badge.svg)](https://github.com/opengood-ai/py-ml-plot/actions?query=workflow%3Arelease)
5
+ [![CodeQL](https://github.com/opengood-ai/py-ml-plot/actions/workflows/codeql.yml/badge.svg)](https://github.com/opengood-ai/py-ml-plot/actions/workflows/codeql.yml)
6
+ [![Codecov](https://codecov.io/gh/opengood-ai/py-ml-plot/graph/badge.svg?token=WX6Er5S6Vj)](https://codecov.io/gh/opengood-ai/py-ml-plot)
7
+ [![Release Version](https://img.shields.io/github/release/opengood-ai/py-ml-plot.svg)](https://github.com/opengood-ai/py-ml-plot/releases/latest)
8
8
  [![PyPI](https://img.shields.io/pypi/v/opengood.py-ml-plot)](https://pypi.org/project/opengood.py-ml-plot/)
9
9
  ![Python](https://img.shields.io/pypi/pyversions/opengood.py-ml-plot)
10
- [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/opengood-aio/py-ml-plot/master/LICENSE)
10
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/opengood-ai/py-ml-plot/master/LICENSE)
11
11
 
12
12
  Modules containing reusable functions for machine learning visualization
13
13
  plotting
@@ -78,6 +78,10 @@ setup_classification_plot(
78
78
  title="Logistic Regression",
79
79
  x_label="Age",
80
80
  y_label="Estimated Salary",
81
+ meshgrid={
82
+ 0: {"min": 10, "max": 10, "step": 0.25},
83
+ 1: {"min": 1000, "max": 1000, "step": 0.25},
84
+ },
81
85
  feature_scale=lambda x_set, y_set: (
82
86
  sc.inverse_transform(x_set), y_set
83
87
  ),
@@ -94,7 +98,7 @@ plt.show()
94
98
 
95
99
  ##### Output
96
100
 
97
- ![Setup Classification Plot Visualization](https://raw.githubusercontent.com/opengood-aio/py-ml-plot/main/docs/images/setup-classification-plot-visualization.png)
101
+ ![Setup Classification Plot Visualization](https://raw.githubusercontent.com/opengood-ai/py-ml-plot/main/docs/images/setup-classification-plot-visualization.png)
98
102
 
99
103
  ---
100
104
 
@@ -105,8 +109,8 @@ plt.show()
105
109
  `feature_scale` lambda implementation logic for function
106
110
  `setup_classification_plot` is as follows:
107
111
 
108
- * Inverse feature scaling is invoked via a featuring scaling object, such as
109
- the `StandardScalar` object `sc` created earlier for feature scaling
112
+ * Inverse feature scaling is invoked via a feature scaling object, such as
113
+ the `StandardScaler` object `sc` created earlier for feature scaling
110
114
  * `x_set` and `y_set` are assigned non-feature scaled values of the matrix of
111
115
  features and the dependent variable
112
116
  * `x_set` values are inverted from their feature-scaled values in `x`
@@ -136,18 +140,22 @@ is as follows:
136
140
  Visualization implementation logic for function `setup_classification_plot` is
137
141
  as follows:
138
142
 
139
- * `ListedColormap` class from the Matplotlib library creates an object that
140
- generates a colormap visual from a list of colors
143
+ * If the `meshgrid` dict is not defined, a default set of dict attributes are
144
+ set providing min, max, and step values for each axis:
145
+ * `0` and `1` are used for the keys
146
+ * `10` and `1000` are used for `min` and `max` values
147
+ * `0.25` is used for `step` value
148
+ * If the `feature_scale` lambda is not defined, `x_set` and `y_set` are
149
+ assigned the values of `x` and `y`, respectively
141
150
  * If the `feature_scale` lambda is defined, `x_set` and `y_set` are
142
151
  assigned non-feature scaled values of the matrix of features and the dependent
143
152
  variable from the sets using a feature scaling object, such as the
144
- `StandardScalar` object created earlier for feature scaling
153
+ `StandardScaler` object created earlier for feature scaling
145
154
  * `x_set` values are inverted from their feature-scaled values in `x`
146
155
  * `y_set` values are not inverted and taken directly from `y`
147
- * If the `feature_scale` lambda is not defined, `x_set` and `y_set` are
148
- assigned the values of `x` and `y`, respectively
149
156
  * `meshgrid` function from the NumPy library returns a tuple of coordinate
150
157
  matrices from coordinate vectors
158
+ * The ranges for each axis are controlled by the `meshgrid` dict parameter
151
159
  * Two sets of matrices (`x1` and `x2`) are returned with coordinate vectors
152
160
  * `x1`
153
161
  * `arange` function is called with a defined start and stop interval
@@ -179,7 +187,7 @@ as follows:
179
187
  * `step` parameter
180
188
  * Spacing between values
181
189
  * Value of `0.25` is added for spacing
182
- * The prediction logic implemented in the `preodict` lambda is executed, and
190
+ * The prediction logic implemented in the `predict` lambda is executed, and
183
191
  the result is assigned to `y_pred`, containing the predictions
184
192
  * `contourf` function from the Matplotlib library is used for creating filled
185
193
  contour plots
@@ -256,32 +264,54 @@ as follows:
256
264
 
257
265
  ## Python Virtual Environment
258
266
 
259
- Create Python virtual environment:
267
+ Create and activate Python virtual environment:
260
268
 
261
269
  ```bash
262
- cd ~/workspace/opengood-aio/py-ml-plot/.venv
263
- python3 -m venv ~/workspace/opengood-aio/py-ml-plot/.venv
270
+ python3 -m venv .venv
264
271
  source .venv/bin/activate
265
272
  ```
266
273
 
267
- ## Install Packages
274
+ ## Install Dependencies
275
+
276
+ Install the package in editable mode with all dependencies:
277
+
278
+ ```bash
279
+ python3 -m pip install -e .
280
+ ```
281
+
282
+ Install with development dependencies (includes `pip-tools`, `pytest`, `pytest-cov`):
268
283
 
269
284
  ```bash
270
- python3 -m pip install matplotlib
271
- python3 -m pip install numpy
272
- python3 -m pip install pandas
273
- python3 -m pip install scikit-learn
285
+ python3 -m pip install -e ".[dev]"
274
286
  ```
275
287
 
276
- ## Create Requirements File
288
+ ## Generate Requirements File
289
+
290
+ Generate a pinned `requirements.txt` file from pyproject.toml:
277
291
 
278
292
  ```bash
279
- pip freeze > requirements.txt
293
+ pip-compile pyproject.toml -o requirements.txt
280
294
  ```
281
295
 
296
+ This creates a `requirements.txt` with exact versions of all dependencies and their transitive dependencies.
297
+
282
298
  ## Run Tests
283
299
 
300
+ Run all tests with coverage:
301
+
284
302
  ```bash
285
303
  python -m pytest tests/
286
304
  ```
287
305
 
306
+ Run tests with verbose output and coverage report:
307
+
308
+ ```bash
309
+ python -m pytest tests/ -v --cov=src.opengood.py_ml_plot --cov-report=term-missing
310
+ ```
311
+
312
+ Run a specific test:
313
+
314
+ ```bash
315
+ python -m pytest tests/py_ml_plot/test_classification_plot.py::TestClassificationPlot::test_logistic_regression_setup_classification_plot_with_shaded_regions
316
+ ```
317
+
@@ -1,10 +1,10 @@
1
1
  [build-system]
2
- requires = ["setuptools >= 77.0.3", "wheel"]
2
+ requires = ["setuptools >= 82.0.1", "wheel"]
3
3
  build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "opengood.py_ml_plot"
7
- version = "2.2.0"
7
+ version = "2.4.0"
8
8
  description = "Modules containing reusable functions for machine learning visualization plotting"
9
9
  authors = [
10
10
  { name = "OpenGood", email = "ai@opengood.ai" }
@@ -19,18 +19,26 @@ readme = "README.md"
19
19
  license = { file = "LICENSE" }
20
20
 
21
21
  dependencies = [
22
- "matplotlib >= 3.10.3",
23
- "numpy >= 2.3.0rc1",
24
- "pandas >= 2.2.3",
25
- "scikit-learn >= 1.7.0rc1",
22
+ "matplotlib >= 3.10.8",
23
+ "numpy >= 2.4.3",
24
+ "pandas >= 3.0.1",
25
+ "scikit-learn >= 1.8.0",
26
+ ]
27
+
28
+ [project.optional-dependencies]
29
+ dev = [
30
+ "pip-tools >= 7.5.3",
31
+ "pytest >= 9.0.2",
32
+ "pytest-cov >= 7.0.0",
26
33
  ]
27
34
 
28
35
  [project.urls]
29
- Homepage = "https://github.com/opengood-aio/py-ml-plot"
30
- Documentation = "https://github.com/opengood-aio/py-ml-plot"
36
+ Homepage = "https://github.com/opengood-ai/py-ml-plot"
37
+ Documentation = "https://github.com/opengood-ai/py-ml-plot"
31
38
 
32
39
  [tool.pytest.ini_options]
33
- addopts = "tests/ -v --cov=src.opengood.py_ml_plot --cov-report=xml --cov-fail-under=70"
40
+ addopts = "-v --cov=src.opengood.py_ml_plot --cov-report=xml --cov-fail-under=70"
41
+ testpaths = ["tests"]
34
42
  python_files = "test_*.py"
35
43
  python_functions = "test_*"
36
44
  markers = [
@@ -10,8 +10,9 @@ def setup_classification_plot(
10
10
  title,
11
11
  x_label,
12
12
  y_label,
13
- feature_scale: lambda x1, y1: (),
14
- predict: lambda x1, x2: (),
13
+ meshgrid=None,
14
+ feature_scale=None,
15
+ predict=None,
15
16
  ):
16
17
  """
17
18
  Sets up a classification plot with decision boundaries and classified regions.
@@ -27,6 +28,13 @@ def setup_classification_plot(
27
28
  title (str): Title for the plot.
28
29
  x_label (str): Label for the x-axis.
29
30
  y_label (str): Label for the y-axis.
31
+ meshgrid (dict[int, dict[str, float]]): Controls the np.meshgrid arange parameters for each axis.
32
+ Provide a dict with two entries indexed by 0 and 1 (x-axis and y-axis respectively),
33
+ where each entry is a dict with keys:
34
+ - "min": float padding to subtract from the min value for the start of the range
35
+ - "max": float padding to add to the max value for the end of the range
36
+ - "step": float step size between values in the range
37
+ Example: {0: {"min": 10, "max": 10, "step": 0.25}, 1: {"min": 1000, "max": 1000, "step": 0.25}}
30
38
  feature_scale (callable): Function to transform the feature data for visualization.
31
39
  Should take x and y as input and return the transformed x and y.
32
40
  If None, no transformation is applied.
@@ -44,18 +52,30 @@ def setup_classification_plot(
44
52
  ... title="Logistic Regression",
45
53
  ... x_label="Feature 1",
46
54
  ... y_label="Feature 2",
55
+ ... meshgrid={0: {"min": 10, "max": 10, "step": 0.25}, 1: {"min": 1000, "max": 1000, "step": 0.25}},
47
56
  ... feature_scale=lambda x_set, y_set: (x_set, y_set),
48
57
  ... predict=lambda x1, x2: classifier.predict(np.array([x1.ravel(), x2.ravel()]).T).reshape(x1.shape)
49
58
  ... )
50
59
  """
60
+ if meshgrid is None:
61
+ meshgrid = {
62
+ 0: {"min": 10, "max": 10, "step": 0.25},
63
+ 1: {"min": 1000, "max": 1000, "step": 0.25},
64
+ }
51
65
  if feature_scale is not None:
52
66
  x_set, y_set = feature_scale(x, y)
53
67
  else:
54
68
  x_set, y_set = x, y
55
69
  x1, x2 = np.meshgrid(
56
- np.arange(start=x_set[:, 0].min() - 10, stop=x_set[:, 0].max() + 10, step=0.25),
57
70
  np.arange(
58
- start=x_set[:, 1].min() - 1000, stop=x_set[:, 1].max() + 1000, step=0.25
71
+ start=x_set[:, 0].min() - meshgrid[0]["min"],
72
+ stop=x_set[:, 0].max() + meshgrid[0]["max"],
73
+ step=meshgrid[0]["step"],
74
+ ),
75
+ np.arange(
76
+ start=x_set[:, 1].min() - meshgrid[1]["min"],
77
+ stop=x_set[:, 1].max() + meshgrid[1]["max"],
78
+ step=meshgrid[1]["step"],
59
79
  ),
60
80
  )
61
81
  y_pred = predict(x1, x2)
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: opengood.py_ml_plot
3
- Version: 2.2.0
3
+ Version: 2.4.0
4
4
  Summary: Modules containing reusable functions for machine learning visualization plotting
5
5
  Author-email: OpenGood <ai@opengood.ai>
6
6
  License: MIT License
7
7
 
8
- Copyright (c) 2025 OpenGood
8
+ Copyright (c) 2025-2026 OpenGood
9
9
 
10
10
  Permission is hereby granted, free of charge, to any person obtaining a copy
11
11
  of this software and associated documentation files (the "Software"), to deal
@@ -25,30 +25,34 @@ License: MIT License
25
25
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
26
  SOFTWARE.
27
27
 
28
- Project-URL: Homepage, https://github.com/opengood-aio/py-ml-plot
29
- Project-URL: Documentation, https://github.com/opengood-aio/py-ml-plot
28
+ Project-URL: Homepage, https://github.com/opengood-ai/py-ml-plot
29
+ Project-URL: Documentation, https://github.com/opengood-ai/py-ml-plot
30
30
  Classifier: Programming Language :: Python :: 3
31
31
  Classifier: License :: OSI Approved :: MIT License
32
32
  Classifier: Operating System :: OS Independent
33
33
  Requires-Python: >=3.12
34
34
  Description-Content-Type: text/markdown
35
35
  License-File: LICENSE
36
- Requires-Dist: matplotlib>=3.10.3
37
- Requires-Dist: numpy>=2.3.0rc1
38
- Requires-Dist: pandas>=2.2.3
39
- Requires-Dist: scikit-learn>=1.7.0rc1
36
+ Requires-Dist: matplotlib>=3.10.8
37
+ Requires-Dist: numpy>=2.4.3
38
+ Requires-Dist: pandas>=3.0.1
39
+ Requires-Dist: scikit-learn>=1.8.0
40
+ Provides-Extra: dev
41
+ Requires-Dist: pip-tools>=7.5.3; extra == "dev"
42
+ Requires-Dist: pytest>=9.0.2; extra == "dev"
43
+ Requires-Dist: pytest-cov>=7.0.0; extra == "dev"
40
44
  Dynamic: license-file
41
45
 
42
46
  # Python Machine Learning (ML) Plot
43
47
 
44
- [![Build](https://github.com/opengood-aio/py-ml-plot/workflows/build/badge.svg)](https://github.com/opengood-aio/py-ml-plot/actions?query=workflow%3Abuild)
45
- [![Release](https://github.com/opengood-aio/py-ml-plot/workflows/release/badge.svg)](https://github.com/opengood-aio/py-ml-plot/actions?query=workflow%3Arelease)
46
- [![CodeQL](https://github.com/opengood-aio/py-ml-plot/actions/workflows/codeql.yml/badge.svg)](https://github.com/opengood-aio/py-ml-plot/actions/workflows/codeql.yml)
47
- [![Codecov](https://codecov.io/gh/opengood-aio/py-ml-plot/graph/badge.svg?token=WX6Er5S6Vj)](https://codecov.io/gh/opengood-aio/py-ml-plot)
48
- [![Release Version](https://img.shields.io/github/release/opengood-aio/py-ml-plot.svg)](https://github.com/opengood-aio/py-ml-plot/releases/latest)
48
+ [![Build](https://github.com/opengood-ai/py-ml-plot/workflows/build/badge.svg)](https://github.com/opengood-ai/py-ml-plot/actions?query=workflow%3Abuild)
49
+ [![Release](https://github.com/opengood-ai/py-ml-plot/workflows/release/badge.svg)](https://github.com/opengood-ai/py-ml-plot/actions?query=workflow%3Arelease)
50
+ [![CodeQL](https://github.com/opengood-ai/py-ml-plot/actions/workflows/codeql.yml/badge.svg)](https://github.com/opengood-ai/py-ml-plot/actions/workflows/codeql.yml)
51
+ [![Codecov](https://codecov.io/gh/opengood-ai/py-ml-plot/graph/badge.svg?token=WX6Er5S6Vj)](https://codecov.io/gh/opengood-ai/py-ml-plot)
52
+ [![Release Version](https://img.shields.io/github/release/opengood-ai/py-ml-plot.svg)](https://github.com/opengood-ai/py-ml-plot/releases/latest)
49
53
  [![PyPI](https://img.shields.io/pypi/v/opengood.py-ml-plot)](https://pypi.org/project/opengood.py-ml-plot/)
50
54
  ![Python](https://img.shields.io/pypi/pyversions/opengood.py-ml-plot)
51
- [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/opengood-aio/py-ml-plot/master/LICENSE)
55
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/opengood-ai/py-ml-plot/master/LICENSE)
52
56
 
53
57
  Modules containing reusable functions for machine learning visualization
54
58
  plotting
@@ -119,6 +123,10 @@ setup_classification_plot(
119
123
  title="Logistic Regression",
120
124
  x_label="Age",
121
125
  y_label="Estimated Salary",
126
+ meshgrid={
127
+ 0: {"min": 10, "max": 10, "step": 0.25},
128
+ 1: {"min": 1000, "max": 1000, "step": 0.25},
129
+ },
122
130
  feature_scale=lambda x_set, y_set: (
123
131
  sc.inverse_transform(x_set), y_set
124
132
  ),
@@ -135,7 +143,7 @@ plt.show()
135
143
 
136
144
  ##### Output
137
145
 
138
- ![Setup Classification Plot Visualization](https://raw.githubusercontent.com/opengood-aio/py-ml-plot/main/docs/images/setup-classification-plot-visualization.png)
146
+ ![Setup Classification Plot Visualization](https://raw.githubusercontent.com/opengood-ai/py-ml-plot/main/docs/images/setup-classification-plot-visualization.png)
139
147
 
140
148
  ---
141
149
 
@@ -146,8 +154,8 @@ plt.show()
146
154
  `feature_scale` lambda implementation logic for function
147
155
  `setup_classification_plot` is as follows:
148
156
 
149
- * Inverse feature scaling is invoked via a featuring scaling object, such as
150
- the `StandardScalar` object `sc` created earlier for feature scaling
157
+ * Inverse feature scaling is invoked via a feature scaling object, such as
158
+ the `StandardScaler` object `sc` created earlier for feature scaling
151
159
  * `x_set` and `y_set` are assigned non-feature scaled values of the matrix of
152
160
  features and the dependent variable
153
161
  * `x_set` values are inverted from their feature-scaled values in `x`
@@ -177,18 +185,22 @@ is as follows:
177
185
  Visualization implementation logic for function `setup_classification_plot` is
178
186
  as follows:
179
187
 
180
- * `ListedColormap` class from the Matplotlib library creates an object that
181
- generates a colormap visual from a list of colors
188
+ * If the `meshgrid` dict is not defined, a default set of dict attributes are
189
+ set providing min, max, and step values for each axis:
190
+ * `0` and `1` are used for the keys
191
+ * `10` and `1000` are used for `min` and `max` values
192
+ * `0.25` is used for `step` value
193
+ * If the `feature_scale` lambda is not defined, `x_set` and `y_set` are
194
+ assigned the values of `x` and `y`, respectively
182
195
  * If the `feature_scale` lambda is defined, `x_set` and `y_set` are
183
196
  assigned non-feature scaled values of the matrix of features and the dependent
184
197
  variable from the sets using a feature scaling object, such as the
185
- `StandardScalar` object created earlier for feature scaling
198
+ `StandardScaler` object created earlier for feature scaling
186
199
  * `x_set` values are inverted from their feature-scaled values in `x`
187
200
  * `y_set` values are not inverted and taken directly from `y`
188
- * If the `feature_scale` lambda is not defined, `x_set` and `y_set` are
189
- assigned the values of `x` and `y`, respectively
190
201
  * `meshgrid` function from the NumPy library returns a tuple of coordinate
191
202
  matrices from coordinate vectors
203
+ * The ranges for each axis are controlled by the `meshgrid` dict parameter
192
204
  * Two sets of matrices (`x1` and `x2`) are returned with coordinate vectors
193
205
  * `x1`
194
206
  * `arange` function is called with a defined start and stop interval
@@ -220,7 +232,7 @@ as follows:
220
232
  * `step` parameter
221
233
  * Spacing between values
222
234
  * Value of `0.25` is added for spacing
223
- * The prediction logic implemented in the `preodict` lambda is executed, and
235
+ * The prediction logic implemented in the `predict` lambda is executed, and
224
236
  the result is assigned to `y_pred`, containing the predictions
225
237
  * `contourf` function from the Matplotlib library is used for creating filled
226
238
  contour plots
@@ -297,32 +309,54 @@ as follows:
297
309
 
298
310
  ## Python Virtual Environment
299
311
 
300
- Create Python virtual environment:
312
+ Create and activate Python virtual environment:
301
313
 
302
314
  ```bash
303
- cd ~/workspace/opengood-aio/py-ml-plot/.venv
304
- python3 -m venv ~/workspace/opengood-aio/py-ml-plot/.venv
315
+ python3 -m venv .venv
305
316
  source .venv/bin/activate
306
317
  ```
307
318
 
308
- ## Install Packages
319
+ ## Install Dependencies
320
+
321
+ Install the package in editable mode with all dependencies:
322
+
323
+ ```bash
324
+ python3 -m pip install -e .
325
+ ```
326
+
327
+ Install with development dependencies (includes `pip-tools`, `pytest`, `pytest-cov`):
309
328
 
310
329
  ```bash
311
- python3 -m pip install matplotlib
312
- python3 -m pip install numpy
313
- python3 -m pip install pandas
314
- python3 -m pip install scikit-learn
330
+ python3 -m pip install -e ".[dev]"
315
331
  ```
316
332
 
317
- ## Create Requirements File
333
+ ## Generate Requirements File
334
+
335
+ Generate a pinned `requirements.txt` file from pyproject.toml:
318
336
 
319
337
  ```bash
320
- pip freeze > requirements.txt
338
+ pip-compile pyproject.toml -o requirements.txt
321
339
  ```
322
340
 
341
+ This creates a `requirements.txt` with exact versions of all dependencies and their transitive dependencies.
342
+
323
343
  ## Run Tests
324
344
 
345
+ Run all tests with coverage:
346
+
325
347
  ```bash
326
348
  python -m pytest tests/
327
349
  ```
328
350
 
351
+ Run tests with verbose output and coverage report:
352
+
353
+ ```bash
354
+ python -m pytest tests/ -v --cov=src.opengood.py_ml_plot --cov-report=term-missing
355
+ ```
356
+
357
+ Run a specific test:
358
+
359
+ ```bash
360
+ python -m pytest tests/py_ml_plot/test_classification_plot.py::TestClassificationPlot::test_logistic_regression_setup_classification_plot_with_shaded_regions
361
+ ```
362
+
@@ -0,0 +1,9 @@
1
+ matplotlib>=3.10.8
2
+ numpy>=2.4.3
3
+ pandas>=3.0.1
4
+ scikit-learn>=1.8.0
5
+
6
+ [dev]
7
+ pip-tools>=7.5.3
8
+ pytest>=9.0.2
9
+ pytest-cov>=7.0.0
@@ -1,4 +0,0 @@
1
- matplotlib>=3.10.3
2
- numpy>=2.3.0rc1
3
- pandas>=2.2.3
4
- scikit-learn>=1.7.0rc1