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

failing upstream-dev CI: matplotlib #4226

Closed
keewis opened this issue Jul 15, 2020 · 1 comment · Fixed by #4256
Closed

failing upstream-dev CI: matplotlib #4226

keewis opened this issue Jul 15, 2020 · 1 comment · Fixed by #4256

Comments

@keewis
Copy link
Collaborator

keewis commented Jul 15, 2020

Recent changes in matplotlib (my guess is matplotlib/matplotlib#17830) seem to have broken a few of our tests:

tracebacks
________________________ TestContour.test_single_level _________________________

self = <xarray.tests.test_plot.TestContour object at 0x7fc60f7c3e20>

        # add_colorbar defaults to false
>       self.plotmethod(levels=[0.1])

xarray/tests/test_plot.py:1561: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
xarray/plot/plot.py:827: in plotmethod
    return newplotfunc(**allargs)
xarray/plot/plot.py:699: in newplotfunc
    cmap_params, cbar_kwargs = _process_cmap_cbar_kwargs(
xarray/plot/utils.py:819: in _process_cmap_cbar_kwargs
    cmap_params = _determine_cmap_params(**cmap_kwargs)
xarray/plot/utils.py:291: in _determine_cmap_params
    cmap, newnorm = _build_discrete_cmap(cmap, levels, extend, filled)
xarray/plot/utils.py:77: in _build_discrete_cmap
    new_cmap, cnorm = mpl.colors.from_levels_and_colors(levels, pal, extend=extend)
/usr/share/miniconda/envs/xarray-tests/lib/python3.8/site-packages/matplotlib/colors.py:2200: in from_levels_and_colors
    norm = BoundaryNorm(levels, ncolors=n_data_colors)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <matplotlib.colors.BoundaryNorm object at 0x7fc60f5048e0>
boundaries = [0.1], ncolors = 0, clip = False

    def __init__(self, boundaries, ncolors, clip=False, *, extend='neither'):
        """
        Parameters
        ----------
        boundaries : array-like
            Monotonically increasing sequence of at least 2 boundaries.
        ncolors : int
            Number of colors in the colormap to be used.
        clip : bool, optional
        """
        if clip and extend != 'neither':
            raise ValueError("'clip=True' is not compatible with 'extend'")
        self.clip = clip
        self.vmin = boundaries[0]
        self.vmax = boundaries[-1]
        self.boundaries = np.asarray(boundaries)
        self.N = len(self.boundaries)
        if self.N < 2:
>           raise ValueError("You must provide at least 2 boundaries "
                             f"(1 region) but you passed in {boundaries!r}")
E           ValueError: You must provide at least 2 boundaries (1 region) but you passed in [0.1]

/usr/share/miniconda/envs/xarray-tests/lib/python3.8/site-packages/matplotlib/colors.py:1508: ValueError
________________________ test_facetgrid_single_contour _________________________

    @requires_matplotlib
    def test_facetgrid_single_contour():

    @requires_matplotlib
    def test_facetgrid_single_contour():
        # regression test for GH3569
        x, y = np.meshgrid(np.arange(12), np.arange(12))
        z = xr.DataArray(np.sqrt(x ** 2 + y ** 2))
        z2 = xr.DataArray(np.sqrt(x ** 2 + y ** 2) + 1)
        ds = xr.concat([z, z2], dim="time")
        ds["time"] = [0, 1]
    
>       ds.plot.contour(col="time", levels=[4], colors=["k"])

xarray/tests/test_plot.py:2409: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
xarray/plot/plot.py:827: in plotmethod
    return newplotfunc(**allargs)
xarray/plot/plot.py:638: in newplotfunc
    return _easy_facetgrid(darray, kind="dataarray", **allargs)
xarray/plot/facetgrid.py:644: in _easy_facetgrid
    return g.map_dataarray(plotfunc, x, y, **kwargs)
xarray/plot/facetgrid.py:248: in map_dataarray
    cmap_params, cbar_kwargs = _process_cmap_cbar_kwargs(
xarray/plot/utils.py:819: in _process_cmap_cbar_kwargs
    cmap_params = _determine_cmap_params(**cmap_kwargs)
xarray/plot/utils.py:291: in _determine_cmap_params
    cmap, newnorm = _build_discrete_cmap(cmap, levels, extend, filled)
xarray/plot/utils.py:77: in _build_discrete_cmap
    new_cmap, cnorm = mpl.colors.from_levels_and_colors(levels, pal, extend=extend)
/usr/share/miniconda/envs/xarray-tests/lib/python3.8/site-packages/matplotlib/colors.py:2200: in from_levels_and_colors
    norm = BoundaryNorm(levels, ncolors=n_data_colors)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
self = <matplotlib.colors.BoundaryNorm object at 0x7fc60d47b280>
boundaries = [4], ncolors = 0, clip = False

    def __init__(self, boundaries, ncolors, clip=False, *, extend='neither'):
        """
        Parameters
        ----------
        boundaries : array-like
            Monotonically increasing sequence of at least 2 boundaries.
        ncolors : int
            Number of colors in the colormap to be used.
        clip : bool, optional
            If clip is ``True``, out of range values are mapped to 0 if they
            are below ``boundaries[0]`` or mapped to ``ncolors - 1`` if they
            are above ``boundaries[-1]``.
    
            If clip is ``False``, out of range values are mapped to -1 if
            they are below ``boundaries[0]`` or mapped to *ncolors* if they are
            above ``boundaries[-1]``. These are then converted to valid indices
            by `Colormap.__call__`.
        extend : {'neither', 'both', 'min', 'max'}, default: 'neither'
            Extend the number of bins to include one or both of the
            regions beyond the boundaries.  For example, if ``extend``
            is 'min', then the color to which the region between the first
            pair of boundaries is mapped will be distinct from the first
            color in the colormap, and by default a
            `~matplotlib.colorbar.Colorbar` will be drawn with
            the triangle extension on the left or lower end.
    
        Returns
        -------
        int16 scalar or array
    
        Notes
        -----
        *boundaries* defines the edges of bins, and data falling within a bin
        is mapped to the color with the same index.
    
        If the number of bins, including any extensions, is less than
        *ncolors*, the color index is chosen by linear interpolation, mapping
        the ``[0, nbins - 1]`` range onto the ``[0, ncolors - 1]`` range.
        """
        if clip and extend != 'neither':
            raise ValueError("'clip=True' is not compatible with 'extend'")
        self.clip = clip
        self.vmin = boundaries[0]
        self.vmax = boundaries[-1]
        self.boundaries = np.asarray(boundaries)
        self.N = len(self.boundaries)
        if self.N < 2:
>           raise ValueError("You must provide at least 2 boundaries "
                             f"(1 region) but you passed in {boundaries!r}")
E           ValueError: You must provide at least 2 boundaries (1 region) but you passed in [4]

/usr/share/miniconda/envs/xarray-tests/lib/python3.8/site-packages/matplotlib/colors.py:1508: ValueError
@tacaswell
Copy link

That changes was definitely intentional in BoundaryNorm, but we thought that we were giving a clear error in a case where you used to get a divide by 0 error.

I think we used to implicitly change 1 boundary into a degenerate 2 boundary, I can see the argument that we should be more forgiving, but in boundry norm I'm not sure what that would mean (internally we are going to make every value to either over or under. If you want to support this at the xarray level you should do the [4] -> [4, 4] conversion which will work with all version of Matplotlib.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants