示例#1
0
def _get_line_tups(*args):
    """
    Helper func to parse input to plot()
    """
    # Assume all args are either data or format strings, plt.plot will
    # deal with raising exceptions.
    # A line's arguments consist of [x], y, [fmt]
    lines = []
    while args:
        fmt = ''
        y = Q_(args[0])
        if len(args) > 1:
            if is_string_like(args[1]):
                fmt = args[1]
                x = Q_(np.arange(y.shape[0], dtype=float))
                args = args[2:]
            else:
                x = y
                y = Q_(args[1])
                if len(args) > 2 and is_string_like(args[2]):
                    fmt = args[2]
                    args = args[3:]
                else:
                    args = args[2:]
        else:
            x = Q_(np.arange(y.shape[0], dtype=float))
            args = args[1:]
        lines.append((x, y, fmt))
    return lines
示例#2
0
 def set_linestyles(self, ls):
     """
     Set the linestyles(s) for the collection.
     ACCEPTS: ['solid' | 'dashed', 'dashdot', 'dotted' |  (offset, on-off-dash-seq) ]
     """
     try:
         if cbook.is_string_like(ls):
             dashes = [backend_bases.GraphicsContextBase.dashd[ls]]
         elif cbook.iterable(ls):
             try:
                 dashes = []
                 for x in ls:
                     if cbook.is_string_like(x):
                         dashes.append(backend_bases.GraphicsContextBase.dashd[ls])
                     elif cbook.iterator(x) and len(x) == 2:
                         dashes.append(x)
                     else:
                         raise ValueError()
             except ValueError:
                 if len(ls)==2:
                     dashes = ls
                 else:
                     raise ValueError()
         else:
             raise ValueError()
     except ValueError:
         raise ValueError('Do not know how to convert %s to dashes'%ls)
     self._linestyles = dashes
示例#3
0
    def draw(self, renderer):
        if not self.get_visible(): return
        #renderer.open_group('patch')
        gc = renderer.new_gc()

        if cbook.is_string_like(self._edgecolor) and self._edgecolor.lower()=='none':
            gc.set_linewidth(0)
        else:
            gc.set_foreground(self._edgecolor)
            gc.set_linewidth(self._linewidth)

        gc.set_alpha(self._alpha)
        gc.set_antialiased(self._antialiased)
        self._set_gc_clip(gc)
        gc.set_capstyle('projecting')

        if (not self.fill or self._facecolor is None or
            (cbook.is_string_like(self._facecolor) and self._facecolor.lower()=='none')):
            rgbFace = None
        else:
            rgbFace = colors.colorConverter.to_rgb(self._facecolor)

        if self._hatch:
            gc.set_hatch(self._hatch )

        verts = self.get_verts()
        tverts = self.get_transform().seq_xy_tups(verts)

        renderer.draw_polygon(gc, rgbFace, tverts)
示例#4
0
    def draw(self, renderer):
        if not self.get_visible(): return
        #renderer.open_group('patch')
        gc = renderer.new_gc()

        if cbook.is_string_like(self._edgecolor) and self._edgecolor.lower()=='none':
            gc.set_linewidth(0)
        else:
            gc.set_foreground(self._edgecolor)
            gc.set_linewidth(self._linewidth)

        gc.set_alpha(self._alpha)
        gc.set_antialiased(self._antialiased)
        self._set_gc_clip(gc)
        gc.set_capstyle('projecting')

        if (not self.fill or self._facecolor is None or
            (cbook.is_string_like(self._facecolor) and self._facecolor.lower()=='none')):
            rgbFace = None
        else:
            rgbFace = colors.colorConverter.to_rgb(self._facecolor)

        if self._hatch:
            gc.set_hatch(self._hatch )

        path = self.get_path()
        transform = self.get_transform()
        tpath = transform.transform_path_non_affine(path)
        affine = transform.get_affine()

        renderer.draw_path(gc, tpath, affine, rgbFace)
示例#5
0
def imread(fname, format=None):
    """
    Return image file in *fname* as :class:`numpy.array`.  *fname* may
    be a string path or a Python file-like object.  If using a file
    object, it must be opened in binary mode.

    If *format* is provided, will try to read file of that type,
    otherwise the format is deduced from the filename.  If nothing can
    be deduced, PNG is tried.

    Return value is a :class:`numpy.array`.  For grayscale images, the
    return array is MxN.  For RGB images, the return value is MxNx3.
    For RGBA images the return value is MxNx4.

    matplotlib can only read PNGs natively, but if `PIL
    <http://www.pythonware.com/products/pil/>`_ is installed, it will
    use it to load the image and return an array (if possible) which
    can be used with :func:`~matplotlib.pyplot.imshow`.
    """

    def pilread():
        "try to load the image with PIL or return None"
        try:
            from PIL import Image
        except ImportError:
            return None
        image = Image.open(fname)
        return pil_to_array(image)

    handlers = {"png": _png.read_png}
    if format is None:
        if cbook.is_string_like(fname):
            basename, ext = os.path.splitext(fname)
            ext = ext.lower()[1:]
        else:
            ext = "png"
    else:
        ext = format

    if ext not in handlers.iterkeys():
        im = pilread()
        if im is None:
            raise ValueError(
                "Only know how to handle extensions: %s; with PIL installed matplotlib can handle more images"
                % handlers.keys()
            )
        return im

    handler = handlers[ext]

    # To handle Unicode filenames, we pass a file object to the PNG
    # reader extension, since Python handles them quite well, but it's
    # tricky in C.
    if cbook.is_string_like(fname):
        fname = open(fname, "rb")

    return handler(fname)
示例#6
0
def test_is_string_like():
    y = np.arange( 10 )
    assert_equal( cbook.is_string_like( y ), False )
    y.shape = 10, 1
    assert_equal( cbook.is_string_like( y ), False )
    y.shape = 1, 10
    assert_equal( cbook.is_string_like( y ), False )
    assert cbook.is_string_like( "hello world" )
    assert_equal( cbook.is_string_like(10), False )
示例#7
0
 def test_is_string_like( self ):
    """Test the 'is_string_like cookbook' function."""
    y = npy.arange( 10 )
    self.failUnless( cbook.is_string_like( y ) == False )
    y.shape = 10, 1
    self.failUnless( cbook.is_string_like( y ) == False )
    y.shape = 1, 10
    self.failUnless( cbook.is_string_like( y ) == False )
    self.failUnless( cbook.is_string_like( "hello world" ) )
    self.failUnless( cbook.is_string_like(10) == False )
示例#8
0
def use(style):
    """Use matplotlib style settings from a style specification.

    The style name of 'default' is reserved for reverting back to
    the default style settings.

    Parameters
    ----------
    style : str, dict, or list
        A style specification. Valid options are:

        +------+-------------------------------------------------------------+
        | str  | The name of a style or a path/URL to a style file. For a    |
        |      | list of available style names, see `style.available`.       |
        +------+-------------------------------------------------------------+
        | dict | Dictionary with valid key/value pairs for                   |
        |      | `matplotlib.rcParams`.                                      |
        +------+-------------------------------------------------------------+
        | list | A list of style specifiers (str or dict) applied from first |
        |      | to last in the list.                                        |
        +------+-------------------------------------------------------------+


    """
    if cbook.is_string_like(style) or hasattr(style, "keys"):
        # If name is a single str or dict, make it a single element list.
        styles = [style]
    else:
        styles = style

    for style in styles:
        if not cbook.is_string_like(style):
            mpl.rcParams.update(style)
            continue
        elif style == "default":
            mpl.rcdefaults()
            continue

        if style in library:
            mpl.rcParams.update(library[style])
        else:
            try:
                rc = rc_params_from_file(style, use_default_template=False)
                mpl.rcParams.update(rc)
            except IOError:
                msg = (
                    "'%s' not found in the style library and input is "
                    "not a valid URL or path. See `style.available` for "
                    "list of available styles."
                )
                raise IOError(msg % style)
示例#9
0
def is_sequence_of_strings(obj):
    """
    Returns true if *obj* is iterable and contains strings
    """
    # Note: cbook.is_sequence_of_strings has a bug because
    # a numpy array of strings is recognized as being
    # string_like and therefore not a sequence of strings
    if not cbook.iterable(obj):
        return False
    if not isinstance(obj, np.ndarray) and cbook.is_string_like(obj):
        return False
    for o in obj:
        if not cbook.is_string_like(o):
            return False
    return True
示例#10
0
 def set_family(self, family):
     """
     Change the font family.  May be either an alias (generic name
     is CSS parlance), such as: 'serif', 'sans-serif', 'cursive',
     'fantasy', or 'monospace', a real font name or a list of real
     font names.  Real font names are not supported when
     `text.usetex` is `True`.
     """
     if family is None:
         family = rcParams['font.family']
     if is_string_like(family):
         family = [six.text_type(family)]
     elif (not is_string_like(family) and isinstance(family, Iterable)):
         family = [six.text_type(f) for f in family]
     self._family = family
示例#11
0
	def draw(self, renderer):
		if not self.get_visible(): return
		renderer.open_group('polycollection')
		transform = self.get_transform()
		if hasattr(self, 'get_transoffset'):
			transoffset = self.get_transoffset()	#matplotlib 0.91.2
		else:
			transoffset = getattr(self, '_transOffset', None)	#matplotlib 0.98.3

		transform.freeze()
		transoffset.freeze()
		self.update_scalarmappable()
		if cbook.is_string_like(self._edgecolors) and self._edgecolors[:2] == 'No':
			self._linewidths = (0,)
			#self._edgecolors = self._facecolors
		renderer.draw_poly_collection(
			self._verts, transform, self.clipbox,
			self._facecolors, self._edgecolors,
			self._linewidths, self._antialiaseds,
			self._offsets,  transoffset)
		
		self.update_scalarmappable()
		#print 'calling renderer draw line collection'
		offsets = self._offsets
		renderer.draw_line_collection(
			self._segments, transform, self.clipbox,
			self._colors, self._lw, self._ls, self._aa, offsets,
			transoffset)
		
		transform.thaw()
		transoffset.thaw()
		renderer.close_group('polycollection')
示例#12
0
文件: plots.py 项目: rayg-ssec/MetPy
    def __init__(self,
                 x=0, y=0, text='',
                 color=None,          # defaults to rc params
                 verticalalignment='bottom',
                 horizontalalignment='left',
                 multialignment=None,
                 fontproperties=None, # defaults to FontProperties()
                 rotation=None,
                 linespacing=None,
                 **kwargs
                 ):

        Artist.__init__(self)
        if color is None:
            colors= rcParams['text.color']

        if fontproperties is None:
            fontproperties = FontProperties()
        elif is_string_like(fontproperties):
            fontproperties = FontProperties(fontproperties)

        self._animated = False
#        if is_string_like(text):
#            text = [text]

        self._textobjs = [Text(x[ind], y[ind], text[ind], color,
            verticalalignment, horizontalalignment, multialignment,
            fontproperties, rotation, linespacing, **kwargs)
            for ind in xrange(len(x))]

        self.update(kwargs)
示例#13
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
     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):
             self.ax.xaxis.set_scale("log")
             self.ax.yaxis.set_scale("log")
             self.ax._update_transScale()
             self.cbar_axis.set_minor_locator(ticker.NullLocator())
             formatter = ticker.LogFormatter()
         else:
             formatter = None
     elif cbook.is_string_like(format):
         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('')
示例#14
0
 def draw_labels(self, G, pos,
                 sizes=None,
                 labels=None,
                 font_family='sans-serif'):
     ax = plt.gca()
     i = 0
     for n, label in labels.items():
         (x, y) = pos[n]
         y += 0.015 + 0.03 * math.sqrt(sizes[i])/3.14/10.0
         if not cb.is_string_like(label):
             label = str(label)  # this will cause "1" and 1 to be labeled the same
         font_size = 8
         font_color = 'white'
         font_weight = 'normal'
         if sizes[i] > 50:
             font_size = 12
             font_weight = 'semibold'
         if sizes[i] > 120:
             font_color = 'yellow'
         if sizes[i] > 10:
             t = ax.text(x, y,
                       label,
                       size = font_size,
                       color = font_color,
                       family = font_family,
                       weight = font_weight,
                       style = 'italic',
                       horizontalalignment = 'center',
                       verticalalignment = 'center',
                       transform=ax.transData,
                       clip_on=True,
                       )
         i += 1
     return
示例#15
0
    def print_figure(self, filename, dpi=150,
                     facecolor='w', edgecolor='w',
                     orientation='portrait'):

        """
        Render the figure to hardcopy using self.renderer as the
        renderer if neccessary

        filename can be a string filename or writable file instance

        """

        origDPI = self.figure.dpi.get()
        origfacecolor = self.figure.get_facecolor()
        origedgecolor = self.figure.get_edgecolor()

        self.figure.dpi.set(dpi)
        self.figure.set_facecolor(facecolor)
        self.figure.set_edgecolor(edgecolor)

        im = self.draw()

        if is_string_like(filename):
            basename, ext = os.path.splitext(filename)
            if not len(ext): filename += '.png'
 
        im.writePng( filename )

        self.figure.dpi.set(origDPI)
        self.figure.set_facecolor(origfacecolor)
        self.figure.set_edgecolor(origedgecolor)
示例#16
0
    def print_png(self, filename_or_obj, *args, **kwargs):
        FigureCanvasAgg.draw(self)
        renderer = self.get_renderer()
        original_dpi = renderer.dpi
        renderer.dpi = self.figure.dpi
        if is_string_like(filename_or_obj):
            filename_or_obj = open(filename_or_obj, 'wb')
            close = True
        else:
            close = False

        version_str = 'matplotlib version ' + __version__ + \
            ', http://matplotlib.org/'
        metadata = OrderedDict({'Software': version_str})
        user_metadata = kwargs.pop("metadata", None)
        if user_metadata is not None:
            metadata.update(user_metadata)

        try:
            _png.write_png(renderer._renderer, filename_or_obj,
                           self.figure.dpi, metadata=metadata)
        finally:
            if close:
                filename_or_obj.close()
            renderer.dpi = original_dpi
示例#17
0
def make_option_menu( names, func=None ):
    """
    Make an option menu with list of names in names.  Return value is
    a optMenu, itemDict tuple, where optMenu is the option menu and
    itemDict is a dictionary mapping menu items to labels.  Eg

    optmenu, menud = make_option_menu( ('Bill', 'Ted', 'Fred') )

    ...set up dialog ...
    if response==gtk.RESPONSE_OK:
       item = optmenu.get_menu().get_active()
       print menud[item]  # this is the selected name


    if func is not None, call func with label when selected
    """
    optmenu = gtk.OptionMenu()
    optmenu.show()
    menu = gtk.Menu()
    menu.show()
    d = {}
    for label in names:
        if  not is_string_like(label): continue
        item = gtk.MenuItem(label)
        menu.append(item)
        item.show()
        d[item] = label
        if func is not None:
            item.connect("activate", func, label)
    optmenu.set_menu(menu)
    return optmenu, d
示例#18
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
示例#19
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))
示例#20
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)
示例#21
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))
    def _print_image(self, filename, format):
        if self.flags() & gtk.REALIZED == 0:
            # for self.window(for pixmap) and has a side effect of altering
            # figure width,height (via configure-event?)
            gtk.DrawingArea.realize(self)

        width, height = self.get_width_height()
        pixmap = gdk.Pixmap (self.window, width, height)
        self._renderer.set_pixmap (pixmap)
        self._render_figure(pixmap, width, height)

        # jpg colors don't match the display very well, png colors match
        # better
        pixbuf = gdk.Pixbuf(gdk.COLORSPACE_RGB, 0, 8, width, height)
        pixbuf.get_from_drawable(pixmap, pixmap.get_colormap(),
                                     0, 0, 0, 0, width, height)

        if is_string_like(filename):
            try:
                pixbuf.save(filename, format)
            except gobject.GError as exc:
                error_msg_gtk('Save figure failure:\n%s' % (exc,), parent=self)
        elif is_writable_file_like(filename):
            if hasattr(pixbuf, 'save_to_callback'):
                def save_callback(buf, data=None):
                    data.write(buf)
                try:
                    pixbuf.save_to_callback(save_callback, format, user_data=filename)
                except gobject.GError as exc:
                    error_msg_gtk('Save figure failure:\n%s' % (exc,), parent=self)
            else:
                raise ValueError("Saving to a Python file-like object is only supported by PyGTK >= 2.8")
        else:
            raise ValueError("filename must be a path or a file-like object")
示例#23
0
    def __init__(self, colors, name = 'from_list', N = None):
        """
        Make a colormap from a list of colors.

        colors is a list of matplotlib color specifications,
            or an equivalent Nx3 floating point array (N rgb values)
        name is a string to identify the colormap
        N is the number of entries in the map.  The default is None,
            in which case there is one colormap entry for each
            element in the list of colors.  If N < len(colors)
            the list will be truncated at N.  If N > len(colors),
            the list will be extended by repetition.
        """
        self.colors = colors
        self.monochrome = False  # True only if all colors in map are identical;
                                 # needed for contouring.
        if N is None:
            N = len(self.colors)
        else:
            if cbook.is_string_like(self.colors):
                self.colors = [self.colors] * N
                self.monochrome = True
            elif cbook.iterable(self.colors):
                self.colors = list(self.colors) # in case it was a tuple
                if len(self.colors) == 1:
                    self.monochrome = True
                if len(self.colors) < N:
                    self.colors = list(self.colors) * N
                del(self.colors[N:])
            else:
                try: gray = float(self.colors)
                except TypeError: pass
                else:  self.colors = [gray] * N
                self.monochrome = True
        Colormap.__init__(self, name, N)
示例#24
0
def register_cmap(name=None, cmap=None, data=None, lut=None):
    """
    Add a colormap to the set recognized by :func:`get_cmap`.
    It can be used in two ways::
        register_cmap(name='swirly', cmap=swirly_cmap)
        register_cmap(name='choppy', data=choppydata, lut=128)
    In the first case, *cmap* must be a :class:`colors.Colormap`
    instance.  The *name* is optional; if absent, the name will
    be the :attr:`name` attribute of the *cmap*.
    In the second case, the three arguments are passed to
    the :class:`colors.LinearSegmentedColormap` initializer,
    and the resulting colormap is registered.
    """
    if name is None:
        try:
            name = cmap.name
        except AttributeError:
            raise ValueError("Arguments must include a name or a Colormap")
    if not cbook.is_string_like(name):
        raise ValueError("Colormap name must be a string")
    if isinstance(cmap, colors.Colormap):
        cmap_d[name] = cmap
        return
    if lut is None:
        lut = mpl.rcParams['image.lut']
    cmap = colors.LinearSegmentedColormap(name, data, lut)
    cmap_d[name] = cmap
示例#25
0
    def print_svg(self, filename, *args, **kwargs):
        if is_string_like(filename):
            with io.open(filename, 'w', encoding='utf-8') as svgwriter:
                return self._print_svg(filename, svgwriter, **kwargs)

        if not is_writable_file_like(filename):
            raise ValueError("filename must be a path or a file-like object")

        svgwriter = filename
        filename = getattr(svgwriter, 'name', '')
        if not isinstance(filename, six.string_types):
            filename = ''

        if not isinstance(svgwriter, io.TextIOBase):
            if six.PY3:
                svgwriter = io.TextIOWrapper(svgwriter, 'utf-8')
            else:
                svgwriter = codecs.getwriter('utf-8')(svgwriter)
            detach = True
        else:
            detach = False

        result = self._print_svg(filename, svgwriter, **kwargs)

        # Detach underlying stream from wrapper so that it remains open in the
        # caller.
        if detach:
            if six.PY3:
                svgwriter.detach()
            else:
                svgwriter.reset()
                svgwriter.stream = io.BytesIO()

        return result
