Skip to content

Commit

Permalink
Merge pull request #881 from pbloem/master
Browse files Browse the repository at this point in the history
Add contour kwargs to plot_decision_regions.
  • Loading branch information
rasbt committed Jan 19, 2022
2 parents 80964e4 + 632f636 commit 5a14e37
Show file tree
Hide file tree
Showing 23 changed files with 102 additions and 53 deletions.
20 changes: 15 additions & 5 deletions .github/workflows/python-package-conda.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
name: Python Package using Conda
name: Tests

on: [push]
on:
push:
branches: master
pull_request:
branches: master

jobs:
build-linux:
Expand Down Expand Up @@ -30,9 +34,15 @@ jobs:
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Test with pytest
run: |
conda install numpy scipy scikit-learn pandas tensorflow joblib pytest
conda install imageio scikit-image
conda install -c conda-forge dlib
conda config --add channels conda-forge
conda update numpy scipy scikit-learn pandas -y -q
conda install tensorflow joblib pytest -y -q
conda install imageio scikit-image -y -q
conda install dlib -y -q
pip install markdown
pip install -e .
python -c "import numpy; print('NumPy:', numpy.__version__)"
python -c "import scipy; print('SciPy:', scipy.__version__)"
python -c "import sklearn; print('Scikit-learn:', sklearn.__version__)"
python -c "import pandas; print('Pandas:', pandas.__version__)"
pytest -sv
3 changes: 2 additions & 1 deletion docs/sources/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ The CHANGELOG for the current development version is available at



##### New Features
##### New Features and Enhancements

