diff --git a/src/metpy/plots/declarative.py b/src/metpy/plots/declarative.py index f5558531d44..363ad697c1b 100644 --- a/src/metpy/plots/declarative.py +++ b/src/metpy/plots/declarative.py @@ -498,7 +498,18 @@ def lookup_map_feature(feature_name): return feat.with_scale(scaler) -class Panel(HasTraits): +class MetPyHasTraits(HasTraits): + """Provides modification layer on HasTraits for declarative classes.""" + + def __dir__(self): + """Filter dir to be more helpful for tab-completion in Jupyter.""" + return filter( + lambda name: not (name in dir(HasTraits) or name.startswith('_')), + dir(type(self)) + ) + + +class Panel(MetPyHasTraits): """Draw one or more plots.""" @property @@ -508,7 +519,7 @@ def plot_kwargs(self): @exporter.export -class PanelContainer(HasTraits): +class PanelContainer(MetPyHasTraits): """Collects panels and set complete figure related settings (e.g., size).""" size = Union([Tuple(Union([Int(), Float()]), Union([Int(), Float()])), @@ -677,7 +688,7 @@ def _valid_area(self, proposal): if isinstance(area, str): match = re.match(r'(\w+)([-+]*)$', area) if match is None: - raise TraitError(f'"{area}" is not a valid string area.') + raise TraitError(f'"{area}" is not a valid area.') region, modifier = match.groups() region = region.lower() @@ -865,7 +876,7 @@ def copy(self): return copy.copy(self) -class SubsetTraits(HasTraits): +class SubsetTraits(MetPyHasTraits): """Represent common traits for subsetting data.""" x = Union([Float(allow_none=True, default_value=None), Instance(units.Quantity)]) @@ -1131,7 +1142,7 @@ def draw(self): self._need_redraw = False -class ContourTraits(HasTraits): +class ContourTraits(MetPyHasTraits): """Represents common contour traits.""" contours = Union([List(Float()), Int()], default_value=25) @@ -1158,7 +1169,7 @@ class ContourTraits(HasTraits): """ -class ColorfillTraits(HasTraits): +class ColorfillTraits(MetPyHasTraits): """Represent common colorfill traits.""" colormap = Unicode(allow_none=True, default_value=None) @@ -1507,7 +1518,7 @@ def _build(self): @exporter.export -class PlotObs(HasTraits): +class PlotObs(MetPyHasTraits): """The highest level class related to plotting observed surface and upperair data. This class collects all common methods no matter whether plotting a upper-level or @@ -1837,7 +1848,7 @@ def copy(self): @exporter.export -class PlotGeometry(HasTraits): +class PlotGeometry(MetPyHasTraits): """Plot collections of Shapely objects and customize their appearance.""" parent = Instance(Panel) diff --git a/tests/plots/baseline/test_declarative_contour.png b/tests/plots/baseline/test_declarative_contour.png index 007fd5119ea..eaec887d48a 100644 Binary files a/tests/plots/baseline/test_declarative_contour.png and b/tests/plots/baseline/test_declarative_contour.png differ diff --git a/tests/plots/baseline/test_declarative_contour_convert_units.png b/tests/plots/baseline/test_declarative_contour_convert_units.png index 307a8a4b7da..670bf6c9da3 100644 Binary files a/tests/plots/baseline/test_declarative_contour_convert_units.png and b/tests/plots/baseline/test_declarative_contour_convert_units.png differ diff --git a/tests/plots/baseline/test_declarative_contour_options.png b/tests/plots/baseline/test_declarative_contour_options.png index 5b4d2d17d5b..d98911f174e 100644 Binary files a/tests/plots/baseline/test_declarative_contour_options.png and b/tests/plots/baseline/test_declarative_contour_options.png differ diff --git a/tests/plots/baseline/test_declarative_events.png b/tests/plots/baseline/test_declarative_events.png index 3ba255d0ce7..9ad5c2695b9 100644 Binary files a/tests/plots/baseline/test_declarative_events.png and b/tests/plots/baseline/test_declarative_events.png differ diff --git a/tests/plots/baseline/test_declarative_figsize.png b/tests/plots/baseline/test_declarative_figsize.png index a96b914c5df..1efaa0be5cd 100644 Binary files a/tests/plots/baseline/test_declarative_figsize.png and b/tests/plots/baseline/test_declarative_figsize.png differ diff --git a/tests/plots/test_declarative.py b/tests/plots/test_declarative.py index 5ab52aee9f2..4248ad59f93 100644 --- a/tests/plots/test_declarative.py +++ b/tests/plots/test_declarative.py @@ -65,7 +65,7 @@ def test_declarative_contour(): panel = MapPanel() panel.area = 'us' - panel.proj = 'lcc' + panel.projection = 'lcc' panel.layers = ['coastline', 'borders', 'usstates'] panel.plots = [contour] @@ -94,7 +94,7 @@ def test_declarative_figsize(): panel = MapPanel() panel.area = 'us' - panel.proj = 'lcc' + panel.projection = 'lcc' panel.layers = ['coastline', 'borders', 'usstates'] panel.plots = [contour] @@ -149,7 +149,7 @@ def fix_is_closed_polygon(monkeypatch): @pytest.mark.mpl_image_compare(remove_text=True, - tolerance={'3.0': 23.964}.get(MPL_VERSION, 0.0184)) + tolerance={'3.0': 25.026}.get(MPL_VERSION, 0.0276)) @needs_cartopy def test_declarative_contour_options(fix_is_closed_polygon): """Test making a contour plot.""" @@ -167,7 +167,7 @@ def test_declarative_contour_options(fix_is_closed_polygon): panel = MapPanel() panel.area = 'us' - panel.proj = 'lcc' + panel.projection = 'lcc' panel.layers = ['coastline', 'borders', 'usstates'] panel.plots = [contour] @@ -180,7 +180,7 @@ def test_declarative_contour_options(fix_is_closed_polygon): @pytest.mark.mpl_image_compare(remove_text=True, - tolerance={'3.0': 19.795}.get(MPL_VERSION, 0.0134)) + tolerance={'3.0': 19.795}.get(MPL_VERSION, 0.0157)) @needs_cartopy def test_declarative_contour_convert_units(fix_is_closed_polygon): """Test making a contour plot.""" @@ -199,7 +199,7 @@ def test_declarative_contour_convert_units(fix_is_closed_polygon): panel = MapPanel() panel.area = 'us' - panel.proj = 'lcc' + panel.projection = 'lcc' panel.layers = ['coastline', 'borders', 'usstates'] panel.plots = [contour] @@ -212,7 +212,7 @@ def test_declarative_contour_convert_units(fix_is_closed_polygon): @pytest.mark.mpl_image_compare(remove_text=True, - tolerance={'3.0': 0.051}.get(MPL_VERSION, 0)) + tolerance={'3.0': 0.051}.get(MPL_VERSION, 0.0022)) @needs_cartopy def test_declarative_events(): """Test that resetting traitlets properly propagates.""" @@ -235,7 +235,7 @@ def test_declarative_events(): panel = MapPanel() panel.area = 'us' - panel.proj = 'lcc' + panel.projection = 'lcc' panel.layers = ['coastline', 'borders', 'states'] panel.plots = [contour, img] @@ -1132,7 +1132,7 @@ def test_declarative_sfc_obs_change_units(ccrs): obs.time_window = timedelta(minutes=15) obs.level = None obs.fields = ['air_temperature'] - obs.color = ['black'] + obs.colors = ['black'] obs.plot_units = ['degF'] # Panel for plot with Map features @@ -1497,7 +1497,7 @@ def test_declarative_plot_geometry_polygons(): pc = PanelContainer() pc.size = (12, 12) pc.panels = [panel] - pc.show() + pc.draw() return pc.figure @@ -1536,7 +1536,7 @@ def test_declarative_plot_geometry_lines(ccrs): pc = PanelContainer() pc.size = (12, 12) pc.panels = [panel] - pc.show() + pc.draw() return pc.figure @@ -1576,6 +1576,25 @@ def test_declarative_plot_geometry_points(ccrs): pc = PanelContainer() pc.size = (12, 12) pc.panels = [panel] - pc.show() + pc.draw() return pc.figure + + +@needs_cartopy +def test_drop_traitlets_dir(): + """Test successful drop of inherited members from HasTraits and any '_' or '__' members.""" + for plot_obj in ( + BarbPlot, + ContourPlot, + FilledContourPlot, + ImagePlot, + MapPanel, + PanelContainer, + PlotGeometry, + PlotObs + ): + assert dir(plot_obj)[0].startswith('_') + assert not dir(plot_obj())[0].startswith('_') + assert 'cross_validation_lock' in dir(plot_obj) + assert 'cross_validation_lock' not in dir(plot_obj())