Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add contour kwargs to plot_decision_regions. #881

Merged
merged 9 commits into from
Jan 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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