diff --git a/src/metpy/plots/declarative.py b/src/metpy/plots/declarative.py index cc001e096c3..27450b94cb3 100644 --- a/src/metpy/plots/declarative.py +++ b/src/metpy/plots/declarative.py @@ -647,6 +647,15 @@ class MapPanel(Panel): This trait sets a user-defined title that will plot at the top center of the figure. """ + title_fontsize = Union([Int(), Float(), Unicode()], allow_none=True, default_value=None) + title_fontsize.__doc__ = """An integer or string value for the font size of the title of the + figure. + + This trait sets the font size for the title that will plot at the top center of the figure. + Accepts size in points or relative size. Allowed relative sizes are those of Matplotlib: + 'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large'. + """ + @observe('plots') def _plots_changed(self, change): """Handle when our collection of plots changes.""" @@ -756,7 +765,7 @@ def draw(self): # Use the set title or generate one. title = self.title or ',\n'.join(plot.name for plot in self.plots) - self.ax.set_title(title) + self.ax.set_title(title, fontsize=self.title_fontsize) self._need_redraw = False def __copy__(self): @@ -987,8 +996,9 @@ def draw(self): if getattr(self, 'handle', None) is None: self._build() if getattr(self, 'colorbar', None) is not None: - self.parent.ax.figure.colorbar( - self.handle, orientation=self.colorbar, pad=0, aspect=50) + self.parent.ax.figure.colorbar(self.handle, orientation=self.colorbar, + pad=0, aspect=50)\ + .ax.tick_params(labelsize=self.colorbar_fontsize) self._need_redraw = False @@ -1010,6 +1020,14 @@ class ContourTraits(HasTraits): To plot contour labels set this trait to ``True``, the default value is ``False``. """ + label_fontsize = Union([Int(), Float(), Unicode()], allow_none=True, default_value=None) + label_fontsize.__doc__ = """An integer, float, or string value to set the font size of labels for contours. + + This trait sets the font size for labels that will plot along contour lines. Accepts + size in points or relative size. Allowed relative sizes are those of Matplotlib: + 'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large'. + """ + class ColorfillTraits(HasTraits): """Represent common colorfill traits.""" @@ -1037,6 +1055,15 @@ class ColorfillTraits(HasTraits): ``None``. """ + colorbar_fontsize = Union([Int(), Float(), Unicode()], allow_none=True, default_value=None) + colorbar_fontsize.__doc__ = """An integer, float, or string value to set the font size of + labels for the colorbar. + + This trait sets the font size of labels for the colorbar. Accepts size in points or + relative size. Allowed relative sizes are those of Matplotlib: 'xx-small', 'x-small', + 'small', 'medium', 'large', 'x-large', 'xx-large'. + """ + @exporter.export class ImagePlot(PlotScalar, ColorfillTraits): @@ -1115,7 +1142,7 @@ class ContourPlot(PlotScalar, ContourTraits): dashdot. """ - @observe('contours', 'linecolor', 'linewidth', 'linestyle', 'clabels') + @observe('contours', 'linecolor', 'linewidth', 'linestyle', 'clabels', 'clabelsize') def _set_need_rebuild(self, _): """Handle changes to attributes that need to regenerate everything.""" # Because matplotlib doesn't let you just change these properties, we need @@ -1131,7 +1158,7 @@ def _build(self): transform=imdata.metpy.cartopy_crs) if self.clabels: self.handle.clabel(inline=1, fmt='%.0f', inline_spacing=8, - use_clabeltext=True) + use_clabeltext=True, fontsize=self.label_fontsize) @exporter.export @@ -1336,6 +1363,7 @@ class PlotObs(HasTraits): * vector_field_length (optional) * vector_plot_units (optional) * reduce_points (optional) + * fontsize (optional) """ parent = Instance(Panel) @@ -1431,6 +1459,10 @@ class PlotObs(HasTraits): plotting using the MetPy Units module, provided that units are attached to the DataFrame. """ + fontsize = Int(10) + fontsize.__doc__ = """An integer value to set the font size of station plots. Default + is 10 pt.""" + def clear(self): """Clear the plot. @@ -1579,7 +1611,7 @@ def _build(self): subset = reduce_point_density(point_locs, self.reduce_points * scale) self.handle = StationPlot(self.parent.ax, lon[subset], lat[subset], clip_on=True, - transform=ccrs.PlateCarree(), fontsize=10) + transform=ccrs.PlateCarree(), fontsize=self.fontsize) for i, ob_type in enumerate(self.fields): field_kwargs = {} diff --git a/tests/plots/baseline/test_declarative_font_sizes.png b/tests/plots/baseline/test_declarative_font_sizes.png new file mode 100644 index 00000000000..8cddbe1f091 Binary files /dev/null and b/tests/plots/baseline/test_declarative_font_sizes.png differ diff --git a/tests/plots/test_declarative.py b/tests/plots/test_declarative.py index 35bb0e60483..b20fbea1d4f 100644 --- a/tests/plots/test_declarative.py +++ b/tests/plots/test_declarative.py @@ -1150,6 +1150,131 @@ def test_declarative_multiple_sfc_obs_change_units(ccrs): return pc.figure +@pytest.mark.mpl_image_compare(remove_text=False, tolerance=0.607) +@needs_cartopy +def test_declarative_title_fontsize(): + """Test adjusting the font size of a MapPanel's title text.""" + data = xr.open_dataset(get_test_data('NAM_test.nc', as_file_obj=False)) + + contour = ContourPlot() + contour.data = data + contour.field = 'Geopotential_height_isobaric' + contour.level = 300 * units.hPa + contour.linewidth = 2 + contour.contours = list(range(0, 2000, 12)) + contour.scale = 1e-1 + + panel = MapPanel() + panel.area = (-124, -72, 20, 53) + panel.projection = 'lcc' + panel.layers = ['coastline', 'borders', 'usstates'] + panel.plots = [contour] + panel.title = '300 mb Geopotential Height' + panel.title_fontsize = 20 + + pc = PanelContainer() + pc.size = (8, 8) + pc.panels = [panel] + pc.draw() + + return pc.figure + + +@pytest.mark.mpl_image_compare(remove_text=False, tolerance=0.607) +@needs_cartopy +def test_declarative_colorbar_fontsize(): + """Test adjusting the font size of a colorbar.""" + data = xr.open_dataset(get_test_data('GFS_test.nc', as_file_obj=False)) + + cfill = FilledContourPlot() + cfill.data = data + cfill.field = 'Temperature_isobaric' + cfill.level = 300 * units.hPa + cfill.time = datetime(2010, 10, 26, 12) + cfill.contours = list(range(210, 250, 2)) + cfill.colormap = 'BuPu' + cfill.colorbar = 'horizontal' + cfill.colorbar_fontsize = 'x-small' + + panel = MapPanel() + panel.area = (-124, -72, 20, 53) + panel.projection = 'lcc' + panel.layers = ['coastline', 'borders', 'usstates'] + panel.plots = [cfill] + + pc = PanelContainer() + pc.size = (8, 8) + pc.panels = [panel] + pc.draw() + + return pc.figure + + +@pytest.mark.mpl_image_compare(remove_text=True, tolerance=0.607) +@needs_cartopy +def test_declarative_station_plot_fontsize(): + """Test adjusting the font size for station plots in PlotObs.""" + data = parse_metar_file(get_test_data('metar_20190701_1200.txt', + as_file_obj=False), year=2019, month=7) + obs = PlotObs() + obs.data = data + obs.time = datetime(2019, 7, 1, 12) + obs.time_window = timedelta(minutes=15) + obs.level = None + obs.fields = ['cloud_coverage', 'air_temperature', 'dew_point_temperature', + 'air_pressure_at_sea_level', 'current_wx1_symbol'] + obs.plot_units = [None, 'degF', 'degF', None, None] + obs.locations = ['C', 'NW', 'SW', 'NE', 'W'] + obs.formats = ['sky_cover', None, None, lambda v: format(v * 10, '.0f')[-3:], + 'current_weather'] + obs.reduce_points = 3 + obs.vector_field = ['eastward_wind', 'northward_wind'] + obs.fontsize = 8 + + panel = MapPanel() + panel.area = 'centus' + panel.projection = 'lcc' + panel.layers = ['coastline', 'borders', 'usstates'] + panel.plots = [obs] + + pc = PanelContainer() + pc.size = (8, 8) + pc.panels = [panel] + pc.draw() + + return pc.figure + + +@pytest.mark.mpl_image_compare(remove_text=True, tolerance=0.607) +@needs_cartopy +def test_declarative_contour_label_fontsize(): + """Test adjusting the font size of contour labels.""" + data = xr.open_dataset(get_test_data('NAM_test.nc', as_file_obj=False)) + + contour = ContourPlot() + contour.data = data + contour.field = 'Geopotential_height_isobaric' + contour.level = 300 * units.hPa + contour.linewidth = 2 + contour.contours = list(range(0, 2000, 12)) + contour.scale = 1e-1 + contour.clabels = True + contour.label_fontsize = 'xx-large' + + panel = MapPanel() + panel.area = (-124, -72, 20, 53) + panel.projection = 'lcc' + panel.layers = ['coastline', 'borders', 'usstates'] + panel.plots = [contour] + + pc = PanelContainer() + pc.size = (8, 8) + pc.panels = [panel] + pc.draw() + + return pc.figure + + def test_save(): """Test that our saving function works.""" pc = PanelContainer()