def test_get_plot_params_vel_mpl5(self): desired = { 'bitmasks': self.bitmasks()['2.0.2'], 'cmap': 'RdBu_r', 'percentile_clip': [10, 90], 'symmetric': True, 'snr_min': None } actual = get_plot_params(dapver='2.0.2', prop='stellar_vel') self.assertDictEqual(actual, desired)
def test_get_plot_params_sigma_mpl5(self): desired = { 'bitmasks': self.bitmasks()['2.0.2'], 'cmap': 'inferno', 'percentile_clip': [10, 90], 'symmetric': False, 'snr_min': 1 } actual = get_plot_params(dapver='2.0.2', prop='stellar_sigma') self.assertDictEqual(actual, desired)
def test_get_plot_params_default_mpl5(self): desired = { 'bitmasks': self.bitmasks()['2.0.2'], 'cmap': 'linearlab', 'percentile_clip': [5, 95], 'symmetric': False, 'snr_min': 1 } actual = get_plot_params(dapver='2.0.2', prop='emline_gflux') self.assertDictEqual(actual, desired)
def test_format_use_masks(self, use_masks, mask, expected, set_release): if config.release == 'MPL-4': pytest.skip('Skip MPL-4.') for prop in [ 'stellar_vel', 'stellar_sigma', 'emline_gflux', 'specindex' ]: params = get_plot_params(dapver=config.lookUpVersions()[1], prop=prop) actual = mapplot._format_use_masks( use_masks, mask, dapmap=None, default_masks=params['bitmasks']) assert actual == expected
def test_get_plot_params(self, dapver, name, desired): params = get_default_plot_params(dapver) if 'vel' in name: key = 'vel' elif 'sigma' in name: key = 'sigma' else: key = 'default' desired['bitmasks'] = params[key]['bitmasks'] actual = get_plot_params(dapver=dapver, prop=name) assert desired == actual
def plot(*args, **kwargs): """Make single panel map or one panel of multi-panel map plot. Please see the `Plotting Tutorial <http://sdss-marvin.readthedocs.io/en/latest/tutorials/plotting-tutorial.html>`_ for examples. Parameters: dapmap (marvin.tools.quantities.Map): Marvin Map object. Default is ``None``. value (array): Data array. Default is ``None``. ivar (array): Inverse variance array. Default is ``None``. mask (array): Mask array. Default is ``None``. cmap (str): Colormap (see :ref:`marvin-utils-plot-map-default-params` for defaults). percentile_clip (tuple-like): Percentile clip (see :ref:`marvin-utils-plot-map-default-params` for defaults). sigma_clip (float): Sigma clip. Default is ``False``. cbrange (tuple-like): If ``None``, set automatically. Default is ``None``. symmetric (bool): Draw a colorbar that is symmetric around zero (see :ref:`marvin-utils-plot-map-default-params` for default). snr_min (float): Minimum signal-to-noise for keeping a valid measurement (see :ref:`marvin-utils-plot-map-default-params` for default). log_cb (bool): Draw a log normalized colorbar. Default is ``False``. title (str): If ``None``, set automatically from property (and channel) name(s). For no title, set to ''. Default is ``None``. title_mode (str): The mode to generate a title automatically, if ``title`` is not set. Usually ``'string'`` or ``'latex'``. Default is ``'string'``. See :func:`~marvin.utils.datamodel.dap.base.Property.to_string` for details. cblabel (str): If ``None``, set automatically from unit. For no colorbar label, set to ''. Default is ``None``. sky_coords (bool): If ``True``, show plot in sky coordinates (i.e., arcsec), otherwise show in spaxel coordinates. Default is ``False``. use_masks (bool, str, list): Use DAP bitmasks. If ``True``, use the recommended DAP masks. Otherwise provide a mask name as a string or multiple mask names as a list of strings. Default is ``True``. plt_style (str): Matplotlib style sheet to use. Default is 'seaborn-darkgrid'. fig (matplotlib Figure object): Use if creating subplot of a multi-panel plot. Default is ``None``. ax (matplotlib Axis object): Use if creating subplot of a multi-panel plot. Default is ``None``. patch_kws (dict): Keyword args to pass to `matplotlib.patches.Rectangle <https://matplotlib.org/api/_as_gen/matplotlib.patches.Rectangle.html>`_. Default is ``None``. imshow_kws (dict): Keyword args to pass to `ax.imshow <http://matplotlib.org/api/_as_gen/matplotlib.axes.Axes.imshow.html#matplotlib.axes.Axes.imshow>`_. Default is ``None``. cb_kws (dict): Keyword args to set and draw colorbar. Default is ``None``. return_cb (bool): Return colorbar axis. Default is ``False``. return_cbrange (bool): Return colorbar range without drawing plot. Default is ``False``. Returns: fig, ax (tuple): `matplotlib.figure <http://matplotlib.org/api/figure_api.html>`_, `matplotlib.axes <http://matplotlib.org/api/axes_api.html>`_ Example: >>> import marvin.utils.plot.map as mapplot >>> maps = Maps(plateifu='8485-1901') >>> ha = maps['emline_gflux_ha_6564'] >>> fig, ax = mapplot.plot(dapmap=ha) """ valid_kwargs = [ 'dapmap', 'value', 'ivar', 'mask', 'cmap', 'percentile_clip', 'sigma_clip', 'cbrange', 'symmetric', 'snr_min', 'log_cb', 'title', 'title_mode', 'cblabel', 'sky_coords', 'use_masks', 'plt_style', 'fig', 'ax', 'patch_kws', 'imshow_kws', 'cb_kws', 'return_cb', 'return_cbrange' ] assert len( args) == 0, 'Map.plot() does not accept arguments, only keywords.' for kw in kwargs: assert kw in valid_kwargs, 'keyword {0} is not valid'.format(kw) assert ((kwargs.get('percentile_clip', None) is not None) + (kwargs.get('sigma_clip', None) is not None) + (kwargs.get('cbrange', None) is not None) <= 1), \ 'Only set one of percentile_clip, sigma_clip, or cbrange!' dapmap = kwargs.get('dapmap', None) value = kwargs.get('value', None) ivar = kwargs.get('ivar', None) mask = kwargs.get('mask', None) sigma_clip = kwargs.get('sigma_clip', False) cbrange = kwargs.get('cbrange', None) log_cb = kwargs.get('log_cb', False) title = kwargs.get('title', None) title_mode = kwargs.get('title_mode', 'string') cblabel = kwargs.get('cblabel', None) sky_coords = kwargs.get('sky_coords', False) use_masks = kwargs.get('use_masks', True) plt_style = kwargs.get('plt_style', 'seaborn-darkgrid') fig = kwargs.get('fig', None) ax = kwargs.get('ax', None) patch_kws = kwargs.get('patch_kws', {}) imshow_kws = kwargs.get('imshow_kws', {}) cb_kws = kwargs.get('cb_kws', {}) return_cb = kwargs.get('return_cb', False) return_cbrange = kwargs.get('return_cbrange', False) assert (value is not None) or (dapmap is not None), \ 'Map.plot() requires specifying ``value`` or ``dapmap``.' # user-defined value, ivar, or mask overrides dapmap attributes value = value if value is not None else getattr(dapmap, 'value', None) ivar = ivar if ivar is not None else getattr(dapmap, 'ivar', None) all_true = np.zeros(value.shape, dtype=bool) mask = mask if mask is not None else getattr(dapmap, 'mask', all_true) if title is None: if getattr(dapmap, 'datamodel', None) is not None: title = dapmap.datamodel.to_string(title_mode) else: title = '' try: prop = dapmap.datamodel.full() except (AttributeError, TypeError): prop = '' # get plotparams from datamodel dapver = dapmap._datamodel.parent.release if dapmap is not None else config.lookUpVersions( )[1] params = get_plot_params(dapver, prop) cmap = kwargs.get('cmap', params['cmap']) percentile_clip = kwargs.get('percentile_clip', params['percentile_clip']) symmetric = kwargs.get('symmetric', params['symmetric']) snr_min = kwargs.get('snr_min', params['snr_min']) if sigma_clip: percentile_clip = False assert (not symmetric) or ( not log_cb), 'Colorbar cannot be both symmetric and logarithmic.' use_masks = _format_use_masks(use_masks, mask, dapmap, default_masks=params['bitmasks']) # Create no coverage, bad data, low SNR, and negative value masks. nocov_conditions = (('NOCOV' in use_masks) or (ivar is not None)) bad_data_conditions = (use_masks and (dapmap is not None) and (mask is not None)) nocov = _mask_nocov(dapmap, mask, ivar) if nocov_conditions else all_true bad_data = dapmap.pixmask.get_mask( use_masks, mask=mask) if bad_data_conditions else all_true low_snr = mask_low_snr(value, ivar, snr_min) if use_masks else all_true neg_val = mask_neg_values(value) if log_cb else all_true # Final masked array to show. good_spax = np.ma.array(value, mask=np.logical_or.reduce( (nocov, bad_data, low_snr, neg_val))) # setup colorbar cb_kws['cmap'] = cmap cb_kws['percentile_clip'] = percentile_clip cb_kws['sigma_clip'] = sigma_clip cb_kws['cbrange'] = cbrange cb_kws['symmetric'] = symmetric cblabel = cblabel if cblabel is not None else getattr(dapmap, 'unit', '') if isinstance(cblabel, units.UnitBase): cb_kws['label'] = cblabel.to_string('latex_inline') else: cb_kws['label'] = cblabel cb_kws['log_cb'] = log_cb cb_kws = colorbar._set_cb_kws(cb_kws) cb_kws = colorbar._set_cbrange(good_spax, cb_kws) if return_cbrange: return cb_kws['cbrange'] # setup unmasked spaxels extent = _set_extent(value.shape, sky_coords) imshow_kws.setdefault('extent', extent) imshow_kws.setdefault('interpolation', 'nearest') imshow_kws.setdefault('origin', 'lower') imshow_kws['norm'] = LogNorm() if log_cb else None # setup background nocov_kws = copy.deepcopy(imshow_kws) nocov_image = np.ma.array(np.ones(value.shape), mask=~nocov.astype(bool)) A8A8A8 = colorbar._one_color_cmap(color='#A8A8A8') # setup masked spaxels patch_kws = _set_patch_style(patch_kws, extent=imshow_kws['extent']) # finish setup of unmasked spaxels and colorbar range imshow_kws = colorbar._set_vmin_vmax(imshow_kws, cb_kws['cbrange']) # set hatch color and linewidths (in matplotlib 2.0+) try: mpl_rc = { it: mpl.rcParams[it] for it in ['hatch.color', 'hatch.linewidth'] } mpl.rc_context({'hatch.color': 'w', 'hatch.linewidth': '0.5'}) except KeyError as ee: mpl_rc = {} with plt.style.context(plt_style): fig, ax = ax_setup(sky_coords=sky_coords, fig=fig, ax=ax) # plot hatched regions by putting one large patch as lowest layer # hatched regions are bad data, low SNR, or negative values if the colorbar is logarithmic ax.add_patch(mpl.patches.Rectangle(**patch_kws)) # plot regions without IFU coverage as a solid color (gray #A8A8A8) ax.imshow(nocov_image, cmap=A8A8A8, zorder=1, **nocov_kws) # plot unmasked spaxels p = ax.imshow(good_spax, cmap=cb_kws['cmap'], zorder=10, **imshow_kws) fig, cb = colorbar._draw_colorbar(fig, mappable=p, ax=ax, **cb_kws) if title is not '': ax.set_title(label=title) # restore previous matplotlib rc parameters (as of matplotlib 2.0.2 this # redraws the hatches with the original rcParam settings) # mpl.rc_context(mpl_rc) # turn on to preserve zorder when saving to pdf (or other vector based graphics format) mpl.rcParams['image.composite_image'] = False output = (fig, ax) if not return_cb else (fig, ax, cb) return output
def plot(*args, **kwargs): """Make single panel map or one panel of multi-panel map plot. Parameters: dapmap (marvin.tools.map.Map): Marvin Map object. Default is ``None``. value (array): Data array. Default is ``None``. ivar (array): Inverse variance array. Default is ``None``. mask (array): Mask array. Default is ``None``. cmap (str): Colormap (see datamodel for defaults). percentile_clip (tuple-like): Percentile clip (see datamodel for defaults. sigma_clip (float): Sigma clip. Default is ``None``. cbrange (tuple-like): If ``None``, set automatically. Default is ``None``. symmetric (bool): Draw a colorbar that is symmetric around zero (see datamodel for default). snr_min (float): Minimum signal-to-noise for keeping a valid measurement (see datamodel for default). log_cb (bool): Draw a log normalized colorbar. Default is ``False``. title (str): If ``None``, set automatically from property (and channel) name(s). For no title, set to ''. Default is ``None``. cblabel (str): If ``None``, set automatically from unit. For no colorbar label, set to ''. Default is ``None``. sky_coords (bool): If ``True``, show plot in sky coordinates (i.e., arcsec), otherwise show in spaxel coordinates. Default is ``False``. use_mask (bool): Use DAP bitmasks. Default is ``True``. plt_style (str): Matplotlib style sheet to use. Default is 'seaborn-darkgrid'. fig (matplotlib Figure object): Use if creating subplot of a multi-panel plot. Default is ``None``. ax (matplotlib Axis object): Use if creating subplot of a multi-panel plot. Default is ``None``. imshow_kws (dict): Keyword args to pass to `ax.imshow <http://matplotlib.org/api/_as_gen/matplotlib.axes.Axes.imshow.html#matplotlib.axes.Axes.imshow>`_. Default is ``None``. cb_kws (dict): Keyword args to set and draw colorbar. Default is ``None``. Returns: fig, ax (tuple): `matplotlib.figure <http://matplotlib.org/api/figure_api.html>`_, `matplotlib.axes <http://matplotlib.org/api/axes_api.html>`_ Example: >>> import marvin.utils.plot.map as mapplot >>> maps = Maps(plateifu='8485-1901') >>> ha = maps['emline_gflux_ha_6564'] >>> fig, ax = mapplot.plot(dapmap=ha) """ valid_kwargs = ['dapmap', 'value', 'ivar', 'mask', 'cmap', 'percentile_clip', 'sigma_clip', 'cbrange', 'symmetric', 'snr_min', 'log_cb', 'title', 'cblabel', 'sky_coords', 'use_mask', 'plt_style', 'fig', 'ax', 'imshow_kws', 'cb_kws'] assert len(args) == 0, 'Map.plot() does not accept arguments, only keywords.' for kw in kwargs: assert kw in valid_kwargs, 'keyword {0} is not valid'.format(kw) assert ((kwargs.get('percentile_clip', None) is not None) + (kwargs.get('sigma_clip', None) is not None) + (kwargs.get('cbrange', None) is not None) <= 1), \ 'Only set one of percentile_clip, sigma_clip, or cbrange!' dapmap = kwargs.get('dapmap', None) value = kwargs.get('value', None) ivar = kwargs.get('ivar', None) mask = kwargs.get('mask', None) sigma_clip = kwargs.get('sigma_clip', None) cbrange = kwargs.get('cbrange', None) log_cb = kwargs.get('log_cb', False) title = kwargs.get('title', None) cblabel = kwargs.get('cblabel', None) sky_coords = kwargs.get('sky_coords', False) use_mask = kwargs.get('use_mask', True) plt_style = kwargs.get('plt_style', 'seaborn-darkgrid') fig = kwargs.get('fig', None) ax = kwargs.get('ax', None) imshow_kws = kwargs.get('imshow_kws', {}) cb_kws = kwargs.get('cb_kws', {}) assert (value is not None) or (dapmap is not None), \ 'Map.plot() requires specifying ``value`` or ``dapmap``.' # user-defined value, ivar, or mask overrides dapmap attributes value = value if value is not None else getattr(dapmap, 'value', None) ivar = ivar if ivar is not None else getattr(dapmap, 'ivar', None) mask = mask if mask is not None else getattr(dapmap, 'mask', np.zeros(value.shape, dtype=bool)) title = set_title(title, property_name=getattr(dapmap, 'property_name', None), channel=getattr(dapmap, 'channel', None)) # get plotparams from datamodel dapver = config.lookUpVersions()[1] prop = _get_prop(title) params = get_plot_params(dapver, prop) cmap = kwargs.get('cmap', params['cmap']) percentile_clip = kwargs.get('percentile_clip', params['percentile_clip']) symmetric = kwargs.get('symmetric', params['symmetric']) snr_min = kwargs.get('snr_min', params['snr_min']) if sigma_clip is not None: percentile_clip = None # create no coverage, bad data, low SNR, and log colorbar masks nocov_mask = no_coverage_mask(value, ivar, mask, params['bitmasks'].get('nocov', None)) badData = params['bitmasks']['badData'] bad_data = bad_data_mask(value, mask, badData) if use_mask else np.zeros(value.shape) low_snr = low_snr_mask(value, ivar, snr_min) if use_mask else np.zeros(value.shape) log_cb_mask = log_colorbar_mask(value, log_cb) # final masked array to show image = select_good_spaxels(value, nocov_mask, bad_data, low_snr, log_cb_mask) # setup colorbar cb_kws['cmap'] = cmap cb_kws['percentile_clip'] = percentile_clip cb_kws['sigma_clip'] = sigma_clip cb_kws['cbrange'] = cbrange cb_kws['symmetric'] = symmetric cb_kws['label'] = cblabel if cblabel is not None else getattr(dapmap, 'unit', '') cb_kws = colorbar.set_cb_kws(cb_kws) cb_kws = colorbar.set_cbrange(image, cb_kws) # setup unmasked spaxels extent = set_extent(value.shape, sky_coords) imshow_kws.setdefault('extent', extent) imshow_kws.setdefault('interpolation', 'nearest') imshow_kws.setdefault('origin', 'lower') imshow_kws['norm'] = LogNorm() if log_cb else None # setup background nocov_kws = copy.deepcopy(imshow_kws) nocov = np.ma.array(np.ones(value.shape), mask=~nocov_mask) A8A8A8 = colorbar.one_color_cmap(color='#A8A8A8') # setup masked spaxels patch_kws = set_patch_style(extent=extent) # finish setup of unmasked spaxels and colorbar range imshow_kws = colorbar.set_vmin_vmax(imshow_kws, cb_kws['cbrange']) # set hatch color and linewidths (in matplotlib 2.0+) try: mpl_rc = {it: mpl.rcParams[it] for it in ['hatch.color', 'hatch.linewidth']} mpl.rc_context({'hatch.color': 'w', 'hatch.linewidth': '0.5'}) except KeyError as ee: mpl_rc = {} with plt.style.context(plt_style): fig, ax = ax_setup(sky_coords=sky_coords, fig=fig, ax=ax) # plot hatched regions by putting one large patch as lowest layer # hatched regions are bad data, low SNR, or negative values if the colorbar is logarithmic ax.add_patch(mpl.patches.Rectangle(**patch_kws)) # plot regions without IFU coverage as a solid color (gray #A8A8A8) ax.imshow(nocov, cmap=A8A8A8, zorder=1, **nocov_kws) # plot unmasked spaxels p = ax.imshow(image, cmap=cb_kws['cmap'], zorder=10, **imshow_kws) fig, cb = colorbar.draw_colorbar(fig, mappable=p, ax=ax, **cb_kws) if title is not '': ax.set_title(label=title) # restore previous matplotlib rc parameters (as of matplotlib 2.0.2 this # redraws the hatches with the original rcParam settings) # mpl.rc_context(mpl_rc) # turn on to preserve zorder when saving to pdf (or other vector based graphics format) mpl.rcParams['image.composite_image'] = False return fig, ax
def bits(request, set_release): params = get_plot_params(dapver=config.lookUpVersions()[1], prop=request.param) return params['bitmasks']