def parse_options(): doc = (__doc__ and __doc__.split('\n\n')) or " " op = OptionParser( description=doc[0].strip(), usage='%prog [options] [--] [backends and switches]', #epilog='\n'.join(doc[1:]) # epilog not supported on my python2.4 machine: JDH ) op.disable_interspersed_args() op.set_defaults(dirs='pylab,api,units,mplot3d', clean=False, coverage=False, valgrind=False) op.add_option('-d', '--dirs', '--directories', type='string', dest='dirs', help=dedent(''' Run only the tests in these directories; comma-separated list of one or more of: pylab (or pylab_examples), api, units, mplot3d''')) op.add_option('-b', '--backends', type='string', dest='backends', help=dedent(''' Run tests only for these backends; comma-separated list of one or more of: agg, ps, svg, pdf, template, cairo, Default is everything except cairo.''')) op.add_option('--clean', action='store_true', dest='clean', help='Remove result directories, run no tests') op.add_option('-c', '--coverage', action='store_true', dest='coverage', help='Run in coverage.py') op.add_option('-v', '--valgrind', action='store_true', dest='valgrind', help='Run in valgrind') options, args = op.parse_args() switches = [x for x in args if x.startswith('--')] backends = [x.lower() for x in args if not x.startswith('--')] if options.backends: backends += [be.lower() for be in options.backends.split(',')] result = Bunch(dirs=options.dirs.split(','), backends=backends or ['agg', 'ps', 'svg', 'pdf', 'template'], clean=options.clean, coverage=options.coverage, valgrind=options.valgrind, switches=switches) if 'pylab_examples' in result.dirs: result.dirs[result.dirs.index('pylab_examples')] = 'pylab' #print(result) return (result)
def h_pseudocode(e, doc): if not isinstance(e, pf.CodeBlock) or not "algorithm" in e.classes: return None content = e.text if e.identifier: doc.label_descriptions[e.identifier] = "Algorithm" label = labelref(e, doc) _, number_, _ = get_full_label(label, doc) if number_ and number_ != "??": i = number_.rfind(".") number = int(number_[i + 1:]) if i > -1 else int(number_) else: number = 0 title = e.attributes.get("title", "") if doc.format == "latex": textitle = f"[{title}]" if title else "" result = (dedent(rf""" \begin{{algorithm}}{textitle} \label[algorithm]{{{label}}} ~ \\ \noindent \begin{{algorithmic}}[1] """) + "\n" + format_pseudocode(content) + dedent(fr""" \end{{algorithmic}} \end{{algorithm}} """)) return pf.RawBlock(result, format="latex") if doc.format == "html": textitle = f"\caption{{{title}}}" if title else "" uid = str(uuid.uuid4()) content = (format_pseudocode(content).replace( "\\INPUT", "\\REQUIRE").replace("\\OUTPUT", "\\ENSURE")) result = (dedent(rf""" <pre id="{uid}" class="pseudocodetext" style="display:none;"> \begin{{algorithm}} {textitle} \begin{{algorithmic}} """) + "\n" + content + dedent(fr""" \end{{algorithmic}} \end{{algorithm}} </pre> <div id="{uid}result" class="pseudocodeoutput" ></div> <script> document.addEventListener('readystatechange', event => {{ if (event.target.readyState === "complete") {{ var code = document.getElementById('{uid}').textContent; var resultEl = document.getElementById('{uid}result'); resultEl.innerHTML = ''; var options = {{ captionCount: {number-1}, lineNumber: true }}; pseudocode.render(code, resultEl, options); }} }}); </script> """)) return pf.RawBlock(result, format="html") return None
def parse_options(): doc = (__doc__ and __doc__.split("\n\n")) or " " op = OptionParser( description=doc[0].strip(), usage="%prog [options] [--] [backends and switches]", # epilog='\n'.join(doc[1:]) # epilog not supported on my python2.4 machine: JDH ) op.disable_interspersed_args() op.set_defaults(dirs="pylab,api,units,mplot3d", clean=False, coverage=False, valgrind=False) op.add_option( "-d", "--dirs", "--directories", type="string", dest="dirs", help=dedent( """ Run only the tests in these directories; comma-separated list of one or more of: pylab (or pylab_examples), api, units, mplot3d""" ), ) op.add_option( "-b", "--backends", type="string", dest="backends", help=dedent( """ Run tests only for these backends; comma-separated list of one or more of: agg, ps, svg, pdf, template, cairo, Default is everything except cairo.""" ), ) op.add_option("--clean", action="store_true", dest="clean", help="Remove result directories, run no tests") op.add_option("-c", "--coverage", action="store_true", dest="coverage", help="Run in coverage.py") op.add_option("-v", "--valgrind", action="store_true", dest="valgrind", help="Run in valgrind") options, args = op.parse_args() switches = [x for x in args if x.startswith("--")] backends = [x.lower() for x in args if not x.startswith("--")] if options.backends: backends += [be.lower() for be in options.backends.split(",")] result = Bunch( dirs=options.dirs.split(","), backends=backends or ["agg", "ps", "svg", "pdf", "template"], clean=options.clean, coverage=options.coverage, valgrind=options.valgrind, switches=switches, ) if "pylab_examples" in result.dirs: result.dirs[result.dirs.index("pylab_examples")] = "pylab" # print(result) return result
class Ring(patches.Patch): """ Ring patch. """ def __str__(self): return "Ring(%g,%g,%g,%g)"%(self.r1,self.r2,self.theta1,self.theta2) def __init__(self, center=(0,0), r1=0, r2=None, theta1=0, theta2=360, **kwargs ): """ Draw a ring centered at *x*, *y* center with inner radius *r1* and outer radius *r2* that sweeps *theta1* to *theta2* (in degrees). Valid kwargs are: %(Patch)s """ patches.Patch.__init__(self, **kwargs) self.center = center self.r1, self.r2 = r1,r2 self.theta1, self.theta2 = theta1,theta2 # Inner and outer rings are connected unless the annulus is complete delta=abs(theta2-theta1) if fmod(delta,360)<=1e-12*delta: theta1,theta2 = 0,360 connector = Path.MOVETO else: connector = Path.LINETO # Form the outer ring arc = Path.arc(theta1,theta2) if r1 > 0: # Partial annulus needs to draw the outter ring # followed by a reversed and scaled inner ring v1 = arc.vertices v2 = arc.vertices[::-1]*float(r1)/r2 v = numpy.vstack([v1,v2,v1[0,:],(0,0)]) c = numpy.hstack([arc.codes,arc.codes,connector,Path.CLOSEPOLY]) c[len(arc.codes)]=connector else: # Wedge doesn't need an inner ring v = numpy.vstack([arc.vertices,[(0,0),arc.vertices[0,:],(0,0)]]) c = numpy.hstack([arc.codes,[connector,connector,Path.CLOSEPOLY]]) v *= r2 v += numpy.array(center) self._path = Path(v,c) self._patch_transform = transforms.IdentityTransform() __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd def get_path(self): return self._path
class Circle(Ellipse): """ A circle patch. """ def __str__(self): return "Circle((%g,%g),r=%g)" % (self.center[0], self.center[1], self.radius) def __init__(self, xy, radius=5, **kwargs): """ Create true circle at center *xy* = (*x*, *y*) with given *radius*. Unlike :class:`~matplotlib.patches.CirclePolygon` which is a polygonal approximation, this uses Bézier splines and is much closer to a scale-free circle. Valid kwargs are: %(Patch)s """ if kwargs.has_key('resolution'): import warnings warnings.warn( 'Circle is now scale free. Use CirclePolygon instead!', DeprecationWarning) kwargs.pop('resolution') self.radius = radius Ellipse.__init__(self, xy, radius * 2, radius * 2, **kwargs) __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd
class CirclePolygon(RegularPolygon): """ A polygon-approximation of a circle patch. """ def __str__(self): return "CirclePolygon(%d,%d)" % self.center def __init__( self, xy, radius=5, resolution=20, # the number of vertices **kwargs): """ Create a circle at *xy* = (*x*, *y*) with given *radius*. This circle is approximated by a regular polygon with *resolution* sides. For a smoother circle drawn with splines, see :class:`~matplotlib.patches.Circle`. Valid kwargs are: %(Patch)s """ RegularPolygon.__init__(self, xy, resolution, radius, orientation=0, **kwargs) __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd
class Ellipse(Patch): """ A scale-free ellipse. """ def __str__(self): return "Ellipse(%s,%s;%sx%s)" % (self.center[0], self.center[1], self.width, self.height) def __init__(self, xy, width, height, angle=0.0, **kwargs): """ *xy* center of ellipse *width* length of horizontal axis *height* length of vertical axis *angle* rotation in degrees (anti-clockwise) Valid kwargs are: %(Patch)s """ Patch.__init__(self, **kwargs) self.center = xy self.width, self.height = width, height self.angle = angle self._path = Path.unit_circle() self._patch_transform = transforms.IdentityTransform() self._recompute_transform() __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd def _recompute_transform(self): center = (self.convert_xunits(self.center[0]), self.convert_yunits(self.center[1])) width = self.convert_xunits(self.width) height = self.convert_yunits(self.height) self._patch_transform = transforms.Affine2D() \ .scale(width * 0.5, height * 0.5) \ .rotate_deg(self.angle) \ .translate(*center) def get_path(self): """ Return the vertices of the rectangle """ return self._path def get_patch_transform(self): self._recompute_transform() return self._patch_transform def contains(self, ev): if ev.x is None or ev.y is None: return False, {} x, y = self.get_transform().inverted().transform_point((ev.x, ev.y)) return (x * x + y * y) <= 1.0, {}
class Wedge(Patch): def __str__(self): return "Wedge(%g,%g)" % self.xy[0] def __init__(self, center, r, theta1, theta2, **kwargs): """ Draw a wedge centered at *x*, *y* center with radius *r* that sweeps *theta1* to *theta2* (in degrees). Valid kwargs are: %(Patch)s """ Patch.__init__(self, **kwargs) self.center = center self.r = r self.theta1 = theta1 self.theta2 = theta2 self._patch_transform = transforms.IdentityTransform() self._path = Path.wedge(self.theta1, self.theta2) __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd def get_path(self): return self._path def get_patch_transform(self): x = self.convert_xunits(self.center[0]) y = self.convert_yunits(self.center[1]) rx = self.convert_xunits(self.r) ry = self.convert_yunits(self.r) self._patch_transform = transforms.Affine2D() \ .scale(rx, ry).translate(x, y) return self._patch_transform
class CircleCollection(Collection): """ A collection of circles, drawn using splines. """ def __init__(self, sizes): """ *sizes* Gives the area of the circle in points^2 %(Collection)s """ Collection.__init__(self, **kwargs) self._sizes = sizes self.set_transform(transforms.IdentityTransform()) self._paths = [mpath.Path.unit_circle()] __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd def draw(self, renderer): # sizes is the area of the circle circumscribing the polygon # in points^2 self._transforms = [ transforms.Affine2D().scale( (np.sqrt(x) * renderer.dpi / 72.0) / np.sqrt(np.pi)) for x in self._sizes ] return Collection.draw(self, renderer)
def __call__(self, func): if func.__doc__: doc = func.__doc__ if self.auto_dedent: doc = dedent(doc) func.__doc__ = self._format(doc) return func
def get_metric_tables(names): """Get data, average, and return as table. :names: list of models to search for metric data :returns: metric summary tables as rst source. """ data = get_metric_data(names).reset_index() data = (pd.melt(data, id_vars=['name', 'metric', 'site' ]).pivot_table(index=['variable', 'name', 'site'], columns='metric', values='value').reset_index()) summary = data.groupby(['variable', 'name']).mean() table_text = '' for v in data.variable.unique(): table = dataframe_to_rst( summary.filter(like=v, axis=0).reset_index('variable', drop=True)) table_text += dedent(""" {variable} ------------- .. rst-class:: tablesorter {table} """).format(variable=v, table=table) table_text += "\n\n" return table_text
class Polygon(Patch): """ A general polygon patch. """ def __str__(self): return "Poly(%g,%g)" % self.xy[0] def __init__(self, xy, **kwargs): """ xy is a sequence of (x,y) 2 tuples Valid kwargs are: %(Patch)s See Patch documentation for additional kwargs """ Patch.__init__(self, **kwargs) if not isinstance(xy, list): xy = list(xy) self.xy = xy __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd def get_verts(self): xs, ys = zip(*self.xy)[:2] xs = self.convert_xunits(xs) ys = self.convert_yunits(ys) return zip(xs, ys)
class AsteriskPolygonCollection(RegularPolyCollection): def __init__(self, dpi, numsides, rotation=0, sizes=(1, ), **kwargs): """ Draw a regular asterisk Polygone with numsides spikes. * dpi is the figure dpi instance, and is required to do the area scaling. * numsides: the number of spikes of the polygon * sizes gives the area of the circle circumscribing the regular polygon in points^2 * rotation is the rotation of the polygon in radians %(PatchCollection)s """ RegularPolyCollection.__init__(self, dpi, numsides, rotation, sizes, **kwargs) __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd def _update_verts(self): scale = 1.0 / math.sqrt(math.pi) r = scale * npy.ones(self.numsides * 2) r[1::2] = 0 theta = (math.pi / self.numsides) * npy.arange( 2 * self.numsides) + self.rotation self._verts = zip(r * npy.sin(theta), r * npy.cos(theta))
class Wedge(Polygon): def __str__(self): return "Wedge(%g,%g)" % self.xy[0] def __init__(self, center, r, theta1, theta2, dtheta=5.0, **kwargs): """ Draw a wedge centered at x,y tuple center with radius r that sweeps theta1 to theta2 (angles) dtheta is the resolution in degrees Valid kwargs are: %(Patch)s """ xc, yc = center theta1 = float(theta1) theta2 = float(theta2) dtheta = float(dtheta) num_points = (abs(theta2 - theta1) / dtheta) if num_points < 2.0: num_points = 2.0 rads = (npy.pi / 180.) * npy.linspace( theta1, theta2, num_points, endpoint=True) xs = r * npy.cos(rads) + xc ys = r * npy.sin(rads) + yc verts = [center] verts.extend([(x, y) for x, y in zip(xs, ys)]) Polygon.__init__(self, verts, **kwargs) __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd
class Arrow(Polygon): """ An arrow patch """ def __str__(self): return "Arrow()" _path = Path([[0.0, 0.1], [0.0, -0.1], [0.8, -0.1], [0.8, -0.3], [1.0, 0.0], [0.8, 0.3], [0.8, 0.1], [0.0, 0.1]]) def __init__(self, x, y, dx, dy, width=1.0, **kwargs): """Draws an arrow, starting at (x,y), direction and length given by (dx,dy) the width of the arrow is scaled by width Valid kwargs are: %(Patch)s """ L = npy.sqrt(dx**2 + dy**2) or 1 # account for div by zero cx = float(dx) / L sx = float(dy) / L trans1 = transforms.Affine2D().scale(L, width) trans2 = transforms.Affine2D.from_values(cx, sx, -sx, cx, 0.0, 0.0) trans3 = transforms.Affine2d().translate(x, y) trans = trans1 + trans2 + trans3 self._patch_transform = trans.frozen() __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd def get_path(self): return self._path def get_patch_transform(self): return self._patch_transform
class Wedge(Polygon): def __str__(self): return "Wedge(%g,%g)" % self.xy[0] def __init__(self, center, r, theta1, theta2, dtheta=0.1, **kwargs): """ Draw a wedge centered at x,y tuple center with radius r that sweeps theta1 to theta2 (angles) dtheta is the resolution in degrees Valid kwargs are: %(Patch)s """ xc, yc = center rads = (math.pi / 180.) * npy.arange(theta1, theta2 + 0.1 * dtheta, dtheta) xs = r * npy.cos(rads) + xc ys = r * npy.sin(rads) + yc verts = [center] verts.extend([(x, y) for x, y in zip(xs, ys)]) Polygon.__init__(self, verts, **kwargs) __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd
class CirclePolygon(RegularPolygon): """ A circle patch """ def __str__(self): return "CirclePolygon(%d,%d)" % self.center def __init__( self, xy, radius=5, resolution=20, # the number of vertices **kwargs): """ Create a circle at xy=(x,y) with radius given by 'radius' Valid kwargs are: %(Patch)s """ self.center = xy self.radius = radius RegularPolygon.__init__(self, xy, resolution, radius, orientation=0, **kwargs) __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd
def indexhtml(doc): """Generate HTML index for title page""" keys = sorted(doc.toc.keys(), key=placekey) def depth(key): return key.count(".") HTML = fr"""<ul>""" for k in keys: e = doc.toc[k] title = e["title"] file = os.path.splitext(e["filename"])[0] base = doc.get_metadata("binarybaseurl", "") if depth(k) > 0: continue entry = dedent(fr""" <li><a href="{file+'.html'}"><b>Chapter {k}:</b> {title}</a> <small>(<a href="{base+'/'+file+'.pdf'}"><i class="fas fa-file-pdf"></i>PDF: best formatting</a> , <a href="{base+'/'+file+'.docx'}"><i class="fas fa-file-word"></i>Word: buggy</a>)</small> </li> """) HTML += entry HTML += r"""</ul>""" doc.metadata["indexcontents"] = pf.MetaBlocks( pf.RawBlock(HTML, format="html"))
class Arrow(Polygon): """ An arrow patch """ def __str__(self): x1, y1 = self.xy[0] x2, y2 = self.xy[1] cx, cy = (x1 + x2) / 2., (y1 + y2) / 2. return "Arrow(%g,%g)" % (cx, cy) def __init__(self, x, y, dx, dy, width=1.0, **kwargs): """Draws an arrow, starting at (x,y), direction and length given by (dx,dy) the width of the arrow is scaled by width Valid kwargs are: %(Patch)s """ arrow = npy.array([[0.0, 0.1], [0.0, -0.1], [0.8, -0.1], [0.8, -0.3], [1.0, 0.0], [0.8, 0.3], [0.8, 0.1]]) L = npy.sqrt(dx**2 + dy**2) or 1 # account for div by zero arrow[:, 0] *= L arrow[:, 1] *= width cx = float(dx) / L sx = float(dy) / L M = npy.array([[cx, sx], [-sx, cx]]) verts = npy.dot(arrow, M) + [x, y] Polygon.__init__(self, [tuple(t) for t in verts], **kwargs) __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd
class Polygon(Patch): """ A general polygon patch. """ def __str__(self): return "Poly((%g, %g) ...)" % tuple(self._path.vertices[0]) def __init__(self, xy, **kwargs): """ xy is a numpy array with shape Nx2 Valid kwargs are: %(Patch)s See Patch documentation for additional kwargs """ Patch.__init__(self, **kwargs) self._path = Path(xy) __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd def get_path(self): return self._path def _get_xy(self): return self._path.vertices def _set_xy(self, vertices): self._path = Path(vertices) xy = property(_get_xy, _set_xy)
class PolyCollection(Collection): def __init__(self, verts, sizes=None, closed=True, **kwargs): """ *verts* is a sequence of ( *verts0*, *verts1*, ...) where *verts_i* is a sequence of *xy* tuples of vertices, or an equivalent :mod:`numpy` array of shape (*nv*, 2). *sizes* is *None* (default) or a sequence of floats that scale the corresponding *verts_i*. The scaling is applied before the Artist master transform; if the latter is an identity transform, then the overall scaling is such that if *verts_i* specify a unit square, then *sizes_i* is the area of that square in points^2. If len(*sizes*) < *nv*, the additional values will be taken cyclically from the array. *closed*, when *True*, will explicitly close the polygon. %(Collection)s """ Collection.__init__(self, **kwargs) self._sizes = sizes self.set_verts(verts, closed) __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd def set_verts(self, verts, closed=True): '''This allows one to delay initialization of the vertices.''' if np.ma.isMaskedArray(verts): verts = verts.astype(np.float_).filled(np.nan) # This is much faster than having Path do it one at a time. if closed: self._paths = [] for xy in verts: if len(xy): if np.ma.isMaskedArray(xy): xy = np.ma.concatenate([xy, np.zeros((1, 2))]) else: xy = np.asarray(xy) xy = np.concatenate([xy, np.zeros((1, 2))]) codes = np.empty(xy.shape[0], dtype='uint8') codes[:] = mpath.Path.LINETO codes[0] = mpath.Path.MOVETO codes[-1] = mpath.Path.CLOSEPOLY self._paths.append(mpath.Path(xy, codes)) else: self._paths.append(mpath.Path(xy)) else: self._paths = [mpath.Path(xy) for xy in verts] def get_paths(self): return self._paths def draw(self, renderer): if self._sizes is not None: self._transforms = [ transforms.Affine2D().scale( (np.sqrt(x) * self.figure.dpi / 72.0)) for x in self._sizes ] return Collection.draw(self, renderer)
class Circle(Ellipse): """ A circle patch """ def __str__(self): return "Circle((%g,%g),r=%g)" % (self.center[0], self.center[1], self.radius) def __init__(self, xy, radius=5, **kwargs): """ Create true circle at center xy=(x,y) with given radius; unlike circle polygon which is a polygonal approcimation, this uses splines and is much closer to a scale free circle Valid kwargs are: %(Patch)s """ if kwargs.has_key('resolution'): import warnings warnings.warn( 'Circle is now scale free. Use CirclePolygon instead!', DeprecationWarning) kwargs.pop('resolution') self.radius = radius Ellipse.__init__(self, xy, radius * 2, radius * 2, **kwargs) __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd
class Shadow(Patch): def __str__(self): return "Shadow(%s)" % (str(self.patch)) def __init__(self, patch, ox, oy, props=None, **kwargs): """ Create a shadow of the patch offset by ox, oy. props, if not None is a patch property update dictionary. If None, the shadow will have have the same color as the face, but darkened kwargs are %(Patch)s """ Patch.__init__(self) self.patch = patch self.props = props self._ox, self._oy = ox, oy self._update_transform() self._update() __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd def _update(self): self.update_from(self.patch) if self.props is not None: self.update(self.props) else: r, g, b, a = colors.colorConverter.to_rgba( self.patch.get_facecolor()) rho = 0.3 r = rho * r g = rho * g b = rho * b self.set_facecolor((r, g, b, 0.5)) self.set_edgecolor((r, g, b, 0.5)) def _update_transform(self): self._shadow_transform = transforms.Affine2D().translate( self._ox, self._oy) def _get_ox(self): return self._ox def _set_ox(self, ox): self._ox = ox self._update_transform() def _get_oy(self): return self._oy def _set_oy(self, oy): self._oy = oy self._update_transform() def get_path(self): return self.patch.get_path() def get_patch_transform(self): return self.patch.get_patch_transform() + self._shadow_transform
class Polygon(Patch): """ A general polygon patch. """ def __str__(self): return "Poly((%g, %g) ...)" % tuple(self._path.vertices[0]) def __init__(self, xy, closed=True, **kwargs): """ *xy* is a numpy array with shape Nx2. If *closed* is *True*, the polygon will be closed so the starting and ending points are the same. Valid kwargs are: %(Patch)s See Patch documentation for additional kwargs """ Patch.__init__(self, **kwargs) xy = np.asarray(xy, np.float_) self._path = Path(xy) self.set_closed(closed) __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd def get_path(self): return self._path def get_closed(self): return self._closed def set_closed(self, closed): self._closed = closed xy = self._get_xy() if closed: if len(xy) and (xy[0] != xy[-1]).any(): xy = np.concatenate([xy, [xy[0]]]) else: if len(xy) > 2 and (xy[0] == xy[-1]).all(): xy = xy[0:-1] self._set_xy(xy) def get_xy(self): return self._path.vertices def set_xy(self, vertices): self._path = Path(vertices) _get_xy = get_xy _set_xy = set_xy xy = property( get_xy, set_xy, None, """Set/get the vertices of the polygon. This property is provided for backward compatibility with matplotlib 0.91.x only. New code should use :meth:`~matplotlib.patches.Polygon.get_xy` and :meth:`~matplotlib.patches.Polygon.set_xy` instead.""")
class PolyCollection(PatchCollection): def __init__(self, verts, **kwargs): """ verts is a sequence of ( verts0, verts1, ...) where verts_i is a sequence of xy tuples of vertices, or an equivalent numpy array of shape (nv,2). %(PatchCollection)s """ PatchCollection.__init__(self, **kwargs) self._verts = verts __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd def set_verts(self, verts): '''This allows one to delay initialization of the vertices.''' self._verts = verts def draw(self, renderer): if not self.get_visible(): return renderer.open_group('polycollection') transform = self.get_transform() transoffset = self.get_transoffset() 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) transform.thaw() transoffset.thaw() renderer.close_group('polycollection') def get_verts(self, dataTrans=None): '''Return vertices in data coordinates. The calculation is incomplete in general; it is based on the vertices or the offsets, whichever is using dataTrans as its transformation, so it does not take into account the combined effect of segments and offsets. ''' verts = [] if self._offsets is None: for seg in self._verts: verts.extend(seg) return [tuple(xy) for xy in verts] if self.get_transoffset() == dataTrans: return [tuple(xy) for xy in self._offsets] raise NotImplementedError( 'Vertices in data coordinates are calculated\n' + 'with offsets only if _transOffset == dataTrans.')
def parse_options(): doc = (__doc__ and __doc__.split('\n\n')) or " " op = OptionParser(description=doc[0].strip(), usage='%prog [options] [--] [backends and switches]', #epilog='\n'.join(doc[1:]) # epilog not supported on my python2.4 machine: JDH ) op.disable_interspersed_args() op.set_defaults(dirs='pylab,api,units,mplot3d', clean=False, coverage=False, valgrind=False) op.add_option('-d', '--dirs', '--directories', type='string', dest='dirs', help=dedent(''' Run only the tests in these directories; comma-separated list of one or more of: pylab (or pylab_examples), api, units, mplot3d''')) op.add_option('-b', '--backends', type='string', dest='backends', help=dedent(''' Run tests only for these backends; comma-separated list of one or more of: agg, ps, svg, pdf, template, cairo, cairo.png, cairo.ps, cairo.pdf, cairo.svg. Default is everything except cairo.''')) op.add_option('--clean', action='store_true', dest='clean', help='Remove result directories, run no tests') op.add_option('-c', '--coverage', action='store_true', dest='coverage', help='Run in coverage.py') op.add_option('-v', '--valgrind', action='store_true', dest='valgrind', help='Run in valgrind') options, args = op.parse_args() switches = [x for x in args if x.startswith('--')] backends = [x.lower() for x in args if not x.startswith('--')] if options.backends: backends += map(string.lower, options.backends.split(',')) result = Bunch( dirs = options.dirs.split(','), backends = backends or ['agg', 'ps', 'svg', 'pdf', 'template'], clean = options.clean, coverage = options.coverage, valgrind = options.valgrind, switches = switches) if 'pylab_examples' in result.dirs: result.dirs[result.dirs.index('pylab_examples')] = 'pylab' #print result return result
class RegularPolyCollection(Collection): """Draw a collection of regular polygons with *numsides*.""" _path_generator = mpath.Path.unit_regular_polygon def __init__(self, numsides, rotation=0, sizes=(1, ), **kwargs): """ *numsides* the number of sides of the polygon *rotation* the rotation of the polygon in radians *sizes* gives the area of the circle circumscribing the regular polygon in points^2 %(Collection)s Example: see :file:`examples/dynamic_collection.py` for complete example:: offsets = np.random.rand(20,2) facecolors = [cm.jet(x) for x in np.random.rand(20)] black = (0,0,0,1) collection = RegularPolyCollection( numsides=5, # a pentagon rotation=0, sizes=(50,), facecolors = facecolors, edgecolors = (black,), linewidths = (1,), offsets = offsets, transOffset = ax.transData, ) """ Collection.__init__(self, **kwargs) self._sizes = sizes self._paths = [self._path_generator(numsides)] self._rotation = rotation self.set_transform(transforms.IdentityTransform()) __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd def draw(self, renderer): # sizes is the area of the circle circumscribing the polygon # in points^2 self._transforms = [ transforms.Affine2D().rotate(-self._rotation).scale( (np.sqrt(x) * renderer.dpi / 72.0) / np.sqrt(np.pi)) for x in self._sizes ] return Collection.draw(self, renderer) def get_paths(self): return self._paths
class RegularPolyCollection(Collection): _path_generator = mpath.Path.unit_regular_polygon def __init__(self, dpi, numsides, rotation=0, sizes=(1, ), **kwargs): """ Draw a regular polygon with numsides. * dpi is the figure dpi instance, and is required to do the area scaling. * numsides: the number of sides of the polygon * sizes gives the area of the circle circumscribing the regular polygon in points^2 * rotation is the rotation of the polygon in radians %(Collection)s Example: see examples/dynamic_collection.py for complete example offsets = npy.random.rand(20,2) facecolors = [cm.jet(x) for x in npy.random.rand(20)] black = (0,0,0,1) collection = RegularPolyCollection( fig.dpi, numsides=5, # a pentagon rotation=0, sizes=(50,), facecolors = facecolors, edgecolors = (black,), linewidths = (1,), offsets = offsets, transOffset = ax.transData, ) """ Collection.__init__(self, **kwargs) self._sizes = sizes self._dpi = dpi self._paths = [self._path_generator(numsides)] # sizes is the area of the circle circumscribing the polygon # in points^2 self._transforms = [ transforms.Affine2D().rotate(-rotation).scale( (math.sqrt(x) * self._dpi / 72.0) / math.sqrt(math.pi)) for x in sizes ] self.set_transform(transforms.IdentityTransform()) __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd def get_paths(self): return self._paths
def tochtml(toc, title=""): """Generate HTML from toc""" keys = sorted(toc.keys(), key=placekey) def depth(key): return key.count(".") d = 0 HTML = dedent(fr""" <ul class="summary"> <li><a href="./">{title}</a></li> <li class="divider"></li> """) first = True for k in keys: e = toc[k] title = e["title"] file = e["filename"] ref = "#" + e["href"] if e["href"] else "" entry = "" if depth(k) == d and not first: entry = r"</li>" first = False if depth(k) > d: entry = r"<ul>" + r"<li><ul>" * (depth(k) - d - 1) if depth(k) < d: entry = r"</li>" + r"</ul></li>" * (d - depth(k)) entry += dedent(fr""" <li class="chapter" data-level="{k}" data-path="{file}"><a href="{file}{ref}"><i class="fa fa-check"></i><b>{k}</b> {title}</a> """) HTML += entry d = depth(k) entry = r"</li>" + r"</ul></li>" * d HTML += entry + dedent(r""" <li class="divider"></li> </ul> """) return HTML
def get_scale_docs(): """ Helper function for generating docstrings related to scales. """ docs = [] for name in get_scale_names(): scale_class = _scale_mapping[name] docs.append(" '%s'" % name) docs.append("") class_docs = dedent(scale_class.__init__.__doc__) class_docs = "".join([" %s\n" % x for x in class_docs.split("\n")]) docs.append(class_docs) docs.append("") return "\n".join(docs)
def _get_scale_docs(): """ Helper function for generating docstrings related to scales. """ docs = [] for name in get_scale_names(): scale_class = _scale_mapping[name] docs.append(" '%s'" % name) docs.append("") class_docs = cbook.dedent(scale_class.__init__.__doc__) class_docs = "".join( [" %s\n" % x for x in class_docs.split("\n")]) docs.append(class_docs) docs.append("") return "\n".join(docs)
class PolyCollection(Collection): def __init__(self, verts, sizes=None, closed=True, **kwargs): """ *verts* is a sequence of ( *verts0*, *verts1*, ...) where *verts_i* is a sequence of *xy* tuples of vertices, or an equivalent :mod:`numpy` array of shape (*nv*, 2). *sizes* is *None* (default) or a sequence of floats that scale the corresponding *verts_i*. The scaling is applied before the Artist master transform; if the latter is an identity transform, then the overall scaling is such that if *verts_i* specify a unit square, then *sizes_i* is the area of that square in points^2. If len(*sizes*) < *nv*, the additional values will be taken cyclically from the array. *closed*, when *True*, will explicitly close the polygon. %(Collection)s """ Collection.__init__(self, **kwargs) self._sizes = sizes self.set_verts(verts, closed) __init__.__doc__ = cbook.dedent(__init__.__doc__) % artist.kwdocd def set_verts(self, verts, closed=True): '''This allows one to delay initialization of the vertices.''' if closed: self._paths = [] for xy in verts: xy = np.asarray(xy) if len(xy) and (xy[0] != xy[-1]).any(): xy = np.concatenate([xy, [xy[0]]]) self._paths.append(mpath.Path(xy)) else: self._paths = [mpath.Path(xy) for xy in verts] def get_paths(self): return self._paths def draw(self, renderer): if self._sizes is not None: self._transforms = [ transforms.Affine2D().scale( (np.sqrt(x) * self.figure.dpi / 72.0)) for x in self._sizes ] return Collection.draw(self, renderer)
def test_lazy_imports(): source = dedent(""" import sys import matplotlib.figure import matplotlib.backend_bases import matplotlib.pyplot assert 'matplotlib._png' not in sys.modules assert 'matplotlib._tri' not in sys.modules assert 'matplotlib._qhull' not in sys.modules assert 'matplotlib._contour' not in sys.modules assert 'urllib.request' not in sys.modules """) subprocess.check_call([sys.executable, '-c', source])
def test_lazy_imports(): source = dedent(""" import sys import matplotlib.figure import matplotlib.backend_bases import matplotlib.pyplot assert 'matplotlib._png' not in sys.modules assert 'matplotlib._tri' not in sys.modules assert 'matplotlib._qhull' not in sys.modules assert 'matplotlib._contour' not in sys.modules assert 'urllib.request' not in sys.modules """) subprocess.check_call([ sys.executable, '-c', source ])
def __init__(self,projparams,llcrnrlon,llcrnrlat, urcrnrlon,urcrnrlat,urcrnrislatlon=True): """ initialize a Proj class instance. Input 'projparams' is a dictionary containing proj map projection control parameter key/value pairs. See the proj documentation (http://www.remotesensing.org/proj/) for details. llcrnrlon,llcrnrlat are lon and lat (in degrees) of lower left hand corner of projection region. urcrnrlon,urcrnrlat are lon and lat (in degrees) of upper right hand corner of projection region if urcrnrislatlon=True (default). Otherwise, urcrnrlon,urcrnrlat are x,y in projection coordinates (units meters), assuming the lower left corner is x=0,y=0. """ self.projparams = projparams self.projection = projparams['proj'] # rmajor is the semi-major axis. # rminor is the semi-minor axis. # esq is eccentricity squared. try: self.rmajor = projparams['a'] self.rminor = projparams['b'] except: try: self.rmajor = projparams['R'] except: self.rmajor = projparams['bR_a'] self.rminor = self.rmajor if self.rmajor == self.rminor: self.ellipsoid = False else: self.ellipsoid = True self.flattening = (self.rmajor-self.rminor)/self.rmajor self.esq = (self.rmajor**2 - self.rminor**2)/self.rmajor**2 self.llcrnrlon = llcrnrlon self.llcrnrlat = llcrnrlat if self.projection == 'cyl': llcrnrx = llcrnrlon llcrnry = llcrnrlat elif self.projection == 'ob_tran': self._proj4 = pyproj.Proj(projparams) llcrnrx,llcrnry = self(llcrnrlon,llcrnrlat) llcrnrx = _rad2dg*llcrnrx; llcrnry = _rad2dg*llcrnry if llcrnrx < 0: llcrnrx = llcrnrx + 360 elif self.projection in 'ortho': if (llcrnrlon == -180 and llcrnrlat == -90 and urcrnrlon == 180 and urcrnrlat == 90): self._fulldisk = True self._proj4 = pyproj.Proj(projparams) llcrnrx = -self.rmajor llcrnry = -self.rmajor self._width = 0.5*(self.rmajor+self.rminor) self._height = 0.5*(self.rmajor+self.rminor) urcrnrx = -llcrnrx urcrnry = -llcrnry else: self._fulldisk = False self._proj4 = pyproj.Proj(projparams) llcrnrx, llcrnry = self(llcrnrlon,llcrnrlat) if llcrnrx > 1.e20 or llcrnry > 1.e20: raise ValueError(_lower_left_out_of_bounds) elif self.projection == 'aeqd' and\ (llcrnrlon == -180 and llcrnrlat == -90 and urcrnrlon == 180 and\ urcrnrlat == 90): self._fulldisk = True self._proj4 = pyproj.Proj(projparams) # raise an exception for ellipsoids - there appears to be a bug # in proj4 that causes the inverse transform to fail for points # more than 90 degrees of arc away from center point for ellipsoids # (works fine for spheres) - below is an example #from pyproj import Proj #p1 = Proj(proj='aeqd',a=6378137.00,b=6356752.3142,lat_0=0,lon_0=0) #x,y= p1(91,0) #lon,lat = p1(x,y,inverse=True) # lon is 89 instead of 91 if self.ellipsoid: msg = dedent(""" full disk (whole world) Azimuthal Equidistant projection can only be drawn for a perfect sphere""") raise ValueError(msg) llcrnrx = -np.pi*self.rmajor llcrnry = -np.pi*self.rmajor self._width = -llcrnrx self._height = -llcrnry urcrnrx = -llcrnrx urcrnry = -llcrnry elif self.projection == 'geos': self._proj4 = pyproj.Proj(projparams) # find major and minor axes of ellipse defining map proj region. # h is measured from surface of earth at equator. h = projparams['h'] + self.rmajor # latitude of horizon on central meridian lonmax = 90.-(180./np.pi)*np.arcsin(self.rmajor/h) # longitude of horizon on equator latmax = 90.-(180./np.pi)*np.arcsin(self.rminor/h) # truncate to nearest hundredth of a degree (to make sure # they aren't slightly over the horizon) latmax = int(100*latmax)/100. lonmax = int(100*lonmax)/100. # width and height of visible projection P = pyproj.Proj(proj='geos',a=self.rmajor,\ b=self.rminor,lat_0=0,lon_0=0,h=projparams['h']) x1,y1 = P(0.,latmax); x2,y2 = P(lonmax,0.) width = x2; height = y1 self._height = height self._width = width if (llcrnrlon == -180 and llcrnrlat == -90 and urcrnrlon == 180 and urcrnrlat == 90): self._fulldisk = True llcrnrx = -width llcrnry = -height urcrnrx = -llcrnrx urcrnry = -llcrnry else: self._fulldisk = False llcrnrx, llcrnry = self(llcrnrlon,llcrnrlat) if llcrnrx > 1.e20 or llcrnry > 1.e20: raise ValueError(_lower_left_out_of_bounds) elif self.projection == 'nsper': self._proj4 = pyproj.Proj(projparams) # find major and minor axes of ellipse defining map proj region. # h is measured from surface of earth at equator. h = projparams['h'] + self.rmajor # latitude of horizon on central meridian lonmax = 90.-(180./np.pi)*np.arcsin(self.rmajor/h) # longitude of horizon on equator latmax = 90.-(180./np.pi)*np.arcsin(self.rmajor/h) # truncate to nearest hundredth of a degree (to make sure # they aren't slightly over the horizon) latmax = int(100*latmax)/100. lonmax = int(100*lonmax)/100. # width and height of visible projection P = pyproj.Proj(proj='nsper',a=self.rmajor,\ b=self.rminor,lat_0=0,lon_0=0,h=projparams['h']) x1,y1 = P(0.,latmax); x2,y2 = P(lonmax,0.) width = x2; height = y1 self._height = height self._width = width if (llcrnrlon == -180 and llcrnrlat == -90 and urcrnrlon == 180 and urcrnrlat == 90): self._fulldisk = True llcrnrx = -width llcrnry = -height urcrnrx = -llcrnrx urcrnry = -llcrnry else: self._fulldisk = False llcrnrx, llcrnry = self(llcrnrlon,llcrnrlat) if llcrnrx > 1.e20 or llcrnry > 1.e20: raise ValueError(_lower_left_out_of_bounds) elif self.projection in _pseudocyl: self._proj4 = pyproj.Proj(projparams) xtmp,urcrnry = self(projparams['lon_0'],90.) urcrnrx,xtmp = self(projparams['lon_0']+180.,0) llcrnrx = -urcrnrx llcrnry = -urcrnry if self.ellipsoid and self.projection in ['kav7','eck4','mbtfpq']: msg = "this projection can only be drawn for a perfect sphere" raise ValueError(msg) else: self._proj4 = pyproj.Proj(projparams) llcrnrx, llcrnry = self(llcrnrlon,llcrnrlat) if self.projection == 'aeqd': self._fulldisk=False # compute x_0, y_0 so ll corner of domain is x=0,y=0. # note that for 'cyl' x,y == lon,lat if self.projection != 'ob_tran': self.projparams['x_0']=-llcrnrx self.projparams['y_0']=-llcrnry # reset with x_0, y_0. if self.projection not in ['cyl','ob_tran']: self._proj4 = pyproj.Proj(projparams) llcrnry = 0. llcrnrx = 0. elif self.projection != 'ob_tran': llcrnrx = llcrnrlon llcrnry = llcrnrlat if urcrnrislatlon: self.urcrnrlon = urcrnrlon self.urcrnrlat = urcrnrlat if self.projection not in ['ortho','geos','nsper','aeqd'] + _pseudocyl: urcrnrx,urcrnry = self(urcrnrlon,urcrnrlat) if self.projection == 'ob_tran': urcrnrx = _rad2dg*urcrnrx; urcrnry = _rad2dg*urcrnry if urcrnrx < 0: urcrnrx = urcrnrx + 360 elif self.projection in ['ortho','geos','nsper','aeqd']: if self._fulldisk: urcrnrx = 2.*self._width urcrnry = 2.*self._height else: urcrnrx,urcrnry = self(urcrnrlon,urcrnrlat) if urcrnrx > 1.e20 or urcrnry > 1.e20: raise ValueError(_upper_right_out_of_bounds) elif self.projection in _pseudocyl: xtmp,urcrnry = self(projparams['lon_0'],90.) urcrnrx,xtmp = self(projparams['lon_0']+180.,0) else: urcrnrx = urcrnrlon urcrnry = urcrnrlat urcrnrlon, urcrnrlat = self(urcrnrx, urcrnry, inverse=True) self.urcrnrlon = urcrnrlon self.urcrnrlat = urcrnrlat # corners of domain. self.llcrnrx = llcrnrx self.llcrnry = llcrnry self.urcrnrx = urcrnrx self.urcrnry = urcrnry if urcrnrx > llcrnrx: self.xmin = llcrnrx self.xmax = urcrnrx else: self.xmax = llcrnrx self.xmin = urcrnrx if urcrnry > llcrnry: self.ymin = llcrnry self.ymax = urcrnry else: self.ymax = llcrnry self.ymin = urcrnry
def scale_factory(scale, axis, **kwargs): """ Return a scale class by name. ACCEPTS: [ %(names)s ] """ scale = scale.lower() if scale is None: scale = 'linear' if scale not in _scale_mapping: raise ValueError("Unknown scale type '%s'" % scale) return _scale_mapping[scale](axis, **kwargs) scale_factory.__doc__ = dedent(scale_factory.__doc__) % \ {'names': " | ".join(get_scale_names())} def register_scale(scale_class): """ Register a new kind of scale. *scale_class* must be a subclass of :class:`ScaleBase`. """ _scale_mapping[scale_class.name] = scale_class def get_scale_docs(): """ Helper function for generating docstrings related to scales.
""" Return a scale class by name. ACCEPTS: [ %(names)s ] """ scale = scale.lower() if scale is None: scale = "linear" if scale not in _scale_mapping: raise ValueError("Unknown scale type '%s'" % scale) return _scale_mapping[scale](axis, **kwargs) scale_factory.__doc__ = dedent(scale_factory.__doc__) % {"names": " | ".join(get_scale_names())} def register_scale(scale_class): """ Register a new kind of scale. *scale_class* must be a subclass of :class:`ScaleBase`. """ _scale_mapping[scale_class.name] = scale_class def get_scale_docs(): """ Helper function for generating docstrings related to scales. """
def scale_factory(scale, axis, **kwargs): """ Return a scale class by name. ACCEPTS: [ %(names)s ] """ scale = scale.lower() if scale is None: scale = 'linear' if scale not in _scale_mapping: raise ValueError("Unknown scale type '%s'" % scale) return _scale_mapping[scale](axis, **kwargs) scale_factory.__doc__ = cbook.dedent(scale_factory.__doc__) % \ {'names': " | ".join(get_scale_names())} def register_scale(scale_class): """ Register a new kind of scale. *scale_class* must be a subclass of :class:`ScaleBase`. """ _scale_mapping[scale_class.name] = scale_class def get_scale_docs(): """ Helper function for generating docstrings related to scales.
def dedent(func): "Dedent a docstring (if present)" func.__doc__ = func.__doc__ and cbook.dedent(func.__doc__) return func
spec = spec[:, 0] return spec, freqs # Split out these keyword docs so that they can be used elsewhere docstring.interpd.update(Spectral=cbook.dedent(""" Fs : scalar The sampling frequency (samples per time unit). It is used to calculate the Fourier frequencies, freqs, in cycles per time unit. The default value is 2. window : callable or ndarray A function or a vector of length *NFFT*. To create window vectors see `window_hanning`, `window_none`, `numpy.blackman`, `numpy.hamming`, `numpy.bartlett`, `scipy.signal`, `scipy.signal.get_window`, etc. The default is `window_hanning`. If a function is passed as the argument, it must take a data segment as an argument and return the windowed version of the segment. sides : {'default', 'onesided', 'twosided'} Specifies which sides of the spectrum to return. Default gives the default behavior, which returns one-sided for real data and both for complex data. 'onesided' forces the return of a one-sided spectrum, while 'twosided' forces two-sided. """)) docstring.interpd.update(Single_Spectrum=cbook.dedent(""" pad_to : int The number of points to which the data segment is padded when performing the FFT. While not increasing the actual resolution of