def __init__(self, frame, sec=None, jd=None, daynum=None, dt=None): """Create a new Epoch object. Build an epoch 1 of 2 ways: Using seconds past a Julian date: # Epoch( 'ET', sec=1e8, jd=2451545 ) or using a matplotlib day number # Epoch( 'ET', daynum=730119.5 ) = ERROR CONDITIONS - If the input units are not in the allowed list, an error is thrown. = INPUT VARIABLES - frame The frame of the epoch. Must be 'ET' or 'UTC' - sec The number of seconds past the input JD. - jd The Julian date of the epoch. - daynum The matplotlib day number of the epoch. - dt A python datetime instance. """ if ((sec is None and jd is not None) or (sec is not None and jd is None) or (daynum is not None and (sec is not None or jd is not None)) or (daynum is None and dt is None and (sec is None or jd is None)) or (daynum is not None and dt is not None) or (dt is not None and (sec is not None or jd is not None)) or ((dt is not None) and not isinstance(dt, DT.datetime))): msg = "Invalid inputs. Must enter sec and jd together, " \ "daynum by itself, or dt (must be a python datetime).\n" \ "Sec = %s\nJD = %s\ndnum= %s\ndt = %s" \ % ( str( sec ), str( jd ), str( daynum ), str( dt ) ) raise ValueError(msg) if frame not in self.allowed: msg = "Input frame '%s' is not one of the supported frames of %s" \ % ( frame, str( list(six.iterkeys(self.allowed) ) ) ) raise ValueError(msg) self._frame = frame if dt is not None: daynum = date2num(dt) if daynum is not None: # 1-JAN-0001 in JD = 1721425.5 jd = float(daynum) + 1721425.5 self._jd = math.floor(jd) self._seconds = (jd - self._jd) * 86400.0 else: self._seconds = float(sec) self._jd = float(jd) # Resolve seconds down to [ 0, 86400 ) deltaDays = int(math.floor(self._seconds / 86400.0)) self._jd += deltaDays self._seconds -= deltaDays * 86400.0
def test_Bug_2543(): # Test that it possible to add all values to itself / deepcopy # This was not possible because validate_bool_maybe_none did not # accept None as an argument. # https://github.com/matplotlib/matplotlib/issues/2543 # We filter warnings at this stage since a number of them are raised # for deprecated rcparams as they should. We dont want these in the # printed in the test suite. with warnings.catch_warnings(): warnings.filterwarnings('ignore', message='.*(deprecated|obsolete)', category=UserWarning) with mpl.rc_context(): _copy = mpl.rcParams.copy() for key in six.iterkeys(_copy): mpl.rcParams[key] = _copy[key] mpl.rcParams['text.dvipnghack'] = None with mpl.rc_context(): from copy import deepcopy _deep_copy = deepcopy(mpl.rcParams) # real test is that this does not raise assert_true(validate_bool_maybe_none(None) is None) assert_true(validate_bool_maybe_none("none") is None) _fonttype = mpl.rcParams['svg.fonttype'] assert_true(_fonttype == mpl.rcParams['svg.embed_char_paths']) with mpl.rc_context(): mpl.rcParams['svg.embed_char_paths'] = False assert_true(mpl.rcParams['svg.fonttype'] == "none")
def validate_fonttype(s): """ confirm that this is a Postscript of PDF font type that we know how to convert to """ fonttypes = {"type3": 3, "truetype": 42} try: fonttype = validate_int(s) except ValueError: if s.lower() in six.iterkeys(fonttypes): return fonttypes[s.lower()] raise ValueError("Supported Postscript/PDF font types are %s" % list(six.iterkeys(fonttypes))) else: if fonttype not in six.itervalues(fonttypes): raise ValueError("Supported Postscript/PDF font types are %s" % list(six.itervalues(fonttypes))) return fonttype
def __init__(self, ax, loc=None, bbox=None, **kwargs): Artist.__init__(self) if is_string_like(loc) and loc not in self.codes: warnings.warn('Unrecognized location %s. Falling back on ' 'bottom; valid locations are\n%s\t' % (loc, '\n\t'.join(six.iterkeys(self.codes)))) loc = 'bottom' if is_string_like(loc): loc = self.codes.get(loc, 1) self.set_figure(ax.figure) self._axes = ax self._loc = loc self._bbox = bbox # use axes coords self.set_transform(ax.transAxes) self._texts = [] self._cells = {} self._edges = None self._autoRows = [] self._autoColumns = [] self._autoFontsize = True self.update(kwargs) self.set_clip_on(False) self._cachedRenderer = None
def get_legend_handler(legend_handler_map, orig_handle): """ return a legend handler from *legend_handler_map* that corresponds to *orig_handler*. *legend_handler_map* should be a dictionary object (that is returned by the get_legend_handler_map method). It first checks if the *orig_handle* itself is a key in the *legend_hanler_map* and return the associated value. Otherwise, it checks for each of the classes in its method-resolution-order. If no matching key is found, it returns None. """ legend_handler_keys = list(six.iterkeys(legend_handler_map)) if orig_handle in legend_handler_keys: handler = legend_handler_map[orig_handle] else: for handle_type in type(orig_handle).mro(): if handle_type in legend_handler_map: handler = legend_handler_map[handle_type] break else: handler = None return handler
def comparable_formats(): """ Returns the list of file formats that compare_images can compare on this system. """ return ['png'] + list(six.iterkeys(converter))
def __init__( self, frame, sec=None, jd=None, daynum=None, dt=None ): """Create a new Epoch object. Build an epoch 1 of 2 ways: Using seconds past a Julian date: # Epoch( 'ET', sec=1e8, jd=2451545 ) or using a matplotlib day number # Epoch( 'ET', daynum=730119.5 ) = ERROR CONDITIONS - If the input units are not in the allowed list, an error is thrown. = INPUT VARIABLES - frame The frame of the epoch. Must be 'ET' or 'UTC' - sec The number of seconds past the input JD. - jd The Julian date of the epoch. - daynum The matplotlib day number of the epoch. - dt A python datetime instance. """ if ( ( sec is None and jd is not None ) or ( sec is not None and jd is None ) or ( daynum is not None and ( sec is not None or jd is not None ) ) or ( daynum is None and dt is None and ( sec is None or jd is None ) ) or ( daynum is not None and dt is not None ) or ( dt is not None and ( sec is not None or jd is not None ) ) or ( (dt is not None) and not isinstance(dt, DT.datetime) ) ): msg = "Invalid inputs. Must enter sec and jd together, " \ "daynum by itself, or dt (must be a python datetime).\n" \ "Sec = %s\nJD = %s\ndnum= %s\ndt = %s" \ % ( str( sec ), str( jd ), str( daynum ), str( dt ) ) raise ValueError( msg ) if frame not in self.allowed: msg = "Input frame '%s' is not one of the supported frames of %s" \ % ( frame, str( list(six.iterkeys(self.allowed) ) ) ) raise ValueError(msg) self._frame = frame if dt is not None: daynum = date2num( dt ) if daynum is not None: # 1-JAN-0001 in JD = 1721425.5 jd = float( daynum ) + 1721425.5 self._jd = math.floor( jd ) self._seconds = ( jd - self._jd ) * 86400.0 else: self._seconds = float( sec ) self._jd = float( jd ) # Resolve seconds down to [ 0, 86400 ) deltaDays = int( math.floor( self._seconds / 86400.0 ) ) self._jd += deltaDays self._seconds -= deltaDays * 86400.0
def get_projection_names(self): """ Get a list of the names of all projections currently registered. """ names = list(six.iterkeys(self._all_projection_types)) names.sort() return names
def validate_fonttype(s): """ confirm that this is a Postscript of PDF font type that we know how to convert to """ fonttypes = {'type3': 3, 'truetype': 42} try: fonttype = validate_int(s) except ValueError: if s.lower() in six.iterkeys(fonttypes): return fonttypes[s.lower()] raise ValueError('Supported Postscript/PDF font types are %s' % list(six.iterkeys(fonttypes))) else: if fonttype not in six.itervalues(fonttypes): raise ValueError('Supported Postscript/PDF font types are %s' % list(six.itervalues(fonttypes))) return fonttype
def _get_grid_bbox(self, renderer): """Get a bbox, in axes co-ordinates for the cells. Only include those in the range (0,0) to (maxRow, maxCol)""" boxes = [self._cells[pos].get_window_extent(renderer) for pos in six.iterkeys(self._cells) if pos[0] >= 0 and pos[1] >= 0] bbox = Bbox.union(boxes) return bbox.inverse_transformed(self.get_transform())
def test_colormap_reversing(): """Check the generated _lut data of a colormap and corresponding reversed colormap if they are almost the same.""" for name in six.iterkeys(cm.cmap_d): cmap = plt.get_cmap(name) cmap_r = cmap.reversed() if not cmap_r._isinit: cmap._init() cmap_r._init() assert_array_almost_equal(cmap._lut[:-3], cmap_r._lut[-4::-1])
def __init__(self, scale, tfm, texname, vf): if six.PY3 and isinstance(texname, bytes): texname = texname.decode('ascii') self._scale, self._tfm, self.texname, self._vf = \ scale, tfm, texname, vf self.size = scale * (72.0 / (72.27 * 2**16)) try: nchars = max(six.iterkeys(tfm.width)) + 1 except ValueError: nchars = 0 self.widths = [(1000 * tfm.width.get(char, 0)) >> 20 for char in xrange(nchars)]
def __init__(self, scale, tfm, texname, vf): if six.PY3 and isinstance(texname, bytes): texname = texname.decode('ascii') self._scale, self._tfm, self.texname, self._vf = \ scale, tfm, texname, vf self.size = scale * (72.0 / (72.27 * 2**16)) try: nchars = max(six.iterkeys(tfm.width)) + 1 except ValueError: nchars = 0 self.widths = [(1000*tfm.width.get(char, 0)) >> 20 for char in xrange(nchars)]
def checkUnits( self, units ): """Check to see if some units are valid. = ERROR CONDITIONS - If the input units are not in the allowed list, an error is thrown. = INPUT VARIABLES - units The string name of the units to check. """ if units not in self.allowed: msg = "Input units '%s' are not one of the supported types of %s" \ % ( units, str( list(six.iterkeys(self.allowed)) ) ) raise ValueError( msg )
def checkUnits(self, units): """Check to see if some units are valid. = ERROR CONDITIONS - If the input units are not in the allowed list, an error is thrown. = INPUT VARIABLES - units The string name of the units to check. """ if units not in self.allowed: msg = "Input units '%s' are not one of the supported types of %s" \ % ( units, str( list(six.iterkeys(self.allowed)) ) ) raise ValueError(msg)
def test_RcParams_class(): rc = mpl.RcParams({ 'font.cursive': ['Apple Chancery', 'Textile', 'Zapf Chancery', 'cursive'], 'font.family': 'sans-serif', 'font.weight': 'normal', 'font.size': 12 }) if six.PY3: expected_repr = """ RcParams({'font.cursive': ['Apple Chancery', 'Textile', 'Zapf Chancery', 'cursive'], 'font.family': ['sans-serif'], 'font.size': 12.0, 'font.weight': 'normal'})""".lstrip() else: expected_repr = """ RcParams({u'font.cursive': [u'Apple Chancery', u'Textile', u'Zapf Chancery', u'cursive'], u'font.family': [u'sans-serif'], u'font.size': 12.0, u'font.weight': u'normal'})""".lstrip() assert_str_equal(expected_repr, repr(rc)) if six.PY3: expected_str = """ font.cursive: ['Apple Chancery', 'Textile', 'Zapf Chancery', 'cursive'] font.family: ['sans-serif'] font.size: 12.0 font.weight: normal""".lstrip() else: expected_str = """ font.cursive: [u'Apple Chancery', u'Textile', u'Zapf Chancery', u'cursive'] font.family: [u'sans-serif'] font.size: 12.0 font.weight: normal""".lstrip() assert_str_equal(expected_str, str(rc)) # test the find_all functionality assert ['font.cursive', 'font.size'] == sorted(rc.find_all('i[vz]').keys()) assert ['font.family'] == list(six.iterkeys(rc.find_all('family')))
def aliased_name(self, s): """ return 'PROPNAME or alias' if *s* has an alias, else return PROPNAME. e.g., for the line markerfacecolor property, which has an alias, return 'markerfacecolor or mfc' and for the transform property, which does not, return 'transform' """ if s in self.aliasd: return s + "".join([" or %s" % x for x in six.iterkeys(self.aliasd[s])]) else: return s
def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None): if not len(path.vertices): return writer = self.writer path_data = self._convert_path(marker_path, marker_trans + Affine2D().scale(1.0, -1.0), simplify=False) style = self._get_style_dict(gc, rgbFace) dictkey = (path_data, generate_css(style)) oid = self._markers.get(dictkey) for key in list(six.iterkeys(style)): if not key.startswith('stroke'): del style[key] style = generate_css(style) if oid is None: oid = self._make_id('m', dictkey) writer.start('defs') writer.element('path', id=oid, d=path_data, style=style) writer.end('defs') self._markers[dictkey] = oid attrib = {} clipid = self._get_clip(gc) if clipid is not None: attrib['clip-path'] = 'url(#%s)' % clipid writer.start('g', attrib=attrib) trans_and_flip = self._make_flip_transform(trans) attrib = {'xlink:href': '#%s' % oid} clip = (0, 0, self.width * 72, self.height * 72) for vertices, code in path.iter_segments(trans_and_flip, clip=clip, simplify=False): if len(vertices): x, y = vertices[-2:] attrib['x'] = short_float_fmt(x) attrib['y'] = short_float_fmt(y) attrib['style'] = self._get_style(gc, rgbFace) writer.element('use', attrib=attrib) writer.end('g')
def test_RcParams_class(): rc = mpl.RcParams( { "font.cursive": ["Apple Chancery", "Textile", "Zapf Chancery", "cursive"], "font.family": "sans-serif", "font.weight": "normal", "font.size": 12, } ) if six.PY3: expected_repr = """ RcParams({'font.cursive': ['Apple Chancery', 'Textile', 'Zapf Chancery', 'cursive'], 'font.family': ['sans-serif'], 'font.size': 12.0, 'font.weight': 'normal'})""".lstrip() else: expected_repr = """ RcParams({u'font.cursive': [u'Apple Chancery', u'Textile', u'Zapf Chancery', u'cursive'], u'font.family': [u'sans-serif'], u'font.size': 12.0, u'font.weight': u'normal'})""".lstrip() assert_str_equal(expected_repr, repr(rc)) if six.PY3: expected_str = """ font.cursive: ['Apple Chancery', 'Textile', 'Zapf Chancery', 'cursive'] font.family: ['sans-serif'] font.size: 12.0 font.weight: normal""".lstrip() else: expected_str = """ font.cursive: [u'Apple Chancery', u'Textile', u'Zapf Chancery', u'cursive'] font.family: [u'sans-serif'] font.size: 12.0 font.weight: normal""".lstrip() assert_str_equal(expected_str, str(rc)) # test the find_all functionality assert ["font.cursive", "font.size"] == sorted(rc.find_all("i[vz]").keys()) assert ["font.family"] == list(six.iterkeys(rc.find_all("family")))
def _do_cell_alignment(self): """ Calculate row heights and column widths. Position cells accordingly. """ # Calculate row/column widths widths = {} heights = {} for (row, col), cell in six.iteritems(self._cells): height = heights.setdefault(row, 0.0) heights[row] = max(height, cell.get_height()) width = widths.setdefault(col, 0.0) widths[col] = max(width, cell.get_width()) # work out left position for each column xpos = 0 lefts = {} cols = list(six.iterkeys(widths)) cols.sort() for col in cols: lefts[col] = xpos xpos += widths[col] ypos = 0 bottoms = {} rows = list(six.iterkeys(heights)) rows.sort() rows.reverse() for row in rows: bottoms[row] = ypos ypos += heights[row] # set cell positions for (row, col), cell in six.iteritems(self._cells): cell.set_x(lefts[col]) cell.set_y(bottoms[row])
def aliased_name_rest(self, s, target): """ return 'PROPNAME or alias' if *s* has an alias, else return PROPNAME formatted for ReST e.g., for the line markerfacecolor property, which has an alias, return 'markerfacecolor or mfc' and for the transform property, which does not, return 'transform' """ if s in self.aliasd: aliases = "".join([" or %s" % x for x in six.iterkeys(self.aliasd[s])]) else: aliases = "" return ":meth:`%s <%s>`%s" % (s, target, aliases)
def aliased_name(self, s): """ return 'PROPNAME or alias' if *s* has an alias, else return PROPNAME. e.g., for the line markerfacecolor property, which has an alias, return 'markerfacecolor or mfc' and for the transform property, which does not, return 'transform' """ if s in self.aliasd: return s + ''.join( [' or %s' % x for x in six.iterkeys(self.aliasd[s])]) else: return s
def aliased_name_rest(self, s, target): """ return 'PROPNAME or alias' if *s* has an alias, else return PROPNAME formatted for ReST e.g., for the line markerfacecolor property, which has an alias, return 'markerfacecolor or mfc' and for the transform property, which does not, return 'transform' """ if s in self.aliasd: aliases = ''.join( [' or %s' % x for x in six.iterkeys(self.aliasd[s])]) else: aliases = '' return ':meth:`%s <%s>`%s' % (s, target, aliases)
def win32InstalledFonts(directory=None, fontext='ttf'): """ Search for fonts in the specified font directory, or use the system directories if none given. A list of TrueType font filenames are returned by default, or AFM fonts if *fontext* == 'afm'. """ from matplotlib.externals.six.moves import winreg if directory is None: directory = win32FontDirectory() fontext = get_fontext_synonyms(fontext) key, items = None, {} for fontdir in MSFontDirectories: try: local = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, fontdir) except OSError: continue if not local: return list_fonts(directory, fontext) try: for j in range(winreg.QueryInfoKey(local)[1]): try: key, direc, any = winreg.EnumValue( local, j) if not is_string_like(direc): continue if not os.path.dirname(direc): direc = os.path.join(directory, direc) direc = direc.split('\0', 1)[0] # direc = os.path.abspath(direc).lower() if os.path.splitext(direc)[1][1:] in fontext: items[direc] = 1 except EnvironmentError: continue except WindowsError: continue except MemoryError: continue return list(six.iterkeys(items)) finally: winreg.CloseKey(local) return None
def win32InstalledFonts(directory=None, fontext="ttf"): """ Search for fonts in the specified font directory, or use the system directories if none given. A list of TrueType font filenames are returned by default, or AFM fonts if *fontext* == 'afm'. """ from matplotlib.externals.six.moves import winreg if directory is None: directory = win32FontDirectory() fontext = get_fontext_synonyms(fontext) key, items = None, {} for fontdir in MSFontDirectories: try: local = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, fontdir) except OSError: continue if not local: return list_fonts(directory, fontext) try: for j in range(winreg.QueryInfoKey(local)[1]): try: key, direc, any = winreg.EnumValue(local, j) if not is_string_like(direc): continue if not os.path.dirname(direc): direc = os.path.join(directory, direc) direc = os.path.abspath(direc).lower() if os.path.splitext(direc)[1][1:] in fontext: items[direc] = 1 except EnvironmentError: continue except WindowsError: continue except MemoryError: continue return list(six.iterkeys(items)) finally: winreg.CloseKey(local) return None
def contains(self, mouseevent): """Test whether the mouse event occurred in the table. Returns T/F, {} """ if six.callable(self._contains): return self._contains(self, mouseevent) # TODO: Return index of the cell containing the cursor so that the user # doesn't have to bind to each one individually. if self._cachedRenderer is not None: boxes = [self._cells[pos].get_window_extent(self._cachedRenderer) for pos in six.iterkeys(self._cells) if pos[0] >= 0 and pos[1] >= 0] bbox = Bbox.union(boxes) return bbox.contains(mouseevent.x, mouseevent.y), {} else: return False, {}
def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None): if not len(path.vertices): return writer = self.writer path_data = self._convert_path( marker_path, marker_trans + Affine2D().scale(1.0, -1.0), simplify=False) style = self._get_style_dict(gc, rgbFace) dictkey = (path_data, generate_css(style)) oid = self._markers.get(dictkey) for key in list(six.iterkeys(style)): if not key.startswith('stroke'): del style[key] style = generate_css(style) if oid is None: oid = self._make_id('m', dictkey) writer.start('defs') writer.element('path', id=oid, d=path_data, style=style) writer.end('defs') self._markers[dictkey] = oid attrib = {} clipid = self._get_clip(gc) if clipid is not None: attrib['clip-path'] = 'url(#%s)' % clipid writer.start('g', attrib=attrib) trans_and_flip = self._make_flip_transform(trans) attrib = {'xlink:href': '#%s' % oid} clip = (0, 0, self.width*72, self.height*72) for vertices, code in path.iter_segments( trans_and_flip, clip=clip, simplify=False): if len(vertices): x, y = vertices[-2:] attrib['x'] = short_float_fmt(x) attrib['y'] = short_float_fmt(y) attrib['style'] = self._get_style(gc, rgbFace) writer.element('use', attrib=attrib) writer.end('g')
def findSystemFonts(fontpaths=None, fontext='ttf'): """ Search for fonts in the specified font paths. If no paths are given, will use a standard set of system paths, as well as the list of fonts tracked by fontconfig if fontconfig is installed and available. A list of TrueType fonts are returned by default with AFM fonts as an option. """ fontfiles = {} fontexts = get_fontext_synonyms(fontext) if fontpaths is None: if sys.platform == 'win32': fontdir = win32FontDirectory() fontpaths = [fontdir] # now get all installed fonts directly... for f in win32InstalledFonts(fontdir): base, ext = os.path.splitext(f) if len(ext) > 1 and ext[1:].lower() in fontexts: fontfiles[f] = 1 else: fontpaths = X11FontDirectories # check for OS X & load its fonts if present if sys.platform == 'darwin': for f in OSXInstalledFonts(fontext=fontext): fontfiles[f] = 1 for f in get_fontconfig_fonts(fontext): fontfiles[f] = 1 elif isinstance(fontpaths, six.string_types): fontpaths = [fontpaths] for path in fontpaths: files = list_fonts(path, fontexts) for fname in files: fontfiles[os.path.abspath(fname)] = 1 return [ fname for fname in six.iterkeys(fontfiles) if os.path.exists(fname) ]
def pprint_getters(self): """ Return the getters and actual values as list of strings. """ d = self.properties() names = list(six.iterkeys(d)) names.sort() lines = [] for name in names: val = d[name] if getattr(val, "shape", ()) != () and len(val) > 6: s = str(val[:6]) + "..." else: s = str(val) s = s.replace("\n", " ") if len(s) > 50: s = s[:50] + "..." name = self.aliased_name(name) lines.append(" %s = %s" % (name, s)) return lines
def pprint_getters(self): """ Return the getters and actual values as list of strings. """ d = self.properties() names = list(six.iterkeys(d)) names.sort() lines = [] for name in names: val = d[name] if getattr(val, 'shape', ()) != () and len(val) > 6: s = str(val[:6]) + '...' else: s = str(val) s = s.replace('\n', ' ') if len(s) > 50: s = s[:50] + '...' name = self.aliased_name(name) lines.append(' %s = %s' % (name, s)) return lines
def findSystemFonts(fontpaths=None, fontext='ttf'): """ Search for fonts in the specified font paths. If no paths are given, will use a standard set of system paths, as well as the list of fonts tracked by fontconfig if fontconfig is installed and available. A list of TrueType fonts are returned by default with AFM fonts as an option. """ fontfiles = {} fontexts = get_fontext_synonyms(fontext) if fontpaths is None: if sys.platform == 'win32': fontdir = win32FontDirectory() fontpaths = [fontdir] # now get all installed fonts directly... for f in win32InstalledFonts(fontdir): base, ext = os.path.splitext(f) if len(ext)>1 and ext[1:].lower() in fontexts: fontfiles[f] = 1 else: fontpaths = X11FontDirectories # check for OS X & load its fonts if present if sys.platform == 'darwin': for f in OSXInstalledFonts(fontext=fontext): fontfiles[f] = 1 for f in get_fontconfig_fonts(fontext): fontfiles[f] = 1 elif isinstance(fontpaths, six.string_types): fontpaths = [fontpaths] for path in fontpaths: files = list_fonts(path, fontexts) for fname in files: fontfiles[os.path.abspath(fname)] = 1 return [fname for fname in six.iterkeys(fontfiles) if os.path.exists(fname)]
def draw(self, renderer): # Need a renderer to do hit tests on mouseevent; assume the last one # will do if renderer is None: renderer = self._cachedRenderer if renderer is None: raise RuntimeError('No renderer defined') self._cachedRenderer = renderer if not self.get_visible(): return renderer.open_group('table') self._update_positions(renderer) keys = list(six.iterkeys(self._cells)) keys.sort() for key in keys: self._cells[key].draw(renderer) # for c in self._cells.itervalues(): # c.draw(renderer) renderer.close_group('table') self.stale = False
def _fast_from_codes_and_verts(cls, verts, codes, internals=None): """ Creates a Path instance without the expense of calling the constructor Parameters ---------- verts : numpy array codes : numpy array internals : dict or None The attributes that the resulting path should have. Allowed keys are ``readonly``, ``should_simplify``, ``simplify_threshold``, ``has_nonfinite`` and ``interpolation_steps``. """ internals = internals or {} pth = cls.__new__(cls) if ma.isMaskedArray(verts): verts = verts.astype(np.float_).filled(np.nan) else: verts = np.asarray(verts, np.float_) pth._vertices = verts pth._codes = codes pth._readonly = internals.pop('readonly', False) pth.should_simplify = internals.pop('should_simplify', True) pth.simplify_threshold = ( internals.pop('simplify_threshold', rcParams['path.simplify_threshold']) ) pth._has_nonfinite = internals.pop('has_nonfinite', False) pth._interpolation_steps = internals.pop('interpolation_steps', 1) if internals: raise ValueError('Unexpected internals provided to ' '_fast_from_codes_and_verts: ' '{0}'.format('\n *'.join(six.iterkeys( internals )))) return pth
def get_scale_names(): names = list(six.iterkeys(_scale_mapping)) names.sort() return names
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, 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, displace=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 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. displace the legend posistion will be anchored ================ ==================================================== 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 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. if rcParams["legend.facecolor"] == 'inherit': facecolor = rcParams["axes.facecolor"] else: facecolor = rcParams["legend.facecolor"] if rcParams["legend.edgecolor"] == 'inherit': edgecolor = rcParams["axes.edgecolor"] else: edgecolor = rcParams["legend.edgecolor"] self.legendPatch = FancyBboxPatch(xy=(0.0, 0.0), width=1., height=1., facecolor=facecolor, edgecolor=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 if displace is not None: self.set_displace(displace)
def __iter__(self): return six.iterkeys(self.weak_key_dict)
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(six.iterkeys(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)
class Line2D(Artist): """ A line - the line can have both a solid linestyle connecting all the vertices, and a marker at each vertex. Additionally, the drawing of the solid line is influenced by the drawstyle, e.g., one can create "stepped" lines in various styles. """ lineStyles = _lineStyles = { # hidden names deprecated '-': '_draw_solid', '--': '_draw_dashed', '-.': '_draw_dash_dot', ':': '_draw_dotted', 'None': '_draw_nothing', ' ': '_draw_nothing', '': '_draw_nothing', } _drawStyles_l = { 'default': '_draw_lines', 'steps-mid': '_draw_steps_mid', 'steps-pre': '_draw_steps_pre', 'steps-post': '_draw_steps_post', } _drawStyles_s = { 'steps': '_draw_steps_pre', } drawStyles = {} drawStyles.update(_drawStyles_l) drawStyles.update(_drawStyles_s) # Need a list ordered with long names first: drawStyleKeys = (list(six.iterkeys(_drawStyles_l)) + list(six.iterkeys(_drawStyles_s))) # Referenced here to maintain API. These are defined in # MarkerStyle markers = MarkerStyle.markers filled_markers = MarkerStyle.filled_markers fillStyles = MarkerStyle.fillstyles zorder = 2 validCap = ('butt', 'round', 'projecting') validJoin = ('miter', 'round', 'bevel') def __str__(self): if self._label != "": return "Line2D(%s)" % (self._label) elif hasattr(self, '_x') and len(self._x) > 3: return "Line2D((%g,%g),(%g,%g),...,(%g,%g))"\ % (self._x[0], self._y[0], self._x[0], self._y[0], self._x[-1], self._y[-1]) elif hasattr(self, '_x'): return "Line2D(%s)"\ % (",".join(["(%g,%g)" % (x, y) for x, y in zip(self._x, self._y)])) else: return "Line2D()" def __init__( self, xdata, ydata, linewidth=None, # all Nones default to rc linestyle=None, color=None, marker=None, markersize=None, markeredgewidth=None, markeredgecolor=None, markerfacecolor=None, markerfacecoloralt='none', fillstyle=None, antialiased=None, dash_capstyle=None, solid_capstyle=None, dash_joinstyle=None, solid_joinstyle=None, pickradius=5, drawstyle=None, markevery=None, **kwargs): """ Create a :class:`~matplotlib.lines.Line2D` instance with *x* and *y* data in sequences *xdata*, *ydata*. The kwargs are :class:`~matplotlib.lines.Line2D` properties: %(Line2D)s See :meth:`set_linestyle` for a decription of the line styles, :meth:`set_marker` for a description of the markers, and :meth:`set_drawstyle` for a description of the draw styles. """ Artist.__init__(self) #convert sequences to numpy arrays if not iterable(xdata): raise RuntimeError('xdata must be a sequence') if not iterable(ydata): raise RuntimeError('ydata must be a sequence') if linewidth is None: linewidth = rcParams['lines.linewidth'] if linestyle is None: linestyle = rcParams['lines.linestyle'] if marker is None: marker = rcParams['lines.marker'] if color is None: color = rcParams['lines.color'] if markersize is None: markersize = rcParams['lines.markersize'] if antialiased is None: antialiased = rcParams['lines.antialiased'] if dash_capstyle is None: dash_capstyle = rcParams['lines.dash_capstyle'] if dash_joinstyle is None: dash_joinstyle = rcParams['lines.dash_joinstyle'] if solid_capstyle is None: solid_capstyle = rcParams['lines.solid_capstyle'] if solid_joinstyle is None: solid_joinstyle = rcParams['lines.solid_joinstyle'] if drawstyle is None: drawstyle = 'default' self._dashcapstyle = None self._dashjoinstyle = None self._solidjoinstyle = None self._solidcapstyle = None self.set_dash_capstyle(dash_capstyle) self.set_dash_joinstyle(dash_joinstyle) self.set_solid_capstyle(solid_capstyle) self.set_solid_joinstyle(solid_joinstyle) self._linestyles = None self._drawstyle = None self._linewidth = None self.set_linestyle(linestyle) self.set_drawstyle(drawstyle) self.set_linewidth(linewidth) self._color = None self.set_color(color) self._marker = MarkerStyle() self.set_marker(marker) self._markevery = None self._markersize = None self._antialiased = None self.set_markevery(markevery) self.set_antialiased(antialiased) self.set_markersize(markersize) self._dashSeq = None self._markeredgecolor = None self._markeredgewidth = None self._markerfacecolor = None self._markerfacecoloralt = None self.set_markerfacecolor(markerfacecolor) self.set_markerfacecoloralt(markerfacecoloralt) self.set_markeredgecolor(markeredgecolor) self.set_markeredgewidth(markeredgewidth) self.set_fillstyle(fillstyle) self.verticalOffset = None # update kwargs before updating data to give the caller a # chance to init axes (and hence unit support) self.update(kwargs) self.pickradius = pickradius self.ind_offset = 0 if is_numlike(self._picker): self.pickradius = self._picker self._xorig = np.asarray([]) self._yorig = np.asarray([]) self._invalidx = True self._invalidy = True self.set_data(xdata, ydata) def __getstate__(self): state = super(Line2D, self).__getstate__() # _linefunc will be restored on draw time. state.pop('_lineFunc', None) return state def contains(self, mouseevent): """ Test whether the mouse event occurred on the line. The pick radius determines the precision of the location test (usually within five points of the value). Use :meth:`~matplotlib.lines.Line2D.get_pickradius` or :meth:`~matplotlib.lines.Line2D.set_pickradius` to view or modify it. Returns *True* if any values are within the radius along with ``{'ind': pointlist}``, where *pointlist* is the set of points within the radius. TODO: sort returned indices by distance """ if six.callable(self._contains): return self._contains(self, mouseevent) if not is_numlike(self.pickradius): raise ValueError("pick radius should be a distance") # Make sure we have data to plot if self._invalidy or self._invalidx: self.recache() if len(self._xy) == 0: return False, {} # Convert points to pixels transformed_path = self._get_transformed_path() path, affine = transformed_path.get_transformed_path_and_affine() path = affine.transform_path(path) xy = path.vertices xt = xy[:, 0] yt = xy[:, 1] # Convert pick radius from points to pixels if self.figure is None: warnings.warn('no figure set when check if mouse is on line') pixels = self.pickradius else: pixels = self.figure.dpi / 72. * self.pickradius # the math involved in checking for containment (here and inside of # segment_hits) assumes that it is OK to overflow. In case the # application has set the error flags such that an exception is raised # on overflow, we temporarily set the appropriate error flags here and # set them back when we are finished. olderrflags = np.seterr(all='ignore') try: # Check for collision if self._linestyle in ['None', None]: # If no line, return the nearby point(s) d = (xt - mouseevent.x)**2 + (yt - mouseevent.y)**2 ind, = np.nonzero(np.less_equal(d, pixels**2)) else: # If line, return the nearby segment(s) ind = segment_hits(mouseevent.x, mouseevent.y, xt, yt, pixels) finally: np.seterr(**olderrflags) ind += self.ind_offset # Debugging message if False and self._label != '': print("Checking line", self._label, "at", mouseevent.x, mouseevent.y) print('xt', xt) print('yt', yt) #print 'dx,dy', (xt-mouseevent.x)**2., (yt-mouseevent.y)**2. print('ind', ind) # Return the point(s) within radius return len(ind) > 0, dict(ind=ind) def get_pickradius(self): """return the pick radius used for containment tests""" return self.pickradius def set_pickradius(self, d): """Sets the pick radius used for containment tests ACCEPTS: float distance in points """ self.pickradius = d def get_fillstyle(self): """ return the marker fillstyle """ return self._marker.get_fillstyle() def set_fillstyle(self, fs): """ Set the marker fill style; 'full' means fill the whole marker. 'none' means no filling; other options are for half-filled markers. ACCEPTS: ['full' | 'left' | 'right' | 'bottom' | 'top' | 'none'] """ self._marker.set_fillstyle(fs) self.stale = True def set_markevery(self, every): """Set the markevery property to subsample the plot when using markers. e.g., if `every=5`, every 5-th marker will be plotted. ACCEPTS: [None | int | length-2 tuple of int | slice | list/array of int | float | length-2 tuple of float] Parameters ---------- every: None | int | length-2 tuple of int | slice | list/array of int | float | length-2 tuple of float Which markers to plot. - every=None, every point will be plotted. - every=N, every N-th marker will be plotted starting with marker 0. - every=(start, N), every N-th marker, starting at point start, will be plotted. - every=slice(start, end, N), every N-th marker, starting at point start, upto but not including point end, will be plotted. - every=[i, j, m, n], only markers at points i, j, m, and n will be plotted. - every=0.1, (i.e. a float) then markers will be spaced at approximately equal distances along the line; the distance along the line between markers is determined by multiplying the display-coordinate distance of the axes bounding-box diagonal by the value of every. - every=(0.5, 0.1) (i.e. a length-2 tuple of float), the same functionality as every=0.1 is exhibited but the first marker will be 0.5 multiplied by the display-cordinate-diagonal-distance along the line. Notes ----- Setting the markevery property will only show markers at actual data points. When using float arguments to set the markevery property on irregularly spaced data, the markers will likely not appear evenly spaced because the actual data points do not coincide with the theoretical spacing between markers. When using a start offset to specify the first marker, the offset will be from the first data point which may be different from the first the visible data point if the plot is zoomed in. If zooming in on a plot when using float arguments then the actual data points that have markers will change because the distance between markers is always determined from the display-coordinates axes-bounding-box-diagonal regardless of the actual axes data limits. """ if self._markevery != every: self.stale = True self._markevery = every def get_markevery(self): """return the markevery setting""" return self._markevery def set_picker(self, p): """Sets the event picker details for the line. ACCEPTS: float distance in points or callable pick function ``fn(artist, event)`` """ if six.callable(p): self._contains = p else: self.pickradius = p self._picker = p def get_window_extent(self, renderer): bbox = Bbox([[0, 0], [0, 0]]) trans_data_to_xy = self.get_transform().transform bbox.update_from_data_xy(trans_data_to_xy(self.get_xydata()), ignore=True) # correct for marker size, if any if self._marker: ms = (self._markersize / 72.0 * self.figure.dpi) * 0.5 bbox = bbox.padded(ms) return bbox @Artist.axes.setter def axes(self, ax): # call the set method from the base-class property Artist.axes.fset(self, ax) # connect unit-related callbacks if ax.xaxis is not None: self._xcid = ax.xaxis.callbacks.connect('units', self.recache_always) if ax.yaxis is not None: self._ycid = ax.yaxis.callbacks.connect('units', self.recache_always) def set_data(self, *args): """ Set the x and y data ACCEPTS: 2D array (rows are x, y) or two 1D arrays """ if len(args) == 1: x, y = args[0] else: x, y = args self.set_xdata(x) self.set_ydata(y) def recache_always(self): self.recache(always=True) def recache(self, always=False): if always or self._invalidx: xconv = self.convert_xunits(self._xorig) if ma.isMaskedArray(self._xorig): x = ma.asarray(xconv, np.float_) else: x = np.asarray(xconv, np.float_) x = x.ravel() else: x = self._x if always or self._invalidy: yconv = self.convert_yunits(self._yorig) if ma.isMaskedArray(self._yorig): y = ma.asarray(yconv, np.float_) else: y = np.asarray(yconv, np.float_) y = y.ravel() else: y = self._y if len(x) == 1 and len(y) > 1: x = x * np.ones(y.shape, np.float_) if len(y) == 1 and len(x) > 1: y = y * np.ones(x.shape, np.float_) if len(x) != len(y): raise RuntimeError('xdata and ydata must be the same length') x = x.reshape((len(x), 1)) y = y.reshape((len(y), 1)) if ma.isMaskedArray(x) or ma.isMaskedArray(y): self._xy = ma.concatenate((x, y), 1) else: self._xy = np.concatenate((x, y), 1) self._x = self._xy[:, 0] # just a view self._y = self._xy[:, 1] # just a view self._subslice = False if (self.axes and len(x) > 100 and self._is_sorted(x) and self.axes.name == 'rectilinear' and self.axes.get_xscale() == 'linear' and self._markevery is None and self.get_clip_on() is True): self._subslice = True if hasattr(self, '_path'): interpolation_steps = self._path._interpolation_steps else: interpolation_steps = 1 self._path = Path(self._xy, None, interpolation_steps) self._transformed_path = None self._invalidx = False self._invalidy = False def _transform_path(self, subslice=None): """ Puts a TransformedPath instance at self._transformed_path, all invalidation of the transform is then handled by the TransformedPath instance. """ # Masked arrays are now handled by the Path class itself if subslice is not None: _path = Path(self._xy[subslice, :]) else: _path = self._path self._transformed_path = TransformedPath(_path, self.get_transform()) def _get_transformed_path(self): """ Return the :class:`~matplotlib.transforms.TransformedPath` instance of this line. """ if self._transformed_path is None: self._transform_path() return self._transformed_path def set_transform(self, t): """ set the Transformation instance used by this artist ACCEPTS: a :class:`matplotlib.transforms.Transform` instance """ Artist.set_transform(self, t) self._invalidx = True self._invalidy = True self.stale = True def _is_sorted(self, x): """return true if x is sorted""" if len(x) < 2: return 1 return np.amin(x[1:] - x[0:-1]) >= 0 @allow_rasterization def draw(self, renderer): """draw the Line with `renderer` unless visibility is False""" if not self.get_visible(): return if self._invalidy or self._invalidx: self.recache() self.ind_offset = 0 # Needed for contains() method. if self._subslice and self.axes: # Need to handle monotonically decreasing case also... x0, x1 = self.axes.get_xbound() i0, = self._x.searchsorted([x0], 'left') i1, = self._x.searchsorted([x1], 'right') subslice = slice(max(i0 - 1, 0), i1 + 1) self.ind_offset = subslice.start self._transform_path(subslice) transf_path = self._get_transformed_path() if self.get_path_effects(): from matplotlib.patheffects import PathEffectRenderer renderer = PathEffectRenderer(self.get_path_effects(), renderer) renderer.open_group('line2d', self.get_gid()) funcname = self._lineStyles.get(self._linestyle, '_draw_nothing') if funcname != '_draw_nothing': tpath, affine = transf_path.get_transformed_path_and_affine() if len(tpath.vertices): self._lineFunc = getattr(self, funcname) funcname = self.drawStyles.get(self._drawstyle, '_draw_lines') drawFunc = getattr(self, funcname) gc = renderer.new_gc() self._set_gc_clip(gc) ln_color_rgba = self._get_rgba_ln_color() gc.set_foreground(ln_color_rgba, isRGBA=True) gc.set_alpha(ln_color_rgba[3]) gc.set_antialiased(self._antialiased) gc.set_linewidth(self._linewidth) if self.is_dashed(): cap = self._dashcapstyle join = self._dashjoinstyle else: cap = self._solidcapstyle join = self._solidjoinstyle gc.set_joinstyle(join) gc.set_capstyle(cap) gc.set_snap(self.get_snap()) if self.get_sketch_params() is not None: gc.set_sketch_params(*self.get_sketch_params()) drawFunc(renderer, gc, tpath, affine.frozen()) gc.restore() if self._marker: gc = renderer.new_gc() self._set_gc_clip(gc) rgbaFace = self._get_rgba_face() rgbaFaceAlt = self._get_rgba_face(alt=True) edgecolor = self.get_markeredgecolor() if is_string_like(edgecolor) and edgecolor.lower() == 'none': gc.set_linewidth(0) gc.set_foreground(rgbaFace, isRGBA=True) else: gc.set_foreground(edgecolor) gc.set_linewidth(self._markeredgewidth) mec = self._markeredgecolor if (is_string_like(mec) and mec == 'auto' and rgbaFace is not None): gc.set_alpha(rgbaFace[3]) else: gc.set_alpha(self.get_alpha()) marker = self._marker tpath, affine = transf_path.get_transformed_points_and_affine() if len(tpath.vertices): # subsample the markers if markevery is not None markevery = self.get_markevery() if markevery is not None: subsampled = _mark_every_path(markevery, tpath, affine, self.axes.transAxes) else: subsampled = tpath snap = marker.get_snap_threshold() if type(snap) == float: snap = renderer.points_to_pixels(self._markersize) >= snap gc.set_snap(snap) gc.set_joinstyle(marker.get_joinstyle()) gc.set_capstyle(marker.get_capstyle()) marker_path = marker.get_path() marker_trans = marker.get_transform() w = renderer.points_to_pixels(self._markersize) if marker.get_marker() != ',': # Don't scale for pixels, and don't stroke them marker_trans = marker_trans.scale(w) else: gc.set_linewidth(0) renderer.draw_markers(gc, marker_path, marker_trans, subsampled, affine.frozen(), rgbaFace) alt_marker_path = marker.get_alt_path() if alt_marker_path: alt_marker_trans = marker.get_alt_transform() alt_marker_trans = alt_marker_trans.scale(w) if (is_string_like(mec) and mec == 'auto' and rgbaFaceAlt is not None): gc.set_alpha(rgbaFaceAlt[3]) else: gc.set_alpha(self.get_alpha()) renderer.draw_markers(gc, alt_marker_path, alt_marker_trans, subsampled, affine.frozen(), rgbaFaceAlt) gc.restore() renderer.close_group('line2d') self.stale = False def get_antialiased(self): return self._antialiased def get_color(self): return self._color def get_drawstyle(self): return self._drawstyle def get_linestyle(self): return self._linestyle def get_linewidth(self): return self._linewidth def get_marker(self): return self._marker.get_marker() def get_markeredgecolor(self): mec = self._markeredgecolor if (is_string_like(mec) and mec == 'auto'): if self._marker.get_marker() in ('.', ','): return self._color if self._marker.is_filled() and self.get_fillstyle() != 'none': return 'k' # Bad hard-wired default... else: return self._color else: return mec def get_markeredgewidth(self): return self._markeredgewidth def _get_markerfacecolor(self, alt=False): if alt: fc = self._markerfacecoloralt else: fc = self._markerfacecolor if (is_string_like(fc) and fc.lower() == 'auto'): if self.get_fillstyle() == 'none': return 'none' else: return self._color else: return fc def get_markerfacecolor(self): return self._get_markerfacecolor(alt=False) def get_markerfacecoloralt(self): return self._get_markerfacecolor(alt=True) def get_markersize(self): return self._markersize def get_data(self, orig=True): """ Return the xdata, ydata. If *orig* is *True*, return the original data. """ return self.get_xdata(orig=orig), self.get_ydata(orig=orig) def get_xdata(self, orig=True): """ Return the xdata. If *orig* is *True*, return the original data, else the processed data. """ if orig: return self._xorig if self._invalidx: self.recache() return self._x def get_ydata(self, orig=True): """ Return the ydata. If *orig* is *True*, return the original data, else the processed data. """ if orig: return self._yorig if self._invalidy: self.recache() return self._y def get_path(self): """ Return the :class:`~matplotlib.path.Path` object associated with this line. """ if self._invalidy or self._invalidx: self.recache() return self._path def get_xydata(self): """ Return the *xy* data as a Nx2 numpy array. """ if self._invalidy or self._invalidx: self.recache() return self._xy def set_antialiased(self, b): """ True if line should be drawin with antialiased rendering ACCEPTS: [True | False] """ if self._antialiased != b: self.stale = True self._antialiased = b def set_color(self, color): """ Set the color of the line ACCEPTS: any matplotlib color """ if color != self._color: self.stale = True self._color = color def set_drawstyle(self, drawstyle): """ Set the drawstyle of the plot 'default' connects the points with lines. The steps variants produce step-plots. 'steps' is equivalent to 'steps-pre' and is maintained for backward-compatibility. ACCEPTS: ['default' | 'steps' | 'steps-pre' | 'steps-mid' | 'steps-post'] """ if self._drawstyle != drawstyle: self.stale = True self._drawstyle = drawstyle def set_linewidth(self, w): """ Set the line width in points ACCEPTS: float value in points """ w = float(w) if self._linewidth != w: self.stale = True self._linewidth = w def set_linestyle(self, ls): """ Set the linestyle of the line (also accepts drawstyles, e.g., ``'steps--'``) =========================== ================= linestyle description =========================== ================= ``'-'`` or ``'solid'`` solid line ``'--'`` or ``'dashed'`` dashed line ``'-.'`` or ``'dash_dot'`` dash-dotted line ``':'`` or ``'dotted'`` dotted line ``'None'`` draw nothing ``' '`` draw nothing ``''`` draw nothing =========================== ================= 'steps' is equivalent to 'steps-pre' and is maintained for backward-compatibility. Alternatively a dash tuple of the following form can be provided:: (offset, onoffseq), where ``onoffseq`` is an even length tuple of on and off ink in points. ACCEPTS: ['solid' | 'dashed', 'dashdot', 'dotted' | (offset, on-off-dash-seq) | ``'-'`` | ``'--'`` | ``'-.'`` | ``':'`` | ``'None'`` | ``' '`` | ``''``] .. seealso:: :meth:`set_drawstyle` To set the drawing style (stepping) of the plot. Parameters ---------- ls : { '-', '--', '-.', ':'} and more see description The line style. """ if not is_string_like(ls): if len(ls) != 2: raise ValueError() self.set_dashes(ls[1]) self._linestyle = "--" return for ds in self.drawStyleKeys: # long names are first in the list if ls.startswith(ds): self.set_drawstyle(ds) if len(ls) > len(ds): ls = ls[len(ds):] else: ls = '-' break if ls in [' ', '', 'none']: ls = 'None' if ls not in self._lineStyles: try: ls = ls_mapper_r[ls] except KeyError: raise ValueError(("You passed in an invalid linestyle, " "`{}`. See " "docs of Line2D.set_linestyle for " "valid values.").format(ls)) self._linestyle = ls @docstring.dedent_interpd def set_marker(self, marker): """ Set the line marker ACCEPTS: :mod:`A valid marker style <matplotlib.markers>` Parameters ----------- marker: marker style See `~matplotlib.markers` for full description of possible argument """ self._marker.set_marker(marker) self.stale = True def set_markeredgecolor(self, ec): """ Set the marker edge color ACCEPTS: any matplotlib color """ if ec is None: ec = 'auto' if self._markeredgecolor != ec: self.stale = True self._markeredgecolor = ec def set_markeredgewidth(self, ew): """ Set the marker edge width in points ACCEPTS: float value in points """ if ew is None: ew = rcParams['lines.markeredgewidth'] if self._markeredgewidth != ew: self.stale = True self._markeredgewidth = ew def set_markerfacecolor(self, fc): """ Set the marker face color. ACCEPTS: any matplotlib color """ if fc is None: fc = 'auto' if self._markerfacecolor != fc: self.stale = True self._markerfacecolor = fc def set_markerfacecoloralt(self, fc): """ Set the alternate marker face color. ACCEPTS: any matplotlib color """ if fc is None: fc = 'auto' if self._markerfacecoloralt != fc: self.stale = True self._markerfacecoloralt = fc def set_markersize(self, sz): """ Set the marker size in points ACCEPTS: float """ sz = float(sz) if self._markersize != sz: self.stale = True self._markersize = sz def set_xdata(self, x): """ Set the data np.array for x ACCEPTS: 1D array """ self._xorig = x self._invalidx = True self.stale = True def set_ydata(self, y): """ Set the data np.array for y ACCEPTS: 1D array """ self._yorig = y self._invalidy = True self.stale = True def set_dashes(self, seq): """ Set the dash sequence, sequence of dashes with on off ink in points. If seq is empty or if seq = (None, None), the linestyle will be set to solid. ACCEPTS: sequence of on/off ink in points """ if seq == (None, None) or len(seq) == 0: self.set_linestyle('-') else: self.set_linestyle('--') if self._dashSeq != seq: self.stale = True self._dashSeq = seq # TODO: offset ignored for now def _draw_lines(self, renderer, gc, path, trans): self._lineFunc(renderer, gc, path, trans) def _draw_steps_pre(self, renderer, gc, path, trans): vertices = self._xy steps = ma.zeros((2 * len(vertices) - 1, 2), np.float_) steps[0::2, 0], steps[1::2, 0] = vertices[:, 0], vertices[:-1, 0] steps[0::2, 1], steps[1:-1:2, 1] = vertices[:, 1], vertices[1:, 1] path = Path(steps) path = path.transformed(self.get_transform()) self._lineFunc(renderer, gc, path, IdentityTransform()) def _draw_steps_post(self, renderer, gc, path, trans): vertices = self._xy steps = ma.zeros((2 * len(vertices) - 1, 2), np.float_) steps[::2, 0], steps[1:-1:2, 0] = vertices[:, 0], vertices[1:, 0] steps[0::2, 1], steps[1::2, 1] = vertices[:, 1], vertices[:-1, 1] path = Path(steps) path = path.transformed(self.get_transform()) self._lineFunc(renderer, gc, path, IdentityTransform()) def _draw_steps_mid(self, renderer, gc, path, trans): vertices = self._xy steps = ma.zeros((2 * len(vertices), 2), np.float_) steps[1:-1:2, 0] = 0.5 * (vertices[:-1, 0] + vertices[1:, 0]) steps[2::2, 0] = 0.5 * (vertices[:-1, 0] + vertices[1:, 0]) steps[0, 0] = vertices[0, 0] steps[-1, 0] = vertices[-1, 0] steps[0::2, 1], steps[1::2, 1] = vertices[:, 1], vertices[:, 1] path = Path(steps) path = path.transformed(self.get_transform()) self._lineFunc(renderer, gc, path, IdentityTransform()) def _draw_solid(self, renderer, gc, path, trans): gc.set_linestyle('solid') renderer.draw_path(gc, path, trans) def _draw_dashed(self, renderer, gc, path, trans): gc.set_linestyle('dashed') if self._dashSeq is not None: gc.set_dashes(0, self._dashSeq) renderer.draw_path(gc, path, trans) def _draw_dash_dot(self, renderer, gc, path, trans): gc.set_linestyle('dashdot') renderer.draw_path(gc, path, trans) def _draw_dotted(self, renderer, gc, path, trans): gc.set_linestyle('dotted') renderer.draw_path(gc, path, trans) def update_from(self, other): """copy properties from other to self""" Artist.update_from(self, other) self._linestyle = other._linestyle self._linewidth = other._linewidth self._color = other._color self._markersize = other._markersize self._markerfacecolor = other._markerfacecolor self._markerfacecoloralt = other._markerfacecoloralt self._markeredgecolor = other._markeredgecolor self._markeredgewidth = other._markeredgewidth self._dashSeq = other._dashSeq self._dashcapstyle = other._dashcapstyle self._dashjoinstyle = other._dashjoinstyle self._solidcapstyle = other._solidcapstyle self._solidjoinstyle = other._solidjoinstyle self._linestyle = other._linestyle self._marker = MarkerStyle(other._marker.get_marker(), other._marker.get_fillstyle()) self._drawstyle = other._drawstyle def _get_rgb_face(self, alt=False): facecolor = self._get_markerfacecolor(alt=alt) if is_string_like(facecolor) and facecolor.lower() == 'none': rgbFace = None else: rgbFace = colorConverter.to_rgb(facecolor) return rgbFace def _get_rgba_face(self, alt=False): facecolor = self._get_markerfacecolor(alt=alt) if is_string_like(facecolor) and facecolor.lower() == 'none': rgbaFace = None else: rgbaFace = colorConverter.to_rgba(facecolor, self._alpha) return rgbaFace def _get_rgba_ln_color(self, alt=False): return colorConverter.to_rgba(self._color, self._alpha) # some aliases.... def set_aa(self, val): 'alias for set_antialiased' self.set_antialiased(val) def set_c(self, val): 'alias for set_color' self.set_color(val) def set_ls(self, val): """alias for set_linestyle""" self.set_linestyle(val) def set_lw(self, val): """alias for set_linewidth""" self.set_linewidth(val) def set_mec(self, val): """alias for set_markeredgecolor""" self.set_markeredgecolor(val) def set_mew(self, val): """alias for set_markeredgewidth""" self.set_markeredgewidth(val) def set_mfc(self, val): """alias for set_markerfacecolor""" self.set_markerfacecolor(val) def set_mfcalt(self, val): """alias for set_markerfacecoloralt""" self.set_markerfacecoloralt(val) def set_ms(self, val): """alias for set_markersize""" self.set_markersize(val) def get_aa(self): """alias for get_antialiased""" return self.get_antialiased() def get_c(self): """alias for get_color""" return self.get_color() def get_ls(self): """alias for get_linestyle""" return self.get_linestyle() def get_lw(self): """alias for get_linewidth""" return self.get_linewidth() def get_mec(self): """alias for get_markeredgecolor""" return self.get_markeredgecolor() def get_mew(self): """alias for get_markeredgewidth""" return self.get_markeredgewidth() def get_mfc(self): """alias for get_markerfacecolor""" return self.get_markerfacecolor() def get_mfcalt(self, alt=False): """alias for get_markerfacecoloralt""" return self.get_markerfacecoloralt() def get_ms(self): """alias for get_markersize""" return self.get_markersize() def set_dash_joinstyle(self, s): """ Set the join style for dashed linestyles ACCEPTS: ['miter' | 'round' | 'bevel'] """ s = s.lower() if s not in self.validJoin: raise ValueError('set_dash_joinstyle passed "%s";\n' % (s, ) + 'valid joinstyles are %s' % (self.validJoin, )) if self._dashjoinstyle != s: self.stale = True self._dashjoinstyle = s def set_solid_joinstyle(self, s): """ Set the join style for solid linestyles ACCEPTS: ['miter' | 'round' | 'bevel'] """ s = s.lower() if s not in self.validJoin: raise ValueError('set_solid_joinstyle passed "%s";\n' % (s, ) + 'valid joinstyles are %s' % (self.validJoin, )) if self._solidjoinstyle != s: self.stale = True self._solidjoinstyle = s def get_dash_joinstyle(self): """ Get the join style for dashed linestyles """ return self._dashjoinstyle def get_solid_joinstyle(self): """ Get the join style for solid linestyles """ return self._solidjoinstyle def set_dash_capstyle(self, s): """ Set the cap style for dashed linestyles ACCEPTS: ['butt' | 'round' | 'projecting'] """ s = s.lower() if s not in self.validCap: raise ValueError('set_dash_capstyle passed "%s";\n' % (s, ) + 'valid capstyles are %s' % (self.validCap, )) if self._dashcapstyle != s: self.stale = True self._dashcapstyle = s def set_solid_capstyle(self, s): """ Set the cap style for solid linestyles ACCEPTS: ['butt' | 'round' | 'projecting'] """ s = s.lower() if s not in self.validCap: raise ValueError('set_solid_capstyle passed "%s";\n' % (s, ) + 'valid capstyles are %s' % (self.validCap, )) if self._solidcapstyle != s: self.stale = True self._solidcapstyle = s def get_dash_capstyle(self): """ Get the cap style for dashed linestyles """ return self._dashcapstyle def get_solid_capstyle(self): """ Get the cap style for solid linestyles """ return self._solidcapstyle def is_dashed(self): 'return True if line is dashstyle' return self._linestyle in ('--', '-.', ':')
# store the old values before overriding plugins = [] plugins.append(KnownFailure()) plugins.extend([plugin() for plugin in nose.plugins.builtin.plugins]) manager = PluginManager(plugins=plugins) config = nose.config.Config(verbosity=verbosity, plugins=manager) # Nose doesn't automatically instantiate all of the plugins in the # child processes, so we have to provide the multiprocess plugin with # a list. multiprocess._instantiate_plugins = [KnownFailure] success = nose.run( defaultTest=default_test_modules, config=config, ) finally: if old_backend.lower() != 'agg': use(old_backend) return success test.__test__ = False # nose: this function is not a test verbose.report('matplotlib version %s' % __version__) verbose.report('verbose.level %s' % verbose.level) verbose.report('interactive is %s' % is_interactive()) verbose.report('platform is %s' % sys.platform) verbose.report('loaded modules: %s' % six.iterkeys(sys.modules), 'debug')
def _generate_cmap(name, lutsize): """Generates the requested cmap from it's name *name*. The lut size is *lutsize*.""" spec = datad[name] # Generate the colormap object. if 'red' in spec: return colors.LinearSegmentedColormap(name, spec, lutsize) else: return colors.LinearSegmentedColormap.from_list(name, spec, lutsize) LUTSIZE = mpl.rcParams['image.lut'] # Generate the reversed specifications ... for cmapname in list(six.iterkeys(datad)): spec = datad[cmapname] spec_reversed = _reverse_cmap_spec(spec) datad[cmapname + '_r'] = spec_reversed # Precache the cmaps with ``lutsize = LUTSIZE`` ... # Use datad.keys() to also add the reversed ones added in the section above: for cmapname in six.iterkeys(datad): cmap_d[cmapname] = _generate_cmap(cmapname, LUTSIZE) locals().update(cmap_d) # Continue with definitions ...
plugins = [] plugins.append(KnownFailure()) plugins.extend([plugin() for plugin in nose.plugins.builtin.plugins]) manager = PluginManager(plugins=plugins) config = nose.config.Config(verbosity=verbosity, plugins=manager) # Nose doesn't automatically instantiate all of the plugins in the # child processes, so we have to provide the multiprocess plugin with # a list. multiprocess._instantiate_plugins = [KnownFailure] success = nose.run( defaultTest=default_test_modules, config=config, ) finally: if old_backend.lower() != 'agg': use(old_backend) return success test.__test__ = False # nose: this function is not a test verbose.report('matplotlib version %s' % __version__) verbose.report('verbose.level %s' % verbose.level) verbose.report('interactive is %s' % is_interactive()) verbose.report('platform is %s' % sys.platform) verbose.report('loaded modules: %s' % six.iterkeys(sys.modules), 'debug')
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, 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, displace=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 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. displace the legend posistion will be anchored ================ ==================================================== 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 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. if rcParams["legend.facecolor"] == 'inherit': facecolor = rcParams["axes.facecolor"] else: facecolor = rcParams["legend.facecolor"] if rcParams["legend.edgecolor"] == 'inherit': edgecolor = rcParams["axes.edgecolor"] else: edgecolor = rcParams["legend.edgecolor"] self.legendPatch = FancyBboxPatch( xy=(0.0, 0.0), width=1., height=1., facecolor=facecolor, edgecolor=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 if displace is not None: self.set_displace(displace)
'spline36': _image.SPLINE36, 'hanning': _image.HANNING, 'hamming': _image.HAMMING, 'hermite': _image.HERMITE, 'kaiser': _image.KAISER, 'quadric': _image.QUADRIC, 'catrom': _image.CATROM, 'gaussian': _image.GAUSSIAN, 'bessel': _image.BESSEL, 'mitchell': _image.MITCHELL, 'sinc': _image.SINC, 'lanczos': _image.LANCZOS, 'blackman': _image.BLACKMAN, } interpolations_names = set(six.iterkeys(_interpd_)) def composite_images(images, renderer, magnification=1.0): """ Composite a number of RGBA images into one. The images are composited in the order in which they appear in the `images` list. Parameters ---------- images : list of Images Each must have a `make_image` method. For each image, `can_composite` should return `True`, though this is not enforced by this function. Each image must have a purely affine transformation with no shear.
def ttfFontProperty(font): """ A function for populating the :class:`FontKey` by extracting information from the TrueType font file. *font* is a :class:`FT2Font` instance. """ name = font.family_name # Styles are: italic, oblique, and normal (default) sfnt = font.get_sfnt() sfnt2 = sfnt.get((1, 0, 0, 2)) sfnt4 = sfnt.get((1, 0, 0, 4)) if sfnt2: sfnt2 = sfnt2.decode('macroman').lower() else: sfnt2 = '' if sfnt4: sfnt4 = sfnt4.decode('macroman').lower() else: sfnt4 = '' if sfnt4.find('oblique') >= 0: style = 'oblique' elif sfnt4.find('italic') >= 0: style = 'italic' elif sfnt2.find('regular') >= 0: style = 'normal' elif font.style_flags & ft2font.ITALIC: style = 'italic' else: style = 'normal' # Variants are: small-caps and normal (default) # !!!! Untested if name.lower() in ['capitals', 'small-caps']: variant = 'small-caps' else: variant = 'normal' # Weights are: 100, 200, 300, 400 (normal: default), 500 (medium), # 600 (semibold, demibold), 700 (bold), 800 (heavy), 900 (black) # lighter and bolder are also allowed. weight = None for w in six.iterkeys(weight_dict): if sfnt4.find(w) >= 0: weight = w break if not weight: if font.style_flags & ft2font.BOLD: weight = 700 else: weight = 400 weight = weight_as_number(weight) # Stretch can be absolute and relative # Absolute stretches are: ultra-condensed, extra-condensed, condensed, # semi-condensed, normal, semi-expanded, expanded, extra-expanded, # and ultra-expanded. # Relative stretches are: wider, narrower # Child value is: inherit if sfnt4.find('narrow') >= 0 or sfnt4.find('condensed') >= 0 or \ sfnt4.find('cond') >= 0: stretch = 'condensed' elif sfnt4.find('demi cond') >= 0: stretch = 'semi-condensed' elif sfnt4.find('wide') >= 0 or sfnt4.find('expanded') >= 0: stretch = 'expanded' else: stretch = 'normal' # Sizes can be absolute and relative. # Absolute sizes are: xx-small, x-small, small, medium, large, x-large, # and xx-large. # Relative sizes are: larger, smaller # Length value is an absolute font size, e.g., 12pt # Percentage values are in 'em's. Most robust specification. # !!!! Incomplete if font.scalable: size = 'scalable' else: size = str(float(font.get_fontsize())) # !!!! Incomplete size_adjust = None return FontEntry(font.fname, name, style, variant, weight, stretch, size)
def ttfFontProperty(font): """ A function for populating the :class:`FontKey` by extracting information from the TrueType font file. *font* is a :class:`FT2Font` instance. """ name = font.family_name # Styles are: italic, oblique, and normal (default) sfnt = font.get_sfnt() sfnt2 = sfnt.get((1,0,0,2)) sfnt4 = sfnt.get((1,0,0,4)) if sfnt2: sfnt2 = sfnt2.decode('macroman').lower() else: sfnt2 = '' if sfnt4: sfnt4 = sfnt4.decode('macroman').lower() else: sfnt4 = '' if sfnt4.find('oblique') >= 0: style = 'oblique' elif sfnt4.find('italic') >= 0: style = 'italic' elif sfnt2.find('regular') >= 0: style = 'normal' elif font.style_flags & ft2font.ITALIC: style = 'italic' else: style = 'normal' # Variants are: small-caps and normal (default) # !!!! Untested if name.lower() in ['capitals', 'small-caps']: variant = 'small-caps' else: variant = 'normal' # Weights are: 100, 200, 300, 400 (normal: default), 500 (medium), # 600 (semibold, demibold), 700 (bold), 800 (heavy), 900 (black) # lighter and bolder are also allowed. weight = None for w in six.iterkeys(weight_dict): if sfnt4.find(w) >= 0: weight = w break if not weight: if font.style_flags & ft2font.BOLD: weight = 700 else: weight = 400 weight = weight_as_number(weight) # Stretch can be absolute and relative # Absolute stretches are: ultra-condensed, extra-condensed, condensed, # semi-condensed, normal, semi-expanded, expanded, extra-expanded, # and ultra-expanded. # Relative stretches are: wider, narrower # Child value is: inherit if sfnt4.find('narrow') >= 0 or sfnt4.find('condensed') >= 0 or \ sfnt4.find('cond') >= 0: stretch = 'condensed' elif sfnt4.find('demi cond') >= 0: stretch = 'semi-condensed' elif sfnt4.find('wide') >= 0 or sfnt4.find('expanded') >= 0: stretch = 'expanded' else: stretch = 'normal' # Sizes can be absolute and relative. # Absolute sizes are: xx-small, x-small, small, medium, large, x-large, # and xx-large. # Relative sizes are: larger, smaller # Length value is an absolute font size, e.g., 12pt # Percentage values are in 'em's. Most robust specification. # !!!! Incomplete if font.scalable: size = 'scalable' else: size = str(float(font.get_fontsize())) # !!!! Incomplete size_adjust = None return FontEntry(font.fname, name, style, variant, weight, stretch, size)