Home > Mobile >  Why 'DiscreteNorm' object has no attribute '_vmin'?
Why 'DiscreteNorm' object has no attribute '_vmin'?

Time:07-14

I have an issue while doing a contourf with proplot (advanced Matplotlib in a certain way). I have attached an example of proplot documentation (cells 3 and 4) which is not working neither where I am getting the same error at the end.

Create data

import xarray as xr
import numpy as np
import pandas as pd

# DataArray
state = np.random.RandomState(51423)
linspace = np.linspace(0, np.pi, 20)
data = 50 * state.normal(1, 0.2, size=(20, 20)) * (
    np.sin(linspace * 2) ** 2
    * np.cos(linspace   np.pi / 2)[:, None] ** 2
)
lat = xr.DataArray(
    np.linspace(-90, 90, 20),
    dims=('lat',),
    attrs={'units': '\N{DEGREE SIGN}N'}
)
plev = xr.DataArray(
    np.linspace(1000, 0, 20),
    dims=('plev',),
    attrs={'long_name': 'pressure', 'units': 'hPa'}
)
da = xr.DataArray(
    data,
    name='u',
    dims=('plev', 'lat'),
    coords={'plev': plev, 'lat': lat},
    attrs={'long_name': 'zonal wind', 'units': 'm/s'}
)

# DataFrame
data = state.rand(12, 20)
df = pd.DataFrame(
    (data - 0.4).cumsum(axis=0).cumsum(axis=1)[::1, ::-1],
    index=pd.date_range('2000-01', '2000-12', freq='MS')
)
df.name = 'temperature (\N{DEGREE SIGN}C)'
df.index.name = 'date'
df.columns.name = 'variable (units)'

Trying to plot the data

fig = pp.figure(refwidth=2.5, share=False, suptitle='Automatic subplot formatting')

# Plot DataArray
cmap = pp.Colormap('PuBu', left=0.05)
ax = fig.subplot(121, yreverse=True)
ax.contourf(da, cmap=cmap, colorbar='t', lw=0.7, ec='k')

# Plot DataFrame
ax = fig.subplot(122, yreverse=True)
ax.contourf(df, cmap='YlOrRd', colorbar='t', lw=0.7, ec='k')
ax.format(xtickminor=False, yformatter='%b', ytickminor=False)

Returned error

AttributeError                            Traceback (most recent call last)
Input In [780], in <module>
      4 cmap = pp.Colormap('PuBu', left=0.05)
      5 ax = fig.subplot(121, yreverse=True)
----> 6 ax.contourf(da, cmap=cmap, colorbar='t', lw=0.7, ec='k')
      8 # Plot DataFrame
      9 ax = fig.subplot(122, yreverse=True)

File /opt/anaconda3/envs/argopy-tests/lib/python3.8/site-packages/proplot/internals/process.py:284, in _preprocess_args.<locals>.decorator.<locals>._redirect_or_standardize(self, *args, **kwargs)
    281             ureg.setup_matplotlib(True)
    283 # Call main function
--> 284 return func(self, *args, **kwargs)

File /opt/anaconda3/envs/argopy-tests/lib/python3.8/site-packages/proplot/axes/plot.py:3861, in PlotAxes.contourf(self, x, y, z, **kwargs)
   3859 x, y, z, kw = self._parse_plot2d(x, y, z, **kwargs)
   3860 kw.update(_pop_props(kw, 'collection'))
-> 3861 kw = self._parse_cmap(x, y, z, plot_contours=True, **kw)
   3862 contour_kw = _pop_kwargs(kw, 'edgecolors', 'linewidths', 'linestyles')
   3863 edgefix_kw = _pop_params(kw, self._apply_edgefix)

File /opt/anaconda3/envs/argopy-tests/lib/python3.8/site-packages/proplot/internals/warnings.py:96, in _rename_kwargs.<locals>.decorator.<locals>._deprecate_kwargs(*args, **kwargs)
     91         key_new = key_new.format(value)
     92     _warn_proplot(
     93         f'Keyword {key_old!r} was deprecated in version {version} and will '
     94         f'be removed in a future release. Please use {key_new!r} instead.'
     95     )
---> 96 return func_orig(*args, **kwargs)

File /opt/anaconda3/envs/argopy-tests/lib/python3.8/site-packages/proplot/axes/plot.py:2703, in PlotAxes._parse_cmap(self, cmap, cmap_kw, c, color, colors, default_cmap, norm, norm_kw, extend, vmin, vmax, discrete, default_discrete, skip_autolev, plot_lines, plot_contours, min_levels, *args, **kwargs)
   2700 # Create the discrete normalizer
   2701 # Then finally warn and remove unused args
   2702 if levels is not None:
-> 2703     norm, cmap, kwargs = self._parse_discrete(
   2704         levels, norm, cmap, extend=extend, min_levels=min_levels, **kwargs
   2705     )
   2706 methods = (self._parse_levels, self._parse_autolev, self._parse_vlim)
   2707 params = _pop_params(kwargs, *methods, ignore_internal=True)

File /opt/anaconda3/envs/argopy-tests/lib/python3.8/site-packages/proplot/axes/plot.py:2529, in PlotAxes._parse_discrete(self, levels, norm, cmap, extend, min_levels, **kwargs)
   2526 # Generate DiscreteNorm and update "child" norm with vmin and vmax from
   2527 # levels. This lets the colorbar set tick locations properly!
   2528 if not isinstance(norm, mcolors.BoundaryNorm) and len(levels) > 1:
-> 2529     norm = pcolors.DiscreteNorm(levels, norm=norm, unique=unique, step=step)
   2531 return norm, cmap, kwargs

File /opt/anaconda3/envs/argopy-tests/lib/python3.8/site-packages/proplot/internals/warnings.py:96, in _rename_kwargs.<locals>.decorator.<locals>._deprecate_kwargs(*args, **kwargs)
     91         key_new = key_new.format(value)
     92     _warn_proplot(
     93         f'Keyword {key_old!r} was deprecated in version {version} and will '
     94         f'be removed in a future release. Please use {key_new!r} instead.'
     95     )
---> 96 return func_orig(*args, **kwargs)

File /opt/anaconda3/envs/argopy-tests/lib/python3.8/site-packages/proplot/colors.py:2459, in DiscreteNorm.__init__(self, levels, norm, unique, step, clip)
   2457 self._dest = dest
   2458 self._norm = norm
-> 2459 self.vmin = vmin
   2460 self.vmax = vmax
   2461 self.boundaries = levels

File /opt/anaconda3/envs/argopy-tests/lib/python3.8/site-packages/matplotlib/colors.py:1148, in Normalize.vmin(self, value)
   1145 @vmin.setter
   1146 def vmin(self, value):
   1147     value = _sanitize_extrema(value)
-> 1148     if value != self._vmin:
   1149         self._vmin = value
   1150         self._changed()

AttributeError: 'DiscreteNorm' object has no attribute '_vmin'

Is it my environment ? I don't really know. If you try the same thing from your home it must work. I may have to go into more detail in the proplot source code. I hope someone has an idea before.

CodePudding user response:

There was something wrong between libraries (proplot installed quickly with !pip install proplot), I think between Matplotlib and Proplot.

I double checked creating new environment with conda and the error disappeared. Anyway, better to pass by conda to build the environment than using pip which can bring some discrepancies with previous loaded libraries.

  • Related