What should we add?
I failed to think more generally the last time I submitted a similar issue (#2122). Code like the following generates the desired result (with a suitably defined div):
from itertools import chain
from metpy.plots.declarative import ContourPlot, MapPanel, PanelContainer
# Nonreproducible code skipped
def contours_pn(upper, interval=1):
return chain(range(-upper, 0, interval), range(interval, upper+1, interval))
cp = ContourPlot()
cp.data = div
cp.linestyle = None
cp.contours = list(contours_pn(10))
cp.scale = 1e5
cp.clabels = True
mp = MapPanel()
mp.layout = (1,1,1)
mp.area = [-120, -65, 20, 55]
mp.layers = ['coastline', 'states', 'borders']
mp.plots = [cp]
pc = PanelContainer()
pc.size = (12, 10)
pc.panels = [mp]
pc.save('div.png')

However, omitting the list call, which seems superfluous, crashes:
---------------------------------------------------------------------------
TraitError Traceback (most recent call last)
Input In [29], in <cell line: 4>()
2 cp.data = div
3 cp.linestyle = None
----> 4 cp.contours = contours_pn(10)
5 cp.scale = 1e5
6 cp.clabels = True
File /usr/local/python/3.8/envs/met433/lib/python3.9/site-packages/metpy/plots/declarative.py:526, in ValidationMixin.__setattr__(self, name, value)
524 allowlist.extend(self.trait_names())
525 if name in allowlist or name.startswith('_'):
--> 526 super().__setattr__(name, value)
527 else:
528 closest = get_close_matches(name, allowlist, n=1)
File /usr/local/python/3.8/envs/met433/lib/python3.9/site-packages/traitlets/traitlets.py:715, in TraitType.__set__(self, obj, value)
713 raise TraitError('The "%s" trait is read-only.' % self.name)
714 else:
--> 715 self.set(obj, value)
File /usr/local/python/3.8/envs/met433/lib/python3.9/site-packages/traitlets/traitlets.py:689, in TraitType.set(self, obj, value)
688 def set(self, obj, value):
--> 689 new_value = self._validate(obj, value)
690 try:
691 old_value = obj._trait_values[self.name]
File /usr/local/python/3.8/envs/met433/lib/python3.9/site-packages/traitlets/traitlets.py:721, in TraitType._validate(self, obj, value)
719 return value
720 if hasattr(self, "validate"):
--> 721 value = self.validate(obj, value) # type:ignore[attr-defined]
722 if obj._cross_validation_lock is False:
723 value = self._cross_validate(obj, value)
File /usr/local/python/3.8/envs/met433/lib/python3.9/site-packages/traitlets/traitlets.py:2174, in Union.validate(self, obj, value)
2172 except TraitError:
2173 continue
-> 2174 self.error(obj, value)
File /usr/local/python/3.8/envs/met433/lib/python3.9/site-packages/traitlets/traitlets.py:827, in TraitType.error(self, obj, value, error, info)
821 else:
822 e = "The '{}' trait expected {}, not {}.".format(
823 self.name,
824 self.info(),
825 describe("the", value),
826 )
--> 827 raise TraitError(e)
TraitError: The 'contours' trait of a ContourPlot instance expected a list or an int or a range, not the chain at '0x7f7230b25be0'.
This is definitely in the weeds, easy to work around, and there are bigger fish to fry, but this would be a nice enhancement. On the other hand, this would allow potentially infinite iterable objects to be specified, although I have a hard time thinking of a case where that might happen.
Reference
No response
What should we add?
I failed to think more generally the last time I submitted a similar issue (#2122). Code like the following generates the desired result (with a suitably defined
div):However, omitting the
listcall, which seems superfluous, crashes:This is definitely in the weeds, easy to work around, and there are bigger fish to fry, but this would be a nice enhancement. On the other hand, this would allow potentially infinite iterable objects to be specified, although I have a hard time thinking of a case where that might happen.
Reference
No response