Пример #1
0
 def hist(self, x, **kwargs):  # pylint: disable=arguments-differ
     if iterable(x) and not numpy.size(x):
         x = numpy.ndarray((0,))
     logbins = kwargs.pop('logbins', False)
     bins = kwargs.get('bins', 30)
     weights = kwargs.get('weights', None)
     if isinstance(weights, (float, int)):
         if isinstance(x, numpy.ndarray) or not iterable(x[0]):
             kwargs['weights'] = numpy.ones_like(x) * weights
         else:
             kwargs['weights'] = []
             for arr in x:
                 kwargs['weights'].append(numpy.ones_like(arr) * weights)
             kwargs['weights'] = numpy.asarray(kwargs['weights'])
     if logbins and (bins is None or isinstance(bins, (float, int))):
         bins = bins or 30
         range_ = kwargs.pop('range', self.common_limits(x))
         if range_[1] == range_[0]:
             kwargs['bins'] = bins
         else:
             kwargs['bins'] = self.bin_boundaries(range_[0], range_[1],
                                                  bins, log=True)
     if kwargs.get('histtype', None) == 'stepfilled':
         kwargs.setdefault('edgecolor', 'black')
     return super(HistogramAxes, self).hist(x, **kwargs)
Пример #2
0
def fetch_historical_yahoo(ticker, date1, date2, cachename=None,dividends=False):
    """
    Fetch historical data for ticker between date1 and date2.  date1 and
    date2 are date or datetime instances, or (year, month, day) sequences.

    Ex:
    fh = fetch_historical_yahoo('^GSPC', (2000, 1, 1), (2001, 12, 31))

    cachename is the name of the local file cache.  If None, will
    default to the md5 hash or the url (which incorporates the ticker
    and date range)
    
    set dividends=True to return dividends instead of price data.  With
    this option set, parse functions will not work

    a file handle is returned
    """

    ticker = ticker.upper()


    if iterable(date1):
        d1 = (date1[1]-1, date1[2], date1[0])
    else:
        d1 = (date1.month-1, date1.day, date1.year)
    if iterable(date2):
        d2 = (date2[1]-1, date2[2], date2[0])
    else:
        d2 = (date2.month-1, date2.day, date2.year)


    if dividends:
        g='v'
        verbose.report('Retrieving dividends instead of prices')
    else:
        g='d'

    urlFmt = 'http://table.finance.yahoo.com/table.csv?a=%d&b=%d&c=%d&d=%d&e=%d&f=%d&s=%s&y=0&g=%s&ignore=.csv'


    url =  urlFmt % (d1[0], d1[1], d1[2],
                     d2[0], d2[1], d2[2], ticker, g)


    if cachename is None:
        cachename = os.path.join(cachedir, md5(url).hexdigest())
    if os.path.exists(cachename):
        fh = open(cachename)
        verbose.report('Using cachefile %s for %s'%(cachename, ticker))
    else:
        mkdirs(cachedir)
        urlfh = urlopen(url)

        fh = open(cachename, 'wb')
        fh.write(urlfh.read())
        fh.close()
        verbose.report('Saved %s data to cache file %s'%(ticker, cachename))
        fh = open(cachename, 'r')

    return fh
Пример #3
0
    def from_list(name, colors, N=256, gamma=1.0):
        """
        Make a linear segmented colormap with *name* from a sequence
        of *colors* which evenly transitions from colors[0] at val=0
        to colors[-1] at val=1.  *N* is the number of rgb quantization
        levels.
        Alternatively, a list of (value, color) tuples can be given
        to divide the range unevenly.
        """

        if not cbook.iterable(colors):
            raise ValueError('colors must be iterable')

        if cbook.iterable(colors[0]) and len(colors[0]) == 2 and \
                not cbook.is_string_like(colors[0]):
            # List of value, color pairs
            vals, colors = zip(*colors)
        else:
            vals = np.linspace(0., 1., len(colors))

        cdict = dict(red=[], green=[], blue=[])
        for val, color in zip(vals, colors):
            r,g,b = colorConverter.to_rgb(color)
            cdict['red'].append((val, r, r))
            cdict['green'].append((val, g, g))
            cdict['blue'].append((val, b, b))

        return LinearSegmentedColormap(name, cdict, N, gamma)
Пример #4
0
def getStock(ticker, d1, d2, verbose=False):
    if not iterable(d1): d1 = (d1, 1, 1)
    if not iterable(d2): d2 = (d2, 1, 1)

    saveStock(ticker, d1, d2)

    pickleFile = "%s/%s.pklz" % (storageDir, ticker)

    d = { }
    d["days"] = { }
    try:
        fh = gzip.open(pickleFile, "rb")
        dOld = pickle.load(fh)
        fh.close()
    except:
        if(verbose): print "[MM] Error: file (%s/%s.pklz) does not exist" % (storageDir, ticker)
        return d


    dt1, dt2 = datetime.datetime(*d1), datetime.datetime(*d2)
    day1, day2 = u.tuple2inum(d1), u.tuple2inum(d2)

    for day in dOld["days"].keys():
        if( day1 <= day <= day2 ):
            d["days"][day] = dOld["days"][day]

    return d
Пример #5
0
 def plot(self, xs, ys, *args, **kwargs):
     '''
     Plot 2D or 3D data.
     ==========  ================================================
     Argument    Description
     ==========  ================================================
     *xs*, *ys*  X, y coordinates of vertices
     *zs*        z value(s), either one for all points or one for
                 each point.
     *zdir*      Which direction to use as z ('x', 'y' or 'z')
                 when plotting a 2d set.
     ==========  ================================================
     Other arguments are passed on to
     :func:`~matplotlib.axes.Axes.plot`
     '''
     had_data = self.has_data()
     zs = kwargs.pop('zs', 0)
     zdir = kwargs.pop('zdir', 'z')
     argsi = 0
     if len(args) > 0 and cbook.iterable(args[0]) and \
             len(xs) == len(args[0]) and cbook.is_scalar(args[0][0]):
         zs = args[argsi]
         argsi += 1
     elif len(args) > 0 and cbook.is_scalar(args[0]):
         zs = args[argsi]
         argsi += 1
     if not cbook.iterable(zs):
         zs = np.ones(len(xs)) * zs
     lines = Axes.plot(self, xs, ys, *args[argsi:], **kwargs)
     for line in lines:
         art3d.line_2d_to_3d(line, zs=zs, zdir=zdir)
     self.auto_scale_xyz(xs, ys, zs, had_data)
     return lines
Пример #6
0
    def add_lines(self, levels, colors, linewidths, erase=True):
        """
        Draw lines on the colorbar.

        *colors* and *linewidths* must be scalars or
        sequences the same length as *levels*.

        Set *erase* to False to add lines without first
        removing any previously added lines.
        """
        y = self._locate(levels)
        igood = (y < 1.001) & (y > -0.001)
        y = y[igood]
        if cbook.iterable(colors):
            colors = np.asarray(colors)[igood]
        if cbook.iterable(linewidths):
            linewidths = np.asarray(linewidths)[igood]
        N = len(y)
        x = np.array([0.0, 1.0])
        X, Y = np.meshgrid(x, y)
        if self.orientation == "vertical":
            xy = [list(zip(X[i], Y[i])) for i in range(N)]
        else:
            xy = [list(zip(Y[i], X[i])) for i in range(N)]
        col = collections.LineCollection(xy, linewidths=linewidths)

        if erase and self.lines:
            for lc in self.lines:
                lc.remove()
            self.lines = []
        self.lines.append(col)
        col.set_color(colors)
        self.ax.add_collection(col)
Пример #7
0
    def _fetch_historical_yahoo(self, ticker, date1, date2, freq=None, cachename=None):
        """matplotlib's implementation, modified to provide proxy support and frequency
        Fetch historical data for ticker between date1 and date2.  date1 and
        date2 are date or datetime instances, or (year, month, day) sequences.

        Ex:
        fh = fetch_historical_yahoo('^GSPC', (2000, 1, 1), (2001, 12, 31))

        cachename is the name of the local file cache.  If None, will
        default to the md5 hash or the url (which incorporates the ticker
        and date range)

        a file handle is returned
        """
        if freq is None or type(freq) != str:
            raise ValueError('Must enter a frequency as a string, m, w, or d')

        proxy = self._proxy
        ticker = ticker.upper()
        
        configdir = get_configdir()
        cachedir = os.path.join(configdir, 'finance.cache')

        if iterable(date1):
            d1 = (date1[1]-1, date1[2], date1[0])
        else:
            d1 = (date1.month-1, date1.day, date1.year)
        if iterable(date2):
            d2 = (date2[1]-1, date2[2], date2[0])
        else:
            d2 = (date2.month-1, date2.day, date2.year)

        urlFmt = 'http://table.finance.yahoo.com/table.csv?a=%d&b=%d&c=%d&d=%d&e=%d&f=%d&s=%s&y=0&g=%s&ignore=.csv'

        url =  urlFmt % (d1[0], d1[1], d1[2],
                         d2[0], d2[1], d2[2], ticker, freq)

        if proxy:
            proxy_support = urllib2.ProxyHandler(proxy)
            opener = urllib2.build_opener(proxy_support)
            urllib2.install_opener(opener)

        if cachename is None:
            cachename = os.path.join(cachedir, md5(url).hexdigest())
        if os.path.exists(cachename):
            fh = file(cachename)
            verbose.report('Using cachefile %s for %s'%(cachename, ticker))
        else:
            if not os.path.isdir(cachedir):
                os.mkdir(cachedir)
            urlfh = urllib2.urlopen(url)

            fh = file(cachename, 'w')
            fh.write(urlfh.read())
            fh.close()
            verbose.report('Saved %s data to cache file %s'%(ticker, cachename))
            fh = file(cachename, 'r')

        return fh
Пример #8
0
    def plot(self, xs, ys, *args, **kwargs):
        '''
        Plot 2D or 3D data.

        ==========  ================================================
        Argument    Description
        ==========  ================================================
        *xs*, *ys*  X, y coordinates of vertices

        *zs*        z value(s), either one for all points or one for
                    each point.
        *zdir*      Which direction to use as z ('x', 'y' or 'z')
                    when plotting a 2d set.
        ==========  ================================================

        Other arguments are passed on to
        :func:`~matplotlib.axes.Axes.plot`
        '''
        # FIXME: This argument parsing might be better handled
        #        when we set later versions of python for
        #        minimum requirements.  Currently at 2.4.
        #        Note that some of the reason for the current difficulty
        #        is caused by the fact that we want to insert a new
        #        (semi-optional) positional argument 'Z' right before
        #        many other traditional positional arguments occur
        #        such as the color, linestyle and/or marker.
        had_data = self.has_data()
        zs = kwargs.pop('zs', 0)
        zdir = kwargs.pop('zdir', 'z')

        argsi = 0
        # First argument is array of zs
        if len(args) > 0 and cbook.iterable(args[0]) and \
                len(xs) == len(args[0]) :
            # So, we know that it is an array with
            # first dimension the same as xs.
            # Next, check to see if the data contained
            # therein (if any) is scalar (and not another array).
            if len(args[0]) == 0 or cbook.is_scalar(args[0][0]) :
                zs = args[argsi]
                argsi += 1

        # First argument is z value
        elif len(args) > 0 and cbook.is_scalar(args[0]):
            zs = args[argsi]
            argsi += 1

        # Match length
        if not cbook.iterable(zs):
            zs = np.ones(len(xs)) * zs

        lines = Axes.plot(self, xs, ys, *args[argsi:], **kwargs)
        for line in lines:
            art3d.line_2d_to_3d(line, zs=zs, zdir=zdir)

        self.auto_scale_xyz(xs, ys, zs, had_data)
        return lines
Пример #9
0
    def bar3d(self, x, y, z, dx, dy, dz, color='b'):
        '''
        Generate a 3D bar, or multiple bars.

        When generating multiple bars, x, y, z have to be arrays.
        dx, dy, dz can still be scalars.
        '''

        had_data = self.has_data()

        if not cbook.iterable(x):
            x, y, z = [x], [y], [z]
        if not cbook.iterable(dx):
            dx, dy, dz = [dx], [dy], [dz]
        if len(dx) == 1:
            dx = dx * len(x)
            dy = dy * len(x)
            dz = dz * len(x)

        minx, miny, minz = 1e20, 1e20, 1e20
        maxx, maxy, maxz = -1e20, -1e20, -1e20

        polys = []
        for xi, yi, zi, dxi, dyi, dzi in zip(x, y, z, dx, dy, dz):
            minx = min(xi, minx)
            maxx = max(xi + dxi, maxx)
            miny = min(yi, miny)
            maxy = max(yi + dyi, maxy)
            minz = min(zi, minz)
            maxz = max(zi + dzi, maxz)

            polys.extend([
                ((xi, yi, zi), (xi + dxi, yi, zi),
                    (xi + dxi, yi + dyi, zi), (xi, yi + dyi, zi)),
                ((xi, yi, zi + dzi), (xi + dxi, yi, zi + dzi),
                    (xi + dxi, yi + dyi, zi + dzi), (xi, yi + dyi, zi + dzi)),

                ((xi, yi, zi), (xi + dxi, yi, zi),
                    (xi + dxi, yi, zi + dzi), (xi, yi, zi + dzi)),
                ((xi, yi + dyi, zi), (xi + dxi, yi + dyi, zi),
                    (xi + dxi, yi + dyi, zi + dzi), (xi, yi + dyi, zi + dzi)),

                ((xi, yi, zi), (xi, yi + dyi, zi),
                    (xi, yi + dyi, zi + dzi), (xi, yi, zi + dzi)),
                ((xi + dxi, yi, zi), (xi + dxi, yi + dyi, zi),
                    (xi + dxi, yi + dyi, zi + dzi), (xi + dxi, yi, zi + dzi)),
            ])

        color = np.array(colorConverter.to_rgba(color))
        normals = self._generate_normals(polys)
        colors = self._shade_colors(color, normals)

        col = art3d.Poly3DCollection(polys, facecolor=colors)
        self.add_collection(col)

        self.auto_scale_xyz((minx, maxx), (miny, maxy), (minz, maxz), had_data)
Пример #10
0
 def _process_linewidths(self):
     linewidths = self.linewidths
     Nlev = len(self.levels)
     if linewidths is None:
         tlinewidths = [(mpl.rcParams['lines.linewidth'],)] *Nlev
     else:
         if cbook.iterable(linewidths) and len(linewidths) < Nlev:
             linewidths = list(linewidths) * int(npy.ceil(Nlev/len(linewidths)))
         elif not cbook.iterable(linewidths) and type(linewidths) in [int, float]:
             linewidths = [linewidths] * Nlev
         tlinewidths = [(w,) for w in linewidths]
     return tlinewidths
Пример #11
0
def getTimeIntervall(stream, start=None, end=None, relative='starttime', ret_rel='utc'):
    """
    Create two lists of UTCDateTimes - start list and end list

    'time' can stand for UTCDateTime, list of UTCDateTimes, header entry out of
    ('ponset', 'sonset', 'startime', 'endtime') or 'middle'
    :param start, end: - None (means start- resp. endtime)
        - time object
        - or seconds relative to param relative
    :param relative: times (if given as seconds=numbers) are taken relative to
        this parameter, is also needed for param ret_rel='relative
        -time object
    :param ret_rel: - 'utc'  output in absolute UTCDateTime
        - 'relative': output in seconds relative to param relative
        - time object: output in seconds relative to time
    :return: start and end list of UTCDateTime or None if stream has length 0
    """
    N = len(stream)
    if N == 0:
        return

    # get list of UTCDateTimes for start_out and end_out
    if start == None:
        start = 'starttime'
    if end == None:
        end = 'endtime'
    start_out = _getUTCListFromSth(stream, start)
    end_out = _getUTCListFromSth(stream, end)

    # get list of UTCDateTimes for relative if needed
    if start_out == None or end_out == None or ret_rel == 'relative':
        relative = _getUTCListFromSth(stream, relative, raisenumber=True)
    # get list of UTCDateTimes for start_out and end_out
    if start_out == None:
        if cbook.iterable(start):
            start_out = [utc + start[i] for i, utc in enumerate(relative)]
        else:
            start_out = [i + start for i in relative]
    if end_out == None:
        if cbook.iterable(start):
            end_out = [utc + end[i] for i, utc in enumerate(relative)]
        else:
            end_out = [i + end for i in relative]

    # convert UTCDateTimes to seconds if ret_rel demands it
    if ret_rel == 'utc':
        return start_out, end_out
    elif ret_rel != 'relative':
        relative = _getUTCListFromSth(stream, ret_rel)
    start_out = [start_out[i] - relative[i] for i in range(N)]
    end_out = [end_out[i] - relative[i] for i in range(N)]
    return start_out, end_out
Пример #12
0
    def append_fields(rec, names, arr, dtype=None):
        """
        Appends a field to an existing record array, handling masked fields
        if necessary.

        Parameters
        ----------
        rec : numpy record array
            Array to which the new field should be appended
        names : string
            Names to be given to the new fields
        arr : ndarray
            Array containing the data for the new fields.
        dtype : data-type or None, optional
            Data type of the new fields.  If this is None, the data types will
            be obtained from `arr`.

        Returns
        -------
        out : numpy record array
            `rec` with the new field appended.
        rec = append_fields(rec, name, arr)
        """
        if not iterable(names):
            names = [names]
        if not iterable(arr):
            arr = [arr]

        if dtype is None:
            dtype = [a.dtype for a in arr]

        newdtype = np.dtype(rec.dtype.descr + zip(names, dtype))
        newrec = np.empty(rec.shape, dtype=newdtype).view(type(rec))

        for name in rec.dtype.names:
            newrec[name] = rec[name]
            try:
                newrec.mask[name] = rec.mask[name]
            except AttributeError:
                pass #Not a masked array

        for n,a in zip(names, arr):
            newrec[n] = a
            try:
                old_mask = a.mask
            except AttributeError:
                old_mask = np.array([False]*a.size).reshape(a.shape)
            try:
                newrec[n].mask = old_mask
            except AttributeError:
                pass
        return newrec
Пример #13
0
def wsat(Temp, press):
    """
    wsat(Temp, press)

    Calculates the saturation vapor mixing ratio of an air parcel.

    Parameters
    - - - - - -
    Temp : float or array_like
        Temperature in Kelvin.
    press : float or array_like
        Pressure in Pa.

    Returns
    - - - -
    theWs : float or array_like 
        Saturation water vapor mixing ratio in (kg/kg).

    Raises
    - - - -
    IOError
        If both 'Temp' and 'press' are array_like.

    Examples
    - - - - -
    >>> test.assert_almost_equal(wsat(300, 8e4),0.02875,decimal=4)
    >>> test.assert_array_almost_equal(wsat([300,310], 8e4),[0.0287, 0.0525],decimal=4)
    >>> test.assert_array_almost_equal(wsat(300, [8e4, 7e4]),[0.0287, 0.0330],decimal=4)
    >>> wsat([300, 310], [8e4, 7e4])
    Traceback (most recent call last):
        ...
    IOError: Can't have two vector inputs.

    """
    is_scalar_temp=True
    if cbook.iterable(Temp):
        is_scalar_temp = False
    is_scalar_press=True
    if cbook.iterable(press):
        is_scalar_press = False
    Temp=np.atleast_1d(Temp)
    press=np.atleast_1d(press)
    if (np.size(Temp) !=1) and (np.size(press) != 1):
        raise IOError, "Can't have two vector inputs."
    es = esat(Temp);
    theWs=(c.eps * es/ (press - es))
    theWs[theWs > 0.060]=0.06
    theWs[theWs < 0.0] = 0.
    if is_scalar_temp and is_scalar_press:
        theWs=theWs[0]
    return theWs
Пример #14
0
    def __call__(self, value, clip=None):
        if clip is None:
            clip = self.clip

        if cbook.iterable(value):
            vtype = 'array'
            val = np.ma.asarray(value).astype(np.float)
        else:
            vtype = 'scalar'
            val = np.ma.array([value]).astype(np.float)

        self.autoscale_None(val)

        vmin, vmax = float(self.vmin), float(self.vmax)
        if vmin > vmax:
            raise ValueError("minvalue must be less than or equal to maxvalue")
        elif vmin==vmax:
            return 0.0 * val
        else:
            if clip:
                mask = np.ma.getmask(val)
                val = np.ma.array(np.clip(val.filled(vmax), vmin, vmax),
                                   mask=mask)
            result = np.ma.array(np.interp(val, self.xval, self.yval),
                                  mask=np.ma.getmask(val))
            result[np.isinf(val.data)] = -np.inf
        if vtype == 'scalar':
            result = result[0]
        return result
Пример #15
0
    def set_3d_properties(self, verts, zs=0, zdir='z'):
        if not iterable(zs):
            zs = np.ones(len(verts)) * zs

        self._segment3d = [juggle_axes(x, y, z, zdir) \
                for ((x, y), z) in zip(verts, zs)]
        self._facecolor3d = Patch.get_facecolor(self)
Пример #16
0
 def convert(val, unit, axis):
     if units.ConversionInterface.is_numlike(val):
         return val
     if iterable(val):
         return [thisval.convert_to(unit).get_value() for thisval in val]
     else:
         return val.convert_to(unit).get_value()
Пример #17
0
    def get_converter(self, x):
        'get the converter interface instance for x, or None'

        if not len(self): return None # nothing registered
        #DISABLED idx = id(x)
        #DISABLED cached = self._cached.get(idx)
        #DISABLED if cached is not None: return cached

        converter = None
        classx = getattr(x, '__class__', None)

        if classx is not None:
            converter = self.get(classx)

        # Check explicity for strings here because they would otherwise
        # lead to an infinite recursion, because a single character will
        # pass the iterable() check.
        if converter is None and iterable(x) and not is_string_like(x):
            # if this is anything but an object array, we'll assume
            # there are no custom units
            if isinstance(x, np.ndarray) and x.dtype != np.object:
                return None

            for thisx in x:
                converter = self.get_converter( thisx )
                return converter

        #DISABLED self._cached[idx] = converter
        return converter
Пример #18
0
    def __init__(self, artists, tolerance=5, offsets=(-20, 20), template="x: %0.2f\ny: %0.2f", display_all=False):
        """Create the data cursor and connect it to the relevant figure.
        "artists" is the matplotlib artist or sequence of artists that will be 
            selected. 
        "tolerance" is the radius (in points) that the mouse click must be
            within to select the artist.
        "offsets" is a tuple of (x,y) offsets in points from the selected
            point to the displayed annotation box
        "template" is the format string to be used. Note: For compatibility
            with older versions of python, this uses the old-style (%) 
            formatting specification.
        "display_all" controls whether more than one annotation box will
            be shown if there are multiple axes.  Only one will be shown
            per-axis, regardless. 
        """
        self.template = template
        self.offsets = offsets
        self.display_all = display_all
        if not cbook.iterable(artists):
            artists = [artists]
        self.artists = artists
        self.axes = tuple(set(art.axes for art in self.artists))
        self.figures = tuple(set(ax.figure for ax in self.axes))

        self.annotations = {}
        for ax in self.axes:
            self.annotations[ax] = self.annotate(ax)

        for artist in self.artists:
            artist.set_picker(tolerance)
        for fig in self.figures:
            fig.canvas.mpl_connect("pick_event", self)
Пример #19
0
def hist(*args, **kwargs):
    """
    Plots a histogram of the provided data. Can provide optional argument
    "grid='x'" or "grid='y'" to draw a white grid over the histogram. Almost like "erasing" some of the plot,
     but it adds more information!
    """
    ax, args, kwargs = maybe_get_ax(*args, **kwargs)

    color_cycle = ax._get_lines.color_cycle
    # Reassign the default colors to Set2 by Colorbrewer
    if iterable(args[0]):
        if isinstance(args[0], list):
            ncolors = len(args[0])
        else:
            if len(args[0].shape) == 2:
                ncolors = args[0].shape[1]
            else:
                ncolors = 1
        kwargs.setdefault('color', [next(color_cycle) for _ in range(ncolors)])
    else:
        kwargs.setdefault('color', next(color_cycle))
    kwargs.setdefault('edgecolor', 'white')
    show_ticks = kwargs.pop('show_ticks', False)

    # If no grid specified, don't draw one.
    grid = kwargs.pop('grid', None)

    # print 'hist kwargs', kwargs
    patches = ax.hist(*args, **kwargs)
    remove_chartjunk(ax, ['top', 'right'], grid=grid, show_ticks=show_ticks)
    return ax
Пример #20
0
    def __init__(self, artists, lookUp, formatFunction, convert,
                 tolerance=5, offsets=(-30, 20), display_all=False):
        """Create the data cursor and connect it to the relevant figure.
        "artists" is the matplotlib artist or sequence of artists that will be
            selected.
        "tolerance" is the radius (in points) that the mouse click must be
            within to select the artist.
        "offsets" is a tuple of (x,y) offsets in points from the selected
            point to the displayed annotation box
        "display_all" controls whether more than one annotation box will
            be shown if there are multiple axes.  Only one will be shown
            per-axis, regardless.
        """
        self.lookUp = lookUp
        self.formatFunction = formatFunction
        self.offsets = offsets
        self.display_all = display_all
        if not cbook.iterable(artists):
            artists = [artists]
        self.artists = artists
        self.convert = convert
        self.axes = tuple(set(art.axes for art in self.artists))
        self.figures = tuple(set(ax.figure for ax in self.axes))

        self.annotations = {}
        for ax in self.axes:
            self.annotations[ax] = self.annotate(ax)
        for artist in self.artists:
            artist.set_picker(tolerance)
        for fig in self.figures:
            fig.canvas.mpl_connect('pick_event', self)
            fig.canvas.mpl_connect('key_press_event', self.keyPressed)
Пример #21
0
    def __call__(self, value, clip=None):
        if clip is None:
            clip = self.clip

        if cbook.iterable(value):
            vtype = 'array'
            val = ma.asarray(value).astype(np.float)
        else:
            vtype = 'scalar'
            val = ma.array([value]).astype(np.float)

        self.autoscale_None(val)
        vmin, vmax = self.vmin, self.vmax
        if vmin > vmax:
            raise ValueError("minvalue must be less than or equal to maxvalue")
        elif vmin<=0:
            raise ValueError("values must all be positive")
        elif vmin==vmax:
            return 0.0 * val
        else:
            if clip:
                mask = ma.getmask(val)
                val = ma.array(np.clip(val.filled(vmax), vmin, vmax),
                                mask=mask)
            result = (ma.log(val)-np.log(vmin))/(np.log(vmax)-np.log(vmin))
        if vtype == 'scalar':
            result = result[0]
        return result
Пример #22
0
    def process_value(value):
        """
        Homogenize the input *value* for easy and efficient normalization.

        *value* can be a scalar or sequence.

        Returns *result*, *is_scalar*, where *result* is a
        masked array matching *value*.  Float dtypes are preserved;
        integer types with two bytes or smaller are converted to
        np.float32, and larger types are converted to np.float.
        Preserving float32 when possible, and using in-place operations,
        can greatly improve speed for large arrays.

        Experimental; we may want to add an option to force the
        use of float32.
        """
        if cbook.iterable(value):
            is_scalar = False
            result = ma.asarray(value)
            if result.dtype.kind == 'f':
                if isinstance(value, np.ndarray):
                    result = result.copy()
            elif result.dtype.itemsize > 2:
                result = result.astype(np.float)
            else:
                result = result.astype(np.float32)
        else:
            is_scalar = True
            result = ma.array([value]).astype(np.float)
        return result, is_scalar
Пример #23
0
    def to_rgba(self, arg, alpha=None):
        """
        Returns an *RGBA* tuple of four floats from 0-1.

        For acceptable values of *arg*, see :meth:`to_rgb`.
        If *arg* is an *RGBA* sequence and *alpha* is not *None*,
        *alpha* will replace the original *A*.
        """
        try:
            if not cbook.is_string_like(arg) and cbook.iterable(arg):
                if len(arg) == 4:
                    if [x for x in arg if (float(x) < 0) or  (x > 1)]:
                        # This will raise TypeError if x is not a number.
                        raise ValueError('number in rbga sequence outside 0-1 range')
                    if alpha is None:
                        return tuple(arg)
                    if alpha < 0.0 or alpha > 1.0:
                        raise ValueError("alpha must be in range 0-1")
                    return arg[0], arg[1], arg[2], arg[3] * alpha
                r,g,b = arg[:3]
                if [x for x in (r,g,b) if (float(x) < 0) or  (x > 1)]:
                    raise ValueError('number in rbg sequence outside 0-1 range')
            else:
                r,g,b = self.to_rgb(arg)
            if alpha is None:
                alpha = 1.0
            return r,g,b,alpha
        except (TypeError, ValueError), exc:
            raise ValueError('to_rgba: Invalid rgba arg "%s"\n%s' % (str(arg), exc))
    def __init__(self, artists, x = [], y = [], tolerance = 5, offsets = (-20, 20),
                 formatter = fmt, display_all = False):
        """Create the data cursor and connect it to the relevant figure.
        "artists" is the matplotlib artist or sequence of artists that will be 
            selected. 
        "tolerance" is the radius (in points) that the mouse click must be
            within to select the artist.
        "offsets" is a tuple of (x,y) offsets in points from the selected
            point to the displayed annotation box
        "formatter" is a callback function which takes 2 numeric arguments and
            returns a string
        "display_all" controls whether more than one annotation box will
            be shown if there are multiple axes.  Only one will be shown
            per-axis, regardless. 
        """
        self._points = np.column_stack((x,y))
        self.formatter = formatter
        self.offsets = offsets
        self.display_all = display_all
        if not cbook.iterable(artists):
            artists = [artists]
        self.artists = artists
        self.axes = tuple(set(art.axes for art in self.artists))
        self.figures = tuple(set(ax.figure for ax in self.axes))

        self.annotations = {}
        for ax in self.axes:
            self.annotations[ax] = self.annotate(ax)

        for artist in self.artists:
            artist.set_picker(tolerance)
        for fig in self.figures:
            fig.canvas.mpl_connect('pick_event', self)
Пример #25
0
def get_dir_vector(zdir):
    """
    Return a direction vector.

    Parameters
    ----------
    zdir : {'x', 'y', 'z', None, 3-tuple}
        The direction. Possible values are:
        - 'x': equivalent to (1, 0, 0)
        - 'y': euqivalent to (0, 1, 0)
        - 'z': equivalent to (0, 0, 1)
        - *None*: euqivalent to (0, 0, 0)
        - an iterable (x, y, z) is returned unchanged.

    Returns
    -------
    x, y, z : array-like
        The direction vector. This is either a numpy.array or *zdir* itself if
        *zdir* is already a length-3 iterable.

    """
    if zdir == 'x':
        return np.array((1, 0, 0))
    elif zdir == 'y':
        return np.array((0, 1, 0))
    elif zdir == 'z':
        return np.array((0, 0, 1))
    elif zdir is None:
        return np.array((0, 0, 0))
    elif cbook.iterable(zdir) and len(zdir) == 3:
        return zdir
    else:
        raise ValueError("'x', 'y', 'z', None or vector of length 3 expected")
Пример #26
0
    def get_converter(self, x):
        'get the converter interface instance for x, or None'

        if not len(self): return None # nothing registered
        #DISABLED idx = id(x)
        #DISABLED cached = self._cached.get(idx)
        #DISABLED if cached is not None: return cached

        converter = None
        classx = getattr(x, '__class__', None)

        if classx is not None:
            converter = self.get(classx)

        if converter is None and iterable(x):
            for thisx in x:
                # Make sure that recursing might actually lead to a solution, if
                # we are just going to re-examine another item of the same kind,
                # then do not look at it.
                if classx and classx != getattr(thisx, '__class__', None):
                    converter = self.get_converter( thisx )
                    return converter

        #DISABLED self._cached[idx] = converter
        return converter
Пример #27
0
    def to_rgba(self, arg, alpha=None):
        """
        Returns an RGBA tuple of four floats from 0-1.

        For acceptable values of arg, see to_rgb.
        If arg is an RGBA sequence and alpha is not None,
        alpha will replace the original A.
        """
        try:
            if not cbook.is_string_like(arg) and cbook.iterable(arg):
                if len(arg) == 4 and alpha is None:
                    if [x for x in arg if (float(x) < 0) or  (x > 1)]:
                        # This will raise TypeError if x is not a number.
                        raise ValueError('number in rbga sequence outside 0-1 range')
                    return tuple(arg)
                r,g,b = arg[:3]
                if [x for x in (r,g,b) if (float(x) < 0) or  (x > 1)]:
                    raise ValueError('number in rbg sequence outside 0-1 range')
            else:
                r,g,b = self.to_rgb(arg)
            if alpha is None:
                alpha = 1.0
            return r,g,b,alpha
        except (TypeError, ValueError), exc:
            raise ValueError('to_rgba: Invalid rgba arg "%s"\n%s' % (str(arg), exc))
Пример #28
0
 def _determine_lims(self, xmin=None, xmax=None, *args, **kwargs):
     if xmax is None and cbook.iterable(xmin):
         xmin, xmax = xmin
     if xmin == xmax:
         xmin -= 0.5
         xmax += 0.5
     return (xmin, xmax)
Пример #29
0
    def __call__(self, value, clip=None):
        if clip is None:
            clip = self.clip

        if cbook.iterable(value):
            vtype = 'array'
            val = np.ma.asarray(value).astype(np.float)
        else:
            vtype = 'scalar'
            val = np.ma.array([value]).astype(np.float)

        winf = np.isinf(val.data)
        val = np.ma.masked_where(winf,val)

        self.autoscale_None(val)
        vmin, vmax = float(self.vmin), float(self.vmax)
        if vmin > vmax:
            raise ValueError("minvalue must be less than or equal to maxvalue")
        elif vmin==vmax:
            return type(value)(0.0 * np.asarray(value))
        else:
            if clip:
                mask = np.ma.getmask(val)
                val = np.ma.array(np.clip(val.filled(vmax), vmin, vmax),
                                   mask=mask)
            result = (val-vmin) * (1./(vmax-vmin))
            result.data[result.data<0]=0.0
            result.data[result.data>1]=1.0
            result[winf] = -np.inf
            if result.mask is not np.ma.nomask:
                result.mask[winf] = False
        if vtype == 'scalar':
            result = result[0]
        return result
Пример #30
0
    def common_limits(datasets, default_min=0, default_max=0):
        """Find the global maxima and minima of a list of datasets.

        Parameters
        ----------
        datasets : `iterable`
            list (or any other iterable) of data arrays to analyse.

        default_min : `float`, optional
            fall-back minimum value if datasets are all empty.

        default_max : `float`, optional
            fall-back maximum value if datasets are all empty.

        Returns
        -------
        (min, max) : `float`
            2-tuple of common minimum and maximum over all datasets.
        """
        from glue import iterutils
        if isinstance(datasets, numpy.ndarray) or not iterable(datasets[0]):
            datasets = [datasets]
        max_stat = max(list(iterutils.flatten(datasets)) + [-numpy.inf])
        min_stat = min(list(iterutils.flatten(datasets)) + [numpy.inf])
        if numpy.isinf(-max_stat):
            max_stat = default_max
        if numpy.isinf(min_stat):
            min_stat = default_min
        return min_stat, max_stat
Пример #31
0
def cos(x):
    if iterable(x):
        return [math.cos(val.convert_to(radians).get_value()) for val in x]
    else:
        return math.cos(x.convert_to(radians).get_value())
Пример #32
0
def get_color_dict(color, item_list, vmin=None, vmax=None, cmap=None):
    """ Determine color rgb color values given a data list.

    This function is used to take a sequence of data and convert it
    into a dictionary which of possible rgb values. It can take a
    number of different types of data explained below. If no colormap
    is given it will return the grayscale for scalar values.

    Parameters:
    -----------
    color: A string, scalar, or iterable of either.
           This can be a color in a variety of formats. A matplotlib
           a single color, which can be a matplotlib color specification
           e.g. 'rgbcmykw', a hex color string '#00FFFF', a standard
           html name like 'aqua', or a numeric value to be scaled with
           vmax or vmin. It can also be a list of any of these types
           as well as a dictionary of any of these types.
    item_list: a list
               A list of keys which correspond to the values given in
               color.
    vmin: A scalar
          The minimum value if scalar values are given for color
    vmax: A scalar
          The maximum value if scalar values are given for color
    cmap: A matplotlib colormap
          A colormap to be used if scalar values are given.

    Returns:
    -------
    color_dict: dict
                A dictionary of rgb colors keyed by values in item_list
    """

    CC = mcolors.ColorConverter()

    if cb.is_string_like(color):
        return {}.fromkeys(item_list, CC.to_rgb(color))
    elif cb.is_scalar(color):
        CN = mcolors.Normalize(0.0, 1.0)
        if cmap is not None:
            return {}.fromkeys(item_list, cmap(CN(color)))
        else:
            return {}.fromkeys(item_list, CC.to_rgb(str(CN(color))))
    elif cb.iterable(color) and not cb.is_string_like(color):
        try:
            vals = [color[i] for i in item_list]
        except:
            vals = color
        keys = item_list
        if len(item_list) > len(vals):
            raise nx.NetworkXError("Must provide a value for each item")
        if cb.alltrue([cb.is_string_like(c) for c in vals]):
            return dict(zip(keys, [CC.to_rgb(v) for v in vals]))
        elif cb.alltrue([cb.is_scalar(c) for c in vals]):
            if vmin is None:
                vmin = float(min(vals))
            if vmax is None:
                vmax = float(max(vals))
            CN = mcolors.Normalize(vmin, vmax)
            if cmap is not None:
                return dict(zip(keys, [cmap(CN(v)) for v in vals]))
            else:
                return dict(zip(keys, [CC.to_rgb(str(CN(v))) for v in vals]))
        elif cb.alltrue([cb.iterable(c) and not cb.is_string(c)
                         for c in vals]):
            return dict(zip(keys, vals))
    else:
        raise nx.NetworkXError("Could not convert colors")
Пример #33
0
    maxy = np.amax(temp_y)

    w = max(maxx - minx, 1.0)
    h = max(maxy - miny, 1.0)
    #for scaling

    axcorn = ax.get_position().get_points()

    xperc = (axcorn[1][0] - axcorn[0][0]) * .5
    yperc = (axcorn[1][1] - axcorn[0][1]) * .5

    area2radius = lambda a: math.sqrt(
        (a * w * h) / (ax.figure.get_figheight() * ax.figure.get_figwidth(
        ) * ax.figure.dpi * ax.figure.dpi * math.pi * xperc * yperc))

    if cb.iterable(node_size):
        try:
            vals = node_size.values()
        except:
            vals = node_size
        node_size = dict(zip(nodelist, map(area2radius, vals)))
    else:
        node_size = {}.fromkeys(nodelist, area2radius(node_size))
    for n in node_size:
        if node_size[n] == 0.0:
            node_size[n] = .00001

    if cmap is None:
        cmap = cm.get_cmap(mpl.rcParams['image.cmap'])

    n_colors = get_color_dict(node_color, nodelist, vmin, vmax, cmap)
Пример #34
0
    def __call__(self, X, alpha=None, bytes=False):
        """
        *X* is either a scalar or an array (of any dimension).
        If scalar, a tuple of rgba values is returned, otherwise
        an array with the new shape = oldshape+(4,). If the X-values
        are integers, then they are used as indices into the array.
        If they are floating point, then they must be in the
        interval (0.0, 1.0).
        Alpha must be a scalar between 0 and 1, or None.
        If bytes is False, the rgba values will be floats on a
        0-1 scale; if True, they will be uint8, 0-255.
        """

        if not self._isinit: self._init()
        mask_bad = None
        if not cbook.iterable(X):
            vtype = 'scalar'
            xa = np.array([X])
        else:
            vtype = 'array'
            xma = ma.array(X, copy=False)
            mask_bad = xma.mask
            xa = xma.data.copy()   # Copy here to avoid side effects.
            del xma
            # masked values are substituted below; no need to fill them here

        if xa.dtype.char in np.typecodes['Float']:
            np.putmask(xa, xa==1.0, 0.9999999) #Treat 1.0 as slightly less than 1.
            # The following clip is fast, and prevents possible
            # conversion of large positive values to negative integers.

            xa *= self.N
            if NP_CLIP_OUT:
                np.clip(xa, -1, self.N, out=xa)
            else:
                xa = np.clip(xa, -1, self.N)

            # ensure that all 'under' values will still have negative
            # value after casting to int
            np.putmask(xa, xa<0.0, -1)
            xa = xa.astype(int)
        # Set the over-range indices before the under-range;
        # otherwise the under-range values get converted to over-range.
        np.putmask(xa, xa>self.N-1, self._i_over)
        np.putmask(xa, xa<0, self._i_under)
        if mask_bad is not None:
            if mask_bad.shape == xa.shape:
                np.putmask(xa, mask_bad, self._i_bad)
            elif mask_bad:
                xa.fill(self._i_bad)
        if bytes:
            lut = (self._lut * 255).astype(np.uint8)
        else:
            lut = self._lut.copy() # Don't let alpha modify original _lut.

        if alpha is not None:
            alpha = min(alpha, 1.0) # alpha must be between 0 and 1
            alpha = max(alpha, 0.0)
            if bytes:
                alpha = int(alpha * 255)
            if (lut[-1] == 0).all():
                lut[:-1, -1] = alpha
                # All zeros is taken as a flag for the default bad
                # color, which is no color--fully transparent.  We
                # don't want to override this.
            else:
                lut[:,-1] = alpha
                # If the bad value is set to have a color, then we
                # override its alpha just as for any other value.

        rgba = np.empty(shape=xa.shape+(4,), dtype=lut.dtype)
        lut.take(xa, axis=0, mode='clip', out=rgba)
                    #  twice as fast as lut[xa];
                    #  using the clip or wrap mode and providing an
                    #  output array speeds it up a little more.
        if vtype == 'scalar':
            rgba = tuple(rgba[0,:])
        return rgba
def draw_networkx_edges(G,
                        pos,
                        edgelist=None,
                        width=1.0,
                        edge_color='k',
                        style='solid',
                        alpha=1.0,
                        ax=None,
                        **kwds):
    """Draw the edges of the graph G

	This draws only the edges of the graph G.

	pos is a dictionary keyed by vertex with a two-tuple
	of x-y positions as the value.
	See networkx.layout for functions that compute node positions.

	edgelist is an optional list of the edges in G to be drawn.
	If provided, only the edges in edgelist will be drawn. 
	
	See draw_networkx for the list of other optional parameters.

	"""
    from matplotlib.pylab import gca, hold, draw_if_interactive
    from matplotlib.patches import FancyArrow
    from matplotlib.collections import PolyCollection
    if ax is None:
        ax = gca()

    if edgelist is None:
        edgelist = G.edges()

    if not edgelist:  # no edges!
        return None

    # set edge positions
    head = []
    tail = []
    for e in edgelist:
        # edge e can be a 2-tuple (Graph) or a 3-tuple (Xgraph)
        u = e[0]
        v = e[1]
        head.append(pos[u])
        tail.append(pos[v])
    edge_pos = asarray(zip(head, tail))

    if not cb.iterable(width):
        lw = (width, )
    else:
        lw = width

    # edge colors specified with floats won't work here
    # since LineCollection doesn't use ScalarMappable.
    # You can use an array of RGBA or text labels
    if not cb.is_string_like(edge_color) \
        and cb.iterable(edge_color) \
        and len(edge_color)==len(edge_pos):
        edge_colors = None
    else:
        edge_colors = (colorConverter.to_rgba(edge_color, alpha), )

    if not G.is_directed():
        edge_collection = LineCollection(
            edge_pos,
            colors=edge_colors,
            linewidths=lw,
            antialiaseds=(1, ),
            linestyle=style,
            transOffset=ax.transData,
        )
        edge_collection.set_alpha(alpha)
    else:
        arrows = []
        for src, dst in edge_pos:
            x1, y1 = src
            x2, y2 = dst
            dx = x2 - x1  # x offset
            dy = y2 - y1  # y offset
            vu_x = dx / sqrt(dx * dx + dy * dy)  #direction in arc sense
            vu_y = dy / sqrt(dx * dx + dy * dy)
            p = 0.026
            arrows.append(
                FancyArrow(
                    x1,
                    y1,
                    dx - p * vu_x,
                    dy - p * vu_y,
                    head_width=p,
                    length_includes_head=True,
                ).get_verts())
        edge_collection = PolyCollection(
            arrows,
            facecolors=edge_colors,
            antialiaseds=(1, ),
            transOffset=ax.transData,
        )
    # update view
    xx = [x for (x, y) in head + tail]
    yy = [y for (x, y) in head + tail]
    minx = amin(xx)
    maxx = amax(xx)
    miny = amin(yy)
    maxy = amax(yy)
    w = maxx - minx
    h = maxy - miny
    padx, pady = 0.05 * w, 0.05 * h
    corners = (minx - padx, miny - pady), (maxx + padx, maxy + pady)
    ax.update_datalim(corners)
    ax.autoscale_view()

    edge_collection.set_zorder(1)  # edges go behind nodes
    ax.add_collection(edge_collection)

    return edge_collection
Пример #36
0
    def __init__(
        self,
        ax,
        cmap=None,
        norm=None,
        alpha=1.0,
        values=None,
        boundaries=None,
        orientation='vertical',
        extend='neither',
        spacing='uniform',  # uniform or proportional
        ticks=None,
        format=None,
        drawedges=False,
        filled=True,
    ):
        self.ax = ax

        if cmap is None: cmap = cm.get_cmap()
        if norm is None: norm = colors.Normalize()
        self.alpha = alpha
        cm.ScalarMappable.__init__(self, cmap=cmap, norm=norm)
        self.values = values
        self.boundaries = boundaries
        self.extend = extend
        self.spacing = spacing
        self.orientation = orientation
        self.drawedges = drawedges
        self.filled = filled

        # artists
        self.solids = None
        self.lines = None
        self.dividers = None
        self.extension_patch1 = None
        self.extension_patch2 = None

        if orientation == "vertical":
            self.cbar_axis = self.ax.yaxis
        else:
            self.cbar_axis = self.ax.xaxis

        if format is None:
            if isinstance(self.norm, colors.LogNorm):
                # change both axis for proper aspect
                self.ax.set_xscale("log")
                self.ax.set_yscale("log")
                self.cbar_axis.set_minor_locator(ticker.NullLocator())
                formatter = ticker.LogFormatter()
            else:
                formatter = None
        elif isinstance(format, six.string_types):
            formatter = ticker.FormatStrFormatter(format)
        else:
            formatter = format  # Assume it is a Formatter

        if formatter is None:
            formatter = self.cbar_axis.get_major_formatter()
        else:
            self.cbar_axis.set_major_formatter(formatter)

        if cbook.iterable(ticks):
            self.cbar_axis.set_ticks(ticks)
        elif ticks is not None:
            self.cbar_axis.set_major_locator(ticks)
        else:
            self._select_locator(formatter)

        self._config_axes()

        self.update_artists()

        self.set_label_text('')
Пример #37
0
def psd(x, blocksize=256, NFFT=256, Fs=1, detrend=detrend_none,
        window=window_hanning, noverlap=0):
    """
    The power spectral density by Welches average periodogram method.
    The vector x is divided into blocklength length segments.  Each segment
    is detrended by function detrend and windowed by function window.
    noperlap gives the length of the overlap between segments.  The
    absolute(fft(segment))**2 of each segment are averaged to compute Pxx,
    with a scaling to correct for power loss due to windowing.

    Fs is the sampling frequency (samples per time unit).  It is used
    to calculate the Fourier frequencies, freqs, in cycles per time
    unit.

    -- detrend is a function, unlike in matlab where it is a vector.
    -- window can be a function or a vector of length blocksize. To create window
       vectors see numpy.blackman, numpy.hamming, numpy.bartlett,
       scipy.signal, scipy.signal.get_window etc.
    -- if length x < blocksize, it will be zero padded to blocksize


    Returns the tuple Pxx, freqs

    Refs:
      Bendat & Piersol -- Random Data: Analysis and Measurement
        Procedures, John Wiley & Sons (1986)

    """

    x = np.asarray(x) # make sure we're dealing with a numpy array

    blocksize=int(blocksize)
    NFFT=int(NFFT)

    # zero pad x up to blocksize if it is shorter than blocksize
    if len(x)<blocksize:
        n = len(x)
        x = np.resize(x, (blocksize,))    # Can't use resize method.
        x[n:] = 0

    # for real x, ignore the negative frequencies
    if np.iscomplexobj(x): numFreqs = blocksize
    else: numFreqs = blocksize//2+1

    if cbook.iterable(window):
        assert(len(window) == blocksize)
        windowVals = window
    else:
        windowVals = window(np.ones((blocksize,),x.dtype))

    step = blocksize-noverlap
    ind = range(0,len(x)-blocksize+1,step)
    n = len(ind)
    Pxx = np.zeros((numFreqs,n), np.float_)
    # do the ffts of the slices
    for i in range(n):
        thisX = x[ind[i]:ind[i]+blocksize]
        thisX = windowVals * detrend(thisX)
        fx = (np.absolute(np.fft.fft(thisX,n=NFFT))**2)/(blocksize)
        Pxx[:,i] = fx[:numFreqs]

    if n>1:
        Pxx = Pxx.mean(axis=1)
    # Scale the spectrum by the norm of the window to compensate for
    # windowing loss; see Bendat & Piersol Sec 11.5.2
    Pxx /= (np.abs(windowVals)**2).sum()/(blocksize)

    freqs = Fs/np.float(NFFT) * np.arange(numFreqs)

    return Pxx, freqs
Пример #38
0
 def is_iterable(var):
     return cbook.iterable(var) and not is_string(var)
Пример #39
0
def is_scalar_or_string(val):
    """
    Return whether the given object is a scalar or string like.
    """
    return is_string(val) or not cbook.iterable(val)
Пример #40
0
def setp(obj, *args, **kwargs):
    """
    Set a property on an artist object.

    matplotlib supports the use of :func:`setp` ("set property") and
    :func:`getp` to set and get object properties, as well as to do
    introspection on the object.  For example, to set the linestyle of a
    line to be dashed, you can do::

      >>> line, = plot([1,2,3])
      >>> setp(line, linestyle='--')

    If you want to know the valid types of arguments, you can provide
    the name of the property you want to set without a value::

      >>> setp(line, 'linestyle')
          linestyle: [ '-' | '--' | '-.' | ':' | 'steps' | 'None' ]

    If you want to see all the properties that can be set, and their
    possible values, you can do::

      >>> setp(line)
          ... long output listing omitted

    You may specify another output file to `setp` if `sys.stdout` is not
    acceptable for some reason using the `file` keyword-only argument::

      >>> with fopen('output.log') as f:
      >>>     setp(line, file=f)

    :func:`setp` operates on a single instance or a iterable of
    instances. If you are in query mode introspecting the possible
    values, only the first instance in the sequence is used. When
    actually setting values, all the instances will be set.  e.g.,
    suppose you have a list of two lines, the following will make both
    lines thicker and red::

      >>> x = arange(0,1.0,0.01)
      >>> y1 = sin(2*pi*x)
      >>> y2 = sin(4*pi*x)
      >>> lines = plot(x, y1, x, y2)
      >>> setp(lines, linewidth=2, color='r')

    :func:`setp` works with the MATLAB style string/value pairs or
    with python kwargs.  For example, the following are equivalent::

      >>> setp(lines, 'linewidth', 2, 'color', 'r')  # MATLAB style
      >>> setp(lines, linewidth=2, color='r')        # python style
    """

    if not cbook.iterable(obj):
        objs = [obj]
    else:
        objs = list(cbook.flatten(obj))

    insp = ArtistInspector(objs[0])

    # file has to be popped before checking if kwargs is empty
    printArgs = {}
    if 'file' in kwargs:
        printArgs['file'] = kwargs.pop('file')

    if not kwargs and len(args) < 2:
        if args:
            print(insp.pprint_setters(prop=args[0]), **printArgs)
        else:
            print('\n'.join(insp.pprint_setters()), **printArgs)
        return

    if len(args) % 2:
        raise ValueError('The set args must be string, value pairs')

    # put args into ordereddict to maintain order
    funcvals = OrderedDict()
    for i in range(0, len(args) - 1, 2):
        funcvals[args[i]] = args[i + 1]

    ret = [o.update(funcvals) for o in objs]
    ret.extend([o.set(**kwargs) for o in objs])
    return [x for x in cbook.flatten(ret)]
Пример #41
0
 def default_units(x, axis):
     'return the default unit for x or None'
     if iterable(x):
         for thisx in x:
             return thisx.unit
     return x.unit
    def add(self,
            patchlabel='',
            flows=None,
            orientations=None,
            labels='',
            trunklength=1.0,
            pathlengths=0.25,
            prior=None,
            connect=(0, 0),
            rotation=0,
            **kwargs):
        """
        Add a simple Sankey diagram with flows at the same hierarchical level.

        Return value is the instance of :class:`Sankey`.

        Optional keyword arguments:

          ===============   ===================================================
          Keyword           Description
          ===============   ===================================================
          *patchlabel*      label to be placed at the center of the diagram
                            Note: *label* (not *patchlabel*) will be passed to
                            the patch through ``**kwargs`` and can be used to
                            create an entry in the legend.
          *flows*           array of flow values
                            By convention, inputs are positive and outputs are
                            negative.
          *orientations*    list of orientations of the paths
                            Valid values are 1 (from/to the top), 0 (from/to
                            the left or right), or -1 (from/to the bottom).  If
                            *orientations* == 0, inputs will break in from the
                            left and outputs will break away to the right.
          *labels*          list of specifications of the labels for the flows
                            Each value may be *None* (no labels), '' (just
                            label the quantities), or a labeling string.  If a
                            single value is provided, it will be applied to all
                            flows.  If an entry is a non-empty string, then the
                            quantity for the corresponding flow will be shown
                            below the string.  However, if the *unit* of the
                            main diagram is None, then quantities are never
                            shown, regardless of the value of this argument.
          *trunklength*     length between the bases of the input and output
                            groups
          *pathlengths*     list of lengths of the arrows before break-in or
                            after break-away
                            If a single value is given, then it will be applied
                            to the first (inside) paths on the top and bottom,
                            and the length of all other arrows will be
                            justified accordingly.  The *pathlengths* are not
                            applied to the horizontal inputs and outputs.
          *prior*           index of the prior diagram to which this diagram
                            should be connected
          *connect*         a (prior, this) tuple indexing the flow of the
                            prior diagram and the flow of this diagram which
                            should be connected
                            If this is the first diagram or *prior* is *None*,
                            *connect* will be ignored.
          *rotation*        angle of rotation of the diagram [deg]
                            *rotation* is ignored if this diagram is connected
                            to an existing one (using *prior* and *connect*).
                            The interpretation of the *orientations* argument
                            will be rotated accordingly (e.g., if *rotation*
                            == 90, an *orientations* entry of 1 means to/from
                            the left).
          ===============   ===================================================

        Valid kwargs are :meth:`matplotlib.patches.PathPatch` arguments:

        %(Patch)s

        As examples, ``fill=False`` and ``label='A legend entry'``.
        By default, ``facecolor='#bfd1d4'`` (light blue) and
        ``linewidth=0.5``.

        The indexing parameters (*prior* and *connect*) are zero-based.

        The flows are placed along the top of the diagram from the inside out
        in order of their index within the *flows* list or array.  They are
        placed along the sides of the diagram from the top down and along the
        bottom from the outside in.

        If the the sum of the inputs and outputs is nonzero, the discrepancy
        will appear as a cubic Bezier curve along the top and bottom edges of
        the trunk.

        .. seealso::

            :meth:`finish`
        """
        # Check and preprocess the arguments.
        if flows is None:
            flows = np.array([1.0, -1.0])
        else:
            flows = np.array(flows)
        n = flows.shape[0]  # Number of flows
        if rotation is None:
            rotation = 0
        else:
            # In the code below, angles are expressed in deg/90.
            rotation /= 90.0
        if orientations is None:
            orientations = [0, 0]
        assert len(orientations) == n, (
            "orientations and flows must have the same length.\n"
            "orientations has length %d, but flows has length %d." %
            (len(orientations), n))
        if labels != '' and getattr(labels, '__iter__', False):
            # iterable() isn't used because it would give True if labels is a
            # string
            assert len(labels) == n, (
                "If labels is a list, then labels and flows must have the "
                "same length.\nlabels has length %d, but flows has length %d."
                % (len(labels), n))
        else:
            labels = [labels] * n
        assert trunklength >= 0, (
            "trunklength is negative.\nThis isn't allowed, because it would "
            "cause poor layout.")
        if np.absolute(np.sum(flows)) > self.tolerance:
            verbose.report(
                "The sum of the flows is nonzero (%f).\nIs the "
                "system not at steady state?" % np.sum(flows), 'helpful')
        scaled_flows = self.scale * flows
        gain = sum(max(flow, 0) for flow in scaled_flows)
        loss = sum(min(flow, 0) for flow in scaled_flows)
        if not (0.5 <= gain <= 2.0):
            verbose.report(
                "The scaled sum of the inputs is %f.\nThis may "
                "cause poor layout.\nConsider changing the scale so"
                " that the scaled sum is approximately 1.0." % gain, 'helpful')
        if not (-2.0 <= loss <= -0.5):
            verbose.report(
                "The scaled sum of the outputs is %f.\nThis may "
                "cause poor layout.\nConsider changing the scale so"
                " that the scaled sum is approximately 1.0." % gain, 'helpful')
        if prior is not None:
            assert prior >= 0, "The index of the prior diagram is negative."
            assert min(connect) >= 0, (
                "At least one of the connection indices is negative.")
            assert prior < len(self.diagrams), (
                "The index of the prior diagram is %d, but there are "
                "only %d other diagrams.\nThe index is zero-based." %
                (prior, len(self.diagrams)))
            assert connect[0] < len(self.diagrams[prior].flows), (
                "The connection index to the source diagram is %d, but "
                "that diagram has only %d flows.\nThe index is zero-based." %
                (connect[0], len(self.diagrams[prior].flows)))
            assert connect[1] < n, (
                "The connection index to this diagram is %d, but this diagram"
                "has only %d flows.\n The index is zero-based." %
                (connect[1], n))
            assert self.diagrams[prior].angles[connect[0]] is not None, (
                "The connection cannot be made.  Check that the magnitude "
                "of flow %d of diagram %d is greater than or equal to the "
                "specified tolerance." % (connect[0], prior))
            flow_error = (self.diagrams[prior].flows[connect[0]] +
                          flows[connect[1]])
            assert abs(flow_error) < self.tolerance, (
                "The scaled sum of the connected flows is %f, which is not "
                "within the tolerance (%f)." % (flow_error, self.tolerance))

        # Determine if the flows are inputs.
        are_inputs = [None] * n
        for i, flow in enumerate(flows):
            if flow >= self.tolerance:
                are_inputs[i] = True
            elif flow <= -self.tolerance:
                are_inputs[i] = False
            else:
                verbose.report(
                    "The magnitude of flow %d (%f) is below the "
                    "tolerance (%f).\nIt will not be shown, and it "
                    "cannot be used in a connection." %
                    (i, flow, self.tolerance), 'helpful')

        # Determine the angles of the arrows (before rotation).
        angles = [None] * n
        for i, (orient, is_input) in enumerate(zip(orientations, are_inputs)):
            if orient == 1:
                if is_input:
                    angles[i] = DOWN
                elif not is_input:
                    # Be specific since is_input can be None.
                    angles[i] = UP
            elif orient == 0:
                if is_input is not None:
                    angles[i] = RIGHT
            else:
                assert orient == -1, ("The value of orientations[%d] is %d, "
                                      "but it must be -1, 0, or 1." %
                                      (i, orient))
                if is_input:
                    angles[i] = UP
                elif not is_input:
                    angles[i] = DOWN

        # Justify the lengths of the paths.
        if iterable(pathlengths):
            assert len(pathlengths) == n, (
                "If pathlengths is a list, then pathlengths and flows must "
                "have the same length.\npathlengths has length %d, but flows "
                "has length %d." % (len(pathlengths), n))
        else:  # Make pathlengths into a list.
            urlength = pathlengths
            ullength = pathlengths
            lrlength = pathlengths
            lllength = pathlengths
            d = dict(RIGHT=pathlengths)
            pathlengths = [d.get(angle, 0) for angle in angles]
            # Determine the lengths of the top-side arrows
            # from the middle outwards.
            for i, (angle, is_input,
                    flow) in enumerate(zip(angles, are_inputs, scaled_flows)):
                if angle == DOWN and is_input:
                    pathlengths[i] = ullength
                    ullength += flow
                elif angle == UP and not is_input:
                    pathlengths[i] = urlength
                    urlength -= flow  # Flow is negative for outputs.
            # Determine the lengths of the bottom-side arrows
            # from the middle outwards.
            for i, (angle, is_input, flow) in enumerate(
                    reversed(list(zip(angles, are_inputs, scaled_flows)))):
                if angle == UP and is_input:
                    pathlengths[n - i - 1] = lllength
                    lllength += flow
                elif angle == DOWN and not is_input:
                    pathlengths[n - i - 1] = lrlength
                    lrlength -= flow
            # Determine the lengths of the left-side arrows
            # from the bottom upwards.
            has_left_input = False
            for i, (angle, is_input, spec) in enumerate(
                    reversed(
                        list(
                            zip(angles, are_inputs,
                                zip(scaled_flows, pathlengths))))):
                if angle == RIGHT:
                    if is_input:
                        if has_left_input:
                            pathlengths[n - i - 1] = 0
                        else:
                            has_left_input = True
            # Determine the lengths of the right-side arrows
            # from the top downwards.
            has_right_output = False
            for i, (angle, is_input, spec) in enumerate(
                    zip(angles, are_inputs, list(zip(scaled_flows,
                                                     pathlengths)))):
                if angle == RIGHT:
                    if not is_input:
                        if has_right_output:
                            pathlengths[i] = 0
                        else:
                            has_right_output = True

        # Begin the subpaths, and smooth the transition if the sum of the flows
        # is nonzero.
        urpath = [
            (
                Path.MOVETO,
                [
                    (self.gap - trunklength / 2.0),  # Upper right
                    gain / 2.0
                ]),
            (Path.LINETO, [(self.gap - trunklength / 2.0) / 2.0, gain / 2.0]),
            (Path.CURVE4, [(self.gap - trunklength / 2.0) / 8.0, gain / 2.0]),
            (Path.CURVE4, [(trunklength / 2.0 - self.gap) / 8.0, -loss / 2.0]),
            (Path.LINETO, [(trunklength / 2.0 - self.gap) / 2.0, -loss / 2.0]),
            (Path.LINETO, [(trunklength / 2.0 - self.gap), -loss / 2.0])
        ]
        llpath = [
            (
                Path.LINETO,
                [
                    (trunklength / 2.0 - self.gap),  # Lower left
                    loss / 2.0
                ]),
            (Path.LINETO, [(trunklength / 2.0 - self.gap) / 2.0, loss / 2.0]),
            (Path.CURVE4, [(trunklength / 2.0 - self.gap) / 8.0, loss / 2.0]),
            (Path.CURVE4, [(self.gap - trunklength / 2.0) / 8.0, -gain / 2.0]),
            (Path.LINETO, [(self.gap - trunklength / 2.0) / 2.0, -gain / 2.0]),
            (Path.LINETO, [(self.gap - trunklength / 2.0), -gain / 2.0])
        ]
        lrpath = [(
            Path.LINETO,
            [
                (trunklength / 2.0 - self.gap),  # Lower right
                loss / 2.0
            ])]
        ulpath = [(
            Path.LINETO,
            [
                self.gap - trunklength / 2.0,  # Upper left
                gain / 2.0
            ])]

        # Add the subpaths and assign the locations of the tips and labels.
        tips = np.zeros((n, 2))
        label_locations = np.zeros((n, 2))
        # Add the top-side inputs and outputs from the middle outwards.
        for i, (angle, is_input, spec) in enumerate(
                zip(angles, are_inputs, list(zip(scaled_flows, pathlengths)))):
            if angle == DOWN and is_input:
                tips[i, :], label_locations[i, :] = self._add_input(
                    ulpath, angle, *spec)
            elif angle == UP and not is_input:
                tips[i, :], label_locations[i, :] = self._add_output(
                    urpath, angle, *spec)
        # Add the bottom-side inputs and outputs from the middle outwards.
        for i, (angle, is_input, spec) in enumerate(
                reversed(
                    list(
                        zip(angles, are_inputs,
                            list(zip(scaled_flows, pathlengths)))))):
            if angle == UP and is_input:
                tip, label_location = self._add_input(llpath, angle, *spec)
                tips[n - i - 1, :] = tip
                label_locations[n - i - 1, :] = label_location
            elif angle == DOWN and not is_input:
                tip, label_location = self._add_output(lrpath, angle, *spec)
                tips[n - i - 1, :] = tip
                label_locations[n - i - 1, :] = label_location
        # Add the left-side inputs from the bottom upwards.
        has_left_input = False
        for i, (angle, is_input, spec) in enumerate(
                reversed(
                    list(
                        zip(angles, are_inputs,
                            list(zip(scaled_flows, pathlengths)))))):
            if angle == RIGHT and is_input:
                if not has_left_input:
                    # Make sure the lower path extends
                    # at least as far as the upper one.
                    if llpath[-1][1][0] > ulpath[-1][1][0]:
                        llpath.append(
                            (Path.LINETO, [ulpath[-1][1][0],
                                           llpath[-1][1][1]]))
                    has_left_input = True
                tip, label_location = self._add_input(llpath, angle, *spec)
                tips[n - i - 1, :] = tip
                label_locations[n - i - 1, :] = label_location
        # Add the right-side outputs from the top downwards.
        has_right_output = False
        for i, (angle, is_input, spec) in enumerate(
                zip(angles, are_inputs, list(zip(scaled_flows, pathlengths)))):
            if angle == RIGHT and not is_input:
                if not has_right_output:
                    # Make sure the upper path extends
                    # at least as far as the lower one.
                    if urpath[-1][1][0] < lrpath[-1][1][0]:
                        urpath.append(
                            (Path.LINETO, [lrpath[-1][1][0],
                                           urpath[-1][1][1]]))
                    has_right_output = True
                tips[i, :], label_locations[i, :] = self._add_output(
                    urpath, angle, *spec)
        # Trim any hanging vertices.
        if not has_left_input:
            ulpath.pop()
            llpath.pop()
        if not has_right_output:
            lrpath.pop()
            urpath.pop()

        # Concatenate the subpaths in the correct order (clockwise from top).
        path = (urpath + self._revert(lrpath) + llpath + self._revert(ulpath) +
                [(Path.CLOSEPOLY, urpath[0][1])])

        # Create a patch with the Sankey outline.
        codes, vertices = list(zip(*path))
        vertices = np.array(vertices)

        def _get_angle(a, r):
            if a is None:
                return None
            else:
                return a + r

        if prior is None:
            if rotation != 0:  # By default, none of this is needed.
                angles = [_get_angle(angle, rotation) for angle in angles]
                rotate = Affine2D().rotate_deg(rotation * 90).transform_point
                tips = rotate(tips)
                label_locations = rotate(label_locations)
                vertices = rotate(vertices)
            text = self.ax.text(0, 0, s=patchlabel, ha='center', va='center')
        else:
            rotation = (self.diagrams[prior].angles[connect[0]] -
                        angles[connect[1]])
            angles = [_get_angle(angle, rotation) for angle in angles]
            rotate = Affine2D().rotate_deg(rotation * 90).transform_point
            tips = rotate(tips)
            offset = self.diagrams[prior].tips[connect[0]] - tips[connect[1]]
            translate = Affine2D().translate(*offset).transform_point
            tips = translate(tips)
            label_locations = translate(rotate(label_locations))
            vertices = translate(rotate(vertices))
            kwds = dict(s=patchlabel, ha='center', va='center')
            text = self.ax.text(*offset, **kwds)
        if False:  # Debug
            print("llpath\n", llpath)
            print("ulpath\n", self._revert(ulpath))
            print("urpath\n", urpath)
            print("lrpath\n", self._revert(lrpath))
            xs, ys = list(zip(*vertices))
            self.ax.plot(xs, ys, 'go-')
        patch = PathPatch(
            Path(vertices, codes),
            fc=kwargs.pop('fc', kwargs.pop('facecolor',
                                           '#bfd1d4')),  # Custom defaults
            lw=kwargs.pop('lw', kwargs.pop('linewidth', 0.5)),
            **kwargs)
        self.ax.add_patch(patch)

        # Add the path labels.
        texts = []
        for number, angle, label, location in zip(flows, angles, labels,
                                                  label_locations):
            if label is None or angle is None:
                label = ''
            elif self.unit is not None:
                quantity = self.format % abs(number) + self.unit
                if label != '':
                    label += "\n"
                label += quantity
            texts.append(
                self.ax.text(x=location[0],
                             y=location[1],
                             s=label,
                             ha='center',
                             va='center'))
        # Text objects are placed even they are empty (as long as the magnitude
        # of the corresponding flow is larger than the tolerance) in case the
        # user wants to provide labels later.

        # Expand the size of the diagram if necessary.
        self.extent = (min(np.min(vertices[:, 0]),
                           np.min(label_locations[:, 0]), self.extent[0]),
                       max(np.max(vertices[:, 0]),
                           np.max(label_locations[:, 0]), self.extent[1]),
                       min(np.min(vertices[:, 1]),
                           np.min(label_locations[:, 1]), self.extent[2]),
                       max(np.max(vertices[:, 1]),
                           np.max(label_locations[:, 1]), self.extent[3]))
        # Include both vertices _and_ label locations in the extents; there are
        # where either could determine the margins (e.g., arrow shoulders).

        # Add this diagram as a subdiagram.
        self.diagrams.append(
            Bunch(patch=patch,
                  flows=flows,
                  angles=angles,
                  tips=tips,
                  text=text,
                  texts=texts))

        # Allow a daisy-chained call structure (see docstring for the class).
        return self
