def twin(self, aux_trans=None, axes_class=None): """ Create a twin of Axes with no shared axis. While self will have ticks on the left and bottom axis, the returned axes will have ticks on the top and right axis. """ if aux_trans is None: aux_trans = mtransforms.IdentityTransform() ax = self._add_twin_axes(axes_class, aux_transform=aux_trans, viewlim_mode="transform") self.axis["top", "right"].set_visible(False) ax.axis["top", "right"].set_visible(True) ax.axis["left", "bottom"].set_visible(False) return ax
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)
def draw(self, renderer): if not self.get_visible(): return renderer.open_group(self.__class__.__name__) transform = self.get_transform() transOffset = self._transOffset offsets = self._offsets if self.have_units(): if len(self._offsets): xs = self.convert_xunits(self._offsets[:0]) ys = self.convert_yunits(self._offsets[:1]) offsets = zip(xs, ys) offsets = np.asarray(offsets, np.float_) if self.check_update('array'): self.update_scalarmappable() if not transform.is_affine: coordinates = self._coordinates.reshape( (self._coordinates.shape[0] * self._coordinates.shape[1], 2)) coordinates = transform.transform(coordinates) coordinates = coordinates.reshape(self._coordinates.shape) transform = transforms.IdentityTransform() else: coordinates = self._coordinates if not transOffset.is_affine: offsets = transOffset.transform_non_affine(offsets) transOffset = transOffset.get_affine() gc = renderer.new_gc() self._set_gc_clip(gc) if self._shading == 'gouraud': triangles, colors = self.convert_mesh_to_triangles( self._meshWidth, self._meshHeight, coordinates) renderer.draw_gouraud_triangles(gc, triangles, colors, transform.frozen()) else: renderer.draw_quad_mesh( gc, transform.frozen(), self._meshWidth, self._meshHeight, coordinates, offsets, transOffset, self.get_facecolor(), self._antialiased, self._showedges) gc.restore() renderer.close_group(self.__class__.__name__)
def twin(self, aux_trans=None): """ call signature:: ax2 = ax.twin() create a twin of Axes for generating a plot with a sharex x-axis but independent y axis. The y-axis of self will have ticks on left and the returned axes will have ticks on the right """ if aux_trans is None: ax2 = ParasiteAxesAuxTrans( self, mtransforms.IdentityTransform(), viewlim_mode="equal", ) else: ax2 = ParasiteAxesAuxTrans( self, aux_trans, viewlim_mode="transform", ) self.parasites.append(ax2) # for normal axes self.yaxis.tick_left() self.xaxis.tick_bottom() ax2.yaxis.tick_right() ax2.yaxis.set_label_position('right') ax2.xaxis.tick_top() ax2.xaxis.set_label_position('top') # for axisline axes self._axislines["right"].set_visible(False) self._axislines["top"].set_visible(False) ax2._axislines["left"].set_visible(False) ax2._axislines["bottom"].set_visible(False) ax2._axislines["right"].set_visible(True) ax2._axislines["top"].set_visible(True) ax2._axislines["right"].major_ticklabels.set_visible(True) ax2._axislines["top"].major_ticklabels.set_visible(True) return ax2
def check(master_transform, paths, all_transforms, offsets, facecolors, edgecolors): rb = RendererBase() raw_paths = list(rb._iter_collection_raw_paths( master_transform, paths, all_transforms)) gc = rb.new_gc() ids = [path_id for xo, yo, path_id, gc0, rgbFace in rb._iter_collection(gc, master_transform, all_transforms, range(len(raw_paths)), offsets, transforms.IdentityTransform(), facecolors, edgecolors, [], [], [False], [], 'data')] uses = rb._iter_collection_uses_per_path( paths, all_transforms, offsets, facecolors, edgecolors) if raw_paths: seen = np.bincount(ids, minlength=len(raw_paths)) assert set(seen).issubset([uses - 1, uses])
def twin(self, aux_trans=None, axes_class=None): """ call signature:: ax2 = ax.twin() create a twin of Axes for generating a plot with a sharex x-axis but independent y axis. The y-axis of self will have ticks on left and the returned axes will have ticks on the right """ if axes_class is None: axes_class = self._get_base_axes() parasite_axes_auxtrans_class = parasite_axes_auxtrans_class_factory( axes_class) if aux_trans is None: ax2 = parasite_axes_auxtrans_class( self, mtransforms.IdentityTransform(), viewlim_mode="equal", ) else: ax2 = parasite_axes_auxtrans_class( self, aux_trans, viewlim_mode="transform", ) self.parasites.append(ax2) ax2._remove_method = lambda h: self.parasites.remove(h) self.axis["top", "right"].set_visible(False) ax2.axis["top", "right"].set_visible(True) ax2.axis["left", "bottom"].set_visible(False) def _remove_method(h): self.parasites.remove(h) self.axis["top", "right"].set_visible(True) self.axis["top", "right"].toggle(ticklabels=False, label=False) ax2._remove_method = _remove_method return ax2
def __init__(self, ax, line): self.ax = ax ax.set_title('drag polygon around to test clipping') self.canvas = ax.figure.canvas self.line = line self.poly = RegularPolygon((200, 200), numVertices=10, radius=100, facecolor='yellow', alpha=0.25, transform=transforms.IdentityTransform()) ax.add_patch(self.poly) self.canvas.mpl_connect('button_press_event', self.onpress) self.canvas.mpl_connect('button_release_event', self.onrelease) self.canvas.mpl_connect('motion_notify_event', self.onmove) self.x, self.y = None, None
def _render_ep_lines(self): """ Render energy profile lines in canvas. """ for line in self.lines: for idx in range(line.shadow_depth): identity_trans = transforms.IdentityTransform() offset = transforms.ScaledTranslation(idx, -idx, identity_trans) shadow_trans = self.axes.transData + offset # Create matplotlib Line2D. alpha = (line.shadow_depth-idx)/2.0/line.shadow_depth shadow_line = Line2D(line.x, line.y, linewidth=line.line_width, color=line.shadow_color, transform=shadow_trans, alpha=alpha) self.shadow_lines.append(shadow_line)
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())
def __init__(self, xy, width, height, **kwargs): """ *fill* is a boolean indicating whether to fill the rectangle Valid kwargs are: %(Patch)s """ Patch.__init__(self, **kwargs) self._x = xy[0] self._y = xy[1] self._width = width self._height = height self._rect_transform = transforms.IdentityTransform() self._update_patch_transform()
def __init__(self, ax, *args, **kw): """ The constructor takes one required argument, an Axes instance, followed by the args and kwargs described by the following pylab interface documentation: %(barbs_doc)s""" self._pivot = kw.pop('pivot', 'tip') self._length = kw.pop('length', 7) barbcolor = kw.pop('barbcolor', None) flagcolor = kw.pop('flagcolor', None) self.sizes = kw.pop('sizes', dict()) self.fill_empty = kw.pop('fill_empty', False) self.barb_increments = kw.pop('barb_increments', dict()) self.rounding = kw.pop('rounding', True) self.flip = kw.pop('flip_barb', False) #Flagcolor and and barbcolor provide convenience parameters for setting #the facecolor and edgecolor, respectively, of the barb polygon. We #also work here to make the flag the same color as the rest of the barb #by default if None in (barbcolor, flagcolor): kw['edgecolors'] = 'face' if flagcolor: kw['facecolors'] = flagcolor elif barbcolor: kw['facecolors'] = barbcolor else: #Set to facecolor passed in or default to black kw.setdefault('facecolors', 'k') else: kw['edgecolors'] = barbcolor kw['facecolors'] = flagcolor #Parse out the data arrays from the various configurations supported x, y, u, v, c = _parse_args(*args) self.x = x self.y = y xy = np.hstack((x[:,np.newaxis], y[:,np.newaxis])) #Make a collection barb_size = self._length**2 / 4 #Empirically determined collections.PolyCollection.__init__(self, [], (barb_size,), offsets=xy, transOffset=ax.transData, **kw) self.set_transform(transforms.IdentityTransform()) self.set_UVC(u, v, c)
def test_patch_transform_of_none(): # tests the behaviour of patches added to an Axes with various transform # specifications ax = plt.axes() ax.set_xlim([1, 3]) ax.set_ylim([1, 3]) # Draw an ellipse over data coord (2,2) by specifying device coords. xy_data = (2, 2) xy_pix = ax.transData.transform_point(xy_data) # Not providing a transform of None puts the ellipse in data coordinates . e = mpatches.Ellipse(xy_data, width=1, height=1, fc='yellow', alpha=0.5) ax.add_patch(e) assert e._transform == ax.transData # Providing a transform of None puts the ellipse in device coordinates. e = mpatches.Ellipse(xy_pix, width=120, height=120, fc='coral', transform=None, alpha=0.5) assert e.is_transform_set() is True ax.add_patch(e) assert isinstance(e._transform, mtransforms.IdentityTransform) # Providing an IdentityTransform puts the ellipse in device coordinates. e = mpatches.Ellipse(xy_pix, width=100, height=100, transform=mtransforms.IdentityTransform(), alpha=0.5) ax.add_patch(e) assert isinstance(e._transform, mtransforms.IdentityTransform) # Not providing a transform, and then subsequently "get_transform" should # not mean that "is_transform_set". e = mpatches.Ellipse(xy_pix, width=120, height=120, fc='coral', alpha=0.5) intermediate_transform = e.get_transform() assert e.is_transform_set() is False ax.add_patch(e) assert e.get_transform() != intermediate_transform assert e.is_transform_set() is True assert e._transform == ax.transData
def __init__(self, axes, spine_type, path, **kwargs): """ - *axes* : the Axes instance containing the spine - *spine_type* : a string specifying the spine type - *path* : the path instance used to draw the spine Valid kwargs are: %(Patch)s """ super(Spine, self).__init__(**kwargs) self.axes = axes self.set_figure(self.axes.figure) self.spine_type = spine_type self.set_facecolor('none') self.set_edgecolor(rcParams['axes.edgecolor']) self.set_linewidth(rcParams['axes.linewidth']) self.set_capstyle('projecting') self.axis = None self.set_zorder(2.5) self.set_transform(self.axes.transData) # default transform self._bounds = None # default bounds self._smart_bounds = False # Defer initial position determination. (Not much support for # non-rectangular axes is currently implemented, and this lets # them pass through the spines machinery without errors.) self._position = None if not isinstance(path, matplotlib.path.Path): msg = "'path' must be an instance of 'matplotlib.path.Path'" raise ValueError(msg) self._path = path # To support drawing both linear and circular spines, this # class implements Patch behavior three ways. If # self._patch_type == 'line', behave like a mpatches.PathPatch # instance. If self._patch_type == 'circle', behave like a # mpatches.Ellipse instance. If self._patch_type == 'arc', behave like # a mpatches.Arc instance. self._patch_type = 'line' # Behavior copied from mpatches.Ellipse: # Note: This cannot be calculated until this is added to an Axes self._patch_transform = mtransforms.IdentityTransform()
def parseTransformation(transform_text: str) -> mtransforms.Transform: """ convert a transform string in the svg file to a matplotlib transformation """ base_trans = mtransforms.IdentityTransform() if transform_text is None or transform_text == "": return base_trans transformations_list = re.findall(r"\w*\([-.,\d\s]*\)", transform_text) for transform_text in transformations_list: data = [float(s) for s in re.findall(r"[-.\d]+", transform_text)] command = re.findall(r"^\w+", transform_text)[0] if command == "translate": try: ox, oy = data except ValueError: ox, oy = data[0], data[0] base_trans = mtransforms.Affine2D([[1, 0, ox], [0, 1, oy], [0, 0, 1]]) + base_trans elif command == "rotate": a = np.deg2rad(data[0]) ca, sa = np.cos(a), np.sin(a) base_trans = mtransforms.Affine2D([[ca, -sa, 0], [sa, ca, 0], [0, 0, 1]]) + base_trans elif command == "scale": if len(data) >= 2: x, y = data else: x, y = data[0], data[0] base_trans = mtransforms.Affine2D([[x, 0, 0], [0, y, 0], [0, 0, 1] ]) + base_trans elif command == "skewX": x, = data x = np.tan(x * np.pi / 180) base_trans = mtransforms.Affine2D([[1, x, 0], [0, 1, 0], [0, 0, 1] ]) + base_trans elif command == "skewY": y, = data y = np.tan(y * np.pi / 180) base_trans = mtransforms.Affine2D([[1, 0, 0], [y, 1, 0], [0, 0, 1] ]) + base_trans elif command == "matrix": x, sy, sx, y, ox, oy = data base_trans = mtransforms.Affine2D([[x, sx, ox], [sy, y, oy], [0, 0, 1]]) + base_trans else: print("ERROR: unknown transformation", transform_text) return base_trans
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()
def draw(self, renderer): if not self.get_visible(): return renderer.open_group(self.__class__.__name__) transform = self.get_transform() transOffset = self._transOffset offsets = self._offsets if self.have_units(): if len(self._offsets): xs = self.convert_xunits(self._offsets[:0]) ys = self.convert_yunits(self._offsets[:1]) offsets = zip(xs, ys) offsets = np.asarray(offsets, np.float_) if self.check_update('array'): self.update_scalarmappable() clippath, clippath_trans = self.get_transformed_clip_path_and_affine() if clippath_trans is not None: clippath_trans = clippath_trans.frozen() if not transform.is_affine: coordinates = self._coordinates.reshape( (self._coordinates.shape[0] * self._coordinates.shape[1], 2)) coordinates = transform.transform(coordinates) coordinates = coordinates.reshape(self._coordinates.shape) transform = transforms.IdentityTransform() else: coordinates = self._coordinates if not transOffset.is_affine: offsets = transOffset.transform_non_affine(offsets) transOffset = transOffset.get_affine() renderer.draw_quad_mesh( transform.frozen(), self.clipbox, clippath, clippath_trans, self._meshWidth, self._meshHeight, coordinates, offsets, transOffset, self.get_facecolor(), self._antialiased, self._showedges) renderer.close_group(self.__class__.__name__)
def _generate_node_artist(pos, styles, *, ax): N = len(pos) proto_node = next(iter(pos)) x = np.zeros(N) * np.nan y = np.zeros(N) * np.nan properties = { k: [None] * N for k in styles[proto_node] if k in _VALID_NODE_STYLE } for j, node in enumerate(pos): x[j], y[j] = pos[node] for key, values in properties.items(): values[j] = styles[node][key] key_map = { 'size': 'sizes', 'color': 'facecolors', 'shape': 'marker', 'width': 'linewidths', 'edgecolor': 'edgecolors' } renamed_properties = {key_map[k]: v for k, v in properties.items()} markers = renamed_properties.pop('marker', None) if markers is None: paths = (MarkerStyle('o'), ) else: paths = [MarkerStyle(m) for m in markers] paths = [p.get_path().transformed(p.get_transform()) for p in paths] offsets = np.column_stack([x, y]) node_art = PathCollection(paths, offsets=offsets, transOffset=ax.transData, **renamed_properties) node_art.set_transform(mtransforms.IdentityTransform()) ax.add_collection(node_art) ax.autoscale_view() return node_art
def __init__(self, text, anchor_pt, next_pt, ax=None, **kwargs): # Get the Artiste to draw on self.ax = ax or plt.gca() # Save the anchor point self.anchor_pt = np.array(anchor_pt)[None] # Compute the slope of the text in data coordinate system. dx = next_pt[0] - anchor_pt[0] dy = next_pt[1] - anchor_pt[1] ang = np.arctan2(dy, dx) self.angle_data = np.rad2deg(ang) # Create the text objects and display it kwargs.update(rotation_mode=kwargs.get("rotation_mode", "anchor")) kwargs.update(annotation_clip=kwargs.get("annotation_clip", True)) super().__init__(text, anchor_pt, **kwargs) self.set_transform(mpl_transforms.IdentityTransform()) self.ax._add_text(self)
def test_set_offsets_late(): identity = mtransforms.IdentityTransform() sizes = [2] null = mcollections.CircleCollection(sizes=sizes) init = mcollections.CircleCollection(sizes=sizes, offsets=(10, 10)) late = mcollections.CircleCollection(sizes=sizes) late.set_offsets((10, 10)) # Bbox.__eq__ doesn't compare bounds null_bounds = null.get_datalim(identity).bounds init_bounds = init.get_datalim(identity).bounds late_bounds = late.get_datalim(identity).bounds # offsets and transform are applied when set after initialization assert null_bounds != init_bounds assert init_bounds == late_bounds
def check(master_transform, paths, all_transforms, offsets, facecolors, edgecolors): rb = RendererBase() raw_paths = list(rb._iter_collection_raw_paths( master_transform, paths, all_transforms)) gc = rb.new_gc() ids = [path_id for xo, yo, path_id, gc0, rgbFace in rb._iter_collection(gc, master_transform, all_transforms, range(len(raw_paths)), offsets, transforms.IdentityTransform(), facecolors, edgecolors, [], [], [False], [], 'data')] uses = rb._iter_collection_uses_per_path( paths, all_transforms, offsets, facecolors, edgecolors) seen = [0] * len(raw_paths) for i in ids: seen[i] += 1 for n in seen: assert n in (uses-1, uses)
def make_newartist(self, s='', **kywds): self.check_loaded_gp_data() container = self.get_container() xd, yd = self.get_device_point(0) # print xd, yd, self.get_gp(0).x, self.get_gp(0).y kywds['family'] = str(self.getp('fontfamily')) kywds['style'] = str(self.getp('fontstyle')) kywds['weight'] = str(self.getp('fontweight')) # multialingment and horizontal alignment # should be the same, somehow...(2014 01 07) kywds['multialignment'] = str(self.getp('multialignment')) kywds['ha'] = str(self.getp('multialignment')) if self._2d_text: self._artists = [container.text(xd, yd, s, **kywds)] self._artists[0].set_transform(mpltransforms.IdentityTransform()) else: x, y, z, s = self._eval_s() self._artists = [container.text(x, y, z, s, **kywds)] lp = self.getp("loaded_property") if lp is not None: self.set_artist_property(self._artists[0], lp[0]) # self._artists[0].set_size(self.getp('size')) self._artists[0].figobj = self self._artists[0].figobj_hl = [] self._artists[0].set_zorder(self.getp('zorder')) if self.get_figaxes() is not None and self.getp('clip'): bbox = mpltransforms.Bbox.from_extents( container.get_window_extent().extents) try: self._artists[0].set_clip_box(bbox) self._artists[0].set_clip_on(True) self._artists[0]._bbox_patch.set_clip_box(bbox) self._artists[0]._bbox_patch.set_clip_on(True) except: pass self.delp("loaded_property") return self._artists[0]
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._numsides = numsides self._paths = [self._path_generator(numsides)] self._rotation = rotation self.set_transform(transforms.IdentityTransform())
def test_start_with_moveto(): # Should be entirely clipped away to a single MOVETO data = b""" ZwAAAAku+v9UAQAA+Tj6/z8CAADpQ/r/KAMAANlO+v8QBAAAyVn6//UEAAC6ZPr/2gUAAKpv+v+8 BgAAm3r6/50HAACLhfr/ewgAAHyQ+v9ZCQAAbZv6/zQKAABepvr/DgsAAE+x+v/lCwAAQLz6/7wM AAAxx/r/kA0AACPS+v9jDgAAFN36/zQPAAAF6Pr/AxAAAPfy+v/QEAAA6f36/5wRAADbCPv/ZhIA AMwT+/8uEwAAvh77//UTAACwKfv/uRQAAKM0+/98FQAAlT/7/z0WAACHSvv//RYAAHlV+/+7FwAA bGD7/3cYAABea/v/MRkAAFF2+//pGQAARIH7/6AaAAA3jPv/VRsAACmX+/8JHAAAHKL7/7ocAAAP rfv/ah0AAAO4+/8YHgAA9sL7/8QeAADpzfv/bx8AANzY+/8YIAAA0OP7/78gAADD7vv/ZCEAALf5 +/8IIgAAqwT8/6kiAACeD/z/SiMAAJIa/P/oIwAAhiX8/4QkAAB6MPz/HyUAAG47/P+4JQAAYkb8 /1AmAABWUfz/5SYAAEpc/P95JwAAPmf8/wsoAAAzcvz/nCgAACd9/P8qKQAAHIj8/7cpAAAQk/z/ QyoAAAWe/P/MKgAA+aj8/1QrAADus/z/2isAAOO+/P9eLAAA2Mn8/+AsAADM1Pz/YS0AAMHf/P/g LQAAtur8/10uAACr9fz/2C4AAKEA/f9SLwAAlgv9/8ovAACLFv3/QDAAAIAh/f+1MAAAdSz9/ycx AABrN/3/mDEAAGBC/f8IMgAAVk39/3UyAABLWP3/4TIAAEFj/f9LMwAANm79/7MzAAAsef3/GjQA ACKE/f9+NAAAF4/9/+E0AAANmv3/QzUAAAOl/f+iNQAA+a/9/wA2AADvuv3/XDYAAOXF/f+2NgAA 29D9/w83AADR2/3/ZjcAAMfm/f+7NwAAvfH9/w44AACz/P3/XzgAAKkH/v+vOAAAnxL+//04AACW Hf7/SjkAAIwo/v+UOQAAgjP+/905AAB5Pv7/JDoAAG9J/v9pOgAAZVT+/606AABcX/7/7zoAAFJq /v8vOwAASXX+/207AAA/gP7/qjsAADaL/v/lOwAALZb+/x48AAAjof7/VTwAABqs/v+LPAAAELf+ /788AAAHwv7/8TwAAP7M/v8hPQAA9df+/1A9AADr4v7/fT0AAOLt/v+oPQAA2fj+/9E9AADQA/// +T0AAMYO//8fPgAAvRn//0M+AAC0JP//ZT4AAKsv//+GPgAAojr//6U+AACZRf//wj4AAJBQ///d PgAAh1v///c+AAB+Zv//Dz8AAHRx//8lPwAAa3z//zk/AABih///TD8AAFmS//9dPwAAUJ3//2w/ AABHqP//ej8AAD6z//+FPwAANb7//48/AAAsyf//lz8AACPU//+ePwAAGt///6M/AAAR6v//pj8A AAj1//+nPwAA/////w==""" import base64 if hasattr(base64, 'encodebytes'): # Python 3 case decodebytes = base64.decodebytes else: # Python 2 case decodebytes = base64.decodestring verts = np.fromstring(decodebytes(data), dtype='<i4') verts = verts.reshape((len(verts) / 2, 2)) path = Path(verts) segs = path.iter_segments(transforms.IdentityTransform(), clip=(0.0, 0.0, 100.0, 100.0)) segs = list(segs) assert len(segs) == 1 assert segs[0][1] == Path.MOVETO
def create_labels(da, labels, locations, direction): """ Return an OffsetBox with label texts """ # The box dimensions are determined by the size of # the text objects. We put two dummy children at # either end to gaurantee that when center packed # the labels in the labels_box matchup with the ticks. fontsize = 9 aux_transform = mtransforms.IdentityTransform() labels_box = MyAuxTransformBox(aux_transform) xs, ys = [0]*len(labels), locations ha, va = 'left', 'center' x1, y1 = 0, 0 x2, y2 = 0, da.height if direction == 'horizontal': xs, ys = ys, xs ha, va = 'center', 'top' x2, y2 = da.width, 0 txt1 = mtext.Text(x1, y1, '', horizontalalignment=ha, verticalalignment=va) txt2 = mtext.Text(x2, y2, '', horizontalalignment=ha, verticalalignment=va) labels_box.add_artist(txt1) labels_box.add_artist(txt2) legend_text = [] for i, (x, y, text) in enumerate(zip(xs, ys, labels)): txt = mtext.Text(x, y, text, size=fontsize, horizontalalignment=ha, verticalalignment=va) labels_box.add_artist(txt) legend_text.append(txt) return labels_box, legend_text
def svgread(filename: str): """ read an SVG file """ doc = minidom.parse(filename) svg = doc.getElementsByTagName("svg")[0] try: x1, y1, x2, y2 = [ svgUnitToMpl(s.strip()) for s in svg.getAttribute("viewBox").split() ] width, height = (x2 - x1) / plt.gcf().dpi, (y2 - y1) / plt.gcf().dpi if max([width, height]) > 8: f = 8 / max([width, height]) plt.gcf().set_size_inches(width * f, height * f) else: plt.gcf().set_size_inches(width, height) except ValueError: width = svgUnitToMpl(svg.getAttribute("width"), default=100) height = svgUnitToMpl(svg.getAttribute("height"), default=100) x1, y1, x2, y2 = 0, 0, width, height width /= plt.gcf().dpi height /= plt.gcf().dpi if max([width, height]) > 8: f = 8 / max([width, height]) plt.gcf().set_size_inches(width * f, height * f) else: plt.gcf().set_size_inches(width, height) ax = plt.axes([0, 0, 1, 1], label=filename, frameon=False) plt.xticks([]) plt.yticks([]) for spine in ["left", "right", "top", "bottom"]: ax.spines[spine].set_visible(False) plt.xlim(x1, x2) plt.ylim(y2, y1) parseGroup( doc.getElementsByTagName("svg")[0], mtransforms.IdentityTransform(), {}, {"css": []})
def shadow_curve(): x = np.arange(0., 2., 0.01) y = np.sin(2 * np.pi * x) # 设置阴影的条数 N = 7 for i in xrange(N, 0, -1): # 向X轴偏移i单位,向Y轴偏移i单位 offset = transforms.ScaledTranslation(i, -i, transforms.IdentityTransform()) shadow_trans = plt.gca().transData + offset # shadow_trans = plt.gca().transAxes + offset # 将shadow_trans参数传给transform plt.plot(x, y, lw=4, color="black", transform=shadow_trans, alpha=(N - i) / 2.0 / N) plt.plot(x, y, lw=4, color="black") plt.ylim((-1.5, 1.5)) plt.show()
def my_scatter(self, ax, x, y): from matplotlib.collections import PathCollection from matplotlib.path import Path import matplotlib.transforms as mtransforms phi = np.linspace(0, 2 * np.pi, 100) # Scale, in pixel coordinates rad = 2 x_circle = np.cos(phi) * rad y_circle = np.sin(phi) * rad verts = np.vstack([x_circle, y_circle]).T path = Path(verts, closed=False) collection = PathCollection( [path], facecolor='blue', edgecolor='black', transOffset=ax.transData, ) collection.set_transform(mtransforms.IdentityTransform()) ax.add_collection(collection, autolim=True) ax.autoscale()
def _set_lim_and_transforms(self): """Override transform initialization.""" # axis coords to display coords self.transAxes = transforms.BboxTransformTo(self.bbox) # X and Y axis scaling self.transScale = transforms.TransformWrapper( transforms.IdentityTransform()) # transform from given Bbox to unit Bbox # the given transformedBbox is updated every time the # viewLim changes or the transScale changes self.transLimits = transforms.BboxTransformFrom( transforms.TransformedBbox(self.viewLim, self.transScale)) # data to display coordinates self.transData = self.transScale + (self.transLimits + self.transAxes) # blended transforms for xaxis and yaxis self._xaxis_transform = transforms.blended_transform_factory( self.transData, self.transAxes) self._yaxis_transform = transforms.blended_transform_factory( self.transAxes, self.transData)
def twin(self, aux_trans=None, axes_class=None): """ Create a twin of Axes with no shared axis. While self will have ticks on the left and bottom axis, the returned axes will have ticks on the top and right axis. """ if axes_class is None: axes_class = self._get_base_axes() parasite_axes_auxtrans_class = \ parasite_axes_auxtrans_class_factory(axes_class) if aux_trans is None: ax2 = parasite_axes_auxtrans_class(self, mtransforms.IdentityTransform(), viewlim_mode="equal") else: ax2 = parasite_axes_auxtrans_class(self, aux_trans, viewlim_mode="transform") self.parasites.append(ax2) ax2._remove_method = self.parasites.remove self.axis["top", "right"].set_visible(False) ax2.axis["top", "right"].set_visible(True) ax2.axis["left", "bottom"].set_visible(False) def _remove_method(h): self.parasites.remove(h) self.axis["top", "right"].set_visible(True) self.axis["top", "right"].toggle(ticklabels=False, label=False) ax2._remove_method = _remove_method return ax2
def draw(self, renderer): if not self.get_visible(): return renderer.open_group(self.__class__.__name__) transform = self.get_transform() # Get a list of triangles and the color at each vertex. verts = self._verts self.update_scalarmappable() colors = self._facecolors.reshape(-1, 3, 4) oldshape = list(verts.shape) verts = transform.transform(verts.reshape(-1, 2)).reshape(oldshape) gc = renderer.new_gc() self._set_gc_clip(gc) gc.set_linewidth(self.get_linewidth()[0]) renderer.draw_gouraud_triangles(gc, verts, colors, mtransforms.IdentityTransform()) gc.restore() renderer.close_group(self.__class__.__name__)