27 from __future__ 
import absolute_import, division, print_function
    34 import matplotlib.pyplot 
as pyplot
    35 import matplotlib.cbook
    36 import matplotlib.colors 
as mpColors
    37 from matplotlib.blocking_input 
import BlockingInput
    60     interactiveBackends = [
    69         afwDisplay.GREEN : 
"#00FF00",   
    73         """Map the ctype to a potentially different ctype    75         Specifically, if matplotlibCtypes[ctype] exists, use it instead    77         This is used e.g. to map "green" to a brighter shade    79         return matplotlibCtypes[ctype] 
if ctype 
in matplotlibCtypes 
else ctype
    83     """Provide a matplotlib backend for afwDisplay    85     Recommended backends in notebooks are:    97     Apparently only qt supports Display.interact(); the list of interactive backends    98     is given by lsst.display.matplotlib.interactiveBackends   100     def __init__(self, display, verbose=False,
   101                  interpretMaskBits=True, mtvOrigin=afwImage.PARENT, fastMaskDisplay=True,
   102                  reopenPlot=False, *args, **kwargs):
   104         Initialise a matplotlib display   106         @param fastMaskDisplay      If True, only show the first bitplane that's set in each pixel   107                                     (e.g. if (SATURATED & DETECTED), ignore DETECTED)   108                                     Not really what we want, but a bit faster   109         @param interpretMaskBits    Interpret the mask value under the cursor   110         @param mtvOrigin            Display pixel coordinates with LOCAL origin   111                                     (bottom left == 0,0 not XY0)   112         @param reopenPlot           If true, close the plot before opening it.   113                                     (useful with e.g. %ipympl)   115         virtualDevice.DisplayImpl.__init__(self, display, verbose)
   118             pyplot.close(display.frame)
   119         self.
_figure = pyplot.figure(display.frame)
   128         self.
__alpha = unicodedata.lookup(
"GREEK SMALL LETTER alpha")  
   129         self.
__delta = unicodedata.lookup(
"GREEK SMALL LETTER delta")  
   143             warnings.filterwarnings(
"ignore", category=matplotlib.cbook.mplDeprecation)
   146         """!Close the display, cleaning up any allocated resources"""   150         self.
_figure.gca().format_coord = 
None     153         """Put the plot at the top of the window stacking order"""   156             self.
_figure.canvas._tkcanvas._root().lift()  
   157         except AttributeError:
   161             self.
_figure.canvas.manager.window.raise_()  
   162         except AttributeError:
   167         except AttributeError:
   174         """Defer to figure.savefig()"""   178         """Show (or hide) the colour bar"""   183     def wait(self, prompt="[c(ontinue) p(db)] :
", allowPdb=True):   184         """Wait for keyboard input   188         @param allowPdb `bool`   189            If true, entering a 'p' or 'pdb' puts you into pdb   191         Returns the string you entered   193         Useful when plotting from a programme that exits such as a processCcd   194         Any key except 'p' continues; 'p' puts you into pdb (unless allowPdb is False)   198             if allowPdb 
and s 
in (
"p", 
"pdb"):
   208     def _setMaskTransparency(self, transparency, maskplane):
   209         """Specify mask transparency (percent)"""   213     def _getMaskTransparency(self, maskplane=None):
   214         """Return the current mask transparency"""   217     def _mtv(self, image, mask=None, wcs=None, title=""):
   218         """Display an Image and/or Mask on a matplotlib display   220         title = 
str(title) 
if title 
else ""   235         self.
_i_mtv(image, wcs, title, 
False)
   239             self.
_i_mtv(mask, wcs, title, 
True)
   246         def format_coord(x, y, wcs=self._wcs, x0=self._xy0[0], y0=self._xy0[1],
   247                          origin=afwImage.PARENT, bbox=self._image.getBBox(afwImage.PARENT)):
   249             fmt = 
'(%1.2f, %1.2f)'   253                 msg = (fmt + 
"L") % (x - x0, y - y0)
   259                     ra, dec = wcs.pixelToSky(x, y)
   260                     msg += 
r" (%s, %s): (%9.4f, %9.4f)" % (self.
__alpha, self.
__delta, ra, dec)
   262                 msg += 
' %1.3f' % (self.
_image[col, row])
   264                     val = self.
_mask[col, row]
   266                         msg += 
" [%s]" % self.
_mask.interpret(val)
   272         ax.format_coord = format_coord
   274         from matplotlib.image 
import AxesImage
   275         for a 
in ax.mouseover_set:
   276             if isinstance(a, AxesImage):
   277                 a.get_cursor_data = 
lambda ev: 
None     280         self.
_figure.canvas.draw_idle()
   282     def _i_mtv(self, data, wcs, title, isMask):
   283         """Internal routine to display an Image or Mask on a DS9 display"""   285         title = 
str(title) 
if title 
else ""   286         dataArr = data.getArray()
   289             maskPlanes = data.getMaskPlaneDict()
   290             nMaskPlanes = 
max(maskPlanes.values()) + 1
   293             for key 
in maskPlanes:
   294                 planes[maskPlanes[key]] = key
   296             planeList = range(nMaskPlanes)
   298             maskArr = np.zeros_like(dataArr, dtype=np.int32)
   300             colorNames = [
'black']
   301             colorGenerator = self.display.maskColorGenerator(omitBW=
True)
   306                     color = next(colorGenerator)
   307                 elif color.lower() == afwDisplay.IGNORE:
   310                 colorNames.append(color)
   318             colors = mpColors.to_rgba_array(colorNames)
   320             colors[0][alphaChannel] = 0.0      
   321             for i, p 
in enumerate(planeList):
   322                 if colorNames[i + 1] == 
'black':
   327                 colors[i + 1][alphaChannel] = alpha
   329             cmap = mpColors.ListedColormap(colors)
   330             norm = mpColors.NoNorm()
   336         bbox = data.getBBox()
   337         extent = (bbox.getBeginX() - 0.5, bbox.getEndX() - 0.5,
   338                   bbox.getBeginY() - 0.5, bbox.getEndY() - 0.5)
   340         with pyplot.rc_context(dict(interactive=
False)):
   342                 for i, p 
in reversed(
list(enumerate(planeList))):
   343                     if colors[i + 1][alphaChannel] == 0:  
   346                     bitIsSet = (dataArr & (1 << p)) != 0
   347                     if bitIsSet.sum() == 0:
   350                     maskArr[bitIsSet] = i + 1  
   353                         ax.imshow(maskArr, origin=
'lower', interpolation=
'nearest',
   354                                   extent=extent, cmap=cmap, norm=norm)
   358                     ax.imshow(maskArr, origin=
'lower', interpolation=
'nearest',
   359                               extent=extent, cmap=cmap, norm=norm)
   361                 mappable = ax.imshow(dataArr, origin=
'lower', interpolation=
'nearest',
   362                                      extent=extent, cmap=cmap, norm=norm)
   365         self.
_figure.canvas.draw_idle()
   367     def _i_setImage(self, image, mask=None, wcs=None):
   368         """Save the current image, mask, wcs, and XY0"""   376             self._width, self.
_height = 0, 0
   380         self.
_xcen = 0.5*self._width
   383     def _setImageColormap(self, cmap):
   384         """Set the colormap used for the image   386         cmap should be either the name of an attribute of pyplot.cm or an mpColors.Colormap   387         (e.g. "gray" or pyplot.cm.gray)   390         if not isinstance(cmap, mpColors.Colormap):
   391             cmap = getattr(pyplot.cm, cmap)
   399     def _buffer(self, enable=True):
   410         """Erase the display"""   419             zoomfac = self._zoomfac
   423             self._mtv(self._image, mask=self._mask, wcs=self._wcs, title=self._title)
   429         self._figure.canvas.draw_idle()
   431     def _dot(self, symb, c, r, size, ctype,
   432              fontFamily="helvetica", textAngle=None):
   433         """Draw a symbol at (col,row) = (c,r) [0-based coordinates]   439             @:Mxx,Mxy,Myy    Draw an ellipse with moments (Mxx, Mxy, Myy) (argument size is ignored)   440             An afwGeom.ellipses.Axes Draw the ellipse (argument size is ignored)   441     Any other value is interpreted as a string to be drawn. Strings obey the fontFamily (which may be extended   442     with other characteristics, e.g. "times bold italic".  Text will be drawn rotated by textAngle   443     (textAngle is ignored otherwise).   446             ctype = afwDisplay.GREEN
   448         axis = self._figure.gca()
   451         if isinstance(symb, afwGeom.ellipses.Axes):
   452             from matplotlib.patches 
import Ellipse
   456             axis.add_artist(Ellipse((c + x0, r + y0), height=2*symb.getA(), width=2*symb.getB(),
   457                                     angle=90.0 + math.degrees(symb.getTheta()),
   458                                     edgecolor=
mapCtype(ctype), facecolor=
'none'))
   460             from matplotlib.patches 
import CirclePolygon 
as Circle
   462             axis.add_artist(Circle((c + x0, r + y0), radius=size, color=
mapCtype(ctype), fill=
False))
   464             from matplotlib.lines 
import Line2D
   466             for ds9Cmd 
in ds9Regions.dot(symb, c + x0, r + y0, size, fontFamily=
"helvetica", textAngle=
None):
   467                 tmp = ds9Cmd.split(
'#')
   468                 cmd = tmp.pop(0).split()
   469                 comment = tmp.pop(0) 
if tmp 
else ""    471                 cmd, args = cmd[0], cmd[1:]
   474                     args = np.array(args).astype(float) - 1.0
   476                     x = np.empty(len(args)//2)
   478                     i = np.arange(len(args), dtype=int)
   482                     axis.add_line(Line2D(x, y, color=
mapCtype(ctype)))
   484                     x, y = np.array(args[0:2]).astype(float) - 1.0
   485                     axis.text(x, y, symb, color=
mapCtype(ctype),
   486                               horizontalalignment=
'center', verticalalignment=
'center')
   488                     raise RuntimeError(ds9Cmd)
   490     def _drawLines(self, points, ctype):
   491         """Connect the points, a list of (col,row)   492         Ctype is the name of a colour (e.g. 'red')"""   494         from matplotlib.lines 
import Line2D
   497             ctype = afwDisplay.GREEN
   499         points = np.array(points)
   500         x = points[:, 0] + self._xy0[0]
   501         y = points[:, 1] + self._xy0[1]
   503         self._figure.gca().add_line(Line2D(x, y, color=
mapCtype(ctype)))
   505     def _scale(self, algorithm, minval, maxval, unit, *args, **kwargs):
   509         self._scaleArgs[
'algorithm'] = algorithm
   510         self._scaleArgs[
'minval'] = minval
   511         self._scaleArgs[
'maxval'] = maxval
   512         self._scaleArgs[
'unit'] = unit
   513         self._scaleArgs[
'args'] = args
   514         self._scaleArgs[
'kwargs'] = kwargs
   517             self._i_scale(algorithm, minval, maxval, unit, *args, **kwargs)
   518         except (AttributeError, RuntimeError):
   522     def _i_scale(self, algorithm, minval, maxval, unit, *args, **kwargs):
   523         if minval == 
"minmax":
   524             if self._image 
is None:
   525                 raise RuntimeError(
"You may only use minmax if an image is loaded into the display")
   528             minval = stats.getValue(afwMath.MIN)
   529             maxval = stats.getValue(afwMath.MAX)
   531         if algorithm 
is None:
   532             self._normalize = 
None   533         elif algorithm == 
"asinh":
   534             if minval == 
"zscale":
   535                 if self._image 
is None:
   536                     raise RuntimeError(
"You may only use zscale if an image is loaded into the display")
   538                 self._normalize = AsinhZScaleNormalize(image=self._image, Q=kwargs.get(
"Q", 8.0))
   540                 self._normalize = AsinhNormalize(minimum=minval,
   541                                                  dataRange=maxval - minval, Q=kwargs.get(
"Q", 8.0))
   542         elif algorithm == 
"linear":
   543             if minval == 
"zscale":
   544                 if self._image 
is None:
   545                     raise RuntimeError(
"You may only use zscale if an image is loaded into the display")
   547                 self._normalize = ZScaleNormalize(image=self._image,
   548                                                   nSamples=kwargs.get(
"nSamples", 1000),
   549                                                   contrast=kwargs.get(
"contrast", 0.25))
   551                 self._normalize = LinearNormalize(minimum=minval, maximum=maxval)
   553             raise RuntimeError(
"Unsupported stretch algorithm \"%s\"" % algorithm)
   558     def _zoom(self, zoomfac):
   559         """Zoom by specified amount"""   561         self._zoomfac = zoomfac
   565         size = 
min(self._width, self._height)
   566         if size < self._zoomfac:        
   568         xmin, xmax = self._xcen + x0 + size/self._zoomfac*np.array([-1, 1])
   569         ymin, ymax = self._ycen + y0 + size/self._zoomfac*np.array([-1, 1])
   571         ax = self._figure.gca()
   573         tb = self._figure.canvas.toolbar
   577         ax.set_xlim(xmin, xmax)
   578         ax.set_ylim(ymin, ymax)
   579         ax.set_aspect(
'equal', 
'datalim')
   581         self._figure.canvas.draw_idle()
   583     def _pan(self, colc, rowc):
   584         """Pan to (colc, rowc)"""   589         self._zoom(self._zoomfac)
   591     def _getEvent(self, timeout=-1):
   592         """Listen for a key press, returning (key, x, y)"""   594         mpBackend = matplotlib.get_backend()
   595         if mpBackend 
not in interactiveBackends:
   596             print(
"The %s matplotlib backend doesn't support display._getEvent()" %
   597                   (matplotlib.get_backend(),), file=sys.stderr)
   598             return interface.Event(
'q')
   600         blocking_input = BlockingKeyInput(self._figure)
   601         return blocking_input(timeout=timeout)
   608     Callable class to retrieve a single keyboard click   611         r"""Create a BlockingKeyInput   613         \param fig The figure to monitor for keyboard events   615         BlockingInput.__init__(self, fig=fig, eventslist=(
'key_press_event',))
   619         Return the event containing the key and (x, y)   622             event = self.events[-1]
   627             self.
ev = interface.Event(event.key, event.xdata, event.ydata)
   631         Blocking call to retrieve a single key click   632         Returns key or None if timeout   636         BlockingInput.__call__(self, n=1, timeout=timeout)
   644     """Class to support stretches for mtv()"""   648         Return a MaskedArray with value mapped to [0, 255]   650         @param value Input pixel value or array to be mapped   652         if isinstance(value, np.ndarray):
   657         data = data - self.mapping.minimum[0]
   658         return ma.array(data*self.mapping.mapIntensityToUint8(data)/255.0)
   662     """Provide an asinh stretch for mtv()"""   664         """Initialise an object able to carry out an asinh mapping   666         @param minimum   Minimum pixel value (default: 0)   667         @param dataRange Range of values for stretch if Q=0; roughly the linear part (default: 1)   668         @param Q Softening parameter (default: 8)   670         See Lupton et al., PASP 116, 133   672         Normalize.__init__(self)
   675         self.
mapping = afwRgb.AsinhMapping(minimum, dataRange, Q)
   679     """Provide an asinh stretch using zscale to set limits for mtv()"""   681         """Initialise an object able to carry out an asinh mapping   683         @param image  image to use estimate minimum and dataRange using zscale (see AsinhNormalize)   684         @param Q Softening parameter (default: 8)   686         See Lupton et al., PASP 116, 133   688         Normalize.__init__(self)
   691         self.
mapping = afwRgb.AsinhZScaleMapping(image, Q)
   695     """Provide a zscale stretch for mtv()"""   696     def __init__(self, image=None, nSamples=1000, contrast=0.25):
   697         """Initialise an object able to carry out a zscale mapping   699         @param image to be used to estimate the stretch   700         @param nSamples Number of data points to use (default: 1000)   701         @param contrast Control the range of pixels to display around the median (default: 0.25)   704         Normalize.__init__(self)
   707         self.
mapping = afwRgb.ZScaleMapping(image, nSamples, contrast)
   711     """Provide a linear stretch for mtv()"""   713         """Initialise an object able to carry out a linear mapping   715         @param minimum  Minimum value to display   716         @param maximum  Maximum value to display   719         Normalize.__init__(self)
   722         self.
mapping = afwRgb.LinearMapping(minimum, maximum)
 def __init__(self, minimum=0, maximum=1)
def _i_mtv(self, data, wcs, title, isMask)
def __init__(self, display, verbose=False, interpretMaskBits=True, mtvOrigin=afwImage.PARENT, fastMaskDisplay=True, reopenPlot=False, args, kwargs)
def _i_scale(self, algorithm, minval, maxval, unit, args, kwargs)
def savefig(self, args, kwargs)
Statistics makeStatistics(lsst::afw::math::MaskedVector< EntryT > const &mv, std::vector< WeightPixel > const &vweights, int const flags, StatisticsControl const &sctrl=StatisticsControl())
The makeStatistics() overload to handle lsst::afw::math::MaskedVector<> 
def __init__(self, image=None, Q=8)
def getMaskPlaneColor(name, frame=None)
def _i_setImage(self, image, mask=None, wcs=None)
def wait(self, prompt="[c(ontinue) p(db)] :", allowPdb=True)
def __init__(self, image=None, nSamples=1000, contrast=0.25)
def show_colorbar(self, show=True)
def _getMaskTransparency(self, maskplane=None)
def __init__(self, minimum=0, dataRange=1, Q=8)
def __call__(self, value, clip=None)
daf::base::PropertyList * list