Пример #43
0
    def bar3d(self,
              x,
              y,
              z,
              dx,
              dy,
              dz,
              color='b',
              zsort='average',
              *args,
              **kwargs):
        '''
        Generate a 3D bar, or multiple bars.

        When generating multiple bars, x, y, z have to be arrays.
        dx, dy, dz can be arrays or scalars.

        *color* can be:

         - A single color value, to color all bars the same color.

         - An array of colors of length N bars, to color each bar
           independently.

         - An array of colors of length 6, to color the faces of the
           bars similarly.

         - An array of colors of length 6 * N bars, to color each face
           independently.

         When coloring the faces of the boxes specifically, this is
         the order of the coloring:

          1. -Z (bottom of box)
          2. +Z (top of box)
          3. -Y
          4. +Y
          5. -X
          6. +X

        Keyword arguments are passed onto
        :func:`~mpl_toolkits.mplot3d.art3d.Poly3DCollection`
        '''
        had_data = self.has_data()

        if not cbook.iterable(x):
            x = [x]
        if not cbook.iterable(y):
            y = [y]
        if not cbook.iterable(z):
            z = [z]

        if not cbook.iterable(dx):
            dx = [dx]
        if not cbook.iterable(dy):
            dy = [dy]
        if not cbook.iterable(dz):
            dz = [dz]

        if len(dx) == 1:
            dx = dx * len(x)
        if len(dy) == 1:
            dy = dy * len(y)
        if len(dz) == 1:
            dz = dz * len(z)

        if len(x) != len(y) or len(x) != len(z):
            warnings.warn('x, y, and z must be the same length.')

        minx, miny, minz = 1e20, 1e20, 1e20
        maxx, maxy, maxz = -1e20, -1e20, -1e20

        polys = []
        for xi, yi, zi, dxi, dyi, dzi in zip(x, y, z, dx, dy, dz):
            minx = min(xi, minx)
            maxx = max(xi + dxi, maxx)
            miny = min(yi, miny)
            maxy = max(yi + dyi, maxy)
            minz = min(zi, minz)
            maxz = max(zi + dzi, maxz)

            polys.extend([
                ((xi, yi, zi), (xi + dxi, yi, zi), (xi + dxi, yi + dyi, zi),
                 (xi, yi + dyi, zi)),
                ((xi, yi, zi + dzi), (xi + dxi, yi, zi + dzi),
                 (xi + dxi, yi + dyi, zi + dzi), (xi, yi + dyi, zi + dzi)),
                ((xi, yi, zi), (xi + dxi, yi, zi), (xi + dxi, yi, zi + dzi),
                 (xi, yi, zi + dzi)),
                ((xi, yi + dyi, zi), (xi + dxi, yi + dyi, zi),
                 (xi + dxi, yi + dyi, zi + dzi), (xi, yi + dyi, zi + dzi)),
                ((xi, yi, zi), (xi, yi + dyi, zi), (xi, yi + dyi, zi + dzi),
                 (xi, yi, zi + dzi)),
                ((xi + dxi, yi, zi), (xi + dxi, yi + dyi, zi),
                 (xi + dxi, yi + dyi, zi + dzi), (xi + dxi, yi, zi + dzi)),
            ])

        facecolors = []
        if color is None:
            # no color specified
            facecolors = [None] * len(x)
        elif len(color) == len(x):
            # bar colors specified, need to expand to number of faces
            for c in color:
                facecolors.extend([c] * 6)
        else:
            # a single color specified, or face colors specified explicitly
            facecolors = list(colorConverter.to_rgba_array(color))
            if len(facecolors) < len(x):
                facecolors *= (6 * len(x))

        normals = self._generate_normals(polys)
        sfacecolors = self._shade_colors(facecolors, normals)
        col = art3d.Poly3DCollection(polys,
                                     zsort=zsort,
                                     facecolor=sfacecolors,
                                     *args,
                                     **kwargs)
        self.add_collection(col)

        self.auto_scale_xyz((minx, maxx), (miny, maxy), (minz, maxz), had_data)
Пример #44
0
def julian2num(j):
    'convert a Julian date (or sequence) to a matplotlib date (or sequence)'
    if cbook.iterable(j): j = npy.asarray(j)
    return j + 1721425.5
Пример #45
0
def fetch_historical_yahoo(ticker,
                           date1,
                           date2,
                           cachename=None,
                           dividends=False):
    """
    Fetch historical data for ticker between date1 and date2.  date1 and
    date2 are date or datetime instances, or (year, month, day) sequences.

    Ex:
    fh = fetch_historical_yahoo('^GSPC', (2000, 1, 1), (2001, 12, 31))

    cachename is the name of the local file cache.  If None, will
    default to the md5 hash or the url (which incorporates the ticker
    and date range)

    set dividends=True to return dividends instead of price data.  With
    this option set, parse functions will not work

    a file handle is returned
    """

    ticker = ticker.upper()

    if iterable(date1):
        d1 = (date1[1] - 1, date1[2], date1[0])
    else:
        d1 = (date1.month - 1, date1.day, date1.year)
    if iterable(date2):
        d2 = (date2[1] - 1, date2[2], date2[0])
    else:
        d2 = (date2.month - 1, date2.day, date2.year)

    if dividends:
        g = 'v'
        verbose.report('Retrieving dividends instead of prices')
    else:
        g = 'd'

    urlFmt = 'http://ichart.yahoo.com/table.csv?a=%d&b=%d&c=%d&d=%d&e=%d&f=%d&s=%s&y=0&g=%s&ignore=.csv'

    url = urlFmt % (d1[0], d1[1], d1[2], d2[0], d2[1], d2[2], ticker, g)

    # Cache the finance data if cachename is supplied, or there is a writable
    # cache directory.
    if cachename is None and cachedir is not None:
        cachename = os.path.join(cachedir, md5(url).hexdigest())
    if cachename is not None:
        if os.path.exists(cachename):
            fh = open(cachename)
            verbose.report('Using cachefile %s for %s' % (cachename, ticker))
        else:
            mkdirs(os.path.abspath(os.path.dirname(cachename)))
            with contextlib.closing(urlopen(url)) as urlfh:
                with open(cachename, 'wb') as fh:
                    fh.write(urlfh.read())
            verbose.report('Saved %s data to cache file %s' %
                           (ticker, cachename))
            fh = open(cachename, 'r')

        return fh
    else:
        return urlopen(url)
Пример #46
0
def num2julian(n):
    'convert a matplotlib date (or seguence) to a Julian date (or sequence)'
    if cbook.iterable(n): n = npy.asarray(n)
    return n - 1721425.5
Пример #47
0
def draw_nx_tapered_edges(G,
                          pos,
                          edgelist=None,
                          width=0.5,
                          edge_color='k',
                          style='solid',
                          alpha=1.0,
                          edge_cmap=None,
                          edge_vmin=None,
                          edge_vmax=None,
                          ax=None,
                          label=None,
                          highlight=None,
                          tapered=False,
                          **kwds):
    """Draw the edges of the graph G.

    This draws only the edges of the graph G.

    Parameters
    ----------
    G : graph
       A networkx graph
    pos : dictionary
       A dictionary with nodes as keys and positions as values.
       Positions should be sequences of length 2.
    edgelist : collection of edge tuples
       Draw only specified edges(default=G.edges())
    width : float, or array of floats
       Line width of edges (default=1.0)
    edge_color : color string, or array of floats
       Edge color. Can be a single color format string (default='r'),
       or a sequence of colors with the same length as edgelist.
       If numeric values are specified they will be mapped to
       colors using the edge_cmap and edge_vmin,edge_vmax parameters.
    style : string
       Edge line style (default='solid') (solid|dashed|dotted,dashdot)
    alpha : float
       The edge transparency (default=1.0)
    edge_ cmap : Matplotlib colormap
       Colormap for mapping intensities of edges (default=None)
    edge_vmin,edge_vmax : floats
       Minimum and maximum for edge colormap scaling (default=None)
    ax : Matplotlib Axes object, optional
       Draw the graph in the specified Matplotlib axes.
    label : [None| string]
       Label for legend
    Returns
    -------
    matplotlib.collection.LineCollection
        `LineCollection` of the edges
    Examples
    --------
    >>> G=nx.dodecahedral_graph()
    >>> edges=nx.draw_networkx_edges(G,pos=nx.spring_layout(G))
    Also see the NetworkX drawing examples at
    http://networkx.github.io/documentation/latest/gallery.html
    See Also
    --------
    draw()
    draw_networkx()
    draw_networkx_nodes()
    draw_networkx_labels()
    draw_networkx_edge_labels()
    """
    if ax is None:
        ax = plt.gca()

    if edgelist is None:
        edgelist = list(G.edges())

    if not edgelist or len(edgelist) == 0:  # no edges!
        return None

    if highlight is not None and (isinstance(edge_color, str)
                                  or not cb.iterable(edge_color)):
        idMap = {}
        nodes = G.nodes()
        for i in range(len(nodes)):
            idMap[nodes[i]] = i
        ecol = [edge_color] * len(edgelist)
        eHighlight = [
            highlight[idMap[edge[0]]] or highlight[idMap[edge[1]]]
            for edge in edgelist
        ]
        for i in range(len(eHighlight)):
            if eHighlight[i]:
                ecol[i] = '0.0'
        edge_color = ecol

    # set edge positions
    if not np.iterable(width):
        lw = np.full(len(edgelist), width)
    else:
        lw = width

    edge_pos = []
    wdScale = 0.01
    for i in range(len(edgelist)):
        e = edgelist[i]
        w = wdScale * lw[i] / 2
        p0 = pos[e[0]]
        p1 = pos[e[1]]
        dx = p1[0] - p0[0]
        dy = p1[1] - p0[1]
        l = math.sqrt(dx * dx + dy * dy)
        edge_pos.append(
            ((p0[0] + w * dy / l, p0[1] - w * dx / l),
             (p0[0] - w * dy / l, p0[1] + w * dx / l), (p1[0], p1[1])))

    edge_vertices = np.asarray(edge_pos)

    if not isinstance(edge_color, str) \
           and np.iterable(edge_color) \
           and len(edge_color) == len(edge_vertices):
        if np.alltrue([isinstance(c, str) for c in edge_color]):
            # (should check ALL elements)
            # list of color letters such as ['k','r','k',...]
            edge_colors = tuple(
                [colorConverter.to_rgba(c, alpha) for c in edge_color])
        elif np.alltrue([not isinstance(c, str) for c in edge_color]):
            # If color specs are given as (rgb) or (rgba) tuples, we're OK
            if np.alltrue(
                [cb.iterable(c) and len(c) in (3, 4) for c in edge_color]):
                edge_colors = tuple(edge_color)
            else:
                # numbers (which are going to be mapped with a colormap)
                edge_colors = None
        else:
            raise ValueError(
                'edge_color must consist of either color names or numbers')
    else:
        if isinstance(edge_color, str) or len(edge_color) == 1:
            edge_colors = (colorConverter.to_rgba(edge_color, alpha), )
        else:
            raise ValueError(
                'edge_color must be a single color or list of exactly m colors where m is the number or edges'
            )

    if tapered:
        edge_collection = PolyCollection(
            edge_vertices,
            facecolors=edge_colors,
            linewidths=0,
            antialiaseds=(1, ),
            transOffset=ax.transData,
        )
    else:
        edge_collection = LineCollection(
            edge_pos,
            colors=edge_colors,
            linewidths=lw,
            antialiaseds=(1, ),
            linestyle=style,
            transOffset=ax.transData,
        )

    edge_collection.set_zorder(1)  # edges go behind nodes
    edge_collection.set_label(label)
    ax.add_collection(edge_collection)

    # Set alpha globally if provided as a scalar.
    if isinstance(alpha, numbers.Number):
        edge_collection.set_alpha(alpha)
    if edge_colors is None:
        if edge_cmap is not None:
            assert (isinstance(edge_cmap, Colormap))
        edge_collection.set_array(np.asarray(edge_color))
        edge_collection.set_cmap(edge_cmap)
        if edge_vmin is not None or edge_vmax is not None:
            edge_collection.set_clim(edge_vmin, edge_vmax)
        else:
            edge_collection.autoscale()

    # update view
    minx = np.amin(np.ravel(edge_vertices[:, :, 0]))
    maxx = np.amax(np.ravel(edge_vertices[:, :, 0]))
    miny = np.amin(np.ravel(edge_vertices[:, :, 1]))
    maxy = np.amax(np.ravel(edge_vertices[:, :, 1]))

    w = maxx - minx
    h = maxy - miny
    padx, pady = 0.05 * w, 0.05 * h
    corners = (minx - padx, miny - pady), (maxx + padx, maxy + pady)
    ax.update_datalim(corners)
    ax.autoscale_view()

    return edge_collection
