Skip to content

image_range trait in declarative plotting interface doesn't accept arbitrary floating point values #3027

@wxmann

Description

@wxmann

What went wrong?

There's really two issues in one, but I didn't want to clog up the issue list. The two are related, and both seem to be small changes.

  1. The image_range trait for ImagePlot in the declarative plotting interface doesn't accept arbitrary floating point values, only integer ranges.

  2. The image_range trait accepts mpl.Normalize instances, but setting an mpl.Normalize instance causes the plotting to blow up.

These are small changes and I'm more than happy to put up PR's to fix these, but wanted to run them by the team.

Operating System

MacOS

Version

1.4.1

Python Version

3.11.3

Code to Reproduce

ds = xr.open_dataset(get_test_data('narr_example.nc')).metpy.parse_cf().sel(time='1987-04-04T18:00:00', isobaric=500)

img = ImagePlot()
img.data = ds
img.field = 'Temperature'

# first issue:
img.image_range = (14.5, 25.5)

# second issue: 
from matplotlib.colors import Normalize
img.image_range = Normalize(vmin=14.5, vmax=25.5)

panel = MapPanel()
panel.area = [-107, -93, 29, 41]
panel.projection = 'lcc'
panel.layers = ['states', 'coastline', 'borders']
panel.plots = [img]

pc = PanelContainer()
pc.size = (14, 18)
pc.panels = [panel]

pc.show()

Errors, Traceback, and Logs

TraitError                                Traceback (most recent call last)
Cell In[5], line 4
      2 img.data = ds
      3 img.field = 'Temperature'
----> 4 img.image_range = (14.5, 25.5)
      6 panel = MapPanel()
      7 panel.area = [-107, -93, 29, 41]

File ~/miniconda3/envs/yt-env/lib/python3.11/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 ~/miniconda3/envs/yt-env/lib/python3.11/site-packages/traitlets/traitlets.py:732, in TraitType.__set__(self, obj, value)
    730     raise TraitError('The "%s" trait is read-only.' % self.name)
    731 else:
--> 732     self.set(obj, value)

File ~/miniconda3/envs/yt-env/lib/python3.11/site-packages/traitlets/traitlets.py:706, in TraitType.set(self, obj, value)
    705 def set(self, obj, value):
--> 706     new_value = self._validate(obj, value)
    707     try:
    708         old_value = obj._trait_values[self.name]

File ~/miniconda3/envs/yt-env/lib/python3.11/site-packages/traitlets/traitlets.py:738, in TraitType._validate(self, obj, value)
    736     return value
    737 if hasattr(self, "validate"):
--> 738     value = self.validate(obj, value)
    739 if obj._cross_validation_lock is False:
    740     value = self._cross_validate(obj, value)

File ~/miniconda3/envs/yt-env/lib/python3.11/site-packages/traitlets/traitlets.py:2306, in Union.validate(self, obj, value)
   2304         except TraitError:
   2305             continue
-> 2306 self.error(obj, value)

File ~/miniconda3/envs/yt-env/lib/python3.11/site-packages/traitlets/traitlets.py:844, in TraitType.error(self, obj, value, error, info)
    838 else:
    839     e = "The '{}' trait expected {}, not {}.".format(
    840         self.name,
    841         self.info(),
    842         describe("the", value),
    843     )
--> 844 raise TraitError(e)

TraitError: The 'image_range' trait of an ImagePlot instance expected a tuple or a Normalize, not the tuple (14.5, 25.5).

Here's the traceback for the Normalize issue:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[7], line 18
     15 pc.size = (14, 18)
     16 pc.panels = [panel]
---> 18 pc.show()

File ~/miniconda3/envs/yt-env/lib/python3.11/site-packages/metpy/plots/declarative.py:622, in PanelContainer.show(self)
    620 def show(self):
    621     """Show the constructed graphic on the screen."""
--> 622     self.draw()
    623     plt.show()

File ~/miniconda3/envs/yt-env/lib/python3.11/site-packages/metpy/plots/declarative.py:609, in PanelContainer.draw(self)
    607 for panel in self.panels:
    608     with panel.hold_trait_notifications():
--> 609         panel.draw()

File ~/miniconda3/envs/yt-env/lib/python3.11/site-packages/metpy/plots/declarative.py:897, in MapPanel.draw(self)
    895 for p in self.plots:
    896     with p.hold_trait_notifications():
--> 897         p.draw()
    899 # Add all of the maps
    900 if len(self.layers) > len(self.layers_edgecolor):

File ~/miniconda3/envs/yt-env/lib/python3.11/site-packages/metpy/plots/declarative.py:1259, in PlotScalar.draw(self)
   1257 if self._need_redraw:
   1258     if getattr(self, 'handle', None) is None:
-> 1259         self._build()
   1260     if getattr(self, 'colorbar', None) is not None:
   1261         cbar = self.parent.ax.figure.colorbar(
   1262             self.handle, orientation=self.colorbar, pad=0, aspect=50)

File ~/miniconda3/envs/yt-env/lib/python3.11/site-packages/metpy/plots/declarative.py:1383, in ImagePlot._build(self)
   1377 kwargs['extent'] = (x_like[0], x_like[-1], y_like.min(), y_like.max())
   1378 kwargs['origin'] = 'upper' if y_like[0] > y_like[-1] else 'lower'
   1380 self.handle = self.parent.ax.imshow(
   1381     imdata,
   1382     cmap=self._cmap_obj,
-> 1383     norm=self._norm_obj,
   1384     **kwargs
   1385 )

File ~/miniconda3/envs/yt-env/lib/python3.11/site-packages/metpy/plots/declarative.py:1049, in Plots2D._norm_obj(self)
   1042 @property
   1043 def _norm_obj(self):
   1044     """Return the normalization object.
   1045 
   1046     Converts the tuple image range to a matplotlib normalization instance.
   1047 
   1048     """
-> 1049     return plt.Normalize(*self.image_range)

TypeError: matplotlib.colors.Normalize() argument after * must be an iterable, not Normalize

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area: PlotsPertains to producing plotsType: BugSomething is not working like it should

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions