Example #1
0
 def testSquare(self):
     vectors = Matrix(helpers.ascomplex(numpy.random.randn(
         numpy.random.randint(1,10),numpy.random.randint(1,10),2
     )))
     cov = vectors.H*vectors
     Xcov = vectors*vectors.H 
     (Xval,Xvec) = numpy.linalg.eigh(Xcov)
     vec = Xvec.H*vectors
     self.assertTrue( vec.H*vec == cov )
Example #2
0
    def patch(self, nstd=2, alpha='auto', slope=0.5, minalpha=0.3, **kwargs):
        """
        :param nstd:
        :param alpha:
        :param slope:
        :param minalpha:
        :param ** kwargs:
            
        get a matplotlib Ellipse patch representing the Mvn, all **kwargs are 
        passed on to the call to matplotlib.patches.Ellipse

        not surprisingly Ellipse only works for 2d data.

        the number of standard deviations, 'nstd', is just a multiplier for 
        the eigen values. So the standard deviations are projected, if you 
        want volumetric standard deviations I think you need to multiply by 
        sqrt(ndim)

        if  you don't specify a value for alpha it is set to the exponential of 
        the area, as if it has a fixed amount if ink that is spread over it's area.

        the 'slope' and 'minalpha' parameters control this auto-alpha:
            'slope' controls how quickly the the alpha drops to zero
            'minalpha' is used to make sure that very large elipses are not invisible.  
        """
        shape = self.dist.shape

        assert shape[
            1] == 2, 'this method can only produce patches for 2d data'

        if shape[0] < 2:
            kwargs = self._kwargs2Marker(**kwargs)

            coords = self.dist.getX(nstd=nstd)

            return matplotlib.lines.Line2D(coords[:, 0], coords[:, 1],
                                           **kwargs)

        if alpha == 'auto':
            alpha = numpy.max(
                [minalpha,
                 numpy.exp(-slope * mvn.sqrt(self.dist.det()))])

            facecolor = kwargs.get('facecolor', None)
            if facecolor is None:
                kwargs['alpha'] = alpha
            else:
                kwargs['facecolor'] = self._convertAlpha(facecolor, alpha)

            edgecolor = kwargs.get('edgecolor', None)
            if edgecolor is not None:
                kwargs['edgecolor'] = self._convertAlpha(edgecolor, alpha)

        else:
            kwargs['alpha'] = alpha

        #unpack the width and height from the scale matrix
        wh = nstd * mvn.sqrt(self.dist.var)
        wh[wh > 1e5] = 1e5

        #convert from radius to diameters
        width, height = 2 * wh

        #calculate angle
        angle = 180 / numpy.pi * (numpy.angle(
            helpers.ascomplex(self.dist.vectors)[0]))

        #return an Ellipse patch
        return matplotlib.patches.Ellipse(
            #with the Mvn's mean at the centre
            xy=tuple(self.dist.mean.flatten()),
            #matching width and height
            width=width,
            height=height,
            #and rotation angle pulled from the vectors matrix
            angle=angle,
            #while transmitting any kwargs.
            **kwargs)
Example #3
0
File: plot.py Project: 9578577/mvn
    def patch(self, nstd=2, alpha='auto', slope=0.5, minalpha=0.3, **kwargs):
        """
        :param nstd:
        :param alpha:
        :param slope:
        :param minalpha:
        :param ** kwargs:
            
        get a matplotlib Ellipse patch representing the Mvn, all **kwargs are 
        passed on to the call to matplotlib.patches.Ellipse

        not surprisingly Ellipse only works for 2d data.

        the number of standard deviations, 'nstd', is just a multiplier for 
        the eigen values. So the standard deviations are projected, if you 
        want volumetric standard deviations I think you need to multiply by 
        sqrt(ndim)

        if  you don't specify a value for alpha it is set to the exponential of 
        the area, as if it has a fixed amount if ink that is spread over it's area.

        the 'slope' and 'minalpha' parameters control this auto-alpha:
            'slope' controls how quickly the the alpha drops to zero
            'minalpha' is used to make sure that very large elipses are not invisible.  
        """
        shape = self.dist.shape

        assert shape[1] == 2,'this method can only produce patches for 2d data'
        
        if shape[0] < 2:
            kwargs = self._kwargs2Marker(**kwargs)   
            
            coords = self.dist.getX(nstd = nstd)
                    
            return matplotlib.lines.Line2D(
                coords[:, 0], 
                coords[:, 1], 
                **kwargs
            )
            

        if alpha == 'auto':
            alpha = numpy.max([
                minalpha,
                numpy.exp(-slope*mvn.sqrt(self.dist.det()))
            ])

            facecolor = kwargs.get('facecolor', None)
            if facecolor is None:
                kwargs['alpha'] = alpha
            else:
                kwargs['facecolor'] = self._convertAlpha(facecolor,alpha)

            edgecolor = kwargs.get('edgecolor', None)
            if edgecolor is not None:
                kwargs['edgecolor'] = self._convertAlpha(edgecolor,alpha)

        else:
            kwargs['alpha'] = alpha

        #unpack the width and height from the scale matrix 
        wh = nstd*mvn.sqrt(self.dist.var)
        wh[wh>1e5] = 1e5

        #convert from radius to diameters
        width,height = 2*wh

        #calculate angle
        angle = 180/numpy.pi*(
            numpy.angle(helpers.ascomplex(self.dist.vectors)[0])
        )        
        
        #return an Ellipse patch
        return matplotlib.patches.Ellipse(
            #with the Mvn's mean at the centre 
            xy=tuple(self.dist.mean.flatten()),
            #matching width and height
            width=width, height=height,
            #and rotation angle pulled from the vectors matrix
            angle=angle,
            #while transmitting any kwargs.
            **kwargs
        )