Пример #48
0
def hist(self, x, bins=10, range=None, normed=False, weights=None,
         cumulative=False, bottom=None, histtype='bar', align='mid',
         orientation='vertical', rwidth=None, log=False,
         color=None, label=None,
         **kwargs):
    """
    call signature::

      hist(x, bins=10, range=None, normed=False, cumulative=False,
           bottom=None, histtype='bar', align='mid',
           orientation='vertical', rwidth=None, log=False, **kwargs)

    Compute and draw the histogram of *x*. The return value is a
    tuple (*n*, *bins*, *patches*) or ([*n0*, *n1*, ...], *bins*,
    [*patches0*, *patches1*,...]) if the input contains multiple
    data.

    Multiple data can be provided via *x* as a list of datasets
    of potentially different length ([*x0*, *x1*, ...]), or as
    a 2-D ndarray in which each column is a dataset.  Note that
    the ndarray form is transposed relative to the list form.

    Masked arrays are not supported at present.

    Keyword arguments:

      *bins*:
        Either an integer number of bins or a sequence giving the
        bins.  If *bins* is an integer, *bins* + 1 bin edges
        will be returned, consistent with :func:`numpy.histogram`
        for numpy version >= 1.3, and with the *new* = True argument
        in earlier versions.
        Unequally spaced bins are supported if *bins* is a sequence.

      *range*:
        The lower and upper range of the bins. Lower and upper outliers
        are ignored. If not provided, *range* is (x.min(), x.max()).
        Range has no effect if *bins* is a sequence.

        If *bins* is a sequence or *range* is specified, autoscaling
        is based on the specified bin range instead of the
        range of x.

      *normed*:
        If *True*, the first element of the return tuple will
        be the counts normalized to form a probability density, i.e.,
        ``n/(len(x)*dbin)``.  In a probability density, the integral of
        the histogram should be 1; you can verify that with a
        trapezoidal integration of the probability density function::

          pdf, bins, patches = ax.hist(...)
          print np.sum(pdf * np.diff(bins))

        .. Note:: Until numpy release 1.5, the underlying numpy
                  histogram function was incorrect with *normed*=*True*
                  if bin sizes were unequal.  MPL inherited that
                  error.  It is now corrected within MPL when using
                  earlier numpy versions

      *weights*
        An array of weights, of the same shape as *x*.  Each value in
        *x* only contributes its associated weight towards the bin
        count (instead of 1).  If *normed* is True, the weights are
        normalized, so that the integral of the density over the range
        remains 1.

      *cumulative*:
        If *True*, then a histogram is computed where each bin
        gives the counts in that bin plus all bins for smaller values.
        The last bin gives the total number of datapoints.  If *normed*
        is also *True* then the histogram is normalized such that the
        last bin equals 1. If *cumulative* evaluates to less than 0
        (e.g. -1), the direction of accumulation is reversed.  In this
        case, if *normed* is also *True*, then the histogram is normalized
        such that the first bin equals 1.

      *histtype*: [ 'bar' | 'barstacked' | 'step' | 'stepfilled' ]
        The type of histogram to draw.

          - 'bar' is a traditional bar-type histogram.  If multiple data
            are given the bars are aranged side by side.

          - 'barstacked' is a bar-type histogram where multiple
            data are stacked on top of each other.

          - 'step' generates a lineplot that is by default
            unfilled.

          - 'stepfilled' generates a lineplot that is by default
            filled.

      *align*: ['left' | 'mid' | 'right' ]
        Controls how the histogram is plotted.

          - 'left': bars are centered on the left bin edges.

          - 'mid': bars are centered between the bin edges.

          - 'right': bars are centered on the right bin edges.

      *orientation*: [ 'horizontal' | 'vertical' ]
        If 'horizontal', :func:`~matplotlib.pyplot.barh` will be
        used for bar-type histograms and the *bottom* kwarg will be
        the left edges.

      *rwidth*:
        The relative width of the bars as a fraction of the bin
        width.  If *None*, automatically compute the width. Ignored
        if *histtype* = 'step' or 'stepfilled'.

      *log*:
        If *True*, the histogram axis will be set to a log scale.
        If *log* is *True* and *x* is a 1D array, empty bins will
        be filtered out and only the non-empty (*n*, *bins*,
        *patches*) will be returned.

      *color*:
        Color spec or sequence of color specs, one per
        dataset.  Default (*None*) uses the standard line
        color sequence.

      *label*:
        String, or sequence of strings to match multiple
        datasets.  Bar charts yield multiple patches per
        dataset, but only the first gets the label, so
        that the legend command will work as expected::

            ax.hist(10+2*np.random.randn(1000), label='men')
            ax.hist(12+3*np.random.randn(1000), label='women', alpha=0.5)
            ax.legend()

    kwargs are used to update the properties of the
    :class:`~matplotlib.patches.Patch` instances returned by *hist*:

    %(Patch)s

    **Example:**

    .. plot:: mpl_examples/pylab_examples/histogram_demo.py
    """
    if not self._hold: self.cla()

    # NOTE: the range keyword overwrites the built-in func range !!!
    #       needs to be fixed in numpy                           !!!

    # Validate string inputs here so we don't have to clutter
    # subsequent code.
    if histtype not in ['bar', 'barstacked', 'step', 'stepfilled']:
        raise ValueError("histtype %s is not recognized" % histtype)

    if align not in ['left', 'mid', 'right']:
        raise ValueError("align kwarg %s is not recognized" % align)

    if orientation not in [ 'horizontal', 'vertical']:
        raise ValueError(
            "orientation kwarg %s is not recognized" % orientation)


    if kwargs.get('width') is not None:
        raise DeprecationWarning(
            'hist now uses the rwidth to give relative width '
            'and not absolute width')

    # Massage 'x' for processing.
    # NOTE: Be sure any changes here is also done below to 'weights'
    if isinstance(x, np.ndarray) or not iterable(x[0]):
        # TODO: support masked arrays;
        x = np.asarray(x)
        if x.ndim == 2:
            x = x.T # 2-D input with columns as datasets; switch to rows
        elif x.ndim == 1:
            x = x.reshape(1, x.shape[0])  # new view, single row
        else:
            raise ValueError("x must be 1D or 2D")
        if x.shape[1] < x.shape[0]:
            warnings.warn('2D hist input should be nsamples x nvariables;\n '
                'this looks transposed (shape is %d x %d)' % x.shape[::-1])
    else:
        # multiple hist with data of different length
        x = [np.array(xi) for xi in x]

    nx = len(x) # number of datasets

    if color is None:
        color = [next(self._get_lines.color_cycle)
                                        for i in range(nx)]
    else:
        color = mcolors.colorConverter.to_rgba_array(color)
        if len(color) != nx:
            raise ValueError("color kwarg must have one color per dataset")

    # We need to do to 'weights' what was done to 'x'
    if weights is not None:
        if isinstance(weights, np.ndarray) or not iterable(weights[0]) :
            w = np.array(weights)
            if w.ndim == 2:
                w = w.T
            elif w.ndim == 1:
                w.shape = (1, w.shape[0])
            else:
                raise ValueError("weights must be 1D or 2D")
        else:
            w = [np.array(wi) for wi in weights]

        if len(w) != nx:
            raise ValueError('weights should have the same shape as x')
        for i in range(nx):
            if len(w[i]) != len(x[i]):
                raise ValueError(
                    'weights should have the same shape as x')
    else:
        w = [None]*nx


    # Save autoscale state for later restoration; turn autoscaling
    # off so we can do it all a single time at the end, instead
    # of having it done by bar or fill and then having to be redone.
    _saved_autoscalex = self.get_autoscalex_on()
    _saved_autoscaley = self.get_autoscaley_on()
    self.set_autoscalex_on(False)
    self.set_autoscaley_on(False)

    # Save the datalimits for the same reason:
    _saved_bounds = self.dataLim.bounds

    # Check whether bins or range are given explicitly. In that
    # case use those values for autoscaling.
    binsgiven = (cbook.iterable(bins) or range != None)

    # If bins are not specified either explicitly or via range,
    # we need to figure out the range required for all datasets,
    # and supply that to np.histogram.
    if not binsgiven:
        xmin = np.inf
        xmax = -np.inf
        for xi in x:
            xmin = min(xmin, xi.min())
            xmax = max(xmax, xi.max())
        range = (xmin, xmax)

    #hist_kwargs = dict(range=range, normed=bool(normed))
    # We will handle the normed kwarg within mpl until we
    # get to the point of requiring numpy >= 1.5.
    hist_kwargs = dict(range=range)
    if np.__version__ < "1.3": # version 1.1 and 1.2
        hist_kwargs['new'] = True

    n = []
    for i in range(nx):
        # this will automatically overwrite bins,
        # so that each histogram uses the same bins
        m, bins = np.histogram(x[i], bins, weights=w[i], **hist_kwargs)
        if normed:
            db = np.diff(bins)
            m = (m.astype(float) / db) / m.sum()
        n.append(m)
    if normed and db.std() > 0.01 * db.mean():
        warnings.warn("""
        This release fixes a normalization bug in the NumPy histogram
        function prior to version 1.5, occuring with non-uniform
        bin widths. The returned and plotted value is now a density:
            n / (N * bin width),
        where n is the bin count and N the total number of points.
        """)



    if cumulative:
        slc = slice(None)
        if cbook.is_numlike(cumulative) and cumulative < 0:
            slc = slice(None,None,-1)

        if normed:
            n = [(m * np.diff(bins))[slc].cumsum()[slc] for m in n]
        else:
            n = [m[slc].cumsum()[slc] for m in n]

    patches = []

    if histtype.startswith('bar'):
        totwidth = np.diff(bins)

        if rwidth is not None:
            dr = min(1.0, max(0.0, rwidth))
        elif len(n)>1:
            dr = 0.8
        else:
            dr = 1.0

        if histtype=='bar':
            width = dr*totwidth/nx
            dw = width

            if nx > 1:
                boffset = -0.5*dr*totwidth*(1.0-1.0/nx)
            else:
                boffset = 0.0
            stacked = False
        elif histtype=='barstacked':
            width = dr*totwidth
            boffset, dw = 0.0, 0.0
            stacked = True

        if align == 'mid' or align == 'edge':
            boffset += 0.5*totwidth
        elif align == 'right':
            boffset += totwidth

        if orientation == 'horizontal':
            _barfunc = self.barh
        else:  # orientation == 'vertical'
            _barfunc = self.bar

        for m, c in zip(n, color):
            patch = _barfunc(bins[:-1]+boffset, m, width, bottom,
                              align='center', log=log,
                              color=c)
            patches.append(patch)
            if stacked:
                if bottom is None:
                    bottom = 0.0
                bottom += m
            boffset += dw

    elif histtype.startswith('step'):
        x = np.zeros( 2*len(bins), np.float )
        y = np.zeros( 2*len(bins), np.float )

        x[0::2], x[1::2] = bins, bins

        # FIX FIX FIX
        # This is the only real change.
        # minimum = min(bins)
        if log is True:
            minimum = 1.0
        elif log:
            minimum = float(log)
        else:
            minimum = 0.0
        # FIX FIX FIX end

        if align == 'left' or align == 'center':
            x -= 0.5*(bins[1]-bins[0])
        elif align == 'right':
            x += 0.5*(bins[1]-bins[0])

        if log:
            y[0],y[-1] = minimum, minimum
            if orientation == 'horizontal':
                self.set_xscale('log')
            else:  # orientation == 'vertical'
                self.set_yscale('log')

        fill = (histtype == 'stepfilled')

        for m, c in zip(n, color):
            y[1:-1:2], y[2::2] = m, m
            if log:
                y[y<minimum]=minimum
            if orientation == 'horizontal':
                x,y = y,x

            if fill:
                patches.append( self.fill(x, y,
                    closed=False, facecolor=c) )
            else:
                patches.append( self.fill(x, y,
                    closed=False, edgecolor=c, fill=False) )

        # adopted from adjust_x/ylim part of the bar method
        if orientation == 'horizontal':
            xmin0 = max(_saved_bounds[0]*0.9, minimum)
            xmax = self.dataLim.intervalx[1]
            for m in n:
                xmin = np.amin(m[m!=0]) # filter out the 0 height bins
            xmin = max(xmin*0.9, minimum)
            xmin = min(xmin0, xmin)
            self.dataLim.intervalx = (xmin, xmax)
        elif orientation == 'vertical':
            ymin0 = max(_saved_bounds[1]*0.9, minimum)
            ymax = self.dataLim.intervaly[1]
            for m in n:
                ymin = np.amin(m[m!=0]) # filter out the 0 height bins
            ymin = max(ymin*0.9, minimum)
            ymin = min(ymin0, ymin)
            self.dataLim.intervaly = (ymin, ymax)

    if label is None:
        labels = ['_nolegend_']
    elif is_string_like(label):
        labels = [label]
    elif is_sequence_of_strings(label):
        labels = list(label)
    else:
        raise ValueError(
            'invalid label: must be string or sequence of strings')
    if len(labels) < nx:
        labels += ['_nolegend_'] * (nx - len(labels))

    for (patch, lbl) in zip(patches, labels):
        for p in patch:
            p.update(kwargs)
            p.set_label(lbl)
            lbl = '_nolegend_'

    if binsgiven:
        if orientation == 'vertical':
            self.update_datalim([(bins[0],0), (bins[-1],0)], updatey=False)
        else:
            self.update_datalim([(0,bins[0]), (0,bins[-1])], updatex=False)

    self.set_autoscalex_on(_saved_autoscalex)
    self.set_autoscaley_on(_saved_autoscaley)
    self.autoscale_view()

    if nx == 1:
        return n[0], bins, cbook.silent_list('Patch', patches[0])
    else:
        return n, bins, cbook.silent_list('Lists of Patches', patches)
Пример #49
0
    def __init__(self,
                 artists,
                 tolerance=5,
                 formatter=None,
                 point_labels=None,
                 display='one-per-axes',
                 draggable=False,
                 hover=False,
                 props_override=None,
                 keybindings=True,
                 date_format='%x %X',
                 display_button=1,
                 hide_button=3,
                 keep_inside=True,
                 **kwargs):
        """Create the data cursor and connect it to the relevant figure.

        Parameters
        -----------
        artists : a matplotlib artist or sequence of artists.
            The artists to make selectable and display information for.
        tolerance : number, optional
            The radius (in points) that the mouse click must be within to
            select the artist.
        formatter : function, optional
            A function that accepts arbitrary kwargs and returns a string that
            will be displayed with annotate. The `x`, `y`, `event`, `ind`, and
            `label` kwargs will always be present. See the
            ``mpldatacursor.datacursor`` function docstring for more
            information.
        point_labels : sequence or dict, optional
            Labels for "subitems" of an artist, passed to the formatter
            function as the `point_label` kwarg.  May be either a single
            sequence (used for all artists) or a dict of artist:sequence pairs.
        display : {'one-per-axes', 'single', 'multiple'}, optional
            Controls whether more than one annotation box will be shown.
        draggable : boolean, optional
            Controls whether or not the annotation box will be interactively
            draggable to a new location after being displayed. Default: False.
        hover : boolean, optional
            If True, the datacursor will "pop up" when the mouse hovers over an
            artist.  Defaults to False.  Enabling hover also sets
            `display="single"` and `draggable=False`.
        props_override : function, optional
            If specified, this function customizes the parameters passed into
            the formatter function and the x, y location that the datacursor
            "pop up" "points" to.  This is often useful to make the annotation
            "point" to a specific side or corner of an artist, regardless of
            the position clicked. The function is passed the same kwargs as the
            `formatter` function and is expected to return a dict with at least
            the keys "x" and "y" (and probably several others).
            Expected call signature: `props_dict = props_override(**kwargs)`
        keybindings : boolean or dict, optional
            By default, the keys "d" and "t" will be bound to hiding/showing
            all annotation boxes and toggling interactivity for datacursors,
            respectively.  "<shift> + <right>" and "<shift> + <left>" will be
            bound to moving the datacursor to the next and previous item in the
            sequence for artists that support it. If keybindings is False, the
            ability to hide/toggle datacursors interactively will be disabled.
            Alternatively, a dict mapping "hide", "toggle", "next", and
            "previous" to matplotlib key specifications may specified to
            customize the keyboard shortcuts.  Note that hitting the "hide" key
            once will hide datacursors, and hitting it again will show all of
            the hidden datacursors.
        date_format : string, optional
            The strftime-style formatting string for dates. Used only if the x
            or y axes have been set to display dates. Defaults to "%x %X".
        display_button: int, optional
            The mouse button that will triggers displaying an annotation box.
            Defaults to 1, for left-clicking. (Common options are
            1:left-click, 2:middle-click, 3:right-click)
        hide_button: int or None, optional
            The mouse button that triggers hiding the selected annotation box.
            Defaults to 3, for right-clicking. (Common options are
            1:left-click, 2:middle-click, 3:right-click, None:hiding disabled)
        keep_inside : boolean, optional
            Whether or not to adjust the x,y offset to keep the text box inside
            the figure. This option has no effect on draggable datacursors.
            Defaults to True. Note: Currently disabled on OSX and
            NbAgg/notebook backends.
        **kwargs : additional keyword arguments, optional
            Additional keyword arguments are passed on to annotate.
        """
        def filter_artists(artists):
            """Replace ContourSets, etc with their constituent artists."""
            output = []
            for item in artists:
                if isinstance(item, ContourSet):
                    output += item.collections
                elif isinstance(item, Container):
                    children = item.get_children()
                    for child in children:
                        child._mpldatacursor_label = item.get_label()
                        child._mpldatacursor_parent = item
                    output += children
                else:
                    output.append(item)
            return output

        if not cbook.iterable(artists):
            artists = [artists]

        #-- Deal with contour sets... -------------------------------------
        # These are particularly difficult, as the original z-value array
        # is never associated with the ContourSet, and they're not "normal"
        # artists (they're not actually added to the axes). Not only that, but
        # the PatchCollections created by filled contours don't even fire a
        # pick event for points inside them, only on their edges. At any rate,
        # this is a somewhat hackish way of handling contours, but it works.
        self.artists = filter_artists(artists)
        self.contour_levels = {}
        for cs in [x for x in artists if isinstance(x, ContourSet)]:
            for z, artist in zip(cs.levels, cs.collections):
                self.contour_levels[artist] = z

        valid_display_options = ['single', 'one-per-axes', 'multiple']
        if display in valid_display_options:
            self.display = display
        else:
            raise ValueError('"display" must be one of the following: '\
                             ', '.join(valid_display_options))
        self.hover = hover
        if self.hover:
            self.display = 'single'
            self.draggable = False

        self.keep_inside = keep_inside
        self.tolerance = tolerance
        self.point_labels = point_labels
        self.draggable = draggable
        self.date_format = date_format
        self.props_override = props_override
        self.display_button = display_button
        self.hide_button = hide_button
        self.axes = tuple(set(art.axes for art in self.artists))
        self.figures = tuple(set(ax.figure for ax in self.axes))
        self._mplformatter = ScalarFormatter(useOffset=False, useMathText=True)
        self._hidden = False
        self._last_event = None
        self._last_annotation = None

        if self.draggable:
            # If we're dealing with draggable cursors, don't try to override
            # the x,y position.  Otherwise, dragging the cursor outside the
            # figure will have unexpected consequences.
            self.keep_inside = False

        if formatter is None:
            self.formatter = self._formatter
        else:
            self.formatter = formatter

        self._annotation_kwargs = kwargs
        self.annotations = {}
        if self.display is not 'multiple':
            for ax in self.axes:
                self.annotations[ax] = self.annotate(ax, **kwargs)
                # Hide the annotation box until clicked...
                self.annotations[ax].set_visible(False)

        if keybindings:
            if keybindings is True:
                self.keybindings = self.default_keybindings
            else:
                self.keybindings = self.default_keybindings.copy()
                self.keybindings.update(keybindings)
            for fig in self.figures:
                fig.canvas.mpl_connect('key_press_event', self._on_keypress)

        self.enable()

        # We need to make sure the DataCursor isn't garbage collected until the
        # figure is.  Matplotlib's weak references won't keep this DataCursor
        # instance alive in all cases.
        for fig in self.figures:
            try:
                fig._mpldatacursors.append(self)
            except AttributeError:
                fig._mpldatacursors = [self]
