Repository: SarthakJariwala/seaborn-image

Issue:
Drop support for python 3.6, 3.7
`numpy`, `scikit-image` and `scipy` have dropped support for 3.6


Discussion:

Resolving patch:
diff --git a/examples/plot_filtergrid.py b/examples/plot_paramgrid.py
similarity index 62%
rename from examples/plot_filtergrid.py
rename to examples/plot_paramgrid.py
--- a/examples/plot_filtergrid.py
+++ b/examples/plot_paramgrid.py
@@ -1,13 +1,13 @@
 """
-Interplay between filter parameters using FilterGrid
-====================================================
+Interplay between function parameters using ParamGrid
+=====================================================
 """
 
 import seaborn_image as isns
 
 img = isns.load_image("polymer")
 
-g = isns.FilterGrid(
+g = isns.ParamGrid(
     img,
     "gaussian",
     row="sigma",
diff --git a/src/seaborn_image/_grid.py b/src/seaborn_image/_grid.py
--- a/src/seaborn_image/_grid.py
+++ b/src/seaborn_image/_grid.py
@@ -9,7 +9,7 @@
 from ._general import imgplot
 from .utils import despine
 
-__all__ = ["FilterGrid", "ImageGrid", "rgbplot"]
+__all__ = ["ParamGrid", "ImageGrid", "rgbplot", "FilterGrid"]
 
 
 class ImageGrid:
@@ -875,19 +875,24 @@ def rgbplot(
 # TODO allow gridspec_kws and subplot_kws
 
 
-class FilterGrid(object):
-    """Generate a grid of images with the specific filter applied to all
-    the images. This class allows exploration of different parameters of
-    the filters across the rows and columns of the grid. Additional filter
+class ParamGrid(object):
+    """This class allows exploration of different parameters of
+    a function across the rows and columns of the grid. Additional function
     parameters that are not to be varied can also be passed.
 
+    Generates a grid of images with the specific function applied to all
+    the images.
+
     Parameters
     ----------
     data :
         Image data (array-like). Supported array shapes are all
         `matplotlib.pyplot.imshow` array shapes
-    filt : str or callable
-        Filter name or function to be applied.
+    map_func : callable or str
+        Function to be applied/mapped to data. Can be any callable that accepts data
+        as the the first input parameter.
+        If using a `str`, must one of the implemented filter functions in `seaborn_image`.
+        You can check implemented filters using `seaborn_image.implemented_filters()`.
     row : str, optional
         Parameter name that is to be displayed
         along the row. Defaults to None.
@@ -950,9 +955,9 @@ class FilterGrid(object):
         Defaults to None.
     **kwargs : Additional parameters as keyword arguments to be passed to the underlying filter specified.
 
-     Returns
+    Returns
     -------
-        A `seabron_image.FilterGrid` object
+        A `seabron_image.ParamGrid` object
 
     Raises
     ------
@@ -976,28 +981,28 @@ class FilterGrid(object):
 
         >>> import seaborn_image as isns
         >>> img = isns.load_image("polymer")
-        >>> g = isns.FilterGrid(img, "median", col="size", size=[2,3,4,5])
+        >>> g = isns.ParamGrid(img, "median", col="size", size=[2,3,4,5])
 
     Or rows
 
     .. plot::
         :context: close-figs
 
-        >>> g = isns.FilterGrid(img, "median", row="size", size=[2,3,4,5])
+        >>> g = isns.ParamGrid(img, "median", row="size", size=[2,3,4,5])
 
     Use `col_wrap` to control column display
 
     .. plot::
         :context: close-figs
 
-        >>> g = isns.FilterGrid(img, "median", col="size", size=[2,3,4,5], col_wrap=3)
+        >>> g = isns.ParamGrid(img, "median", col="size", size=[2,3,4,5], col_wrap=3)
 
     Use `col` and `row` to display different parameters along the columns and rows
 
     .. plot::
         :context: close-figs
 
-        >>> g = isns.FilterGrid(img,
+        >>> g = isns.ParamGrid(img,
         ...                     "percentile",
         ...                     row="percentile",
         ...                     col="size",
@@ -1009,14 +1014,14 @@ class FilterGrid(object):
     .. plot::
         :context: close-figs
 
-        >>> g = isns.FilterGrid(img, "median", col="size", size=[2,3,4,5], mode="reflect")
+        >>> g = isns.ParamGrid(img, "median", col="size", size=[2,3,4,5], mode="reflect")
 
     General image controls such as changing colormap, scalebar, etc.
 
     .. plot::
         :context: close-figs
 
-        >>> g = isns.FilterGrid(
+        >>> g = isns.ParamGrid(
         ...                     img,
         ...                     "median",
         ...                     col="size",
@@ -1029,7 +1034,7 @@ class FilterGrid(object):
     def __init__(
         self,
         data,
-        filt,
+        map_func,
         *,
         row=None,
         col=None,
@@ -1058,8 +1063,8 @@ def __init__(
         if data is None:
             raise ValueError("image data can not be None")
 
-        if filt is None:
-            raise ValueError("'filt' can not be None; must be a string or callable")
+        if map_func is None:
+            raise ValueError("'map_func' can not be None; must be a string or callable")
 
         row_params = []
         if row is not None:
@@ -1131,7 +1136,7 @@ def __init__(
 
         # Public API
         self.data = data
-        self.filt = filt
+        self.map_func = map_func
         self.fig = fig
         self.axes = axes
         self.row = row
@@ -1229,7 +1234,7 @@ def _plot(self, ax, **func_kwargs):
 
         filterplot(
             self.data,
-            self.filt,
+            self.map_func,
             ax=ax,
             cmap=self.cmap,
             alpha=self.alpha,
@@ -1272,3 +1277,15 @@ def _cleanup_extra_axes(self):
     def _finalize_grid(self):
         """Finalize grid with tight layout."""
         self.fig.tight_layout()
+
+
+class FilterGrid:
+    """Deprecated - use `ParamGrid` instead."""
+
+    def __init__(self, *args, **kwargs):
+        warnings.warn(
+            "FilterGrid is depracted and will be removed in a future release."
+            "Use ParamGrid instead with the same arguments.",
+            UserWarning,
+        )
+        ParamGrid(*args, **kwargs)


Test patch:
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -10,11 +10,11 @@ jobs:
       fail-fast: false
       matrix:
         include:
-          - { python-version: 3.8, os: ubuntu-latest }
-          - { python-version: 3.7, os: ubuntu-latest }
-          - { python-version: 3.6, os: ubuntu-latest }
-          - { python-version: 3.8, os: windows-latest }
-          - { python-version: 3.8, os: macos-latest }
+          - { python-version: "3.10", os: ubuntu-latest }
+          - { python-version: "3.9", os: ubuntu-latest }
+          - { python-version: "3.8", os: ubuntu-latest }
+          - { python-version: "3.10", os: windows-latest }
+          - { python-version: "3.10", os: macos-latest }
 
     steps:
       - uses: actions/checkout@v2.3.4
diff --git a/tests/test_grid.py b/tests/test_grid.py
--- a/tests/test_grid.py
+++ b/tests/test_grid.py
@@ -611,53 +611,53 @@ def test_rgbplot_vmin_vmax():
     plt.close()
 
 
-class TestFilterGrid(object):
+class TestParamGrid(object):
 
     data = np.random.random(2500).reshape((50, 50))
 
     def test_none_data(self):
         with pytest.raises(ValueError):
-            isns.FilterGrid(None, "sobel")
+            isns.ParamGrid(None, "sobel")
 
     def test_none_filt(self):
         with pytest.raises(ValueError):
-            isns.FilterGrid(self.data, None)
+            isns.ParamGrid(self.data, None)
 
     def test_self_data(self):
-        g = isns.FilterGrid(self.data, "sobel")
+        g = isns.ParamGrid(self.data, "sobel")
         np.testing.assert_array_equal(self.data, g.data)
         plt.close()
 
     def test_self_fig(self):
-        g = isns.FilterGrid(self.data, "sobel")
+        g = isns.ParamGrid(self.data, "sobel")
         assert isinstance(g.fig, Figure)
         plt.close()
 
     def test_rows(self):
         with pytest.raises(TypeError):
-            _ = isns.FilterGrid(self.data, "gaussian", row=gaussian, sigma=[1, 2, 3])
+            _ = isns.ParamGrid(self.data, "gaussian", row=gaussian, sigma=[1, 2, 3])
 
         with pytest.raises(ValueError):
-            _ = isns.FilterGrid(self.data, "gaussian", row="sigma")
+            _ = isns.ParamGrid(self.data, "gaussian", row="sigma")
 
     def test_cols(self):
         with pytest.raises(TypeError):
-            _ = isns.FilterGrid(self.data, "gaussian", col=gaussian, sigma=[1, 2, 3])
+            _ = isns.ParamGrid(self.data, "gaussian", col=gaussian, sigma=[1, 2, 3])
 
         with pytest.raises(ValueError):
-            _ = isns.FilterGrid(self.data, "gaussian", col="sigma")
+            _ = isns.ParamGrid(self.data, "gaussian", col="sigma")
 
     def test_self_axes(self):
 
-        g0 = isns.FilterGrid(self.data, "sobel")
+        g0 = isns.ParamGrid(self.data, "sobel")
         for ax in g0.axes.flat:
             assert isinstance(ax, Axes)
 
-        g1 = isns.FilterGrid(self.data, "gaussian", row="sigma", sigma=[1, 2, 3])
+        g1 = isns.ParamGrid(self.data, "gaussian", row="sigma", sigma=[1, 2, 3])
         for ax in g1.axes.flat:
             assert isinstance(ax, Axes)
 
-        g2 = isns.FilterGrid(
+        g2 = isns.ParamGrid(
             self.data,
             "gaussian",
             row="mode",
@@ -672,16 +672,16 @@ def test_self_axes(self):
 
     def test_axes_shape(self):
 
-        g0 = isns.FilterGrid(self.data, "sobel")
+        g0 = isns.ParamGrid(self.data, "sobel")
         assert g0.axes.shape == (1, 1)
 
-        g1 = isns.FilterGrid(self.data, "gaussian", row="sigma", sigma=[1, 2, 3])
+        g1 = isns.ParamGrid(self.data, "gaussian", row="sigma", sigma=[1, 2, 3])
         assert g1.axes.shape == (3, 1)
 
-        g2 = isns.FilterGrid(self.data, "gaussian", col="sigma", sigma=[1, 2, 3])
+        g2 = isns.ParamGrid(self.data, "gaussian", col="sigma", sigma=[1, 2, 3])
         assert g2.axes.shape == (1, 3)
 
-        g3 = isns.FilterGrid(
+        g3 = isns.ParamGrid(
             self.data,
             "gaussian",
             row="sigma",
@@ -691,7 +691,7 @@ def test_axes_shape(self):
         )
         assert g3.axes.shape == (3, 2)
 
-        g4 = isns.FilterGrid(
+        g4 = isns.ParamGrid(
             self.data,
             "gaussian",
             row="mode",
@@ -708,19 +708,19 @@ def test_axes_shape(self):
 
     def test_col_wrap(self):
 
-        g0 = isns.FilterGrid(
+        g0 = isns.ParamGrid(
             self.data, "gaussian", col="sigma", sigma=[1, 2, 3, 4, 5], col_wrap=3
         )
         assert g0.axes.shape == (2, 3)
         plt.close()
 
         with pytest.raises(ValueError):
-            isns.FilterGrid(
+            isns.ParamGrid(
                 self.data, "gaussian", row="sigma", sigma=[1, 2, 3, 4, 5], col_wrap=3
             )
 
         with pytest.raises(ValueError):
-            isns.FilterGrid(
+            isns.ParamGrid(
                 self.data,
                 "gaussian",
                 row="mode",
@@ -732,17 +732,17 @@ def test_col_wrap(self):
 
     def test_additional_kwargs_for_filters(self):
 
-        isns.FilterGrid(
+        isns.ParamGrid(
             self.data, "gaussian", row="sigma", sigma=[1, 2, 3], mode="reflect"
         )
         plt.close()
 
-        isns.FilterGrid(
+        isns.ParamGrid(
             self.data, "gaussian", col="sigma", sigma=[1, 2, 3], mode="reflect"
         )
         plt.close()
 
-        isns.FilterGrid(
+        isns.ParamGrid(
             self.data,
             "gaussian",
             row="sigma",
@@ -755,13 +755,13 @@ def test_additional_kwargs_for_filters(self):
 
     def test_figure_size(self):
 
-        g0 = isns.FilterGrid(self.data, "sobel")
+        g0 = isns.ParamGrid(self.data, "sobel")
         np.testing.assert_array_equal(g0.fig.get_size_inches(), (3, 3))
 
-        g1 = isns.FilterGrid(self.data, "gaussian", row="sigma", sigma=[1, 2, 3])
+        g1 = isns.ParamGrid(self.data, "gaussian", row="sigma", sigma=[1, 2, 3])
         np.testing.assert_array_equal(g1.fig.get_size_inches(), (3, 9))
 
-        g2 = isns.FilterGrid(
+        g2 = isns.ParamGrid(
             self.data,
             "gaussian",
             row="sigma",
@@ -771,7 +771,7 @@ def test_figure_size(self):
         )
         np.testing.assert_array_equal(g2.fig.get_size_inches(), (6, 9))
 
-        g3 = isns.FilterGrid(
+        g3 = isns.ParamGrid(
             self.data,
             "gaussian",
             row="sigma",
@@ -782,7 +782,7 @@ def test_figure_size(self):
         )
         np.testing.assert_array_equal(g3.fig.get_size_inches(), (4, 6))
 
-        g4 = isns.FilterGrid(
+        g4 = isns.ParamGrid(
             self.data,
             "gaussian",
             row="sigma",
@@ -797,7 +797,7 @@ def test_figure_size(self):
         plt.close("all")
 
     def test_vmin_vmax(self):
-        g = isns.FilterGrid(
+        g = isns.ParamGrid(
             self.data,
             "gaussian",
             row="sigma",
@@ -810,3 +810,14 @@ def test_vmin_vmax(self):
             assert ax.images[0].colorbar.vmin == 0
             assert ax.images[0].colorbar.vmax == 2
         plt.close()
+
+
+def test_FilterGrid_deprecation_warning():
+    with pytest.warns(UserWarning, match="FilterGrid is depracted"):
+        _ = isns.FilterGrid(
+            np.random.random(2500).reshape((50, 50)),
+            "median",
+            col="size",
+            size=[2, 3, 4, 5],
+        )
+        plt.close()