- The `mlxtend.evaluate.bootstrap_point632_score` now supports `fit_params`. ([#861](https://github.com/rasbt/mlxtend/pull/861))
- The `mlxtend/plotting/decision_regions.py` function now has a `contourf_kwargs` for matplotlib to change the look of the decision boundaries if desired. ([#881](https://github.com/rasbt/mlxtend/pull/881) via [[pbloem](https://github.com/pbloem)])

##### Changes

Expand Down
34 changes: 31 additions & 3 deletions docs/sources/user_guide/plotting/plot_decision_regions.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -1055,7 +1055,7 @@
"text": [
"## plot_decision_regions\n",
"\n",
"*plot_decision_regions(X, y, clf, feature_index=None, filler_feature_values=None, filler_feature_ranges=None, ax=None, X_highlight=None, zoom_factor=1.0, legend=1, hide_spines=True, markers='s^oxv<>', colors='#1f77b4,#ff7f0e,#3ca02c,#d62728,#9467bd,#8c564b,#e377c2,#7f7f7f,#bcbd22,#17becf', scatter_kwargs=None, contourf_kwargs=None, scatter_highlight_kwargs=None)*\n",
"*plot_decision_regions(X, y, clf, feature_index=None, filler_feature_values=None, filler_feature_ranges=None, ax=None, X_highlight=None, zoom_factor=1.0, legend=1, hide_spines=True, markers='s^oxv<>', colors='#1f77b4,#ff7f0e,#3ca02c,#d62728,#9467bd,#8c564b,#e377c2,#7f7f7f,#bcbd22,#17becf', scatter_kwargs=None, contourf_kwargs=None, contour_kwargs=None, scatter_highlight_kwargs=None)*\n",
"\n",
"Plot decision regions of a classifier.\n",
"\n",
Expand All @@ -1072,69 +1072,90 @@
"\n",
" Feature Matrix.\n",
"\n",
"\n",
"- `y` : array-like, shape = [n_samples]\n",
"\n",
" True class labels.\n",
"\n",
"\n",
"- `clf` : Classifier object.\n",
"\n",
" Must have a .predict method.\n",
"\n",
"\n",
"- `feature_index` : array-like (default: (0,) for 1D, (0, 1) otherwise)\n",
"\n",
" Feature indices to use for plotting. The first index in\n",
" `feature_index` will be on the x-axis, the second index will be\n",
" on the y-axis.\n",
"\n",
"\n",
"- `filler_feature_values` : dict (default: None)\n",
"\n",
" Only needed for number features > 2. Dictionary of feature\n",
" index-value pairs for the features not being plotted.\n",
"\n",
"\n",
"- `filler_feature_ranges` : dict (default: None)\n",
"\n",
" Only needed for number features > 2. Dictionary of feature\n",
" index-value pairs for the features not being plotted. Will use the\n",
" ranges provided to select training samples for plotting.\n",
"\n",
"\n",
"- `ax` : matplotlib.axes.Axes (default: None)\n",
"\n",
" An existing matplotlib Axes. Creates\n",
" one if ax=None.\n",
"\n",
"\n",
"- `X_highlight` : array-like, shape = [n_samples, n_features] (default: None)\n",
"\n",
" An array with data points that are used to highlight samples in `X`.\n",
"\n",
"\n",
"- `zoom_factor` : float (default: 1.0)\n",
"\n",
" Controls the scale of the x- and y-axis of the decision plot.\n",
"\n",
"\n",
"- `hide_spines` : bool (default: True)\n",
"\n",
" Hide axis spines if True.\n",
"\n",
"\n",
"- `legend` : int (default: 1)\n",
"\n",
" Integer to specify the legend location.\n",
" No legend if legend is 0.\n",
"\n",
"\n",
"- `markers` : str (default: 's^oxv<>')\n",
"\n",
" Scatterplot markers.\n",
"\n",
"\n",
"- `colors` : str (default: 'red,blue,limegreen,gray,cyan')\n",
"\n",
" Comma separated list of colors.\n",
"\n",
"\n",
"- `scatter_kwargs` : dict (default: None)\n",
"\n",
" Keyword arguments for underlying matplotlib scatter function.\n",
"\n",
"\n",
"- `contourf_kwargs` : dict (default: None)\n",
"\n",
" Keyword arguments for underlying matplotlib contourf function.\n",
"\n",
"\n",
"- `contour_kwargs` : dict (default: None)\n",
"\n",
" Keyword arguments for underlying matplotlib contour function\n",
" (which draws the lines between decision regions).\n",
"\n",
"\n",
"- `scatter_highlight_kwargs` : dict (default: None)\n",
"\n",
" Keyword arguments for underlying matplotlib scatter function.\n",
Expand All @@ -1157,12 +1178,19 @@
"with open('../../api_modules/mlxtend.plotting/plot_decision_regions.md', 'r') as f:\n",
" print(f.read())"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"anaconda-cloud": {},
"kernelspec": {
"display_name": "Python 3",
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
Expand All @@ -1176,7 +1204,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.8"
"version": "3.9.6"
},
"toc": {
"nav_menu": {},
Expand Down
8 changes: 4 additions & 4 deletions mlxtend/classifier/tests/test_ensemble_vote_classifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from mlxtend.data import iris_data
from mlxtend.utils import assert_raises

from distutils.version import LooseVersion as Version
from packaging.version import Version
from sklearn import __version__ as sklearn_version

X, y = iris_data()
Expand Down Expand Up @@ -198,7 +198,7 @@ def test_EnsembleVoteClassifier_gridsearch():
params = {'logisticregression__C': [1.0, 100.0],
'randomforestclassifier__n_estimators': [20, 200]}

if Version(sklearn_version) < '0.24.1':
if Version(sklearn_version) < Version('0.24.1'):
grid = GridSearchCV(estimator=eclf, param_grid=params, cv=5, iid=False)
else:
grid = GridSearchCV(estimator=eclf, param_grid=params, cv=5)
Expand All @@ -225,7 +225,7 @@ def test_EnsembleVoteClassifier_gridsearch_enumerate_names():
'randomforestclassifier__n_estimators': [5, 20],
'voting': ['hard', 'soft']}

if Version(sklearn_version) < '0.24.1':
if Version(sklearn_version) < Version('0.24.1'):
grid = GridSearchCV(estimator=eclf, param_grid=params, cv=5, iid=False)
else:
grid = GridSearchCV(estimator=eclf, param_grid=params, cv=5)
Expand Down Expand Up @@ -261,7 +261,7 @@ def test_classifier_gridsearch():

params = {'clfs': [[clf1, clf1, clf1], [clf2, clf3]]}

if Version(sklearn_version) < '0.24.1':
if Version(sklearn_version) < Version('0.24.1'):
grid = GridSearchCV(estimator=eclf,
param_grid=params,
iid=False,
Expand Down
2 changes: 1 addition & 1 deletion mlxtend/classifier/tests/test_stacking_classifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# License: BSD 3 clause

import random
from distutils.version import LooseVersion as Version
from packaging.version import Version

import numpy as np
import pytest
Expand Down
8 changes: 4 additions & 4 deletions mlxtend/classifier/tests/test_stacking_cv_classifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# License: BSD 3 clause

import random
from distutils.version import LooseVersion as Version
from packaging.version import Version

import numpy as np
import pandas as pd
Expand Down Expand Up @@ -206,7 +206,7 @@ def test_gridsearch():
params = {'meta_classifier__C': [1.0, 100.0],
'randomforestclassifier__n_estimators': [20, 200]}

if Version(sklearn_version) < '0.24.1':
if Version(sklearn_version) < Version('0.24.1'):
grid = GridSearchCV(estimator=sclf, param_grid=params, cv=5, iid=False)
else:
grid = GridSearchCV(estimator=sclf, param_grid=params, cv=5)
Expand All @@ -233,7 +233,7 @@ def test_gridsearch_enumerate_names():
'randomforestclassifier-2__n_estimators': [5, 20],
'use_probas': [True, False]}

if Version(sklearn_version) < '0.24.1':
if Version(sklearn_version) < Version('0.24.1'):
grid = GridSearchCV(estimator=sclf, param_grid=params, cv=5, iid=False)
else:
grid = GridSearchCV(estimator=sclf, param_grid=params, cv=5)
Expand Down Expand Up @@ -405,7 +405,7 @@ def test_classifier_gridsearch():

params = {'classifiers': [[clf1], [clf1, clf2, clf3]]}

if Version(sklearn_version) < '0.24.1':
if Version(sklearn_version) < Version('0.24.1'):
grid = GridSearchCV(estimator=sclf,
param_grid=params,
cv=5,
Expand Down
10 changes: 5 additions & 5 deletions mlxtend/evaluate/tests/test_bootstrap_point632.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,6 @@ def test_scoring_proba():
random_seed=123)



if 'TRAVIS' in os.environ or os.environ.get('TRAVIS') == 'true':
TRAVIS = True
else:
Expand All @@ -178,15 +177,16 @@ def test_scoring_proba():
else:
APPVEYOR = False


@pytest.mark.skipif(TRAVIS or APPVEYOR, reason="TensorFlow dependency")
def test_keras_fitparams():
import tensorflow as tf

model = tf.keras.Sequential([
tf.keras.layers.Dense(32, activation=tf.nn.relu),
tf.keras.layers.Dense(1)])
tf.keras.layers.Dense(32, activation=tf.nn.relu),
tf.keras.layers.Dense(1)])

optimizer = tf.keras.optimizers.Adam()
model.compile(loss='mean_squared_error', optimizer=optimizer)

model.fit(X, y, epochs=5)
model.fit(X, y, epochs=5)
2 changes: 1 addition & 1 deletion mlxtend/evaluate/tests/test_combined_ftest_5x2cv.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from sklearn.linear_model import Ridge
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from distutils.version import LooseVersion as Version
from packaging.version import Version
from sklearn import __version__ as sklearn_version


Expand Down
6 changes: 3 additions & 3 deletions mlxtend/evaluate/tests/test_holdout.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from mlxtend.evaluate import PredefinedHoldoutSplit
from mlxtend.data import iris_data

from distutils.version import LooseVersion as Version
from packaging.version import Version
from sklearn import __version__ as sklearn_version


Expand Down Expand Up @@ -68,7 +68,7 @@ def test_randomholdoutsplit_in_sfs():
def test_randomholdoutsplit_in_grid():
params = {'n_neighbors': [1, 2, 3, 4, 5]}

if Version(sklearn_version) < '0.24.1':
if Version(sklearn_version) < Version('0.24.1'):
grid = GridSearchCV(KNeighborsClassifier(),
iid=False,
param_grid=params,
Expand Down Expand Up @@ -135,7 +135,7 @@ def test_predefinedholdoutsplit_in_sfs():
def test_predefinedholdoutsplit_in_grid():
params = {'n_neighbors': [1, 3, 5]}

if Version(sklearn_version) < '0.24.1':
if Version(sklearn_version) < Version('0.24.1'):
grid = GridSearchCV(KNeighborsClassifier(),
param_grid=params,
iid=False,
Expand Down
2 changes: 1 addition & 1 deletion mlxtend/evaluate/tests/test_paired_ttest_5x2cv.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from sklearn.linear_model import Ridge
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from distutils.version import LooseVersion as Version
from packaging.version import Version
from sklearn import __version__ as sklearn_version


Expand Down
2 changes: 1 addition & 1 deletion mlxtend/evaluate/tests/test_paired_ttest_resampled.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from sklearn.linear_model import Ridge
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from distutils.version import LooseVersion as Version
from packaging.version import Version
from sklearn import __version__ as sklearn_version


Expand Down
2 changes: 1 addition & 1 deletion mlxtend/feature_selection/tests/test_column_selector.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from sklearn.pipeline import make_pipeline
from sklearn.model_selection import GridSearchCV

from distutils.version import LooseVersion as Version
from packaging.version import Version
from sklearn import __version__ as sklearn_version


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import numpy as np
import pandas as pd
from distutils.version import LooseVersion as Version
from packaging.version import Version
from numpy.testing import assert_almost_equal
from mlxtend.feature_selection import ExhaustiveFeatureSelector as EFS
from sklearn.ensemble import RandomForestClassifier
Expand Down
Loading

0 comments on commit 5a14e37

Please sign in to comment.