Пример #50
0
    def __call__(self, value, clip=None):

        #read in parameters
        method = self.stretch
        exponent = self.exponent
        midpoint = self.midpoint

        # ORIGINAL MATPLOTLIB CODE

        if clip is None:
            clip = self.clip

        if cbook.iterable(value):
            vtype = 'array'
            val = ma.asarray(value).astype(np.float)
        else:
            vtype = 'scalar'
            val = ma.array([value]).astype(np.float)

        self.autoscale_None(val)
        vmin, vmax = self.vmin, self.vmax
        if vmin > vmax:
            raise ValueError("minvalue must be less than or equal to maxvalue")
        elif vmin == vmax:
            return 0.0 * val
        else:
            if clip:
                mask = ma.getmask(val)
                val = ma.array(np.clip(val.filled(vmax), vmin, vmax),
                               mask=mask)
            result = (val - vmin) * (1.0 / (vmax - vmin))

            # CUSTOM APLPY CODE

            # Keep track of negative values
            negative = result < 0.

            if self.stretch == 'linear':

                pass

            elif self.stretch == 'log':

                result = ma.log10(result * (self.midpoint - 1.) + 1.) \
                       / ma.log10(self.midpoint)

            elif self.stretch == 'sqrt':

                result = ma.sqrt(result)

            elif self.stretch == 'arcsinh':

                result = ma.arcsinh(result / self.midpoint) \
                       / ma.arcsinh(1. / self.midpoint)

            elif self.stretch == 'power':

                result = ma.power(result, exponent)

            else:

                raise Exception("Unknown stretch in APLpyNormalize: %s" %
                                self.stretch)

            # Now set previously negative values to 0, as these are
            # different from true NaN values in the FITS image
            result[negative] = -np.inf

        if vtype == 'scalar':
            result = result[0]

        return result
Пример #51
0
    def nyquist(self,
                ax=None,
                pair=(0, 0),
                label='nyquist',
                title="Nyquist plot",
                xlabel="Real axis",
                ylabel="Imaginary axis",
                labels=None,
                colors=['b', 'g', 'r', 'c', 'm', 'y', 'k'],
                leg_kwargs={},
                **kwargs):
        r"""Plot the linearizations onto a single Nyquist diagram.

        This method calls :meth:`~LinRes.nyquist` from the included instances of
        :class:`LinRes`.

        **Parameters:**

        - *ax*: Axes onto which the Nyquist diagrams should be plotted

             If *ax* is not provided, then axes will be created in a new figure.

        - *pair*: Tuple of (input name or index, output name or index) for the
          transfer function to be chosen from each system (applied to all)

             This is ignored if the system is SISO.

        - *label*: Label for the figure (ignored if axes is provided)

             This is used as the base filename if the figure is saved using
             :func:`~modelicares.util.save` or
             :func:`~modelicares.util.saveall`.

        - *title*: Title for the figure

            - *xlabel*: x-axis label

            - *ylabel*: y-axis label

        - *labels*: Label or list of labels for the legends

             If *labels* is *None*, then no label will be used.  If it is an
             empty string (''), then the base filenames will be used.

        - *colors*: Color or list of colors that will be used sequentially

             Each may be a character, grayscale, or rgb value.

             .. Seealso:: http://matplotlib.sourceforge.net/api/colors_api.html

        - *leg_kwargs*: Dictionary of keyword arguments for
          :func:`matplotlib.pyplot.legend`

             If *leg_kwargs* is *None*, then no legend will be shown.

        - *\*\*kwargs*: Additional plotting arguments:

             - *freqs*: List or frequencies or tuple of (min, max) frequencies
               over which to plot the system response.

                  If *freqs* is *None*, then an appropriate range will be
                  determined automatically.

             - *in_Hz*: If *True* (default), the frequencies (*freqs*) are in
               Hz and should be plotted in Hz (otherwise, rad/s)

             - *mark*: *True*, if the -1 point should be marked on the plot

             - *show_axes*: *True*, if the axes should be shown

             - *skip*: Mark every nth frequency on the plot with a dot

                  If *skip* is 0 or *None*, then the frequencies are not marked.

             - *label_freq*: If *True*, if the marked frequencies should be
               labeled

             Other keyword arguments are passed to
             :func:`matplotlib.pyplot.plot`.

        **Returns:**

            1. *ax*: Axes of the Nyquist plot

        **Example:**

        .. plot:: examples/PIDs-nyquist.py
           :alt: Nyquist plot of PID with varying parameters
        """
        # Create axes if necessary.
        if not ax:
            fig = util.figure(label)
            ax = fig.add_subplot(111, aspect='equal')

        # Process the labels input.
        labels = self._get_labels(labels)

        # Set up the color(s).
        if not iterable(colors):
            # Use the single color for all plots.
            colors = (colors, )
        n_colors = len(colors)

        # Create the plots.
        label_freq = kwargs.pop('label_freq', None)
        for i, (lin, label) in enumerate(zip(self, labels)):
            if lin.sys.inputs > 1 or lin.sys.outputs > 1:
                sys = lin.to_siso(pair[0], pair[1])
            else:
                sys = lin.sys
            nyquist_plot(
                sys,
                mark=False,
                label=label,
                ax=ax,
                label_freq=(i == 0 if label_freq is None else label_freq),
                color=colors[np.mod(i, n_colors)],
                **kwargs)

        # Decorate and finish.
        ax.set_title(title)
        if xlabel:
            # Without this check, xlabel=None will give a label of "None".
            ax.set_xlabel(xlabel)
        if ylabel:  # Same purpose
            ax.set_ylabel(ylabel)
        if leg_kwargs is not None:
            loc = leg_kwargs.pop('loc', 'best')
            ax.legend(loc=loc, **leg_kwargs)

        return ax
Пример #52
0
def num2julian(n):
    'Convert a matplotlib date (or sequence) to a Julian date (or sequence).'
    if cbook.iterable(n):
        n = np.asarray(n)
    return n + 1721424.5
Пример #53
0
 def set_3d_properties(self, verts, zs=0, zdir='z'):
     if not iterable(zs):
         zs = [zs] * len(verts)
     self._segment3d = [juggle_axes(x, y, z, zdir) \
             for ((x, y), z) in zip(verts, zs)]
     self._facecolor3d = Patch.get_facecolor(self)
Пример #54
0
def setp(obj, *args, **kwargs):
    """
    Set a property on an artist object.

    matplotlib supports the use of :func:`setp` ("set property") and
    :func:`getp` to set and get object properties, as well as to do
    introspection on the object.  For example, to set the linestyle of a
    line to be dashed, you can do::

      >>> line, = plot([1,2,3])
      >>> setp(line, linestyle='--')

    If you want to know the valid types of arguments, you can provide the
    name of the property you want to set without a value::

      >>> setp(line, 'linestyle')
          linestyle: [ '-' | '--' | '-.' | ':' | 'steps' | 'None' ]

    If you want to see all the properties that can be set, and their
    possible values, you can do::

      >>> setp(line)
          ... long output listing omitted

    :func:`setp` operates on a single instance or a list of instances.
    If you are in query mode introspecting the possible values, only
    the first instance in the sequence is used.  When actually setting
    values, all the instances will be set.  e.g., suppose you have a
    list of two lines, the following will make both lines thicker and
    red::

      >>> x = arange(0,1.0,0.01)
      >>> y1 = sin(2*pi*x)
      >>> y2 = sin(4*pi*x)
      >>> lines = plot(x, y1, x, y2)
      >>> setp(lines, linewidth=2, color='r')

    :func:`setp` works with the MATLAB style string/value pairs or
    with python kwargs.  For example, the following are equivalent::

      >>> setp(lines, 'linewidth', 2, 'color', 'r')  # MATLAB style
      >>> setp(lines, linewidth=2, color='r')        # python style
    """

    insp = ArtistInspector(obj)

    if len(kwargs) == 0 and len(args) == 0:
        print('\n'.join(insp.pprint_setters()))
        return

    if len(kwargs) == 0 and len(args) == 1:
        print(insp.pprint_setters(prop=args[0]))
        return

    if not cbook.iterable(obj):
        objs = [obj]
    else:
        objs = cbook.flatten(obj)

    if len(args) % 2:
        raise ValueError('The set args must be string, value pairs')

    funcvals = []
    for i in range(0, len(args) - 1, 2):
        funcvals.append((args[i], args[i + 1]))
    funcvals.extend(kwargs.items())

    ret = []
    for o in objs:
        for s, val in funcvals:
            s = s.lower()
            funcName = "set_%s" % s
            func = getattr(o, funcName)
            ret.extend([func(val)])
    return [x for x in cbook.flatten(ret)]
Пример #55
0
def draw_networkx_edges(G,
                        pos,
                        edgelist=None,
                        width=1.0,
                        edge_color='k',
                        style='solid',
                        alpha=1.0,
                        arrowstyle='-|>',
                        arrowsize=10,
                        edge_cmap=None,
                        edge_vmin=None,
                        edge_vmax=None,
                        ax=None,
                        arrows=True,
                        label=None,
                        node_size=300,
                        nodelist=None,
                        node_shape="o",
                        **kwds):
    """Draw the edges of the graph G.

    This draws only the edges of the graph G.

    Parameters
    ----------
    G : graph
       A networkx graph

    pos : dictionary
       A dictionary with nodes as keys and positions as values.
       Positions should be sequences of length 2.

    edgelist : collection of edge tuples
       Draw only specified edges(default=G.edges())

    width : float, or array of floats
       Line width of edges (default=1.0)

    edge_color : color string, or array of floats
       Edge color. Can be a single color format string (default='r'),
       or a sequence of colors with the same length as edgelist.
       If numeric values are specified they will be mapped to
       colors using the edge_cmap and edge_vmin,edge_vmax parameters.

    style : string
       Edge line style (default='solid') (solid|dashed|dotted,dashdot)

    alpha : float
       The edge transparency (default=1.0)

    edge_ cmap : Matplotlib colormap
       Colormap for mapping intensities of edges (default=None)

    edge_vmin,edge_vmax : floats
       Minimum and maximum for edge colormap scaling (default=None)

    ax : Matplotlib Axes object, optional
       Draw the graph in the specified Matplotlib axes.

    arrows : bool, optional (default=True)
       For directed graphs, if True draw arrowheads.
       Note: Arrows will be the same color as edges.

    arrowstyle : str, optional (default='-|>')
       For directed graphs, choose the style of the arrow heads.
       See :py:class: `matplotlib.patches.ArrowStyle` for more
       options.

    arrowsize : int, optional (default=10)
       For directed graphs, choose the size of the arrow head head's length and
       width. See :py:class: `matplotlib.patches.FancyArrowPatch` for attribute
       `mutation_scale` for more info.

    label : [None| string]
       Label for legend

    Returns
    -------
    matplotlib.collection.LineCollection
        `LineCollection` of the edges

    list of matplotlib.patches.FancyArrowPatch
        `FancyArrowPatch` instances of the directed edges

    Depending whether the drawing includes arrows or not.

    Notes
    -----
    For directed graphs, arrows are drawn at the head end.  Arrows can be
    turned off with keyword arrows=False. Be sure to include `node_size` as a
    keyword argument; arrows are drawn considering the size of nodes.

    Examples
    --------
    >>> G = nx.dodecahedral_graph()
    >>> edges = nx.draw_networkx_edges(G, pos=nx.spring_layout(G))

    >>> G = nx.DiGraph()
    >>> G.add_edges_from([(1, 2), (1, 3), (2, 3)])
    >>> arcs = nx.draw_networkx_edges(G, pos=nx.spring_layout(G))
    >>> alphas = [0.3, 0.4, 0.5]
    >>> for i, arc in enumerate(arcs):  # change alpha values of arcs
    ...     arc.set_alpha(alphas[i])

    Also see the NetworkX drawing examples at
    https://networkx.github.io/documentation/latest/auto_examples/index.html

    See Also
    --------
    draw()
    draw_networkx()
    draw_networkx_nodes()
    draw_networkx_labels()
    draw_networkx_edge_labels()
    """
    try:
        import matplotlib
        import matplotlib.pyplot as plt
        import matplotlib.cbook as cb
        from matplotlib.colors import colorConverter, Colormap, Normalize
        from matplotlib.collections import LineCollection
        from matplotlib.patches import FancyArrowPatch
        import numpy as np
    except ImportError:
        raise ImportError("Matplotlib required for draw()")
    except RuntimeError:
        print("Matplotlib unable to open display")
        raise

    if ax is None:
        ax = plt.gca()

    if edgelist is None:
        edgelist = list(G.edges())

    if not edgelist or len(edgelist) == 0:  # no edges!
        return None

    if nodelist is None:
        nodelist = list(G.nodes())

    # set edge positions
    edge_pos = np.asarray([(pos[e[0]], pos[e[1]]) for e in edgelist])

    if not cb.iterable(width):
        lw = (width, )
    else:
        lw = width

    if not is_string_like(edge_color) \
            and cb.iterable(edge_color) \
            and len(edge_color) == len(edge_pos):
        if np.alltrue([is_string_like(c) for c in edge_color]):
            # (should check ALL elements)
            # list of color letters such as ['k','r','k',...]
            edge_colors = tuple(
                [colorConverter.to_rgba(c, alpha) for c in edge_color])
        elif np.alltrue([not is_string_like(c) for c in edge_color]):
            # If color specs are given as (rgb) or (rgba) tuples, we're OK
            if np.alltrue(
                [cb.iterable(c) and len(c) in (3, 4) for c in edge_color]):
                edge_colors = tuple(edge_color)
            else:
                # numbers (which are going to be mapped with a colormap)
                edge_colors = None
        else:
            raise ValueError('edge_color must contain color names or numbers')
    else:
        if is_string_like(edge_color) or len(edge_color) == 1:
            edge_colors = (colorConverter.to_rgba(edge_color, alpha), )
        else:
            msg = 'edge_color must be a color or list of one color per edge'
            raise ValueError(msg)

    if (not G.is_directed() or not arrows):
        edge_collection = LineCollection(
            edge_pos,
            colors=edge_colors,
            linewidths=lw,
            antialiaseds=(1, ),
            linestyle=style,
            transOffset=ax.transData,
        )

        edge_collection.set_zorder(1)  # edges go behind nodes
        edge_collection.set_label(label)
        ax.add_collection(edge_collection)

        # Note: there was a bug in mpl regarding the handling of alpha values
        # for each line in a LineCollection. It was fixed in matplotlib by
        # r7184 and r7189 (June 6 2009). We should then not set the alpha
        # value globally, since the user can instead provide per-edge alphas
        # now.  Only set it globally if provided as a scalar.
        if cb.is_numlike(alpha):
            edge_collection.set_alpha(alpha)

        if edge_colors is None:
            if edge_cmap is not None:
                assert (isinstance(edge_cmap, Colormap))
            edge_collection.set_array(np.asarray(edge_color))
            edge_collection.set_cmap(edge_cmap)
            if edge_vmin is not None or edge_vmax is not None:
                edge_collection.set_clim(edge_vmin, edge_vmax)
            else:
                edge_collection.autoscale()
        return edge_collection

    arrow_collection = None

    if G.is_directed() and arrows:
        # Note: Waiting for someone to implement arrow to intersection with
        # marker.  Meanwhile, this works well for polygons with more than 4
        # sides and circle.

        def to_marker_edge(marker_size, marker):
            if marker in "s^>v<d":  # `large` markers need extra space
                return np.sqrt(2 * marker_size) / 2
            else:
                return np.sqrt(marker_size) / 2

        # Draw arrows with `matplotlib.patches.FancyarrowPatch`
        arrow_collection = []
        mutation_scale = arrowsize  # scale factor of arrow head
        arrow_colors = edge_colors
        if arrow_colors is None:
            if edge_cmap is not None:
                assert (isinstance(edge_cmap, Colormap))
            else:
                edge_cmap = plt.get_cmap()  # default matplotlib colormap
            if edge_vmin is None:
                edge_vmin = min(edge_color)
            if edge_vmax is None:
                edge_vmax = max(edge_color)
            color_normal = Normalize(vmin=edge_vmin, vmax=edge_vmax)

        for i, (src, dst) in enumerate(edge_pos):
            x1, y1 = src
            x2, y2 = dst
            arrow_color = None
            line_width = None
            shrink_source = 0  # space from source to tail
            shrink_target = 0  # space from  head to target
            if cb.iterable(node_size):  # many node sizes
                src_node, dst_node = edgelist[i]
                index_node = nodelist.index(dst_node)
                marker_size = node_size[index_node]
                shrink_target = to_marker_edge(marker_size, node_shape)
            else:
                shrink_target = to_marker_edge(node_size, node_shape)
            if arrow_colors is None:
                arrow_color = edge_cmap(color_normal(edge_color[i]))
            elif len(arrow_colors) > 1:
                arrow_color = arrow_colors[i]
            else:
                arrow_color = arrow_colors[0]
            if len(lw) > 1:
                line_width = lw[i]
            else:
                line_width = lw[0]
            arrow = FancyArrowPatch((x1, y1), (x2, y2),
                                    arrowstyle=arrowstyle,
                                    shrinkA=shrink_source,
                                    shrinkB=shrink_target,
                                    mutation_scale=mutation_scale,
                                    color=arrow_color,
                                    linewidth=line_width,
                                    zorder=1)  # arrows go behind nodes

            # There seems to be a bug in matplotlib to make collections of
            # FancyArrowPatch instances. Until fixed, the patches are added
            # individually to the axes instance.
            arrow_collection.append(arrow)
            ax.add_patch(arrow)

    # update view
    minx = np.amin(np.ravel(edge_pos[:, :, 0]))
    maxx = np.amax(np.ravel(edge_pos[:, :, 0]))
    miny = np.amin(np.ravel(edge_pos[:, :, 1]))
    maxy = np.amax(np.ravel(edge_pos[:, :, 1]))

    w = maxx - minx
    h = maxy - miny
    padx, pady = 0.05 * w, 0.05 * h
    corners = (minx - padx, miny - pady), (maxx + padx, maxy + pady)
    ax.update_datalim(corners)
    ax.autoscale_view()

    return arrow_collection
   def convert( value, unit, axis ):
      """: Convert value using unit to a float.  If value is a sequence, return
      the converted sequence.

      = INPUT VARIABLES
      - axis    The axis using this converter.
      - value   The value or list of values that need to be converted.
      - unit    The units to use for a axis with Epoch data.

      = RETURN VALUE
      - Returns the value parameter converted to floats.
      """

      if ( units.ConversionInterface.is_numlike( value ) ):
         return value

      if ( value == [] ):
         return []

      # we delay loading to make matplotlib happy
      ax = axis.axes
      if axis is ax.get_xaxis():
         isXAxis = True
      else:
         isXAxis = False

      axis.get_major_ticks()
      ticks = axis.get_ticklocs()
      labels = axis.get_ticklabels()

      labels = [ l.get_text() for l in labels if l.get_text() ]

      if ( not labels ):
         ticks = []
         labels = []


      if ( not iterable( value ) ):
         value = [ value ]

      newValues = []
      for v in value:
         if ( (v not in labels) and (v not in newValues) ):
            newValues.append( v )

      for v in newValues:
         if ( labels ):
            labels.append( v )
         else:
            labels = [ v ]

      #DISABLED: This is disabled because matplotlib bar plots do not
      #DISABLED: recalculate the unit conversion of the data values
      #DISABLED: this is due to design and is not really a bug.
      #DISABLED: If this gets changed, then we can activate the following
      #DISABLED: block of code.  Note that this works for line plots.
      #DISABLED if ( unit ):
      #DISABLED    if ( unit.find( "sorted" ) > -1 ):
      #DISABLED       labels.sort()
      #DISABLED    if ( unit.find( "inverted" ) > -1 ):
      #DISABLED       labels = labels[ ::-1 ]

      # add padding (so they do not appear on the axes themselves)
      labels = [ '' ] + labels + [ '' ]
      ticks = range( len(labels) )
      ticks[0] = 0.5
      ticks[-1] = ticks[-1] - 0.5

      axis.set_ticks( ticks )
      axis.set_ticklabels( labels )
      # we have to do the following lines to make ax.autoscale_view work
      loc = axis.get_major_locator()
      loc.set_bounds( ticks[0], ticks[-1] )

      if ( isXAxis ):
         ax.set_xlim( ticks[0], ticks[-1] )
      else:
         ax.set_ylim( ticks[0], ticks[-1] )

      result = []
      for v in value:
         # If v is not in labels then something went wrong with adding new
         # labels to the list of old labels.
         errmsg  = "This is due to a logic error in the StrConverter class.  "
         errmsg += "Please report this error and its message in bugzilla."
         assert ( v in labels ), errmsg
         result.append( ticks[ labels.index(v) ] )

      ax.viewLim.ignore(-1)
      return result