示例#26
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`.
     In addition, if *arg* is "none" (case-insensitive),
     then (0,0,0,0) will be returned.
     If *arg* is an *RGBA* sequence and *alpha* is not *None*,
     *alpha* will replace the original *A*.
     """
     try:
         if arg.lower() == "none":
             return (0.0, 0.0, 0.0, 0.0)
     except AttributeError:
         pass
     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)]:
                     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], 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))
示例#27
0
def use(name):
    """Use matplotlib style settings from a known style sheet or from a file.

    Parameters
    ----------
    name : str or list of str
        Name of style or path/URL to a style file. For a list of available
        style names, see `style.available`. If given a list, each style is
        applied from first to last in the list.
    """
    if cbook.is_string_like(name):
        name = [name]

    for style in name:
        if style in library:
            mpl.rcParams.update(library[style])
        else:
            try:
                rc = rc_params_from_file(style, use_default_template=False)
                mpl.rcParams.update(rc)
            except:
                msg = ("'%s' not found in the style library and input is "
                       "not a valid URL or path. See `style.available` for "
                       "list of available styles.")
                raise ValueError(msg % style)
示例#28
0
def _process_attributes(attrs, source, agr, prefix=''):
    for attr, attr_dict in attrs.items():
        attr_type = attr_dict['type']
        if 'static' in attr_type:
            value = ''
        elif 'function' in attr_type:
            value = attr_dict['function'](source)
        else:
            value = getattr(source, 'get_{}'.format(attr))()
            if 'condition' in attr_dict:
                if not attr_dict['condition'](value):
                    continue
            if is_string_like(value):
                value = latex_to_xmgrace(value)
            if 'index' in attr_type:
                attr_list = agr_attr_lists[attr_dict.get('maplist', attr)]
                index = indexed(attr_list)(value)
                if index is None:
                    if 'map' in attr_type:
                        attr_list.append(value)
                        index = attr_list.index(value)
                    else:
                        index = 1
                value = index

        agr.writeline(prefix + attr_dict['fmt'], attr=attr, value=value)
示例#29
0
 def get_label_width(self, lev, fmt, fsize):
     "get the width of the label in points"
     if cbook.is_string_like(lev):
         lw = (len(lev)) * fsize
     else:
         lw = (len(self.get_text(lev,fmt))) * fsize
     return lw
示例#30
0
def draw_networkx_labels(
    G,
    pos,
    labels=None,
    font_size=12,
    font_color="k",
    font_family="sans-serif",
    font_weight="normal",
    alpha=1.0,
    ax=None,
    **kwds
):
    """Draw node labels on 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.

    labels is an optional dictionary keyed by vertex with node labels
    as the values.  If provided only labels for the keys in the dictionary
    are drawn.
    
    See draw_networkx for the list of other optional parameters.

    """
    try:
        import matplotlib.pylab as pylab
        import matplotlib.cbook as cb
    except ImportError:
        raise ImportError, "Matplotlib required for draw()"
    except RuntimeError:
        pass  # unable to open display

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

    if labels is None:
        labels = dict(zip(G.nodes(), G.nodes()))

    text_items = {}  # there is no text collection so we'll fake one
    for (n, label) in labels.items():
        (x, y) = pos[n]
        if not cb.is_string_like(label):
            label = str(label)  # this will cause "1" and 1 to be labeled the same
        t = ax.text(
            x,
            y,
            label,
            size=font_size,
            color=font_color,
            family=font_family,
            weight=font_weight,
            horizontalalignment="center",
            verticalalignment="center",
            transform=ax.transData,
        )
        text_items[n] = t

    return text_items
示例#31
0
class DialogLineprops(object):
    """
    A GUI dialog for controlling lineprops
    """
    signals = (
        'on_combobox_lineprops_changed',
        'on_combobox_linestyle_changed',
        'on_combobox_marker_changed',
        'on_colorbutton_linestyle_color_set',
        'on_colorbutton_markerface_color_set',
        'on_dialog_lineprops_okbutton_clicked',
        'on_dialog_lineprops_cancelbutton_clicked',
    )

    linestyles = [ls for ls in lines.Line2D.lineStyles if ls.strip()]
    linestyled = dict([(s, i) for i, s in enumerate(linestyles)])

    markers = [m for m in lines.Line2D.markers if cbook.is_string_like(m)]

    markerd = dict([(s, i) for i, s in enumerate(markers)])

    def __init__(self, lines):
        import Gtk.glade

        datadir = matplotlib.get_data_path()
        gladefile = os.path.join(datadir, 'lineprops.glade')
        if not os.path.exists(gladefile):
            raise IOError('Could not find gladefile lineprops.glade in %s' %
                          datadir)

        self._inited = False
        self._updateson = True  # suppress updates when setting widgets manually
        self.wtree = Gtk.glade.XML(gladefile, 'dialog_lineprops')
        self.wtree.signal_autoconnect(
            dict([(s, getattr(self, s)) for s in self.signals]))

        self.dlg = self.wtree.get_widget('dialog_lineprops')

        self.lines = lines

        cbox = self.wtree.get_widget('combobox_lineprops')
        cbox.set_active(0)
        self.cbox_lineprops = cbox

        cbox = self.wtree.get_widget('combobox_linestyles')
        for ls in self.linestyles:
            cbox.append_text(ls)
        cbox.set_active(0)
        self.cbox_linestyles = cbox

        cbox = self.wtree.get_widget('combobox_markers')
        for m in self.markers:
            cbox.append_text(m)
        cbox.set_active(0)
        self.cbox_markers = cbox
        self._lastcnt = 0
        self._inited = True

    def show(self):
        'populate the combo box'
        self._updateson = False
        # flush the old
        cbox = self.cbox_lineprops
        for i in range(self._lastcnt - 1, -1, -1):
            cbox.remove_text(i)

        # add the new
        for line in self.lines:
            cbox.append_text(line.get_label())
        cbox.set_active(0)

        self._updateson = True
        self._lastcnt = len(self.lines)
        self.dlg.show()

    def get_active_line(self):
        'get the active line'
        ind = self.cbox_lineprops.get_active()
        line = self.lines[ind]
        return line

    def get_active_linestyle(self):
        'get the active lineinestyle'
        ind = self.cbox_linestyles.get_active()
        ls = self.linestyles[ind]
        return ls

    def get_active_marker(self):
        'get the active lineinestyle'
        ind = self.cbox_markers.get_active()
        m = self.markers[ind]
        return m

    def _update(self):
        'update the active line props from the widgets'
        if not self._inited or not self._updateson: return
        line = self.get_active_line()
        ls = self.get_active_linestyle()
        marker = self.get_active_marker()
        line.set_linestyle(ls)
        line.set_marker(marker)

        button = self.wtree.get_widget('colorbutton_linestyle')
        color = button.get_color()
        r, g, b = [
            val / 65535. for val in (color.red, color.green, color.blue)
        ]
        line.set_color((r, g, b))

        button = self.wtree.get_widget('colorbutton_markerface')
        color = button.get_color()
        r, g, b = [
            val / 65535. for val in (color.red, color.green, color.blue)
        ]
        line.set_markerfacecolor((r, g, b))

        line.figure.canvas.draw()

    def on_combobox_lineprops_changed(self, item):
        'update the widgets from the active line'
        if not self._inited: return
        self._updateson = False
        line = self.get_active_line()

        ls = line.get_linestyle()
        if ls is None: ls = 'None'
        self.cbox_linestyles.set_active(self.linestyled[ls])

        marker = line.get_marker()
        if marker is None: marker = 'None'
        self.cbox_markers.set_active(self.markerd[marker])

        r, g, b = colorConverter.to_rgb(line.get_color())
        color = Gdk.Color(*[int(val * 65535) for val in (r, g, b)])
        button = self.wtree.get_widget('colorbutton_linestyle')
        button.set_color(color)

        r, g, b = colorConverter.to_rgb(line.get_markerfacecolor())
        color = Gdk.Color(*[int(val * 65535) for val in (r, g, b)])
        button = self.wtree.get_widget('colorbutton_markerface')
        button.set_color(color)
        self._updateson = True

    def on_combobox_linestyle_changed(self, item):
        self._update()

    def on_combobox_marker_changed(self, item):
        self._update()

    def on_colorbutton_linestyle_color_set(self, button):
        self._update()

    def on_colorbutton_markerface_color_set(self, button):
        'called colorbutton marker clicked'
        self._update()

    def on_dialog_lineprops_okbutton_clicked(self, button):
        self._update()
        self.dlg.hide()

    def on_dialog_lineprops_cancelbutton_clicked(self, button):
        self.dlg.hide()
示例#32
0
    def _save(self, fo, format, **kwargs):
        # save PDF/PS/SVG
        orientation = kwargs.get('orientation', 'portrait')

        dpi = 72
        self.figure.dpi = dpi
        w_in, h_in = self.figure.get_size_inches()
        width_in_points, height_in_points = w_in * dpi, h_in * dpi

        if orientation == 'landscape':
            width_in_points, height_in_points = (height_in_points,
                                                 width_in_points)

        if format == 'ps':
            if not hasattr(cairo, 'PSSurface'):
                raise RuntimeError('cairo has not been compiled with PS '
                                   'support enabled')
            surface = cairo.PSSurface(fo, width_in_points, height_in_points)
        elif format == 'pdf':
            if not hasattr(cairo, 'PDFSurface'):
                raise RuntimeError('cairo has not been compiled with PDF '
                                   'support enabled')
            surface = cairo.PDFSurface(fo, width_in_points, height_in_points)
        elif format in ('svg', 'svgz'):
            if not hasattr(cairo, 'SVGSurface'):
                raise RuntimeError('cairo has not been compiled with SVG '
                                   'support enabled')
            if format == 'svgz':
                if is_string_like(fo):
                    fo = gzip.GzipFile(fo, 'wb')
                else:
                    fo = gzip.GzipFile(None, 'wb', fileobj=fo)
            surface = cairo.SVGSurface(fo, width_in_points, height_in_points)
        else:
            warnings.warn("unknown format: %s" % format)
            return

        # surface.set_dpi() can be used
        renderer = RendererCairo(self.figure.dpi)
        renderer.set_width_height(width_in_points, height_in_points)
        renderer.set_ctx_from_surface(surface)
        ctx = renderer.gc.ctx

        if orientation == 'landscape':
            ctx.rotate(np.pi / 2)
            ctx.translate(0, -height_in_points)
            # cairo/src/cairo_ps_surface.c
            # '%%Orientation: Portrait' is always written to the file header
            # '%%Orientation: Landscape' would possibly cause problems
            # since some printers would rotate again ?
            # TODO:
            # add portrait/landscape checkbox to FileChooser

        self.figure.draw(renderer)

        show_fig_border = False  # for testing figure orientation and scaling
        if show_fig_border:
            ctx.new_path()
            ctx.rectangle(0, 0, width_in_points, height_in_points)
            ctx.set_line_width(4.0)
            ctx.set_source_rgb(1, 0, 0)
            ctx.stroke()
            ctx.move_to(30, 30)
            ctx.select_font_face('sans-serif')
            ctx.set_font_size(20)
            ctx.show_text('Origin corner')

        ctx.show_page()
        surface.finish()
        if format == 'svgz':
            fo.close()
示例#33
0
def rec2excel(r,
              ws,
              formatd=None,
              rownum=0,
              colnum=0,
              nanstr='NaN',
              infstr='Inf'):
    """
    save record array r to excel pyExcelerator worksheet ws
    starting at rownum.  if ws is string like, assume it is a
    filename and save to it

    start writing at rownum, colnum

    formatd is a dictionary mapping dtype name -> mlab.Format instances

    nanstr is the string that mpl will put into excel for np.nan value
    The next rownum after writing is returned
    """

    autosave = False
    if cbook.is_string_like(ws):
        filename = ws
        wb = excel.Workbook()
        ws = wb.add_sheet('worksheet')
        autosave = True

    if formatd is None:
        formatd = dict()

    formats = []
    font = excel.Font()
    font.bold = True

    stylehdr = excel.XFStyle()
    stylehdr.font = font

    for i, name in enumerate(r.dtype.names):
        dt = r.dtype[name]
        format = formatd.get(name)
        if format is None:
            format = mlab.defaultformatd.get(dt.type, mlab.FormatObj())

        format = xlformat_factory(format)
        ws.write(rownum, colnum + i, name, stylehdr)
        formats.append(format)

    rownum += 1

    ind = np.arange(len(r.dtype.names))
    for row in r:

        for i in ind:
            val = row[i]
            format = formats[i]
            val = format.toval(val)
            if mlab.safe_isnan(val):
                ws.write(rownum, colnum + i, nanstr)
            elif mlab.safe_isinf(val):
                sgn = np.sign(val)
                if sgn < 0: s = infstr
                else: s = '-%s' % infstr
                ws.write(rownum, colnum + i, s)
            elif format.xlstyle is None:
                ws.write(rownum, colnum + i, val)
            else:
                ws.write(rownum, colnum + i, val, format.xlstyle)
        rownum += 1

    if autosave:
        wb.save(filename)
    return rownum
    def to_rgb(self, arg):
        """
        Returns an *RGB* tuple of three floats from 0-1.

        *arg* can be an *RGB* or *RGBA* sequence or a string in any of
        several forms:

            1) a letter from the set 'rgbcmykw'
            2) a hex color string, like '#00FFFF'
            3) a standard name, like 'aqua'
            4) a float, like '0.4', indicating gray on a 0-1 scale

        if *arg* is *RGBA*, the *A* will simply be discarded.
        """
        try:
            return self.cache[arg]
        except KeyError:
            pass
        except TypeError:  # could be unhashable rgb seq
            arg = tuple(arg)
            try:
                return self.cache[arg]
            except KeyError:
                pass
            except TypeError:
                raise ValueError(
                    'to_rgb: arg "%s" is unhashable even inside a tuple' %
                    (str(arg), ))

        try:
            if cbook.is_string_like(arg):
                argl = arg.lower()
                color = self.colors.get(argl, None)
                if color is None:
                    str1 = cnames.get(argl, argl)
                    if str1.startswith('#'):
                        color = hex2color(str1)
                    else:
                        fl = float(argl)
                        if fl < 0 or fl > 1:
                            raise ValueError(
                                'gray (string) must be in range 0-1')
                        color = tuple([fl] * 3)
            elif cbook.iterable(arg):
                if len(arg) > 4 or len(arg) < 3:
                    raise ValueError('sequence length is %d; must be 3 or 4' %
                                     len(arg))
                color = tuple(arg[:3])
                if [x for x in color if (float(x) < 0) or (x > 1)]:
                    # This will raise TypeError if x is not a number.
                    raise ValueError(
                        'number in rbg sequence outside 0-1 range')
            else:
                raise ValueError('cannot convert argument to rgb sequence')

            self.cache[arg] = color

        except (KeyError, ValueError, TypeError) as exc:
            raise ValueError('to_rgb: Invalid rgb arg "%s"\n%s' %
                             (str(arg), exc))
            # Error messages could be improved by handling TypeError
            # separately; but this should be rare and not too hard
            # for the user to figure out as-is.
        return color
示例#35
0
    def save(self,
             filename,
             writer=None,
             fps=None,
             dpi=None,
             codec=None,
             bitrate=None,
             extra_args=None,
             metadata=None,
             extra_anim=None,
             savefig_kwargs=None):
        '''
        Saves a movie file by drawing every frame.

        *filename* is the output filename, e.g., :file:`mymovie.mp4`

        *writer* is either an instance of :class:`MovieWriter` or a string
        key that identifies a class to use, such as 'ffmpeg' or 'mencoder'.
        If nothing is passed, the value of the rcparam `animation.writer` is
        used.

        *fps* is the frames per second in the movie. Defaults to None,
        which will use the animation's specified interval to set the frames
        per second.

        *dpi* controls the dots per inch for the movie frames. This combined
        with the figure's size in inches controls the size of the movie.

        *codec* is the video codec to be used. Not all codecs are supported
        by a given :class:`MovieWriter`. If none is given, this defaults to the
        value specified by the rcparam `animation.codec`.

        *bitrate* specifies the amount of bits used per second in the
        compressed movie, in kilobits per second. A higher number means a
        higher quality movie, but at the cost of increased file size. If no
        value is given, this defaults to the value given by the rcparam
        `animation.bitrate`.

        *extra_args* is a list of extra string arguments to be passed to the
        underlying movie utiltiy. The default is None, which passes the
        additional argurments in the 'animation.extra_args' rcParam.

        *metadata* is a dictionary of keys and values for metadata to include
        in the output file. Some keys that may be of use include:
        title, artist, genre, subject, copyright, srcform, comment.

        *extra_anim* is a list of additional `Animation` objects that should
        be included in the saved movie file. These need to be from the same
        `matplotlib.Figure` instance. Also, animation frames will just be
        simply combined, so there should be a 1:1 correspondence between
        the frames from the different animations.

        *savefig_kwargs* is a dictionary containing keyword arguments to be
        passed on to the 'savefig' command which is called repeatedly to save
        the individual frames. This can be used to set tight bounding boxes,
        for example.
        '''
        if savefig_kwargs is None:
            savefig_kwargs = {}

        # FIXME: Using 'bbox_inches' doesn't currently work with
        # writers that pipe the data to the command because this
        # requires a fixed frame size (see Ryan May's reply in this
        # thread: [1]). Thus we drop the 'bbox_inches' argument if it
        # exists in savefig_kwargs.
        #
        # [1] (http://matplotlib.1069221.n5.nabble.com/
        # Animation-class-let-save-accept-kwargs-which-
        # are-passed-on-to-savefig-td39627.html)
        #
        if 'bbox_inches' in savefig_kwargs:
            if not (writer in ['ffmpeg_file', 'mencoder_file']
                    or isinstance(writer,
                                  (FFMpegFileWriter, MencoderFileWriter))):
                print(
                    "Warning: discarding the 'bbox_inches' argument in "
                    "'savefig_kwargs' as it is only currently supported "
                    "with the writers 'ffmpeg_file' and 'mencoder_file' "
                    "(writer used: "
                    "'{0}').".format(
                        writer if isinstance(writer, six.string_types
                                             ) else writer.__class__.__name__))
                savefig_kwargs.pop('bbox_inches')

        # Need to disconnect the first draw callback, since we'll be doing
        # draws. Otherwise, we'll end up starting the animation.
        if self._first_draw_id is not None:
            self._fig.canvas.mpl_disconnect(self._first_draw_id)
            reconnect_first_draw = True
        else:
            reconnect_first_draw = False

        if fps is None and hasattr(self, '_interval'):
            # Convert interval in ms to frames per second
            fps = 1000. / self._interval

        # If the writer is None, use the rc param to find the name of the one
        # to use
        if writer is None:
            writer = rcParams['animation.writer']

        # Re-use the savefig DPI for ours if none is given
        if dpi is None:
            dpi = rcParams['savefig.dpi']
            if dpi == 'figure':
                dpi = self._fig.dpi

        if codec is None:
            codec = rcParams['animation.codec']

        if bitrate is None:
            bitrate = rcParams['animation.bitrate']

        all_anim = [self]
        if extra_anim is not None:
            all_anim.extend(anim for anim in extra_anim
                            if anim._fig is self._fig)

        # If we have the name of a writer, instantiate an instance of the
        # registered class.
        if is_string_like(writer):
            if writer in writers.avail:
                writer = writers[writer](fps,
                                         codec,
                                         bitrate,
                                         extra_args=extra_args,
                                         metadata=metadata)
            else:
                import warnings
                warnings.warn("MovieWriter %s unavailable" % writer)

                try:
                    writer = writers[writers.list()[0]](fps,
                                                        codec,
                                                        bitrate,
                                                        extra_args=extra_args,
                                                        metadata=metadata)
                except IndexError:
                    raise ValueError("Cannot save animation: no writers are "
                                     "available. Please install mencoder or "
                                     "ffmpeg to save animations.")

        verbose.report('Animation.save using %s' % type(writer),
                       level='helpful')
        # Create a new sequence of frames for saved data. This is different
        # from new_frame_seq() to give the ability to save 'live' generated
        # frame information to be saved later.
        # TODO: Right now, after closing the figure, saving a movie won't work
        # since GUI widgets are gone. Either need to remove extra code to
        # allow for this non-existant use case or find a way to make it work.
        with writer.saving(self._fig, filename, dpi):
            for anim in all_anim:
                # Clear the initial frame
                anim._init_draw()
            for data in zip(*[a.new_saved_frame_seq() for a in all_anim]):
                for anim, d in zip(all_anim, data):
                    # TODO: Need to see if turning off blit is really necessary
                    anim._draw_next_frame(d, blit=False)
                writer.grab_frame(**savefig_kwargs)

        # Reconnect signal for first draw if necessary
        if reconnect_first_draw:
            self._first_draw_id = self._fig.canvas.mpl_connect(
                'draw_event', self._start)
示例#36
0
    def findfont(self, prop, fontext='ttf'):
        """
        Search the font list for the font that most closely matches
        the :class:`FontProperties` *prop*.

        :meth:`findfont` performs a nearest neighbor search.  Each
        font is given a similarity score to the target font
        properties.  The first font with the highest score is
        returned.  If no matches below a certain threshold are found,
        the default font (usually Vera Sans) is returned.

        The result is cached, so subsequent lookups don't have to
        perform the O(n) nearest neighbor search.

        See the `W3C Cascading Style Sheet, Level 1
        <http://www.w3.org/TR/1998/REC-CSS2-19980512/>`_ documentation
        for a description of the font finding algorithm.
        """
        debug = False
        if prop is None:
            return self.defaultFont
        if is_string_like(prop):
            prop = FontProperties(prop)
        fname = prop.get_file()
        if fname is not None:
            verbose.report('findfont returning %s' % fname, 'debug')
            return fname

        if fontext == 'afm':
            font_cache = self.afm_lookup_cache
            fontlist = self.afmlist
        else:
            font_cache = self.ttf_lookup_cache
            fontlist = self.ttflist

        cached = font_cache.get(hash(prop))
        if cached:
            return cached

        best_score = 1e64
        best_font = None

        for font in fontlist:
            # Matching family should have highest priority, so it is multiplied
            # by 10.0
            score = \
                self.score_family(prop.get_family(), font.name) * 10.0 + \
                self.score_style(prop.get_style(), font.style) + \
                self.score_variant(prop.get_variant(), font.variant) + \
                self.score_weight(prop.get_weight(), font.weight) + \
                self.score_stretch(prop.get_stretch(), font.stretch) + \
                self.score_size(prop.get_size(), font.size)
            if score < best_score:
                best_score = score
                best_font = font
            if score == 0:
                break

        if best_font is None or best_score >= 10.0:
            verbose.report('findfont: Could not match %s. Returning %s' %
                           (prop, self.defaultFont))
            result = self.defaultFont
        else:
            verbose.report(
                'findfont: Matching %s to %s (%s) with score of %f' %
                (prop, best_font.name, best_font.fname, best_score))
            result = best_font.fname

        font_cache[hash(prop)] = result
        return result
示例#37
0
    def __init__(
        self,
        fig,
        rect,
        nrows_ncols,
        ngrids=None,
        direction="row",
        axes_pad=0.02,
        add_all=True,
        share_all=False,
        aspect=True,
        label_mode="L",
        cbar_mode=None,
        cbar_location="right",
        cbar_pad=None,
        cbar_size="5%",
        cbar_set_cax=True,
        axes_class=None,
    ):
        """
        Build an :class:`ImageGrid` instance with a grid nrows*ncols
        :class:`~matplotlib.axes.Axes` in
        :class:`~matplotlib.figure.Figure` *fig* with
        *rect=[left, bottom, width, height]* (in
        :class:`~matplotlib.figure.Figure` coordinates) or
        the subplot position code (e.g., "121").

        Optional keyword arguments:

          ================  ========  =========================================
          Keyword           Default   Description
          ================  ========  =========================================
          direction         "row"     [ "row" | "column" ]
          axes_pad          0.02      float| pad between axes given in inches
          add_all           True      [ True | False ]
          share_all         False     [ True | False ]
          aspect            True      [ True | False ]
          label_mode        "L"       [ "L" | "1" | "all" ]
          cbar_mode         None      [ "each" | "single" | "edge" ]
          cbar_location     "right"   [ "left" | "right" | "bottom" | "top" ]
          cbar_pad          None
          cbar_size         "5%"
          cbar_set_cax      True      [ True | False ]
          axes_class        None      a type object which must be a subclass
                                      of :class:`~matplotlib.axes.Axes`
          ================  ========  =========================================

        *cbar_set_cax* : if True, each axes in the grid has a cax
          attribute that is bind to associated cbar_axes.
        """
        self._nrows, self._ncols = nrows_ncols

        if ngrids is None:
            ngrids = self._nrows * self._ncols
        else:
            if (ngrids > self._nrows * self._ncols) or (ngrids <= 0):
                raise Exception("")

        self.ngrids = ngrids

        self._axes_pad = axes_pad

        self._colorbar_mode = cbar_mode
        self._colorbar_location = cbar_location
        if cbar_pad is None:
            self._colorbar_pad = axes_pad
        else:
            self._colorbar_pad = cbar_pad

        self._colorbar_size = cbar_size

        self._init_axes_pad(axes_pad)

        if direction not in ["column", "row"]:
            raise Exception("")

        self._direction = direction

        if axes_class is None:
            axes_class = self._defaultLocatableAxesClass
            axes_class_args = {}
        else:
            if isinstance(axes_class, maxes.Axes):
                axes_class_args = {}
            else:
                axes_class, axes_class_args = axes_class

        self.axes_all = []
        self.axes_column = [[] for i in range(self._ncols)]
        self.axes_row = [[] for i in range(self._nrows)]

        self.cbar_axes = []

        h = []
        v = []
        if cbook.is_string_like(rect) or cbook.is_numlike(rect):
            self._divider = SubplotDivider(fig,
                                           rect,
                                           horizontal=h,
                                           vertical=v,
                                           aspect=aspect)
        elif isinstance(rect, SubplotSpec):
            self._divider = SubplotDivider(fig,
                                           rect,
                                           horizontal=h,
                                           vertical=v,
                                           aspect=aspect)
        elif len(rect) == 3:
            kw = dict(horizontal=h, vertical=v, aspect=aspect)
            self._divider = SubplotDivider(fig, *rect, **kw)
        elif len(rect) == 4:
            self._divider = Divider(fig,
                                    rect,
                                    horizontal=h,
                                    vertical=v,
                                    aspect=aspect)
        else:
            raise Exception("")

        rect = self._divider.get_position()

        # reference axes
        self._column_refax = [None for i in range(self._ncols)]
        self._row_refax = [None for i in range(self._nrows)]
        self._refax = None

        for i in range(self.ngrids):

            col, row = self._get_col_row(i)

            if share_all:
                sharex = self._refax
                sharey = self._refax
            else:
                sharex = self._column_refax[col]
                sharey = self._row_refax[row]

            ax = axes_class(fig,
                            rect,
                            sharex=sharex,
                            sharey=sharey,
                            **axes_class_args)

            if share_all:
                if self._refax is None:
                    self._refax = ax
            else:
                if sharex is None:
                    self._column_refax[col] = ax
                if sharey is None:
                    self._row_refax[row] = ax

            self.axes_all.append(ax)
            self.axes_column[col].append(ax)
            self.axes_row[row].append(ax)

            cax = self._defaultCbarAxesClass(
                fig, rect, orientation=self._colorbar_location)
            self.cbar_axes.append(cax)

        self.axes_llc = self.axes_column[0][-1]

        self._update_locators()

        if add_all:
            for ax in self.axes_all + self.cbar_axes:
                fig.add_axes(ax)

        if cbar_set_cax:
            if self._colorbar_mode == "single":
                for ax in self.axes_all:
                    ax.cax = self.cbar_axes[0]
            else:
                for ax, cax in zip(self.axes_all, self.cbar_axes):
                    ax.cax = cax

        self.set_label_mode(label_mode)
示例#38
0
    def __init__(
        self,
        fig,
        rect,
        nrows_ncols,
        ngrids=None,
        direction="row",
        axes_pad=0.02,
        add_all=True,
        share_all=False,
        share_x=True,
        share_y=True,
        #aspect=True,
        label_mode="L",
        axes_class=None,
    ):
        """
        Build an :class:`Grid` instance with a grid nrows*ncols
        :class:`~matplotlib.axes.Axes` in
        :class:`~matplotlib.figure.Figure` *fig* with
        *rect=[left, bottom, width, height]* (in
        :class:`~matplotlib.figure.Figure` coordinates) or
        the subplot position code (e.g., "121").

        Optional keyword arguments:

          ================  ========  =========================================
          Keyword           Default   Description
          ================  ========  =========================================
          direction         "row"     [ "row" | "column" ]
          axes_pad          0.02      float| pad between axes given in inches
          add_all           True      [ True | False ]
          share_all         False     [ True | False ]
          share_x           True      [ True | False ]
          share_y           True      [ True | False ]
          label_mode        "L"       [ "L" | "1" | "all" ]
          axes_class        None      a type object which must be a subclass
                                      of :class:`~matplotlib.axes.Axes`
          ================  ========  =========================================
        """
        self._nrows, self._ncols = nrows_ncols

        if ngrids is None:
            ngrids = self._nrows * self._ncols
        else:
            if (ngrids > self._nrows * self._ncols) or (ngrids <= 0):
                raise Exception("")

        self.ngrids = ngrids

        self._init_axes_pad(axes_pad)

        if direction not in ["column", "row"]:
            raise Exception("")

        self._direction = direction

        if axes_class is None:
            axes_class = self._defaultLocatableAxesClass
            axes_class_args = {}
        else:
            if (type(axes_class)) == type and \
                   issubclass(axes_class, self._defaultLocatableAxesClass.Axes):
                axes_class_args = {}
            else:
                axes_class, axes_class_args = axes_class

        self.axes_all = []
        self.axes_column = [[] for i in range(self._ncols)]
        self.axes_row = [[] for i in range(self._nrows)]

        h = []
        v = []
        if cbook.is_string_like(rect) or cbook.is_numlike(rect):
            self._divider = SubplotDivider(fig,
                                           rect,
                                           horizontal=h,
                                           vertical=v,
                                           aspect=False)
        elif isinstance(rect, SubplotSpec):
            self._divider = SubplotDivider(fig,
                                           rect,
                                           horizontal=h,
                                           vertical=v,
                                           aspect=False)
        elif len(rect) == 3:
            kw = dict(horizontal=h, vertical=v, aspect=False)
            self._divider = SubplotDivider(fig, *rect, **kw)
        elif len(rect) == 4:
            self._divider = Divider(fig,
                                    rect,
                                    horizontal=h,
                                    vertical=v,
                                    aspect=False)
        else:
            raise Exception("")

        rect = self._divider.get_position()

        # reference axes
        self._column_refax = [None for i in range(self._ncols)]
        self._row_refax = [None for i in range(self._nrows)]
        self._refax = None

        for i in range(self.ngrids):

            col, row = self._get_col_row(i)

            if share_all:
                sharex = self._refax
                sharey = self._refax
            else:
                if share_x:
                    sharex = self._column_refax[col]
                else:
                    sharex = None

                if share_y:
                    sharey = self._row_refax[row]
                else:
                    sharey = None

            ax = axes_class(fig,
                            rect,
                            sharex=sharex,
                            sharey=sharey,
                            **axes_class_args)

            if share_all:
                if self._refax is None:
                    self._refax = ax
            else:
                if sharex is None:
                    self._column_refax[col] = ax
                if sharey is None:
                    self._row_refax[row] = ax

            self.axes_all.append(ax)
            self.axes_column[col].append(ax)
            self.axes_row[row].append(ax)

        self.axes_llc = self.axes_column[0][-1]

        self._update_locators()

        if add_all:
            for ax in self.axes_all:
                fig.add_axes(ax)

        self.set_label_mode(label_mode)
示例#39
0
 def _calc_offset_transform(self):
     """calculate the offset transform performed by the spine"""
     self._ensure_position_is_set()
     position = self._position
     if cbook.is_string_like(position):
         if position == 'center':
             position = ('axes', 0.5)
         elif position == 'zero':
             position = ('data', 0)
     assert len(position) == 2, "position should be 2-tuple"
     position_type, amount = position
     assert position_type in ('axes', 'outward', 'data')
     if position_type == 'outward':
         if amount == 0:
             # short circuit commonest case
             self._spine_transform = ('identity',
                                      mtransforms.IdentityTransform())
         elif self.spine_type in ['left', 'right', 'top', 'bottom']:
             offset_vec = {'left': (-1, 0),
                           'right': (1, 0),
                           'bottom': (0, -1),
                           'top': (0, 1),
                           }[self.spine_type]
             # calculate x and y offset in dots
             offset_x = amount * offset_vec[0] / 72.0
             offset_y = amount * offset_vec[1] / 72.0
             self._spine_transform = ('post',
                                      mtransforms.ScaledTranslation(
                                          offset_x,
                                          offset_y,
                                          self.figure.dpi_scale_trans))
         else:
             warnings.warn('unknown spine type "%s": no spine '
                           'offset performed' % self.spine_type)
             self._spine_transform = ('identity',
                                      mtransforms.IdentityTransform())
     elif position_type == 'axes':
         if self.spine_type in ('left', 'right'):
             self._spine_transform = ('pre',
                                      mtransforms.Affine2D.from_values(
                                          # keep y unchanged, fix x at
                                          # amount
                                          0, 0, 0, 1, amount, 0))
         elif self.spine_type in ('bottom', 'top'):
             self._spine_transform = ('pre',
                                      mtransforms.Affine2D.from_values(
                                          # keep x unchanged, fix y at
                                          # amount
                                          1, 0, 0, 0, 0, amount))
         else:
             warnings.warn('unknown spine type "%s": no spine '
                           'offset performed' % self.spine_type)
             self._spine_transform = ('identity',
                                      mtransforms.IdentityTransform())
     elif position_type == 'data':
         if self.spine_type in ('left', 'right'):
             self._spine_transform = ('data',
                                      mtransforms.Affine2D().translate(
                                          amount, 0))
         elif self.spine_type in ('bottom', 'top'):
             self._spine_transform = ('data',
                                      mtransforms.Affine2D().translate(
                                          0, amount))
         else:
             warnings.warn('unknown spine type "%s": no spine '
                           'offset performed' % self.spine_type)
             self._spine_transform = ('identity',
                                      mtransforms.IdentityTransform())
示例#40
0
def imread(fname, format=None):
    """
    Read an image from a file into an array.

    *fname* may be a string path or a Python file-like object.  If
    using a file object, it must be opened in binary mode.

    If *format* is provided, will try to read file of that type,
    otherwise the format is deduced from the filename.  If nothing can
    be deduced, PNG is tried.

    Return value is a :class:`numpy.array`.  For grayscale images, the
    return array is MxN.  For RGB images, the return value is MxNx3.
    For RGBA images the return value is MxNx4.

    matplotlib can only read PNGs natively, but if `PIL
    <http://www.pythonware.com/products/pil/>`_ is installed, it will
    use it to load the image and return an array (if possible) which
    can be used with :func:`~matplotlib.pyplot.imshow`.
    """
    def pilread(fname):
        """try to load the image with PIL or return None"""
        try:
            from PIL import Image
        except ImportError:
            return None
        if cbook.is_string_like(fname):
            # force close the file after reading the image
            with open(fname, "rb") as fh:
                image = Image.open(fh)
                return pil_to_array(image)
        else:
            image = Image.open(fname)
            return pil_to_array(image)

    handlers = {
        'png': _png.read_png,
    }
    if format is None:
        if cbook.is_string_like(fname):
            basename, ext = os.path.splitext(fname)
            ext = ext.lower()[1:]
        elif hasattr(fname, 'name'):
            basename, ext = os.path.splitext(fname.name)
            ext = ext.lower()[1:]
        else:
            ext = 'png'
    else:
        ext = format

    if ext not in handlers.iterkeys():
        im = pilread(fname)
        if im is None:
            raise ValueError('Only know how to handle extensions: %s; '
                             'with PIL installed matplotlib can handle '
                             'more images' % handlers.keys())
        return im

    handler = handlers[ext]

    # To handle Unicode filenames, we pass a file object to the PNG
    # reader extension, since Python handles them quite well, but it's
    # tricky in C.
    if cbook.is_string_like(fname):
        with open(fname, 'rb') as fd:
            return handler(fd)
    else:
        return handler(fname)
示例#41
0
    def __init__(
        self,
        parent,
        handles,
        labels,
        loc=None,
        numpoints=None,  # the number of points in the legend line
        markerscale=None,  # the relative size of legend markers
        # vs. original
        markerfirst=True,  # controls ordering (left-to-right) of
        # legend marker and label
        scatterpoints=None,  # number of scatter points
        scatteryoffsets=None,
        scatter_uni_size=None,  # set scatter plot to have uniform
        # handle size
        prop=None,  # properties for the legend texts
        fontsize=None,  # keyword to set font size directly

        # spacing & pad defined as a fraction of the font-size
        borderpad=None,  # the whitespace inside the legend border
        labelspacing=None,  # the vertical space between the legend
        # entries
        handlelength=None,  # the length of the legend handles
        handleheight=None,  # the height of the legend handles
        handletextpad=None,  # the pad between the legend handle
        # and text
        borderaxespad=None,  # the pad between the axes and legend
        # border
        columnspacing=None,  # spacing between columns
        ncol=1,  # number of columns
        mode=None,  # mode for horizontal distribution of columns.
        # None, "expand"
        fancybox=None,  # True use a fancy box, false use a rounded
        # box, none use rc
        shadow=None,
        title=None,  # set a title for the legend
        framealpha=None,  # set frame alpha
        bbox_to_anchor=None,  # bbox that the legend will be anchored.
        bbox_transform=None,  # transform for the bbox
        frameon=None,  # draw frame
        handler_map=None,
    ):
        """
        - *parent*: the artist that contains the legend
        - *handles*: a list of artists (lines, patches) to be added to the
                      legend
        - *labels*: a list of strings to label the legend

        Optional keyword arguments:

        ================   ====================================================
        Keyword            Description
        ================   ====================================================
        loc                a location code
        prop               the font property
        fontsize           the font size (used only if prop is not specified)
        markerscale        the relative size of legend markers vs. original
        markerfirst        If true, place legend marker to left of label
                           If false, place legend marker to right of label
        numpoints          the number of points in the legend for line
        scatterpoints      the number of points in the legend for scatter plot
        scatteryoffsets    a list of yoffsets for scatter symbols in legend
        scatter_uni_size   Set the legend handles for satter plots to be of
                           uniform size.
        frameon            if True, draw a frame around the legend.
                           If None, use rc
        fancybox           if True, draw a frame with a round fancybox.
                           If None, use rc
        shadow             if True, draw a shadow behind legend
        framealpha         If not None, alpha channel for the frame.
        ncol               number of columns
        borderpad          the fractional whitespace inside the legend border
        labelspacing       the vertical space between the legend entries
        handlelength       the length of the legend handles
        handleheight       the height of the legend handles
        handletextpad      the pad between the legend handle and text
        borderaxespad      the pad between the axes and legend border
        columnspacing      the spacing between columns
        title              the legend title
        bbox_to_anchor     the bbox that the legend will be anchored.
        bbox_transform     the transform for the bbox. transAxes if None.
        ================   ====================================================


        The pad and spacing parameters are measured in font-size units.  e.g.,
        a fontsize of 10 points and a handlelength=5 implies a handlelength of
        50 points.  Values from rcParams will be used if None.

        Users can specify any arbitrary location for the legend using the
        *bbox_to_anchor* keyword argument. bbox_to_anchor can be an instance
        of BboxBase(or its derivatives) or a tuple of 2 or 4 floats.
        See :meth:`set_bbox_to_anchor` for more detail.

        The legend location can be specified by setting *loc* with a tuple of
        2 floats, which is interpreted as the lower-left corner of the legend
        in the normalized axes coordinate.
        """
        # local import only to avoid circularity
        from matplotlib.axes import Axes
        from matplotlib.figure import Figure

        Artist.__init__(self)

        if prop is None:
            if fontsize is not None:
                self.prop = FontProperties(size=fontsize)
            else:
                self.prop = FontProperties(size=rcParams["legend.fontsize"])
        elif isinstance(prop, dict):
            self.prop = FontProperties(**prop)
            if "size" not in prop:
                self.prop.set_size(rcParams["legend.fontsize"])
        else:
            self.prop = prop

        self._fontsize = self.prop.get_size_in_points()

        self.texts = []
        self.legendHandles = []
        self._legend_title_box = None

        #: A dictionary with the extra handler mappings for this Legend
        #: instance.
        self._custom_handler_map = handler_map

        locals_view = locals()
        for name in [
                "numpoints", "markerscale", "shadow", "columnspacing",
                "scatterpoints", "handleheight", 'borderpad', 'labelspacing',
                'handlelength', 'handletextpad', 'borderaxespad'
        ]:
            if locals_view[name] is None:
                value = rcParams["legend." + name]
            else:
                value = locals_view[name]
            setattr(self, name, value)
        del locals_view

        # If scatter_uni_size is set, use a custom handler with set size.
        if scatter_uni_size:
            # See if custom handler has been provided for PathCollection
            if (self._custom_handler_map is not None
                    and PathCollection in self._custom_handler_map):
                warnings.warn("'scatter_uni_size' was set, but custom " +
                              "handler was provided. The former will " +
                              "be ignored.")
            else:
                # Initialize _custom_handler_map if None.
                if self._custom_handler_map is None:
                    self._custom_handler_map = {}
                # Add entry to custom handler to custom mapping to specify
                # uniform size.
                self._custom_handler_map.update({
                    PathCollection:
                    legend_handler.HandlerPathCollection(
                        sizes=[scatter_uni_size] * 3)
                })

        handles = list(handles)
        if len(handles) < 2:
            ncol = 1
        self._ncol = ncol

        if self.numpoints <= 0:
            raise ValueError("numpoints must be > 0; it was %d" % numpoints)

        # introduce y-offset for handles of the scatter plot
        if scatteryoffsets is None:
            self._scatteryoffsets = np.array([3. / 8., 4. / 8., 2.5 / 8.])
        else:
            self._scatteryoffsets = np.asarray(scatteryoffsets)
        reps = int(self.scatterpoints / len(self._scatteryoffsets)) + 1
        self._scatteryoffsets = np.tile(self._scatteryoffsets,
                                        reps)[:self.scatterpoints]

        # _legend_box is an OffsetBox instance that contains all
        # legend items and will be initialized from _init_legend_box()
        # method.
        self._legend_box = None

        if isinstance(parent, Axes):
            self.isaxes = True
            self.axes = parent
            self.set_figure(parent.figure)
        elif isinstance(parent, Figure):
            self.isaxes = False
            self.set_figure(parent)
        else:
            raise TypeError("Legend needs either Axes or Figure as parent")
        self.parent = parent

        if loc is None:
            loc = rcParams["legend.loc"]
            if not self.isaxes and loc in [0, 'best']:
                loc = 'upper right'
        if is_string_like(loc):
            if loc not in self.codes:
                if self.isaxes:
                    warnings.warn('Unrecognized location "%s". Falling back '
                                  'on "best"; valid locations are\n\t%s\n' %
                                  (loc, '\n\t'.join(six.iterkeys(self.codes))))
                    loc = 0
                else:
                    warnings.warn('Unrecognized location "%s". Falling back '
                                  'on "upper right"; '
                                  'valid locations are\n\t%s\n' %
                                  (loc, '\n\t'.join(six.iterkeys(self.codes))))
                    loc = 1
            else:
                loc = self.codes[loc]
        if not self.isaxes and loc == 0:
            warnings.warn('Automatic legend placement (loc="best") not '
                          'implemented for figure legend. '
                          'Falling back on "upper right".')
            loc = 1

        self._mode = mode
        self.set_bbox_to_anchor(bbox_to_anchor, bbox_transform)

        # We use FancyBboxPatch to draw a legend frame. The location
        # and size of the box will be updated during the drawing time.

        self.legendPatch = FancyBboxPatch(xy=(0.0, 0.0),
                                          width=1.,
                                          height=1.,
                                          facecolor=rcParams["axes.facecolor"],
                                          edgecolor=rcParams["axes.edgecolor"],
                                          mutation_scale=self._fontsize,
                                          snap=True)

        # The width and height of the legendPatch will be set (in the
        # draw()) to the length that includes the padding. Thus we set
        # pad=0 here.
        if fancybox is None:
            fancybox = rcParams["legend.fancybox"]

        if fancybox:
            self.legendPatch.set_boxstyle("round", pad=0, rounding_size=0.2)
        else:
            self.legendPatch.set_boxstyle("square", pad=0)

        self._set_artist_props(self.legendPatch)

        self._drawFrame = frameon
        if frameon is None:
            self._drawFrame = rcParams["legend.frameon"]

        # init with null renderer
        self._init_legend_box(handles, labels, markerfirst)

        if framealpha is None:
            self.get_frame().set_alpha(rcParams["legend.framealpha"])
        else:
            self.get_frame().set_alpha(framealpha)

        self._loc = loc
        self.set_title(title)
        self._last_fontsize_points = self._fontsize
        self._draggable = None
示例#42
0
    def print_figure(self,
                     filename,
                     dpi=150,
                     facecolor='w',
                     edgecolor='w',
                     orientation='portrait'):
        """
        Render the figure to hardcopy.  Set the figure patch face and
        edge colors.  This is useful because some of the GUIs have a
        gray figure face color background and you'll probably want to
        override this on hardcopy

        If the extension matches PNG, write a PNG file

        If the extension matches BMP or RAW, write an RGBA bitmap file

        If filename is a fileobject, write png to file object (thus
        you can, for example, write the png to stdout
        """
        if __debug__:
            verbose.report('FigureCanvasAgg.print_figure', 'debug-annoying')

        # store the orig figure dpi, color and size information so we
        # can restore them later.  For image creation alone, this is
        # not important since after the print the figure is done.  But
        # backend_agg may be used as a renderer for a GUI figure, and
        # restoring figure props will be important in that case.
        # TODO: move most of this functionality into backend_bases

        origDPI = self.figure.dpi.get()
        origfacecolor = self.figure.get_facecolor()
        origedgecolor = self.figure.get_edgecolor()

        self.figure.dpi.set(dpi)
        self.figure.set_facecolor(facecolor)
        self.figure.set_edgecolor(edgecolor)

        # render the printed figure
        self.draw()

        if not is_string_like(filename):
            # assume png and write to fileobject
            self.renderer._renderer.write_png(filename)
            #pass
        else:
            # take a look at the extension and choose the print handler
            basename, ext = os.path.splitext(filename)
            if not len(ext):
                ext = '.png'
                filename += ext

            ext = ext.lower()
            if (ext.find('rgb') >= 0 or ext.find('raw') >= 0
                    or ext.find('bmp') >= 0):
                # agg doesn't handle unicode yet
                self.renderer._renderer.write_rgba(str(filename))
            elif ext.find('png') >= 0:
                # agg doesn't handle unicode yet
                self.renderer._renderer.write_png(str(filename))
                #pass
            elif ext.find('svg') >= 0:
                from backend_svg import FigureCanvasSVG
                svg = self.switch_backends(FigureCanvasSVG)
                svg.print_figure(filename, dpi, facecolor, edgecolor,
                                 orientation)
            elif ext.find('ps') >= 0 or ext.find('ep') >= 0:
                from backend_ps import FigureCanvasPS  # lazy import
                ps = self.switch_backends(FigureCanvasPS)
                ps.print_figure(filename, dpi, facecolor, edgecolor,
                                orientation)
            else:
                raise IOError('Do not know know to handle extension *%s' % ext)

        # restore the original figure properties
        self.figure.dpi.set(origDPI)
        self.figure.set_facecolor(origfacecolor)
        self.figure.set_edgecolor(origedgecolor)
        self.figure.set_canvas(self)
示例#43
0
def rc(group, **kwargs):
    """
    Set the current rc params.  Group is the grouping for the rc, e.g.,
    for ``lines.linewidth`` the group is ``lines``, for
    ``axes.facecolor``, the group is ``axes``, and so on.  Group may
    also be a list or tuple of group names, e.g., (*xtick*, *ytick*).
    *kwargs* is a dictionary attribute name/value pairs, eg::

      rc('lines', linewidth=2, color='r')

    sets the current rc params and is equivalent to::

      rcParams['lines.linewidth'] = 2
      rcParams['lines.color'] = 'r'

    The following aliases are available to save typing for interactive
    users:

    =====   =================
    Alias   Property
    =====   =================
    'lw'    'linewidth'
    'ls'    'linestyle'
    'c'     'color'
    'fc'    'facecolor'
    'ec'    'edgecolor'
    'mew'   'markeredgewidth'
    'aa'    'antialiased'
    =====   =================

    Thus you could abbreviate the above rc command as::

          rc('lines', lw=2, c='r')


    Note you can use python's kwargs dictionary facility to store
    dictionaries of default parameters.  e.g., you can customize the
    font rc as follows::

      font = {'family' : 'monospace',
              'weight' : 'bold',
              'size'   : 'larger'}

      rc('font', **font)  # pass in the font dict as kwargs

    This enables you to easily switch between several configurations.
    Use :func:`~matplotlib.pyplot.rcdefaults` to restore the default
    rc params after changes.
    """

    aliases = {
        'lw'  : 'linewidth',
        'ls'  : 'linestyle',
        'c'   : 'color',
        'fc'  : 'facecolor',
        'ec'  : 'edgecolor',
        'mew' : 'markeredgewidth',
        'aa'  : 'antialiased',
        }

    if is_string_like(group):
        group = (group,)
    for g in group:
        for k, v in six.iteritems(kwargs):
            name = aliases.get(k) or k
            key = '%s.%s' % (g, name)
            try:
                rcParams[key] = v
            except KeyError:
                raise KeyError('Unrecognized key "%s" for group "%s" and name "%s"' %
                               (key, g, name))
示例#44
0
def raise_msg_to_str(msg):
    """msg is a return arg from a raise.  Join with new lines"""
    if not is_string_like(msg):
        msg = '\n'.join(map(str, msg))
    return msg
示例#45
0
def _normalize_font_family(family):
    if is_string_like(family):
        family = [six.text_type(family)]
    elif isinstance(family, Iterable):
        family = [six.text_type(f) for f in family]
    return family
示例#46
0
    def __init__(
        self,
        parent,
        handles,
        labels,
        loc=None,
        numpoints=None,  # the number of points in the legend line
        markerscale=None,  # the relative size of legend markers
        # vs. original
        scatterpoints=3,  # TODO: may be an rcParam
        scatteryoffsets=None,
        prop=None,  # properties for the legend texts
        fontsize=None,  # keyword to set font size directly

        # the following dimensions are in axes coords
        pad=None,  # deprecated; use borderpad
        labelsep=None,  # deprecated; use labelspacing
        handlelen=None,  # deprecated; use handlelength
        handletextsep=None,  # deprecated; use handletextpad
        axespad=None,  # deprecated; use borderaxespad

        # spacing & pad defined as a fraction of the font-size
        borderpad=None,  # the whitespace inside the legend border
        labelspacing=None,  # the vertical space between the legend
        # entries
        handlelength=None,  # the length of the legend handles
        handleheight=None,  # the height of the legend handles
        handletextpad=None,  # the pad between the legend handle
        # and text
        borderaxespad=None,  # the pad between the axes and legend
        # border
        columnspacing=None,  # spacing between columns
        ncol=1,  # number of columns
        mode=None,  # mode for horizontal distribution of columns.
        # None, "expand"
        fancybox=None,  # True use a fancy box, false use a rounded
        # box, none use rc
        shadow=None,
        title=None,  # set a title for the legend
        bbox_to_anchor=None,  # bbox that the legend will be anchored.
        bbox_transform=None,  # transform for the bbox
        frameon=None,  # draw frame
        handler_map=None,
    ):
        """
        - *parent*: the artist that contains the legend
        - *handles*: a list of artists (lines, patches) to be added to the
                      legend
        - *labels*: a list of strings to label the legend

        Optional keyword arguments:

        ================   ====================================================
        Keyword            Description
        ================   ====================================================
        loc                a location code
        prop               the font property
        fontsize           the font size (used only if prop is not specified)
        markerscale        the relative size of legend markers vs. original
        numpoints          the number of points in the legend for line
        scatterpoints      the number of points in the legend for scatter plot
        scatteryoffsets    a list of yoffsets for scatter symbols in legend
        frameon            if True, draw a frame around the legend.
                           If None, use rc
        fancybox           if True, draw a frame with a round fancybox.
                           If None, use rc
        shadow             if True, draw a shadow behind legend
        ncol               number of columns
        borderpad          the fractional whitespace inside the legend border
        labelspacing       the vertical space between the legend entries
        handlelength       the length of the legend handles
        handleheight       the length of the legend handles
        handletextpad      the pad between the legend handle and text
        borderaxespad      the pad between the axes and legend border
        columnspacing      the spacing between columns
        title              the legend title
        bbox_to_anchor     the bbox that the legend will be anchored.
        bbox_transform     the transform for the bbox. transAxes if None.
        ================   ====================================================


        The pad and spacing parameters are measured in font-size units.  E.g.,
        a fontsize of 10 points and a handlelength=5 implies a handlelength of
        50 points.  Values from rcParams will be used if None.

        Users can specify any arbitrary location for the legend using the
        *bbox_to_anchor* keyword argument. bbox_to_anchor can be an instance
        of BboxBase(or its derivatives) or a tuple of 2 or 4 floats.
        See :meth:`set_bbox_to_anchor` for more detail.

        The legend location can be specified by setting *loc* with a tuple of
        2 floats, which is interpreted as the lower-left corner of the legend
        in the normalized axes coordinate.
        """
        # local import only to avoid circularity
        from matplotlib.axes import Axes
        from matplotlib.figure import Figure

        Artist.__init__(self)

        if prop is None:
            if fontsize is not None:
                self.prop = FontProperties(size=fontsize)
            else:
                self.prop = FontProperties(size=rcParams["legend.fontsize"])
        elif isinstance(prop, dict):
            self.prop = FontProperties(**prop)
            if "size" not in prop:
                self.prop.set_size(rcParams["legend.fontsize"])
        else:
            self.prop = prop

        self._fontsize = self.prop.get_size_in_points()

        propnames = [
            "numpoints", "markerscale", "shadow", "columnspacing",
            "scatterpoints", "handleheight"
        ]

        self.texts = []
        self.legendHandles = []
        self._legend_title_box = None

        self._handler_map = handler_map

        localdict = locals()

        for name in propnames:
            if localdict[name] is None:
                value = rcParams["legend." + name]
            else:
                value = localdict[name]
            setattr(self, name, value)

        # Take care the deprecated keywords
        deprecated_kwds = {
            "pad": "borderpad",
            "labelsep": "labelspacing",
            "handlelen": "handlelength",
            "handletextsep": "handletextpad",
            "axespad": "borderaxespad"
        }

        # convert values of deprecated keywords (ginve in axes coords)
        # to new vaules in a fraction of the font size

        # conversion factor
        bbox = parent.bbox
        axessize_fontsize = min(bbox.width, bbox.height) / self._fontsize

        for k, v in deprecated_kwds.iteritems():
            # use deprecated value if not None and if their newer
            # counter part is None.
            if localdict[k] is not None and localdict[v] is None:
                warnings.warn("Use '%s' instead of '%s'." % (v, k),
                              DeprecationWarning)
                setattr(self, v, localdict[k] * axessize_fontsize)
                continue

            # Otherwise, use new keywords
            if localdict[v] is None:
                setattr(self, v, rcParams["legend." + v])
            else:
                setattr(self, v, localdict[v])

        del localdict

        handles = list(handles)
        if len(handles) < 2:
            ncol = 1
        self._ncol = ncol

        if self.numpoints <= 0:
            raise ValueError("numpoints must be > 0; it was %d" % numpoints)

        # introduce y-offset for handles of the scatter plot
        if scatteryoffsets is None:
            self._scatteryoffsets = np.array([3. / 8., 4. / 8., 2.5 / 8.])
        else:
            self._scatteryoffsets = np.asarray(scatteryoffsets)
        reps = int(self.scatterpoints / len(self._scatteryoffsets)) + 1
        self._scatteryoffsets = np.tile(self._scatteryoffsets,
                                        reps)[:self.scatterpoints]

        # _legend_box is an OffsetBox instance that contains all
        # legend items and will be initialized from _init_legend_box()
        # method.
        self._legend_box = None

        if isinstance(parent, Axes):
            self.isaxes = True
            self.set_axes(parent)
            self.set_figure(parent.figure)
        elif isinstance(parent, Figure):
            self.isaxes = False
            self.set_figure(parent)
        else:
            raise TypeError("Legend needs either Axes or Figure as parent")
        self.parent = parent

        if loc is None:
            loc = rcParams["legend.loc"]
            if not self.isaxes and loc in [0, 'best']:
                loc = 'upper right'
        if is_string_like(loc):
            if loc not in self.codes:
                if self.isaxes:
                    warnings.warn('Unrecognized location "%s". Falling back '
                                  'on "best"; valid locations are\n\t%s\n' %
                                  (loc, '\n\t'.join(self.codes.iterkeys())))
                    loc = 0
                else:
                    warnings.warn('Unrecognized location "%s". Falling back '
                                  'on "upper right"; '
                                  'valid locations are\n\t%s\n' %
                                  (loc, '\n\t'.join(self.codes.iterkeys())))
                    loc = 1
            else:
                loc = self.codes[loc]
        if not self.isaxes and loc == 0:
            warnings.warn('Automatic legend placement (loc="best") not '
                          'implemented for figure legend. '
                          'Falling back on "upper right".')
            loc = 1

        self._mode = mode
        self.set_bbox_to_anchor(bbox_to_anchor, bbox_transform)

        # We use FancyBboxPatch to draw a legend frame. The location
        # and size of the box will be updated during the drawing time.

        self.legendPatch = FancyBboxPatch(xy=(0.0, 0.0),
                                          width=1.,
                                          height=1.,
                                          facecolor=rcParams["axes.facecolor"],
                                          edgecolor=rcParams["axes.edgecolor"],
                                          mutation_scale=self._fontsize,
                                          snap=True)

        # The width and height of the legendPatch will be set (in the
        # draw()) to the length that includes the padding. Thus we set
        # pad=0 here.
        if fancybox is None:
            fancybox = rcParams["legend.fancybox"]

        if fancybox:
            self.legendPatch.set_boxstyle("round", pad=0, rounding_size=0.2)
        else:
            self.legendPatch.set_boxstyle("square", pad=0)

        self._set_artist_props(self.legendPatch)

        self._drawFrame = frameon
        if frameon is None:
            self._drawFrame = rcParams["legend.frameon"]

        # init with null renderer
        self._init_legend_box(handles, labels)

        self._loc = loc

        self.set_title(title)

        self._last_fontsize_points = self._fontsize

        self._draggable = None
示例#47
0
    def save(self,
             filename,
             writer=None,
             fps=None,
             dpi=None,
             codec=None,
             bitrate=None,
             extra_args=None,
             metadata=None,
             extra_anim=None):
        '''
        Saves a movie file by drawing every frame.

        *filename* is the output filename, eg :file:`mymovie.mp4`

        *writer* is either an instance of :class:`MovieWriter` or a string
        key that identifies a class to use, such as 'ffmpeg' or 'mencoder'.
        If nothing is passed, the value of the rcparam `animation.writer` is
        used.

        *fps* is the frames per second in the movie. Defaults to None,
        which will use the animation's specified interval to set the frames
        per second.

        *dpi* controls the dots per inch for the movie frames. This combined
        with the figure's size in inches controls the size of the movie.

        *codec* is the video codec to be used. Not all codecs are supported
        by a given :class:`MovieWriter`. If none is given, this defaults to the
        value specified by the rcparam `animation.codec`.

        *bitrate* specifies the amount of bits used per second in the
        compressed movie, in kilobits per second. A higher number means a
        higher quality movie, but at the cost of increased file size. If no
        value is given, this defaults to the value given by the rcparam
        `animation.bitrate`.

        *extra_args* is a list of extra string arguments to be passed to the
        underlying movie utiltiy. The default is None, which passes the
        additional argurments in the 'animation.extra_args' rcParam.

        *metadata* is a dictionary of keys and values for metadata to include
        in the output file. Some keys that may be of use include:
        title, artist, genre, subject, copyright, srcform, comment.

        *extra_anim* is a list of additional `Animation` objects that should
        be included in the saved movie file. These need to be from the same
        `matplotlib.Figure` instance. Also, animation frames will just be
        simply combined, so there should be a 1:1 correspondence between
        the frames from the different animations.
        '''
        # Need to disconnect the first draw callback, since we'll be doing
        # draws. Otherwise, we'll end up starting the animation.
        if self._first_draw_id is not None:
            self._fig.canvas.mpl_disconnect(self._first_draw_id)
            reconnect_first_draw = True
        else:
            reconnect_first_draw = False

        if fps is None and hasattr(self, '_interval'):
            # Convert interval in ms to frames per second
            fps = 1000. / self._interval

        # If the writer is None, use the rc param to find the name of the one
        # to use
        if writer is None:
            writer = rcParams['animation.writer']

        # Re-use the savefig DPI for ours if none is given
        if dpi is None:
            dpi = rcParams['savefig.dpi']

        if codec is None:
            codec = rcParams['animation.codec']

        if bitrate is None:
            bitrate = rcParams['animation.bitrate']

        all_anim = [self]
        if not extra_anim is None:
            all_anim.extend(anim for anim in extra_anim
                            if anim._fig is self._fig)

        # If we have the name of a writer, instantiate an instance of the
        # registered class.
        if is_string_like(writer):
            if writer in writers.avail:
                writer = writers[writer](fps,
                                         codec,
                                         bitrate,
                                         extra_args=extra_args,
                                         metadata=metadata)
            else:
                import warnings
                warnings.warn("MovieWriter %s unavailable" % writer)
                writer = writers.list()[0]

        verbose.report('Animation.save using %s' % type(writer),
                       level='helpful')
        # Create a new sequence of frames for saved data. This is different
        # from new_frame_seq() to give the ability to save 'live' generated
        # frame information to be saved later.
        # TODO: Right now, after closing the figure, saving a movie won't
        # work since GUI widgets are gone. Either need to remove extra code
        # to allow for this non-existant use case or find a way to make it work.
        with writer.saving(self._fig, filename, dpi):
            for data in itertools.izip(
                    *[a.new_saved_frame_seq() for a in all_anim]):
                for anim, d in zip(all_anim, data):
                    #TODO: Need to see if turning off blit is really necessary
                    anim._draw_next_frame(d, blit=False)
                writer.grab_frame()

        # Reconnect signal for first draw if necessary
        if reconnect_first_draw:
            self._first_draw_id = self._fig.canvas.mpl_connect(
                'draw_event', self._start)
示例#48
0
    def pie(self,
            explode=None,
            colors=None,
            autopct=None,
            pctdistance=0.6,
            shadow=False):

        start = time.time()
        labels = self.pdata.getLabels()
        if labels[0][0] == "NoLabels":
            try:
                self.pdata.initialize(key_type='string')
                self.pdata.sortLabels()
                labels = self.pdata.getLabels()
                nLabels = self.pdata.getNumberOfLabels()
                explode = [0.] * nLabels
                if nLabels > 0:
                    explode[0] = 0.1
            except Exception as x:
                print("PieGraph Error: can not interpret data for the plot")

        # labels.reverse()
        values = [l[1] for l in labels]
        x = numpy.array(values, numpy.float64)
        self.legendData = labels

        sx = float(numpy.sum(x))
        if sx > 1:
            x = numpy.divide(x, sx)

        labels = [l[0] for l in labels]
        if explode is None:
            explode = [0] * len(x)
        assert (len(x) == len(labels))
        assert (len(x) == len(explode))
        plot_axis_labels = self.prefs.get('plot_axis_labels', True)

        center = 0, 0
        radius = 1.1
        theta1 = 0
        i = 0
        texts = []
        slices = []
        autotexts = []

        for frac, label, expl in zip(x, labels, explode):
            x, y = center
            theta2 = theta1 + frac
            thetam = 2 * math.pi * 0.5 * (theta1 + theta2)
            x += expl * math.cos(thetam)
            y += expl * math.sin(thetam)
            color = self.palette.getColor(label)
            w = Wedge((x, y),
                      radius,
                      360. * theta1,
                      360. * theta2,
                      facecolor=color,
                      lw=pixelToPoint(0.5, self.dpi),
                      edgecolor='#999999')
            slices.append(w)
            self.ax.add_patch(w)
            w.set_label(label)

            if shadow:
                # make sure to add a shadow after the call to
                # add_patch so the figure and transform props will be
                # set
                shad = Shadow(
                    w,
                    -0.02,
                    -0.02,
                    # props={'facecolor':w.get_facecolor()}
                )
                shad.set_zorder(0.9 * w.get_zorder())
                self.ax.add_patch(shad)

            if plot_axis_labels:
                if frac > 0.03:
                    xt = x + 1.05 * radius * math.cos(thetam)
                    yt = y + 1.05 * radius * math.sin(thetam)

                    thetam %= 2 * math.pi

                    if 0 < thetam and thetam < math.pi:
                        valign = 'bottom'
                    elif thetam == 0 or thetam == math.pi:
                        valign = 'center'
                    else:
                        valign = 'top'

                    if thetam > math.pi / 2.0 and thetam < 3.0 * math.pi / 2.0:
                        halign = 'right'
                    elif thetam == math.pi / 2.0 or thetam == 3.0 * math.pi / 2.0:
                        halign = 'center'
                    else:
                        halign = 'left'

                    t = self.ax.text(xt,
                                     yt,
                                     label,
                                     size=pixelToPoint(
                                         self.prefs['subtitle_size'],
                                         self.dpi),
                                     horizontalalignment=halign,
                                     verticalalignment=valign)

                    t.set_family(self.prefs['font_family'])
                    t.set_fontname(self.prefs['font'])
                    t.set_size(pixelToPoint(self.prefs['text_size'], self.dpi))

                    texts.append(t)

                if autopct is not None:
                    xt = x + pctdistance * radius * math.cos(thetam)
                    yt = y + pctdistance * radius * math.sin(thetam)
                    if is_string_like(autopct):
                        s = autopct % (100. * frac)
                    elif callable(autopct):
                        s = autopct(100. * frac)
                    else:
                        raise TypeError(
                            'autopct must be callable or a format string')

                    t = self.ax.text(xt,
                                     yt,
                                     s,
                                     horizontalalignment='center',
                                     verticalalignment='center')

                    t.set_family(self.prefs['font_family'])
                    t.set_fontname(self.prefs['font'])
                    t.set_size(pixelToPoint(self.prefs['text_size'], self.dpi))

                    autotexts.append(t)

            theta1 = theta2
            i += 1

        self.legendData.reverse()

        self.ax.set_xlim((-1.25, 1.25))
        self.ax.set_ylim((-1.25, 1.25))
        self.ax.set_axis_off()

        if autopct is None:
            return slices, texts
        else:
            return slices, texts, autotexts
示例#49
0
文件: draw.py 项目: sudosurf/mtg
def draw_mtg_labels(G,
                    pos,
                    nodelist=None,
                    labels=None,
                    font_size=12,
                    font_color='k',
                    font_family='sans-serif',
                    font_weight='normal',
                    alpha=1.0,
                    ax=None,
                    **kwds):
    """Draw node labels on the graph G.

    Parameters
    ----------
    G : graph
       A MTG graph

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

    labels : dictionary, optional (default=None)
       Node labels in a dictionary keyed by node of text labels

    font_size : int
       Font size for text labels (default=12)

    font_color : string
       Font color string (default='k' black)

    font_family : string
       Font family (default='sans-serif')

    font_weight : string
       Font weight (default='normal')

    alpha : float
       The text transparency (default=1.0)

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


    Examples
    --------
    >>> G=om.dodecahedral_graph()
    >>> labels=om.draw_mtg_labels(G,pos=om.spring_layout(G))

    Also see the MTG drawing examples at
    gallery.html


    See Also
    --------
    draw()
    draw_mtg()
    draw_mtg_vertices()
    draw_mtg_edges()
    draw_mtg_labels()
    draw_mtg_edge_labels()

    """
    try:
        import matplotlib.pyplot as plt
        import matplotlib.cbook as cb
    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 labels is None:
        if nodelist is None:
            nodelist = G.vertices(scale=G.max_scale())
        labels = dict((n, n) for n in nodelist)

    # set optional alignment
    horizontalalignment = kwds.get('horizontalalignment', 'center')
    verticalalignment = kwds.get('verticalalignment', 'center')

    text_items = {}  # there is no text collection so we'll fake one
    for n, label in labels.items():
        (x, y) = pos[n]
        if not cb.is_string_like(label):
            label = str(
                label)  # this will cause "1" and 1 to be labeled the same
        t = ax.text(
            x,
            y,
            label,
            size=font_size,
            color=font_color,
            family=font_family,
            weight=font_weight,
            horizontalalignment=horizontalalignment,
            verticalalignment=verticalalignment,
            transform=ax.transData,
            clip_on=True,
        )
        text_items[n] = t

    return text_items
示例#50
0
def _is_list_like(obj):
    """Returns whether the obj is iterable and not a string"""
    return not is_string_like(obj) and iterable(obj)
示例#51
0
文件: draw.py 项目: sudosurf/mtg
def draw_mtg_vertices(g,
                      pos,
                      nodelist=None,
                      node_size=300,
                      node_color='r',
                      node_shape='o',
                      alpha=1.0,
                      cmap=None,
                      vmin=None,
                      vmax=None,
                      ax=None,
                      linewidths=None,
                      label=None,
                      **kwds):
    """Draw the nodes of the graph G.

	This draws only the nodes of the graph G.

	Parameters
	----------
	G : graph
		A MTG graph

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

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

	nodelist : list, optional
		Draw only specified nodes (default G.nodes())

	node_size : scalar or array
		Size of nodes (default=300). If an array is specified it must be the
		same length as nodelist.

	node_color : color string, or array of floats
		Node color. Can be a single color format string (default='r'),
		or a sequence of colors with the same length as nodelist.
		If numeric values are specified they will be mapped to
		colors using the cmap and vmin,vmax parameters. See
		matplotlib.scatter for more details.

	node_shape : string
		The shape of the node. Specification is as matplotlib.scatter
		marker, one of 'so^>v<dph8' (default='o').

	alpha : float
		The node transparency (default=1.0)

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

	vmin,vmax : floats
		Minimum and maximum for node colormap scaling (default=None)

	linewidths : [None | scalar | sequence]
		Line width of symbol border (default =1.0)

	label : [None| string]
		Label for legend

	Returns
	-------
	matplotlib.collections.PathCollection
		`PathCollection` of the nodes.

	Examples
	--------
	>>> g = MTG()
	>>> vid = g.add_component(g.root)
	>>> random_tree(g, vid)
	>>> nodes=om.draw_mtg_vertices(G,pos=om.spring_layout(G))


	See Also
	--------
	draw()
	draw_mtg_vertices()
	draw_mtg_edges()
	draw_mtg_labels()
	draw_mtg_edge_labels()
	"""
    try:
        import matplotlib.pyplot as plt
        import matplotlib.cbook as cb
        import numpy
    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 nodelist is None:
        nodelist = g.vertices(scale=g.max_scale())

    if not nodelist or len(nodelist) == 0:  # empty nodelist, no drawing
        return None

    if not cb.is_string_like(node_shape) and cb.iterable(node_shape):
        shapes = list(set(node_shape))
        for sh in shapes:
            sh_index = [i for i, nsh in enumerate(node_shape) if nsh == sh]
            sh_nodelist = [nodelist[i] for i in sh_index]
            sh_node_color = node_color
            if not cb.is_string_like(sh_node_color) and cb.iterable(
                    sh_node_color):
                sh_node_color = [sh_node_color[i] for i in sh_index]
            sh_node_size = node_size
            if not cb.is_string_like(sh_node_size) and cb.iterable(
                    sh_node_size):
                sh_node_size = [sh_node_size[i] for i in sh_index]

            xy = numpy.asarray([pos[v] for v in sh_nodelist])

            node_collection = ax.scatter(xy[:, 0],
                                         xy[:, 1],
                                         s=sh_node_size,
                                         c=sh_node_color,
                                         marker=sh,
                                         cmap=cmap,
                                         vmin=vmin,
                                         vmax=vmax,
                                         alpha=alpha,
                                         linewidths=linewidths,
                                         label=label)

            node_collection.set_zorder(2)
        return node_collection

    # else

    try:
        xy = numpy.asarray([pos[v] for v in nodelist])
    except KeyError as e:
        raise Exception('Node %s has no position.' % e)
    except ValueError:
        raise Exception('Bad value in node positions.')

    node_collection = ax.scatter(xy[:, 0],
                                 xy[:, 1],
                                 s=node_size,
                                 c=node_color,
                                 marker=node_shape,
                                 cmap=cmap,
                                 vmin=vmin,
                                 vmax=vmax,
                                 alpha=alpha,
                                 linewidths=linewidths,
                                 label=label)

    node_collection.set_zorder(2)
    return node_collection
示例#52
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.xaxis.set_scale("log")
                self.ax.yaxis.set_scale("log")
                self.ax._update_transScale()
                self.cbar_axis.set_minor_locator(ticker.NullLocator())
                formatter = ticker.LogFormatter()
            else:
                formatter = None
        elif cbook.is_string_like(format):
            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('')
    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()
示例#54
0
def imread(fname, format=None):
    """
    Read an image from a file into an array.

    *fname* may be a string path, a valid URL, or a Python
    file-like object.  If using a file object, it must be opened in binary
    mode.

    If *format* is provided, will try to read file of that type,
    otherwise the format is deduced from the filename.  If nothing can
    be deduced, PNG is tried.

    Return value is a :class:`numpy.array`.  For grayscale images, the
    return array is MxN.  For RGB images, the return value is MxNx3.
    For RGBA images the return value is MxNx4.

    matplotlib can only read PNGs natively, but if `PIL
    <http://www.pythonware.com/products/pil/>`_ is installed, it will
    use it to load the image and return an array (if possible) which
    can be used with :func:`~matplotlib.pyplot.imshow`. Note, URL strings
    may not be compatible with PIL. Check the PIL documentation for more
    information.
    """
    def pilread(fname):
        """try to load the image with PIL or return None"""
        try:
            from PIL import Image
        except ImportError:
            return None
        with Image.open(fname) as image:
            return pil_to_array(image)

    handlers = {
        'png': _png.read_png,
    }
    if format is None:
        if cbook.is_string_like(fname):
            parsed = urlparse(fname)
            # If the string is a URL, assume png
            if len(parsed.scheme) > 1:
                ext = 'png'
            else:
                basename, ext = os.path.splitext(fname)
                ext = ext.lower()[1:]
        elif hasattr(fname, 'name'):
            basename, ext = os.path.splitext(fname.name)
            ext = ext.lower()[1:]
        else:
            ext = 'png'
    else:
        ext = format

    if ext not in handlers:
        im = pilread(fname)
        if im is None:
            raise ValueError('Only know how to handle extensions: %s; '
                             'with Pillow installed matplotlib can handle '
                             'more images' % list(handlers))
        return im

    handler = handlers[ext]

    # To handle Unicode filenames, we pass a file object to the PNG
    # reader extension, since Python handles them quite well, but it's
    # tricky in C.
    if cbook.is_string_like(fname):
        parsed = urlparse(fname)
        # If fname is a URL, download the data
        if len(parsed.scheme) > 1:
            fd = BytesIO(urlopen(fname).read())
            return handler(fd)
        else:
            with open(fname, 'rb') as fd:
                return handler(fd)
    else:
        return handler(fname)
示例#55
0
 def set_location(self, loc):
     if is_string_like(loc):
         if loc not in self._LOCATIONS:
             raise ValueError('Unknown location code: %s' % loc)
         loc = self._LOCATIONS[loc]
     self._location = loc
示例#56
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.
       Positions should be sequences of length 2.

    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

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

    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.github.io/documentation/latest/gallery.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
        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 = plt.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()

    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
示例#57
0
def draw_networkx_labels(G,
                         pos,
                         labels=None,
                         font_size=12,
                         font_color='k',
                         font_family='sans-serif',
                         font_weight='normal',
                         alpha=1.0,
                         ax=None,
                         **kwds):
    """Draw node labels on 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.

    labels : dictionary, optional (default=None)
       Node labels in a dictionary keyed by node of text labels

    font_size : int
       Font size for text labels (default=12)

    font_color : string
       Font color string (default='k' black)

    font_family : string
       Font family (default='sans-serif')

    font_weight : string
       Font weight (default='normal')

    alpha : float
       The text transparency (default=1.0)

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

    Returns
    -------
    dict
        `dict` of labels keyed on the nodes

    Examples
    --------
    >>> G=nx.dodecahedral_graph()
    >>> labels=nx.draw_networkx_labels(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_edges()
    draw_networkx_edge_labels()
    """
    try:
        import matplotlib.pyplot as plt
        import matplotlib.cbook as cb
    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 labels is None:
        labels = dict((n, n) for n in G.nodes())

    # set optional alignment
    horizontalalignment = kwds.get('horizontalalignment', 'center')
    verticalalignment = kwds.get('verticalalignment', 'center')

    text_items = {}  # there is no text collection so we'll fake one
    for n, label in labels.items():
        (x, y) = pos[n]
        if not cb.is_string_like(label):
            label = str(
                label)  # this will cause "1" and 1 to be labeled the same
        t = ax.text(
            x,
            y,
            label,
            size=font_size,
            color=font_color,
            family=font_family,
            weight=font_weight,
            horizontalalignment=horizontalalignment,
            verticalalignment=verticalalignment,
            transform=ax.transData,
            clip_on=True,
        )
        text_items[n] = t

    return text_items
示例#58
0
def draw_networkx_edge_labels(G,
                              pos,
                              edge_labels=None,
                              label_pos=0.5,
                              font_size=10,
                              font_color='k',
                              font_family='sans-serif',
                              font_weight='normal',
                              alpha=1.0,
                              bbox=None,
                              ax=None,
                              rotate=True,
                              **kwds):
    """Draw edge labels.

    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.

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

    alpha : float
       The text transparency (default=1.0)

    edge_labels : dictionary
       Edge labels in a dictionary keyed by edge two-tuple of text
       labels (default=None). Only labels for the keys in the dictionary
       are drawn.

    label_pos : float
       Position of edge label along edge (0=head, 0.5=center, 1=tail)

    font_size : int
       Font size for text labels (default=12)

    font_color : string
       Font color string (default='k' black)

    font_weight : string
       Font weight (default='normal')

    font_family : string
       Font family (default='sans-serif')

    bbox : Matplotlib bbox
       Specify text box shape and colors.

    clip_on : bool
       Turn on clipping at axis boundaries (default=True)

    Returns
    -------
    dict
        `dict` of labels keyed on the edges

    Examples
    --------
    >>> G=nx.dodecahedral_graph()
    >>> edge_labels=nx.draw_networkx_edge_labels(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_edges()
    draw_networkx_labels()
    """
    try:
        import matplotlib.pyplot as plt
        import matplotlib.cbook as cb
        import numpy
    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 edge_labels is None:
        labels = dict(((u, v), d) for u, v, d in G.edges(data=True))
    else:
        labels = edge_labels
    text_items = {}
    for (n1, n2), label in labels.items():
        (x1, y1) = pos[n1]
        (x2, y2) = pos[n2]
        (x, y) = (x1 * label_pos + x2 * (1.0 - label_pos),
                  y1 * label_pos + y2 * (1.0 - label_pos))

        if rotate:
            angle = numpy.arctan2(y2 - y1,
                                  x2 - x1) / (2.0 * numpy.pi) * 360  # degrees
            # make label orientation "right-side-up"
            if angle > 90:
                angle -= 180
            if angle < -90:
                angle += 180
            # transform data coordinate angle to screen coordinate angle
            xy = numpy.array((x, y))
            trans_angle = ax.transData.transform_angles(
                numpy.array((angle, )), xy.reshape((1, 2)))[0]
        else:
            trans_angle = 0.0
        # use default box of white with white border
        if bbox is None:
            bbox = dict(
                boxstyle='round',
                ec=(1.0, 1.0, 1.0),
                fc=(1.0, 1.0, 1.0),
            )
        if not cb.is_string_like(label):
            label = str(
                label)  # this will cause "1" and 1 to be labeled the same

        # set optional alignment
        horizontalalignment = kwds.get('horizontalalignment', 'center')
        verticalalignment = kwds.get('verticalalignment', 'center')

        t = ax.text(
            x,
            y,
            label,
            size=font_size,
            color=font_color,
            family=font_family,
            weight=font_weight,
            horizontalalignment=horizontalalignment,
            verticalalignment=verticalalignment,
            rotation=trans_angle,
            transform=ax.transData,
            bbox=bbox,
            zorder=1,
            clip_on=True,
        )
        text_items[(n1, n2)] = t

    return text_items
示例#59
0
def error_msg_qt(msg, parent=None):
    if not is_string_like(msg):
        msg = ','.join(map(str, msg))

    QtWidgets.QMessageBox.warning(None, "Matplotlib", msg,
                                  QtGui.QMessageBox.Ok)
示例#60
0
 def get_text(self, lev, fmt):
     "get the text of the label"
     if cbook.is_string_like(lev):
         return lev
     else:
         return fmt%lev