Пример #57
0
def draw_networkx_edges(G,
                        pos,
                        edgelist=None,
                        width=1.0,
                        edge_color='k',
                        style='solid',
                        alpha=None,
                        edge_cmap=None,
                        edge_vmin=None,
                        edge_vmax=None,
                        ax=None,
                        arrows=True,
                        label=None,
                        **kwds):
    """Draw the edges of the graph G.

    This draws only the edges of the graph G.

    Parameters
    ----------
    G : graph
       A networkx graph

    pos : dictionary
       A dictionary with nodes as keys and positions as values.
       If not specified a spring layout positioning will be computed.
       See networkx.layout for functions that compute node positions.

    edgelist : collection of edge tuples
       Draw only specified edges(default=G.edges())

    width : float
       Line width of edges (default =1.0)

    edge_color : color string, or array of floats
       Edge color. Can be a single color format string (default='r'),
       or a sequence of colors with the same length as edgelist.
       If numeric values are specified they will be mapped to
       colors using the edge_cmap and edge_vmin,edge_vmax parameters.

    style : string
       Edge line style (default='solid') (solid|dashed|dotted,dashdot)

    alpha : float
       The edge transparency (default=1.0)

    edge_ cmap : Matplotlib colormap
       Colormap for mapping intensities of edges (default=None)

    edge_vmin,edge_vmax : floats
       Minimum and maximum for edge colormap scaling (default=None)

    ax : Matplotlib Axes object, optional
       Draw the graph in the specified Matplotlib axes.

    arrows : bool, optional (default=True)
       For directed graphs, if True draw arrowheads.

    label : [None| string]
       Label for legend

    Notes
    -----
    For directed graphs, "arrows" (actually just thicker stubs) are drawn
    at the head end.  Arrows can be turned off with keyword arrows=False.
    Yes, it is ugly but drawing proper arrows with Matplotlib this
    way is tricky.

    Examples
    --------
    >>> G=nx.dodecahedral_graph()
    >>> edges=nx.draw_networkx_edges(G,pos=nx.spring_layout(G))

    Also see the NetworkX drawing examples at
    http://networkx.lanl.gov/gallery.html

    See Also
    --------
    draw()
    draw_networkx()
    draw_networkx_nodes()
    draw_networkx_labels()
    draw_networkx_edge_labels()
    """
    try:
        import matplotlib
        import matplotlib.pylab as pylab
        import matplotlib.cbook as cb
        from matplotlib.colors import colorConverter, Colormap
        from matplotlib.collections import LineCollection
        import numpy
    except ImportError:
        raise ImportError("Matplotlib required for draw()")
    except RuntimeError:
        print("Matplotlib unable to open display")
        raise

    if ax is None:
        ax = pylab.gca()

    if edgelist is None:
        edgelist = G.edges()

    if not edgelist or len(edgelist) == 0:  # no edges!
        return None

    # set edge positions
    edge_pos = numpy.asarray([(pos[e[0]], pos[e[1]]) for e in edgelist])

    if not cb.iterable(width):
        lw = (width, )
    else:
        lw = width

    if not cb.is_string_like(edge_color) \
           and cb.iterable(edge_color) \
           and len(edge_color)==len(edge_pos):
        if numpy.alltrue([cb.is_string_like(c) for c in edge_color]):
            # (should check ALL elements)
            # list of color letters such as ['k','r','k',...]
            edge_colors = tuple(
                [colorConverter.to_rgba(c, alpha) for c in edge_color])
        elif numpy.alltrue([not cb.is_string_like(c) for c in edge_color]):
            # If color specs are given as (rgb) or (rgba) tuples, we're OK
            if numpy.alltrue(
                [cb.iterable(c) and len(c) in (3, 4) for c in edge_color]):
                edge_colors = tuple(edge_color)
            else:
                # numbers (which are going to be mapped with a colormap)
                edge_colors = None
        else:
            raise ValueError(
                'edge_color must consist of either color names or numbers')
    else:
        if cb.is_string_like(edge_color) or len(edge_color) == 1:
            edge_colors = (colorConverter.to_rgba(edge_color, alpha), )
        else:
            raise ValueError(
                'edge_color must be a single color or list of exactly m colors where m is the number or edges'
            )

    edge_collection = LineCollection(
        edge_pos,
        colors=edge_colors,
        linewidths=lw,
        antialiaseds=(1, ),
        linestyle=style,
        transOffset=ax.transData,
    )

    edge_collection.set_zorder(1)  # edges go behind nodes
    edge_collection.set_label(label)
    ax.add_collection(edge_collection)

    # Note: there was a bug in mpl regarding the handling of alpha values for
    # each line in a LineCollection.  It was fixed in matplotlib in r7184 and
    # r7189 (June 6 2009).  We should then not set the alpha value globally,
    # since the user can instead provide per-edge alphas now.  Only set it
    # globally if provided as a scalar.
    if cb.is_numlike(alpha):
        edge_collection.set_alpha(alpha)

    if edge_colors is None:
        if edge_cmap is not None:
            assert (isinstance(edge_cmap, Colormap))
        edge_collection.set_array(numpy.asarray(edge_color))
        edge_collection.set_cmap(edge_cmap)
        if edge_vmin is not None or edge_vmax is not None:
            edge_collection.set_clim(edge_vmin, edge_vmax)
        else:
            edge_collection.autoscale()
        pylab.sci(edge_collection)

    arrow_collection = None

    if G.is_directed() and arrows:

        # a directed graph hack
        # draw thick line segments at head end of edge
        # waiting for someone else to implement arrows that will work
        arrow_colors = edge_colors
        a_pos = []
        p = 1.0 - 0.25  # make head segment 25 percent of edge length
        for src, dst in edge_pos:
            x1, y1 = src
            x2, y2 = dst
            dx = x2 - x1  # x offset
            dy = y2 - y1  # y offset
            d = numpy.sqrt(float(dx**2 + dy**2))  # length of edge
            if d == 0:  # source and target at same position
                continue
            if dx == 0:  # vertical edge
                xa = x2
                ya = dy * p + y1
            if dy == 0:  # horizontal edge
                ya = y2
                xa = dx * p + x1
            else:
                theta = numpy.arctan2(dy, dx)
                xa = p * d * numpy.cos(theta) + x1
                ya = p * d * numpy.sin(theta) + y1

            a_pos.append(((xa, ya), (x2, y2)))

        arrow_collection = LineCollection(
            a_pos,
            colors=arrow_colors,
            linewidths=[4 * ww for ww in lw],
            antialiaseds=(1, ),
            transOffset=ax.transData,
        )

        arrow_collection.set_zorder(1)  # edges go behind nodes
        arrow_collection.set_label(label)
        ax.add_collection(arrow_collection)

    # update view
    minx = numpy.amin(numpy.ravel(edge_pos[:, :, 0]))
    maxx = numpy.amax(numpy.ravel(edge_pos[:, :, 0]))
    miny = numpy.amin(numpy.ravel(edge_pos[:, :, 1]))
    maxy = numpy.amax(numpy.ravel(edge_pos[:, :, 1]))

    w = maxx - minx
    h = maxy - miny
    padx, pady = 0.05 * w, 0.05 * h
    corners = (minx - padx, miny - pady), (maxx + padx, maxy + pady)
    ax.update_datalim(corners)
    ax.autoscale_view()

    #    if arrow_collection:

    return edge_collection
Пример #58
0
def julian2num(j):
    'Convert a Julian date (or sequence) to a matplotlib date (or sequence).'
    if cbook.iterable(j):
        j = np.asarray(j)
    return j - 1721424.5
Пример #59
0
    def __init__(
        self,
        ax,
        cmap=None,
        norm=None,
        alpha=None,
        values=None,
        boundaries=None,
        orientation='vertical',
        ticklocation='auto',
        extend='neither',
        spacing='uniform',  # uniform or proportional
        ticks=None,
        format=None,
        drawedges=False,
        filled=True,
        extendfrac=None,
        extendrect=False,
        label='',
    ):
        #: The axes that this colorbar lives in.
        self.ax = ax
        self._patch_ax()
        if cmap is None:
            cmap = cm.get_cmap()
        if norm is None:
            norm = colors.Normalize()
        self.alpha = alpha
        cm.ScalarMappable.__init__(self, cmap=cmap, norm=norm)
        self.values = values
        self.boundaries = boundaries
        self.extend = extend
        self._inside = self._slice_dict[extend]
        self.spacing = spacing
        self.orientation = orientation
        self.drawedges = drawedges
        self.filled = filled
        self.extendfrac = extendfrac
        self.extendrect = extendrect
        self.solids = None
        self.lines = list()
        self.outline = None
        self.patch = None
        self.dividers = None

        if ticklocation == 'auto':
            ticklocation = 'bottom' if orientation == 'horizontal' else 'right'
        self.ticklocation = ticklocation

        self.set_label(label)
        if cbook.iterable(ticks):
            self.locator = ticker.FixedLocator(ticks, nbins=len(ticks))
        else:
            self.locator = ticks  # Handle default in _ticker()
        if format is None:
            if isinstance(self.norm, colors.LogNorm):
                self.formatter = ticker.LogFormatterMathtext()
            else:
                self.formatter = ticker.ScalarFormatter()
        elif cbook.is_string_like(format):
            self.formatter = ticker.FormatStrFormatter(format)
        else:
            self.formatter = format  # Assume it is a Formatter
        # The rest is in a method so we can recalculate when clim changes.
        self.config_axis()
        self.draw_all()
Пример #60
0
    def bode(self,
             axes=None,
             pair=(0, 0),
             label='bode',
             title="Bode plot",
             labels=None,
             colors=['b', 'g', 'r', 'c', 'm', 'y', 'k'],
             styles=[(None, None), (3, 3), (1, 1), (3, 2, 1, 2)],
             leg_kwargs={},
             **kwargs):
        r"""Plot the linearizations onto a single Bode diagram.

        This method calls :meth:`LinRes.bode` from the included instances
        of :class:`LinRes`.

        **Parameters:**

        - *axes*: Tuple (pair) of axes for the magnitude and phase plots

             If *axes* is not provided, then axes will be created in a new
             figure.

        - *pair*: Tuple of (input name or index, output name or index) for the
          transfer function to be chosen from each system (applied to all)

             This is ignored if the system is SISO.

        - *label*: Label for the figure (ignored if axes is provided)

             This is used as the base filename if the figure is saved using
             :func:`~modelicares.util.save` or
             :func:`~modelicares.util.saveall`.

        - *title*: Title for the figure

        - *labels*: Label or list of labels for the legends

             If *labels* is *None*, then no label will be used.  If it is an
             empty string (''), then the base filenames will be used.

        - *colors*: Color or list of colors that will be used sequentially

             Each may be a character, grayscale, or rgb value.

             .. Seealso:: http://matplotlib.sourceforge.net/api/colors_api.html

        - *styles*: Line/dash style or list of line/dash styles that will be
          used sequentially

             Each style is a string representing a linestyle (e.g., '--') or a
             tuple of on/off lengths representing dashes.  Use '' for no line
             and '-' for a solid line.

             .. Seealso::
                http://matplotlib.sourceforge.net/api/collections_api.html

        - *leg_kwargs*: Dictionary of keyword arguments for
          :func:`matplotlib.pyplot.legend`

             If *leg_kwargs* is *None*, then no legend will be shown.

        - *\*\*kwargs*: Additional plotting arguments:

             - *freqs*: List or frequencies or tuple of (min, max) frequencies
               over which to plot the system response.

                  If *freqs* is *None*, then an appropriate range will be
                  determined automatically.

             - *in_Hz*: If *True* (default), the frequencies (*freqs*) are in
               Hz and should be plotted in Hz (otherwise, rad/s)

             - *in_dB*: If *True* (default), plot the magnitude in dB

             - *in_deg*: If *True* (default), plot the phase in degrees
               (otherwise, radians)

             Other keyword arguments are passed to
             :func:`matplotlib.pyplot.plot`.

        **Returns:**

        1. *axes*: Tuple (pair) of axes for the magnitude and phase plots

        **Example:**

        .. plot:: examples/PIDs-bode.py
           :alt: Bode plot of PID with varying parameters
        """
        # Create axes if necessary.
        if not axes:
            fig = util.figure(label)
            axes = (fig.add_subplot(211), fig.add_subplot(212))

        # Process the labels input.
        labels = self._get_labels(labels)

        # Set up the color(s) and line style(s).
        if not iterable(colors):
            # Use the single color for all plots.
            colors = (colors, )
        if not iterable(styles):
            # Use the single line style for all plots.
            styles = [styles]
        elif type(styles[0]) is int:
            # One dashes tuple has been provided; use its value for all plots.
            styles = [styles]
        n_colors = len(colors)
        n_styles = len(styles)

        # Create the plots.
        for i, (lin, label) in enumerate(zip(self, labels)):
            style = styles[np.mod(i, n_styles)]
            if isinstance(style, string_types):
                kwargs['linestyle'] = style
                kwargs.pop('dashes', None)
            else:
                kwargs['dashes'] = style
                kwargs.pop('linestyle', None)
            if lin.sys.inputs > 1 or lin.sys.outputs > 1:
                sys = lin.to_siso(pair[0], pair[1])
            else:
                sys = lin.sys
            bode_plot(sys,
                      label=label,
                      color=colors[np.mod(i, n_colors)],
                      axes=axes,
                      **kwargs)

        # Decorate and finish.
        axes[0].set_title(title)
        if leg_kwargs is not None:
            loc = leg_kwargs.pop('loc', 'best')
            axes[0].legend(loc=loc, **leg_kwargs)
            axes[1].legend(loc=loc, **leg_kwargs)
        return axes