class AnchoredSizeBar(AnchoredOffsetbox): def __init__(self, transform, size, label, loc, pad=0.1, borderpad=0.1, sep=2, prop=None, frameon=True): """ Draw a horizontal bar with the size in data coordinate of the given axes. A label will be drawn underneath (center-aligned). pad, borderpad in fraction of the legend font size (or prop) sep in points. """ self.size_bar = AuxTransformBox(transform) self.size_bar.add_artist(Rectangle((0, 0), size, 0, fc="none", lw=1.0)) self.txt_label = TextArea(label, minimumdescent=False) self._box = VPacker(children=[self.size_bar, self.txt_label], align="center", pad=0, sep=sep) AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad, child=self._box, prop=prop, frameon=frameon)
class AnchoredSizeBar(AnchoredOffsetbox): def __init__(self, transform, size, label, loc, pad=0.1, borderpad=0.1, sep=2, prop=None, frameon=True): """ Draw a horizontal bar with the size in data coordinate of the give axes. A label will be drawn underneath (center-aligned). pad, borderpad in fraction of the legend font size (or prop) sep in points. loc: 'upper right' : 1, 'upper left' : 2, 'lower left' : 3, 'lower right' : 4, 'right' : 5, 'center left' : 6, 'center right' : 7, 'lower center' : 8, 'upper center' : 9, 'center' : 10 """ self.size_bar = AuxTransformBox(transform) self.size_bar.add_artist(Rectangle((0, 0), size, 0, fc='none', color='white', lw=3)) self.txt_label = TextArea(label, dict(color='white', size='x-large', weight='normal'), minimumdescent=False) self._box = VPacker(children=[self.size_bar, self.txt_label], align="center", pad=0, sep=sep) AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad, child=self._box, prop=prop, frameon=frameon)
def __init__(self, transform, sizex=0, sizey=0, labelx=None, labely=None, loc=4, pad=0.1, borderpad=0.1, sep=2, prop=None, barcolor="black", barwidth=None, **kwargs): """ Draw a horizontal and/or vertical bar with the size in data coordinate of the give axes. A label will be drawn underneath (center-aligned). - transform : the coordinate frame (typically axes.transData) - sizex,sizey : width of x,y bar, in data units. 0 to omit - labelx,labely : labels for x,y bars; None to omit - loc : position in containing axes - pad, borderpad : padding, in fraction of the legend font size (or prop) - sep : separation between labels and bars in points. - **kwargs : additional arguments passed to base class constructor """ from matplotlib.patches import Rectangle from matplotlib.offsetbox import AuxTransformBox, VPacker, HPacker, TextArea, DrawingArea bars = AuxTransformBox(transform) if sizex: bars.add_artist(Rectangle((0,0), sizex, 0, ec=barcolor, lw=barwidth, fc="none")) if sizey: bars.add_artist(Rectangle((0,0), 0, sizey, ec=barcolor, lw=barwidth, fc="none")) if sizex and labelx: self.xlabel = TextArea(labelx, minimumdescent=False) bars = VPacker(children=[bars, self.xlabel], align="center", pad=0, sep=sep) if sizey and labely: self.ylabel = TextArea(labely) bars = HPacker(children=[self.ylabel, bars], align="center", pad=0, sep=sep) AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad, child=bars, prop=prop, frameon=False, **kwargs)
def display_points(self, image_idx, image): visible_points_coords = self.database.get_visible_points_coords(image) self.clear_images(image_idx) for point_id, coords in visible_points_coords.items(): color = distinct_colors[divmod(hash(point_id), 19)[1]] text_path = TextPath((0, 0), point_id, size=10) p1 = PathPatch(text_path, transform=IdentityTransform(), alpha=1, color=color) offsetbox2 = AuxTransformBox(IdentityTransform()) offsetbox2.add_artist(p1) ab = AnnotationBbox(offsetbox2, ((coords[0] + 30), (coords[1] + 30)), bboxprops=dict(alpha=0.05)) circle = mpatches.Circle((coords[0], coords[1]), 20, color=color, fill=False) self.plt_artists[image_idx].append(ab) self.plt_artists[image_idx].append(circle) self.subplots[image_idx].add_artist(ab) self.subplots[image_idx].add_artist(circle) self.figures[image_idx].canvas.draw_idle()
def text_banner(axes, text, facecolor="red", edgecolor="darkred", linewidth=1, alpha=0.3, angleadjust=True, zorder=0): """ Paint text across a hole axes. For height > width, angleadjust should be False. """ # draw the text into a patch textpath = TextPath((0, 0), text, size=20, transform=axes.transAxes) tp_bbox = textpath.get_extents() patch = PathPatch(textpath, fc=facecolor, ec=edgecolor, lw=linewidth, alpha=alpha, transform=IdentityTransform(), zorder=11) # get angle and scale to transform text to axes coordinates ax_bbox = axes.get_window_extent() angle = math.atan2(ax_bbox.height, ax_bbox.width) * \ (ax_bbox.height/ax_bbox.width if angleadjust else 1) scale = min(*rotated_scale(tp_bbox.width, tp_bbox.height, angle, ax_bbox.width, ax_bbox.height))*0.95 # paint the patch into the axes offsetbox = AuxTransformBox(Affine2D().rotate(angle).scale(scale)) offsetbox.add_artist(patch) artist = AnnotationBbox(offsetbox, (0.5, 0.5), xycoords='axes fraction', frameon=False) artist.set_zorder(zorder) axes.add_artist(artist)
class AnchoredEllipse(AnchoredOffsetbox): def __init__(self, transform, width, height, angle, loc, pad=0.1, borderpad=0.1, prop=None, frameon=True, **kwargs): """ Draw an ellipse the size in data coordinate of the give axes. pad, borderpad in fraction of the legend font size (or prop) """ self._box = AuxTransformBox(transform) self.ellipse = Ellipse((0, 0), width, height, angle) self._box.add_artist(self.ellipse) AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad, child=self._box, prop=prop, frameon=frameon, **kwargs)
def display_points(self, view): visible_points_coords = self.database.get_visible_points_coords( view.current_image) self.clear_artists(view) for point_id, coords in visible_points_coords.items(): color = distinct_colors[divmod(hash(point_id), 19)[1]] text_path = TextPath((0, 0), point_id, size=10) p1 = PathPatch(text_path, transform=IdentityTransform(), alpha=1, color=color) offsetbox2 = AuxTransformBox(IdentityTransform()) offsetbox2.add_artist(p1) ab = AnnotationBbox(offsetbox2, ((coords[0] + 30), (coords[1] + 30)), bboxprops=dict(alpha=0.05)) circle = mpatches.Circle((coords[0], coords[1]), 10, color=color, fill=False) dot = mpatches.Circle((coords[0], coords[1]), 2, color=color, fill=False) for art in (ab, circle, dot): view.plt_artists.append(art) view.subplot.add_artist(art) view.figure.canvas.draw()
def __init__(self, transform, sizex=0, sizey=0, labelx=None, labely=None, loc=3, pad=0.1, borderpad=0.1, sep=2, prop=None, **kwargs): """ Draw a horizontal and/or vertical bar with the size in data coordinate of the give axes. A label will be drawn underneath (center-aligned). - transform : the coordinate frame (typically axes.transData) - sizex,sizey : width of x,y bar, in data units. 0 to omit - labelx,labely : labels for x,y bars; None to omit - loc : position in containing axes - pad, borderpad : padding, in fraction of legend font size (or prop) - sep : separation between labels and bars in points. - **kwargs : additional arguments passed to base class constructor """ from matplotlib.patches import Rectangle from matplotlib.offsetbox import AuxTransformBox, VPacker, HPacker from matplotlib.offsetbox import TextArea, DrawingArea bars = AuxTransformBox(transform) if sizex: bars.add_artist(Rectangle((0, 0), sizex, 0, fc="none")) if sizey: bars.add_artist(Rectangle((0, 0), 0, sizey, fc="none")) if sizex and labelx: bars = VPacker(children=[bars, TextArea(labelx, minimumdescent=False)], align="center", pad=0, sep=sep) if sizey and labely: bars = HPacker(children=[TextArea(labely), bars], align="center", pad=0, sep=sep) AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad, child=bars, prop=prop, frameon=False, **kwargs)
class AnchoredEllipseBeam(AnchoredOffsetbox ): #class that I need for plotting ellipse def __init__(self, transform, width, height, angle, loc='lower left', pad=0.5, borderpad=0.1, prop=None, frameon=False): """ Draw an ellipse the size in data coordinate of the give axes. pad, borderpad in fraction of the legend font size (or prop) """ self._box = AuxTransformBox(transform) self.ellipse = Ellipse((0, 0), width, height, angle, fill=False, color='k', lw=2) self._box.add_artist(self.ellipse) super().__init__(loc, pad=pad, borderpad=borderpad, child=self._box, prop=prop, frameon=frameon)
class AnchoredEllipse(AnchoredOffsetbox): def __init__(self, transform, width, height, angle, loc, pad=0.1, borderpad=0.1, prop=None, frameon=True, **kwargs): """ Draw an anchored ellipse of a given size. Parameters ---------- transform : `matplotlib.transforms.Transform` The transformation object for the coordinate system in use, i.e., :attr:`matplotlib.axes.Axes.transData`. width, height : float Width and height of the ellipse, given in coordinates of *transform*. angle : float Rotation of the ellipse, in degrees, anti-clockwise. loc : str Location of this ellipse. Valid locations are 'upper left', 'upper center', 'upper right', 'center left', 'center', 'center right', 'lower left', 'lower center, 'lower right'. For backward compatibility, numeric values are accepted as well. See the parameter *loc* of `.Legend` for details. pad : float, default: 0.1 Padding around the ellipse, in fraction of the font size. borderpad : float, default: 0.1 Border padding, in fraction of the font size. frameon : bool, default: True If True, draw a box around the ellipse. prop : `matplotlib.font_manager.FontProperties`, optional Font property used as a reference for paddings. **kwargs Keyword arguments forwarded to `.AnchoredOffsetbox`. Attributes ---------- ellipse : `matplotlib.patches.Ellipse` Ellipse patch drawn. """ self._box = AuxTransformBox(transform) self.ellipse = Ellipse((0, 0), width, height, angle) self._box.add_artist(self.ellipse) super().__init__(loc, pad=pad, borderpad=borderpad, child=self._box, prop=prop, frameon=frameon, **kwargs)
def __init__(self, transform, fig_transform, sizex=0, sizey=0, labelx=None, labely=None, loc=4, xbar_width = 2, ybar_width = 2, pad=3, borderpad=0.1, xsep=3, ysep = 3, prop=None, textprops={'size':10}, **kwargs): """ Draw a horizontal and/or vertical bar with the size in data coordinate of the give axes. A label will be drawn underneath (center-aligned). - transform : the coordinate frame (typically axes.transData) - sizex,sizey : width of x,y bar, in data units. 0 to omit - labelx,labely : labels for x,y bars; None to omit - loc : position in containing axes - pad, borderpad : padding, in fraction of the legend font size (or prop) - sep : separation between labels and bars in points. - **kwargs : additional arguments passed to base class constructor """ from matplotlib.patches import Rectangle from matplotlib.offsetbox import AuxTransformBox, VPacker, HPacker, TextArea, DrawingArea # new shit # try splitting the transform into X and Y so that import matplotlib.transforms as transforms xtransform = transforms.blended_transform_factory(transform, fig_transform) ytransform = transforms.blended_transform_factory(fig_transform, transform) # end new shit # bars = AuxTransformBox(xtransform) # if sizey: # bars.add_artist(Rectangle((0,0), ybar_width, sizey, # fc="Black")) # if sizex: # bars.add_artist(Rectangle((0,0), sizex, xbar_width, # fc="Black")) ybar_width /= 72. xbar_width /= 72. if sizey: ybar = AuxTransformBox(ytransform) ybar.add_artist(Rectangle((0,0), ybar_width, sizey, fc="Black")) bars = ybar if sizex: xbar = AuxTransformBox(xtransform) xbar.add_artist(Rectangle((0,0), sizex, xbar_width, fc="Black")) bars = xbar if sizex and sizey: bars = VPacker(children=[ybar, xbar], pad = 10, sep=ysep) if sizex and labelx: bars = VPacker(children=[bars, TextArea(labelx, minimumdescent=False, textprops = textprops)], align="center", pad=0, sep=-3) if sizey and labely: bars = HPacker(children=[TextArea(labely, textprops = textprops), bars], align="center", pad=0, sep=xsep) AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad, child=bars, prop=prop, frameon=False, **kwargs)
class AnchoredEllipse(AnchoredOffsetbox): def __init__(self, transform, width, height, angle, loc, pad=0.1, borderpad=0.1, prop=None, frameon=True): """ Draw an ellipse the size in data coordinate of the give axes. pad, borderpad in fraction of the legend font size (or prop) """ self._box = AuxTransformBox(transform) self.ellipse = Ellipse((0, 0), width, height, angle) self._box.add_artist(self.ellipse) AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad, child=self._box, prop=prop, frameon=frameon)
def __init__( self, transform, sizex=0, sizey=0, labelx=None, labely=None, loc=4, pad=0.1, borderpad=0.1, sep=2, prop=None, label_fontsize=label_fontsize, color="k", **kwargs ): """ Draw a horizontal and/or vertical bar with the size in data coordinate of the give axes. A label will be drawn underneath (center-aligned). - transform : the coordinate frame (typically axes.transData) - sizex,sizey : width of x,y bar, in data units. 0 to omit - labelx,labely : labels for x,y bars; None to omit - loc : position in containing axes - pad, borderpad : padding, in fraction of the legend font size (or prop) - sep : separation between labels and bars in points. - **kwargs : additional arguments passed to base class constructor """ from matplotlib.patches import Rectangle from matplotlib.offsetbox import AuxTransformBox, VPacker, HPacker, TextArea, DrawingArea bars = AuxTransformBox(transform) if sizex: bars.add_artist(Rectangle((0, 0), sizex, 0, fc="none", linewidth=axes_linewidth, color=color)) if sizey: bars.add_artist(Rectangle((0, 0), 0, sizey, fc="none", linewidth=axes_linewidth, color=color)) if sizex and labelx: textareax = TextArea(labelx, minimumdescent=False, textprops=dict(size=label_fontsize, color=color)) bars = VPacker(children=[bars, textareax], align="center", pad=0, sep=sep) if sizey and labely: ## VPack a padstr below the rotated labely, else label y goes below the scale bar ## Just adding spaces before labely doesn't work! padstr = "\n " * len(labely) textareafiller = TextArea(padstr, textprops=dict(size=label_fontsize / 3.0)) textareay = TextArea(labely, textprops=dict(size=label_fontsize, rotation="vertical", color=color)) ## filler / pad string VPack-ed below labely textareayoffset = VPacker(children=[textareay, textareafiller], align="center", pad=0, sep=sep) ## now HPack this padded labely to the bars bars = HPacker(children=[textareayoffset, bars], align="top", pad=0, sep=sep) AnchoredOffsetbox.__init__( self, loc, pad=pad, borderpad=borderpad, child=bars, prop=prop, frameon=False, **kwargs )
class AnchoredSizeBar(AnchoredOffsetbox): def __init__(self, transform, size, label, loc, pad=0.1, borderpad=0.1, sep=2, prop=None, frameon=True): """ Draw a horizontal bar with the size in data coordinate of the give axes. A label will be drawn underneath (center-alinged). pad, borderpad in fraction of the legend font size (or prop) sep in points. """ self.size_bar = AuxTransformBox(transform) self.size_bar.add_artist(Rectangle((0, 0), size, 0, fc="none")) self.txt_label = TextArea(label, minimumdescent=False) self._box = VPacker(children=[self.size_bar, self.txt_label], align="center", pad=0, sep=sep) AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad, child=self._box, prop=prop, frameon=frameon)
class ScaleBar(AnchoredOffsetbox): def __init__(self, ax, label, bar_length, **props): ''' Draw a horizontal bar with the size in data coordinate of the give axes. A label will be drawn above (center-aligned). ''' label_size = props['label_size'] if 'label_size' in props else \ rcParams.get('scalebar.label_size', 16) label_family = props['label_family'] if 'label_family' in props else \ rcParams.get('scalebar.label_family', 'sans-serif') label_color = props['label_color'] if 'label_color' in props else \ rcParams.get('scalebar.label_color', 'black') location = props['location'] if 'location' in props else \ rcParams.get('scalebar.location', 4) padding = props['padding'] if 'padding' in props else \ rcParams.get('scalebar.padding', 0.5) sep = props['sep'] if 'sep' in props else \ rcParams.get('scalebar.sep', 2) bar_color = props['bar_color'] if 'bar_color' in props else \ rcParams.get('scalebar.bar_color', 'black') bar_width = props['bar_width'] if 'bar_width' in props else \ rcParams.get('scalebar.bar_width', 0.1) bar_length = props['bar_length'] if 'bar_length' in props else \ rcParams.get('scalebar.bar_length', 0.8) frameon = False prop = None self.scale_bar = AuxTransformBox(ax.transData) rect = mpatches.Rectangle((0, 0), bar_length, bar_width, linewidth=0, edgecolor=None, facecolor=bar_color) self.scale_bar.add_artist(rect) textprops = {'size': label_size} self.txt_label = TextArea(label, textprops=textprops, minimumdescent=False) self._box = VPacker(children=[self.txt_label, self.scale_bar], align="center", pad=0, sep=sep) AnchoredOffsetbox.__init__(self, location, pad=padding, borderpad=0, child=self._box, prop=prop, frameon=frameon)
def create_rect_patch(ec="#000000", fc=None): _box = AuxTransformBox(transforms.IdentityTransform()) rect = FancyBboxPatch( xy=(0, 0), width=0.02, height=0.02, boxstyle='square', ec=ec, fc=fc, mutation_scale=14, # font size transform=trans, alpha=1.0 if (ec is not None or fc is not None) else 0.0) _box.add_artist(rect) return _box
def create_rect_patch(ec="#000000", fc=None): _box = AuxTransformBox(transforms.IdentityTransform()) rect = FancyBboxPatch( xy=(0, 0), width=0.02, height=0.02, boxstyle='square', ec=ec, fc=fc, mutation_scale=14, # font size transform=trans, alpha=1.0 if (ec is not None or fc is not None) else 0.0 ) _box.add_artist(rect) return _box
def DrawGraph(self, rnd=None): """ Draw Graph """ plt.clf() if rnd is not None: plt.plot(rnd[0], rnd[1], "^k") for node in self.nodeList: if node.parent is not None: plt.plot([node.x, self.nodeList[node.parent].x], [node.y, self.nodeList[node.parent].y], "-g", alpha=0.2) # Plot the environment boundary xy, w, h = (-1.2, -0.2), 2.4, 2.2 r = Rectangle(xy, w, h, fc='none', ec='gold', lw=1) offsetbox = AuxTransformBox(plt.axes().transData) offsetbox.add_artist(r) ab = AnnotationBbox(offsetbox, (xy[0] + w / 2., xy[1] + w / 2.), boxcoords="data", pad=0.52, fontsize=20, bboxprops=dict(facecolor="none", edgecolor='k', lw=20)) plt.axes().add_artist(ab) # Plot the rectangle obstacles obstacles = [ Rectangle( xy=[ox, oy], width=wd, height=ht, angle=0, color="k", facecolor="k", ) for (ox, oy, wd, ht) in self.obstacleList ] for obstacle in obstacles: plt.axes().add_artist(obstacle) plt.plot(self.start.x, self.start.y, "xr") plt.plot(self.end.x, self.end.y, "xr") plt.axis([-1.3, 1.3, -0.3, 2.3]) plt.grid(True) plt.pause(0.01)
class AnchoredRectangle(AnchoredOffsetbox): def __init__(self, transform, width, height, loc, pad=0.1, borderpad=0.1, prop=None, frameon=False, color="white"): """ Draw a rectangle the size in data coordinate of the give axes. pad, borderpad in fraction of the legend font size (or prop) adapted from :class:`AnchoredEllipse` """ self._box = AuxTransformBox(transform) self.rectangle = patches.Rectangle((2, 1), width, height, color=color) self._box.add_artist(self.rectangle) AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad, child=self._box, prop=prop, frameon=frameon)
class AnchoredSizeBar(AnchoredOffsetbox): def __init__(self, transform, size, label, loc, pad=0.1, borderpad=0.1, sep=2, prop=None, frameon=True): """ Draw a horizontal bar with the size in data coordinate of the given axes. A label will be drawn underneath (center-aligned). pad, borderpad in fraction of the legend font size (or prop) sep in points. """ self.size_bar = AuxTransformBox(transform) self.size_bar.add_artist(Line2D([0, size], [0, 0], color="black")) self.txt_label = TextArea(label) self._box = VPacker(children=[self.size_bar, self.txt_label], align="center", pad=0, sep=sep) super().__init__(loc, pad=pad, borderpad=borderpad, child=self._box, prop=prop, frameon=frameon)
def PlotObstacles(self): """ Plots the obstacles and the starting position. """ # Plot the Starting position plt.plot(self.start.means[-1,0,:], self.start.means[-1,1,:], "Xr",markersize=20) plt.axis([-1.3, 1.3, -0.3, 2.3]) # Plot the environment boundary xy, w, h = (-1.2, -0.2), 2.4, 2.2 r = Rectangle(xy, w, h, fc='none', ec='gold', lw=1) offsetbox = AuxTransformBox(plt.axes().transData) offsetbox.add_artist(r) ab = AnnotationBbox(offsetbox, (xy[0]+w/2.,xy[1]+w/2.), boxcoords="data", pad=0.52,fontsize=20, bboxprops=dict(facecolor = "none", edgecolor='k', lw = 20)) plt.axes().add_artist(ab) # Change ticklabel font size plt.xticks(fontsize=30) plt.yticks(fontsize=30) # Plot the rectangle obstacles obstacles = [Rectangle(xy = [ox, oy], width = wd, height = ht, angle = 0, color = "k", facecolor = "k",) for (ox, oy, wd, ht) in self.obstacleList] for obstacle in obstacles: plt.axes().add_artist(obstacle) # Data for plotting the shaded goal region goalHeight = self.ymingoal x = [-1.20,-1.15,-1.10,-1.05, -1.00] y1 = [goalHeight]*len(x) plt.text(-1.10, 1.0, 'GOAL', rotation=0, weight="bold", color='white', size=20,horizontalalignment='center', verticalalignment='top', multialignment='center') # Shade the area between y1 and line y=2.10 plt.fill_between(x, y1, self.ymaxgoal, facecolor="#CAB8CB", # The fill color color='#CAB8CB') # The outline color
def add_inner_title(ax, title, loc, size=None, **kwargs): from matplotlib.offsetbox import AuxTransformBox, AnchoredOffsetbox from matplotlib.font_manager import FontProperties from matplotlib.patches import PathPatch from matplotlib.textpath import TextPath from matplotlib.transforms import IdentityTransform if size is None: size = FontProperties(size=plt.rcParams['legend.fontsize']) text_path = TextPath((0, 0), title, size=10) p1 = PathPatch(text_path, ec="w", lw=3, transform=IdentityTransform()) p2 = PathPatch(text_path, ec="none", fc="k", transform=IdentityTransform()) offsetbox = AuxTransformBox(IdentityTransform()) offsetbox.add_artist(p1) offsetbox.add_artist(p2) ao = AnchoredOffsetbox(loc=loc, child=offsetbox, pad=0., borderpad=0.5, frameon=False, **kwargs) ax.add_artist(ao) return ao
class AnchoredBasisVector(AnchoredOffsetbox): def __init__(self, transform, vectors, labels, loc=1, color="black", **kwargs): """ Draw a horizontal bar with the size in data coordinate of the give axes. A label will be drawn underneath (center-aligned). kwargs are passed to AnchoredOffsetbox. """ self.basis_vector = AuxTransformBox(transform) vnorm = np.average([np.linalg.norm(v) for v in vectors]) head_width = 0.3 * vnorm head_length = 0.3 * vnorm position = np.array([0, 0]) if labels is None: labels = [None] * len(vectors) for vector, label in zip(vectors, labels): v2d = np.array(vector[:2]) arrow = FancyArrow(*position, *v2d, color=color, head_width=head_width, head_length=head_length) self.basis_vector.add_artist(arrow) if label is not None: pos = position + v2d * 1.9 label = Text(*pos, label, horizontalalignment='center', verticalalignment='center') self.basis_vector.add_artist(label) AnchoredOffsetbox.__init__(self, loc, child=self.basis_vector)
class AnchoredEllipse(AnchoredOffsetbox): def __init__(self, transform, width, height, angle, loc, pad=0.1, borderpad=0.1, prop=None, frameon=False, color="white"): """ Draw an ellipse the size in data coordinate of the give axes. pad, borderpad in fraction of the legend font size (or prop) Copied from https://matplotlib.org/mpl_toolkits/axes_grid/api/anchored_artists_api.html Adapted it a bit (I think) Check how to use original class properly. """ self._box = AuxTransformBox(transform) self.ellipse = patches.Ellipse((0, 0), width, height, angle, color=color) self._box.add_artist(self.ellipse) AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad, child=self._box, prop=prop, frameon=frameon)
def __init__(self, transform, sizex=0, sizey=0, labelx=None, labely=None, loc=4, pad=0.1, borderpad=0.1, sep=2, prop=None, **kwargs): from matplotlib.patches import Rectangle from matplotlib.offsetbox import AuxTransformBox, VPacker, HPacker, TextArea, DrawingArea bars = AuxTransformBox(transform) if sizex: bars.add_artist(Rectangle((0,0), sizex, 0, fc="none")) if sizey: bars.add_artist(Rectangle((0,0), 0, sizey, fc="none")) if sizex and labelx: bars = VPacker(children=[bars, TextArea(labelx, minimumdescent=False)], align="center", pad=0, sep=sep) if sizey and labely: bars = HPacker(children=[TextArea(labely), bars], align="center", pad=0, sep=sep) AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad, child=bars, prop=prop, frameon=False, **kwargs)
def AddTraceScaleBar(xunit, yunit, color='k',linewidth=None,\ fontsize=None, ax=None, xscale=None, yscale=None, loc=5, bbox_to_anchor=None): """Add scale bar on trace. Specifically designed for voltage / current / stimulus vs. time traces. xscale, yscale: add the trace bar to the specified window of x and y. """ if ax is None: ax=plt.gca() def scalebarlabel(x, unitstr): x = int(x) if unitstr.lower()[0] == 'm': return(str(x)+unitstr if x<1000 else str(int(x/1000))+ unitstr.replace('m','')) elif unitstr.lower()[0] == 'p': return(str(x)+unitstr if x<1000 else str(int(x/1000))+ unitstr.replace('p','n')) else: # no prefix return(str(x)+unitstr) ax.set_axis_off() # turn off axis X = np.ptp(ax.get_xlim()) if xscale is None else xscale Y = np.ptp(ax.get_ylim()) if yscale is None else yscale # calculate scale bar unit length X, Y = roundto125(X/5), roundto125(Y/(5 if Y<1200 else 10)) # Parse scale bar labels xlab, ylab = scalebarlabel(X, xunit), scalebarlabel(Y, yunit) # Get color of the scalebar if color is None: color = ax.get_lines()[0] if 'matplotlib.lines.Line2D' in str(type(color)): color = color.get_color() if linewidth is None: try: linewidth = ax.get_lines()[0] except: raise(AttributeError('Did not find any line in this axis. Please explicitly specify the linewidth')) if 'matplotlib.lines.Line2D' in str(type(linewidth)): linewidth = linewidth.get_linewidth() # print(linewidth) if fontsize is None: fontsize = ax.yaxis.get_major_ticks()[2].label.get_fontsize() scalebarBox = AuxTransformBox(ax.transData) scalebarBox.add_artist(matplotlib.patches.Rectangle((0,0),X, 0, fc="none", edgecolor='k', linewidth=linewidth, joinstyle='miter', capstyle='projecting')) scalebarBox.add_artist(matplotlib.patches.Rectangle((X,0),0,Y, fc="none", edgecolor='k', linewidth=linewidth, joinstyle='miter', capstyle='projecting')) scalebarBox.add_artist(matplotlib.text.Text(X/2, -Y/20, xlab, va='top', ha='center', color='k')) scalebarBox.add_artist(matplotlib.text.Text(X+X/20, Y/2, ylab, va='center', ha='left', color='k')) anchored_box = AnchoredOffsetbox(loc=loc, pad=-9, child=scalebarBox, frameon=False, bbox_to_anchor=bbox_to_anchor) ax.add_artist(anchored_box) return(anchored_box)
def AddTraceScaleBar(xunit, yunit, color='k',linewidth=None,\ fontsize=None, ax=None, xscale=None, yscale=None, loc=5, bbox_to_anchor=None): """Add scale bar on trace. Specifically designed for voltage / current / stimulus vs. time traces. xscale, yscale: add the trace bar to the specified window of x and y. """ if ax is None: ax=plt.gca() def scalebarlabel(x, unitstr): x = int(x) if unitstr.lower()[0] == 'm': return(str(x)+unitstr if x<1000 else str(int(x/1000))+ unitstr.replace('m','')) elif unitstr.lower()[0] == 'p': return(str(x)+unitstr if x<1000 else str(int(x/1000))+ unitstr.replace('p','n')) else: # no prefix return(str(x)+unitstr) ax.set_axis_off() # turn off axis X = np.ptp(ax.get_xlim()) if xscale is None else xscale Y = np.ptp(ax.get_ylim()) if yscale is None else yscale # calculate scale bar unit length X, Y = roundto125(X/5), roundto125(Y/(5 if Y<1200 else 10)) # Parse scale bar labels xlab, ylab = scalebarlabel(X, xunit), scalebarlabel(Y, yunit) # Get color of the scalebar if color is None: color = ax.get_lines()[0] if 'matplotlib.lines.Line2D' in str(type(color)): color = color.get_color() if linewidth is None: try: linewidth = ax.get_lines()[0] except: raise(AttributeError('Did not find any line in this axis. Please explicitly specify the linewidth')) if 'matplotlib.lines.Line2D' in str(type(linewidth)): linewidth = linewidth.get_linewidth() # print(linewidth) if fontsize is None: fontsize = ax.yaxis.get_major_ticks()[2].label.get_fontsize() scalebarBox = AuxTransformBox(ax.transData) scalebarBox.add_artist(plt.Rectangle((0,0),X, 0, fc="none", linewidth=linewidth)) scalebarBox.add_artist(plt.Rectangle((X,0),0,Y, fc="none", linewidth=linewidth)) scalebarBox.add_artist(plt.text(X/2, -Y/20, xlab, va='top', ha='center',color='k')) scalebarBox.add_artist(plt.text(X+X/20, Y/2, ylab, va='center', ha='left', color='k')) anchored_box = AnchoredOffsetbox(loc=loc, pad=-9, child=scalebarBox, frameon=False, bbox_to_anchor=bbox_to_anchor) ax.add_artist(anchored_box) return(anchored_box)
def __init__(self, transform, sizex=0, sizey=0, labelx=None, labely=None, loc=4, pad=0.1, borderpad=0.1, sep=2, prop=None, label_fontsize=label_fontsize, color='k', **kwargs): """ Draw a horizontal and/or vertical bar with the size in data coordinate of the give axes. A label will be drawn underneath (center-aligned). - transform : the coordinate frame (typically axes.transData) - sizex,sizey : width of x,y bar, in data units. 0 to omit - labelx,labely : labels for x,y bars; None to omit - loc : position in containing axes - pad, borderpad : padding, in fraction of the legend font size (or prop) - sep : separation between labels and bars in points. - **kwargs : additional arguments passed to base class constructor """ from matplotlib.patches import Rectangle from matplotlib.offsetbox import AuxTransformBox, VPacker, HPacker, TextArea, DrawingArea bars = AuxTransformBox(transform) if sizex: bars.add_artist(Rectangle((0,0), sizex, 0, fc="none", linewidth=axes_linewidth, color=color)) if sizey: bars.add_artist(Rectangle((0,0), 0, sizey, fc="none", linewidth=axes_linewidth, color=color)) if sizex and labelx: textareax = TextArea(labelx,minimumdescent=False,textprops=dict(size=label_fontsize,color=color)) bars = VPacker(children=[bars, textareax], align="center", pad=0, sep=sep) if sizey and labely: ## VPack a padstr below the rotated labely, else label y goes below the scale bar ## Just adding spaces before labely doesn't work! padstr = '\n '*len(labely) textareafiller = TextArea(padstr,textprops=dict(size=label_fontsize/3.0)) textareay = TextArea(labely,textprops=dict(size=label_fontsize,rotation='vertical',color=color)) ## filler / pad string VPack-ed below labely textareayoffset = VPacker(children=[textareay, textareafiller], align="center", pad=0, sep=sep) ## now HPack this padded labely to the bars bars = HPacker(children=[textareayoffset, bars], align="top", pad=0, sep=sep) AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad, child=bars, prop=prop, frameon=False, **kwargs)
def __init__(self, transform, sizex=0, sizey=0, labelx=None, labely=None, loc=4, pad=0.1, borderpad=0.1, sep=2, linewidth=3, prop=None, fontprops={}, **kwargs): """ Args: - transform : the coordinate frame (typically axes.transData) - sizex,sizey : width of x,y bar, in data units. 0 to omit - labelx,labely : labels for x,y bars; None to omit - loc : position in containing axes, see matplotlib.offsetbox.AnchoredOffsetbox for docs - pad, borderpad : padding, in fraction of the legend font size (or prop) - sep : separation between labels and bars in points. - fontprops: dict specifying text label properties, https://matplotlib.org/users/text_props.html - **kwargs : additional arguments passed to base class constructor """ from matplotlib.patches import Rectangle from matplotlib.lines import Line2D from matplotlib.offsetbox import AuxTransformBox, VPacker, HPacker, TextArea, DrawingArea, OffsetBox fontprops.update({'fontsize': 8}) # need fontprops defaults here, otherwise overwritten on change if in fn defn bars = AuxTransformBox(transform) bars.add_artist(Line2D((0,0,sizex),(sizey,0,0), lw=linewidth, color='k', solid_capstyle='butt', solid_joinstyle='miter')) # Note: this packs the y label and both bars together into a box, then packs the x label below the box, so the # x label is slightly off center of the x bar. This can cause some small alignment problems, but fixing it requires knowledge # of matplotlib offsetboxes, auxtransformboxes, and transforms that I don't have. if sizey and labely: bars = HPacker(children=[TextArea(labely.strip(), textprops=fontprops), bars], align="center", pad=0, sep=sep) if sizex and labelx: bars = VPacker(children=[bars, TextArea(labelx.strip(), minimumdescent=False, textprops=fontprops)], align="center", pad=0, sep=sep) AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad, child=bars, prop=prop, frameon=False, **kwargs)
def sm_plot(self,sm_map,ars=None): """ Plot images as SM does """ map_fig = plt.figure() sm_map.plot() sm_map.draw_limb() sm_map.draw_grid(grid_spacing=10)#grid=False, colorbar=False) ax=plt.gca() arr = np.ones(256).reshape(1,256) if ars is not None: for ar_number,pos in ars.items(): text_path = TextPath((0,0),ar_number) text_patch = PathClippedImagePatch(text_path, arr, ec="none", transform=IdentityTransform()) shadow1 = mpatches.Shadow(text_patch,1,-1,props=dict(fc="none", ec="0.6", lw=3)) offsetbox = AuxTransformBox(IdentityTransform()) offsetbox.add_artist(shadow1) offsetbox.add_artist(text_patch) ab = AnnotationBbox(offsetbox,(pos[0],pos[1]),xycoords='data',frameon=False) ax.add_artist(ab) # plt.annotate(ar_number,xy=(pos[0],pos[1]),color='white',weight=600,stretch='condensed') # plt.annotate(ar_number,xy=(pos[0],pos[1]),weight=500) return map_fig
def __init__(self, transform, sizex=0, sizey=0, labelx=None, labely=None, loc=4, pad=0.1, borderpad=0.1, sep=2, prop=None, fontsize='medium', **kwargs): """ Modified, draws a horizontal and/or vertical bar with the size in data coordinate of the give axes. A label will be drawn underneath (center-aligned). Parameters ---------- transform : the coordinate frame (typically axes.transData) sizex, sizey : width of x,y bar, in data units. 0 to omit labelx, labely : labels for x,y bars; None to omit loc : position in containing axes pad, borderpad : padding, in fraction of the legend font size (or prop) sep : separation between labels and bars in points. **kwargs : additional arguments passed to base class constructor Notes ----- Adapted from mpl_toolkits.axes_grid2 """ from matplotlib.lines import Line2D from matplotlib.text import Text from matplotlib.offsetbox import AuxTransformBox bars = AuxTransformBox(transform) inv = transform.inverted() pixelxy = inv.transform((1, 1)) - inv.transform((0, 0)) if sizex: barx = Line2D([sizex, 0], [0, 0], transform=transform, color='k') bars.add_artist(barx) if sizey: bary = Line2D([0, 0], [0, sizey], transform=transform, color='k') bars.add_artist(bary) if sizex and labelx: textx = Text(text=labelx, x=sizex/2.0, y=-5*pixelxy[1], ha='center', va='top', size=fontsize) bars.add_artist(textx) if sizey and labely: texty = Text(text=labely, rotation='vertical', y=sizey/2.0, x=-2*pixelxy[0], va='center', ha='right', size=fontsize) bars.add_artist(texty) AnchoredOffsetbox.__init__(self, loc=loc, pad=pad, borderpad=borderpad, child=bars, prop=prop, frameon=False, **kwargs)
ax = plt.subplot(211) from matplotlib._png import read_png fn = get_sample_data("lena.png", asfileobj=False) arr = read_png(fn) text_path = TextPath((0, 0), "!?", size=150) p = PathClippedImagePatch(text_path, arr, ec="k", transform=IdentityTransform()) #p.set_clip_on(False) # make offset box offsetbox = AuxTransformBox(IdentityTransform()) offsetbox.add_artist(p) # make anchored offset box ao = AnchoredOffsetbox(loc=2, child=offsetbox, frameon=True, borderpad=0.2) ax.add_artist(ao) # another text from matplotlib.patches import PathPatch if usetex: r = r"\mbox{textpath supports mathtext \& \TeX}" else: r = r"textpath supports mathtext & TeX" text_path = TextPath((0, 0), r, size=20, usetex=usetex)
class AnchoredDirectionArrows(AnchoredOffsetbox): def __init__(self, transform, label_x, label_y, length=0.15, fontsize=0.08, loc=2, angle=0, aspect_ratio=1, pad=0.4, borderpad=0.4, frameon=False, color='w', alpha=1, sep_x=0.01, sep_y=0, fontproperties=None, back_length=0.15, head_width=10, head_length=15, tail_width=2, text_props=None, arrow_props=None, **kwargs): """ Draw two perpendicular arrows to indicate directions. Parameters ---------- transform : `matplotlib.transforms.Transform` The transformation object for the coordinate system in use, i.e., :attr:`matplotlib.axes.Axes.transAxes`. label_x, label_y : string Label text for the x and y arrows length : int or float, optional Length of the arrow, given in coordinates of *transform*. Defaults to 0.15. fontsize : int, optional Size of label strings, given in coordinates of *transform*. Defaults to 0.08. loc : int, optional Location of the direction arrows. Valid location codes are:: 'upper right' : 1, 'upper left' : 2, 'lower left' : 3, 'lower right' : 4, 'right' : 5, 'center left' : 6, 'center right' : 7, 'lower center' : 8, 'upper center' : 9, 'center' : 10 Defaults to 2. angle : int or float, optional The angle of the arrows in degrees. Defaults to 0. aspect_ratio : int or float, optional The ratio of the length of arrow_x and arrow_y. Negative numbers can be used to change the direction. Defaults to 1. pad : int or float, optional Padding around the labels and arrows, in fraction of the font size. Defaults to 0.4. borderpad : int or float, optional Border padding, in fraction of the font size. Defaults to 0.4. frameon : bool, optional If True, draw a box around the arrows and labels. Defaults to False. color : str, optional Color for the arrows and labels. Defaults to white. alpha : int or float, optional Alpha values of the arrows and labels Defaults to 1. sep_x, sep_y : int or float, optional Separation between the arrows and labels in coordinates of *transform*. Defaults to 0.01 and 0. fontproperties : `matplotlib.font_manager.FontProperties`, optional Font properties for the label text. back_length : float, optional Fraction of the arrow behind the arrow crossing. Defaults to 0.15. head_width : int or float, optional Width of arrow head, sent to ArrowStyle. Defaults to 10. head_length : int or float, optional Length of arrow head, sent to ArrowStyle. Defaults to 15. tail_width : int or float, optional Width of arrow tail, sent to ArrowStyle. Defaults to 2. text_props, arrow_props : dict Properties of the text and arrows, passed to :class:`matplotlib.text.TextPath` and `matplotlib.patches.FancyArrowPatch` **kwargs Keyworded arguments to pass to :class:`matplotlib.offsetbox.AnchoredOffsetbox`. Attributes ---------- arrow_x, arrow_y : `matplotlib.patches.FancyArrowPatch` Arrow x and y text_path_x, text_path_y : `matplotlib.text.TextPath` Path for arrow labels p_x, p_y : `matplotlib.patches.PathPatch` Patch for arrow labels box : `matplotlib.offsetbox.AuxTransformBox` Container for the arrows and labels. Notes ----- If *prop* is passed as a keyword argument, but *fontproperties* is not, then *prop* is be assumed to be the intended *fontproperties*. Using both *prop* and *fontproperties* is not supported. Examples -------- >>> import matplotlib.pyplot as plt >>> import numpy as np >>> from mpl_toolkits.axes_grid1.anchored_artists import ( ... AnchoredDirectionArrows) >>> fig, ax = plt.subplots() >>> ax.imshow(np.random.random((10,10))) >>> arrows = AnchoredDirectionArrows(ax.transAxes, '111', '110') >>> ax.add_artist(arrows) >>> fig.show() Using several of the optional parameters, creating downward pointing arrow and high contrast text labels. >>> import matplotlib.font_manager as fm >>> fontprops = fm.FontProperties(family='monospace') >>> arrows = AnchoredDirectionArrows(ax.transAxes, 'East', 'South', ... loc='lower left', color='k', ... aspect_ratio=-1, sep_x=0.02, ... sep_y=-0.01, ... text_props={'ec':'w', 'fc':'k'}, ... fontproperties=fontprops) """ if arrow_props is None: arrow_props = {} if text_props is None: text_props = {} arrowstyle = ArrowStyle("Simple", head_width=head_width, head_length=head_length, tail_width=tail_width) if fontproperties is None and 'prop' in kwargs: fontproperties = kwargs.pop('prop') if 'color' not in arrow_props: arrow_props['color'] = color if 'alpha' not in arrow_props: arrow_props['alpha'] = alpha if 'color' not in text_props: text_props['color'] = color if 'alpha' not in text_props: text_props['alpha'] = alpha t_start = transform t_end = t_start + transforms.Affine2D().rotate_deg(angle) self.box = AuxTransformBox(t_end) length_x = length length_y = length*aspect_ratio self.arrow_x = FancyArrowPatch( (0, back_length*length_y), (length_x, back_length*length_y), arrowstyle=arrowstyle, shrinkA=0.0, shrinkB=0.0, **arrow_props) self.arrow_y = FancyArrowPatch( (back_length*length_x, 0), (back_length*length_x, length_y), arrowstyle=arrowstyle, shrinkA=0.0, shrinkB=0.0, **arrow_props) self.box.add_artist(self.arrow_x) self.box.add_artist(self.arrow_y) text_path_x = TextPath(( length_x+sep_x, back_length*length_y+sep_y), label_x, size=fontsize, prop=fontproperties) self.p_x = PathPatch(text_path_x, transform=t_start, **text_props) self.box.add_artist(self.p_x) text_path_y = TextPath(( length_x*back_length+sep_x, length_y*(1-back_length)+sep_y), label_y, size=fontsize, prop=fontproperties) self.p_y = PathPatch(text_path_y, **text_props) self.box.add_artist(self.p_y) AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad, child=self.box, frameon=frameon, **kwargs)
class AnchoredSizeBar(AnchoredOffsetbox): def __init__(self, transform, size, label, loc, pad=0.1, borderpad=0.1, sep=2, frameon=True, size_vertical=0, color='black', label_top=False, fontproperties=None, fill_bar=None, **kwargs): """ Draw a horizontal scale bar with a center-aligned label underneath. Parameters ---------- transform : `matplotlib.transforms.Transform` The transformation object for the coordinate system in use, i.e., :attr:`matplotlib.axes.Axes.transData`. size : int or float Horizontal length of the size bar, given in coordinates of *transform*. label : str Label to display. loc : int Location of this size bar. Valid location codes are:: 'upper right' : 1, 'upper left' : 2, 'lower left' : 3, 'lower right' : 4, 'right' : 5, 'center left' : 6, 'center right' : 7, 'lower center' : 8, 'upper center' : 9, 'center' : 10 pad : int or float, optional Padding around the label and size bar, in fraction of the font size. Defaults to 0.1. borderpad : int or float, optional Border padding, in fraction of the font size. Defaults to 0.1. sep : int or float, optional Separation between the label and the size bar, in points. Defaults to 2. frameon : bool, optional If True, draw a box around the horizontal bar and label. Defaults to True. size_vertical : int or float, optional Vertical length of the size bar, given in coordinates of *transform*. Defaults to 0. color : str, optional Color for the size bar and label. Defaults to black. label_top : bool, optional If True, the label will be over the size bar. Defaults to False. fontproperties : `matplotlib.font_manager.FontProperties`, optional Font properties for the label text. fill_bar : bool, optional If True and if size_vertical is nonzero, the size bar will be filled in with the color specified by the size bar. Defaults to True if `size_vertical` is greater than zero and False otherwise. **kwargs Keyworded arguments to pass to :class:`matplotlib.offsetbox.AnchoredOffsetbox`. Attributes ---------- size_bar : `matplotlib.offsetbox.AuxTransformBox` Container for the size bar. txt_label : `matplotlib.offsetbox.TextArea` Container for the label of the size bar. Notes ----- If *prop* is passed as a keyworded argument, but *fontproperties* is not, then *prop* is be assumed to be the intended *fontproperties*. Using both *prop* and *fontproperties* is not supported. Examples -------- >>> import matplotlib.pyplot as plt >>> import numpy as np >>> from mpl_toolkits.axes_grid1.anchored_artists import ( ... AnchoredSizeBar) >>> fig, ax = plt.subplots() >>> ax.imshow(np.random.random((10,10))) >>> bar = AnchoredSizeBar(ax.transData, 3, '3 data units', 4) >>> ax.add_artist(bar) >>> fig.show() Using all the optional parameters >>> import matplotlib.font_manager as fm >>> fontprops = fm.FontProperties(size=14, family='monospace') >>> bar = AnchoredSizeBar(ax.transData, 3, '3 units', 4, pad=0.5, ... sep=5, borderpad=0.5, frameon=False, ... size_vertical=0.5, color='white', ... fontproperties=fontprops) """ if fill_bar is None: fill_bar = size_vertical > 0 self.size_bar = AuxTransformBox(transform) self.size_bar.add_artist(Rectangle((0, 0), size, size_vertical, fill=fill_bar, facecolor=color, edgecolor=color)) if fontproperties is None and 'prop' in kwargs: fontproperties = kwargs.pop('prop') if fontproperties is None: textprops = {'color': color} else: textprops = {'color': color, 'fontproperties': fontproperties} self.txt_label = TextArea( label, minimumdescent=False, textprops=textprops) if label_top: _box_children = [self.txt_label, self.size_bar] else: _box_children = [self.size_bar, self.txt_label] self._box = VPacker(children=_box_children, align="center", pad=0, sep=sep) AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad, child=self._box, prop=fontproperties, frameon=frameon, **kwargs)
class AnchoredSizeBar(AnchoredOffsetbox): def __init__(self, transform, size, label, loc, pad=0.1, borderpad=0.1, sep=2, frameon=True, size_vertical=0, color='black', label_top=False, fontproperties=None, fill_bar=None, **kwargs): """ Draw a horizontal scale bar with a center-aligned label underneath. Parameters ---------- transform : `matplotlib.transforms.Transform` The transformation object for the coordinate system in use, i.e., :attr:`matplotlib.axes.Axes.transData`. size : float Horizontal length of the size bar, given in coordinates of *transform*. label : str Label to display. loc : int Location of this size bar. Valid location codes are:: 'upper right' : 1, 'upper left' : 2, 'lower left' : 3, 'lower right' : 4, 'right' : 5, 'center left' : 6, 'center right' : 7, 'lower center' : 8, 'upper center' : 9, 'center' : 10 pad : float, optional, default: 0.1 Padding around the label and size bar, in fraction of the font size. borderpad : float, optional, default: 0.1 Border padding, in fraction of the font size. sep : float, optional, default: 2 Separation between the label and the size bar, in points. frameon : bool, optional, default: True If True, draw a box around the horizontal bar and label. size_vertical : float, optional, default: 0 Vertical length of the size bar, given in coordinates of *transform*. color : str, optional, default: 'black' Color for the size bar and label. label_top : bool, optional, default: False If True, the label will be over the size bar. fontproperties : `matplotlib.font_manager.FontProperties`, optional Font properties for the label text. fill_bar : bool, optional If True and if size_vertical is nonzero, the size bar will be filled in with the color specified by the size bar. Defaults to True if `size_vertical` is greater than zero and False otherwise. **kwargs Keyworded arguments to pass to :class:`matplotlib.offsetbox.AnchoredOffsetbox`. Attributes ---------- size_bar : `matplotlib.offsetbox.AuxTransformBox` Container for the size bar. txt_label : `matplotlib.offsetbox.TextArea` Container for the label of the size bar. Notes ----- If *prop* is passed as a keyworded argument, but *fontproperties* is not, then *prop* is be assumed to be the intended *fontproperties*. Using both *prop* and *fontproperties* is not supported. Examples -------- >>> import matplotlib.pyplot as plt >>> import numpy as np >>> from mpl_toolkits.axes_grid1.anchored_artists import ( ... AnchoredSizeBar) >>> fig, ax = plt.subplots() >>> ax.imshow(np.random.random((10, 10))) >>> bar = AnchoredSizeBar(ax.transData, 3, '3 data units', 4) >>> ax.add_artist(bar) >>> fig.show() Using all the optional parameters >>> import matplotlib.font_manager as fm >>> fontprops = fm.FontProperties(size=14, family='monospace') >>> bar = AnchoredSizeBar(ax.transData, 3, '3 units', 4, pad=0.5, ... sep=5, borderpad=0.5, frameon=False, ... size_vertical=0.5, color='white', ... fontproperties=fontprops) """ if fill_bar is None: fill_bar = size_vertical > 0 self.size_bar = AuxTransformBox(transform) self.size_bar.add_artist( Rectangle((0, 0), size, size_vertical, fill=fill_bar, facecolor=color, edgecolor=color)) if fontproperties is None and 'prop' in kwargs: fontproperties = kwargs.pop('prop') if fontproperties is None: textprops = {'color': color} else: textprops = {'color': color, 'fontproperties': fontproperties} self.txt_label = TextArea(label, minimumdescent=False, textprops=textprops) if label_top: _box_children = [self.txt_label, self.size_bar] else: _box_children = [self.size_bar, self.txt_label] self._box = VPacker(children=_box_children, align="center", pad=0, sep=sep) AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad, child=self._box, prop=fontproperties, frameon=frameon, **kwargs)
class AnchoredSizeBar(AnchoredOffsetbox): def __init__(self, transform, size, label, loc, pad=0.1, borderpad=0.1, sep=2, prop=None, frameon=True, size_vertical=0, color='black', label_top=False, **kwargs): """ Draw a horizontal bar with the size in data coordinate of the give axes. A label will be drawn underneath (center-aligned). Parameters: ----------- transform : matplotlib transformation object size : int or float horizontal length of the size bar, given in data coordinates label : str loc : int pad : int or float, optional in fraction of the legend font size (or prop) borderpad : int or float, optional in fraction of the legend font size (or prop) sep : int or float, optional in points frameon : bool, optional if True, will draw a box around the horizontal bar and label size_vertical : int or float, optional vertical length of the size bar, given in data coordinates color : str, optional color for the size bar and label label_top : bool, optional if true, the label will be over the rectangle Example: -------- >>>> import matplotlib.pyplot as plt >>>> import numpy as np >>>> from mpl_toolkits.axes_grid1.anchored_artists import AnchoredSizeBar >>>> fig, ax = plt.subplots() >>>> ax = imshow(np.random.random((10,10))) >>>> bar = AnchoredSizeBar(ax.transData, 3, '3 units', pad=0.5, loc=4, sep=5, borderpad=0.5, frameon=False, size_vertical=0.5, color='white') >>>> ax.add_artist(bar) >>>> plt.show() """ self.size_bar = AuxTransformBox(transform) self.size_bar.add_artist(Rectangle((0,0), size, size_vertical, fill=True, facecolor=color, edgecolor=color)) self.txt_label = TextArea(label, minimumdescent=False) if label_top: _box_children = [self.txt_label, self.size_bar] else: _box_children = [self.size_bar, self.txt_label] self._box = VPacker(children=_box_children, align="center", pad=0, sep=sep) AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad, child=self._box, prop=prop, frameon=frameon, **kwargs)
class AnchoredCompass(AnchoredOffsetbox): """ AnchoredOffsetbox class to create a NE compass on the plot given a value for ori (degrees E of N of the yaxis) """ def __init__(self, ax, ori, loc=4, arrow_fraction=0.15, txt1="E", txt2="N", pad=0.3, borderpad=0.5, prop=None, frameon=False): self._ax = ax self.ori = ori self._box = AuxTransformBox(ax.transData) self.arrow_fraction = arrow_fraction path_effects = [PathEffects.withStroke(linewidth=3, foreground="w")] kwargs = dict(mutation_scale=14, shrinkA=0, shrinkB=7) self.arrow1 = FancyArrowPatch(posA=(0, 0), posB=(1, 1), arrowstyle="-|>", arrow_transmuter=None, connectionstyle="arc3", connector=None, color="k", path_effects=path_effects, **kwargs) self.arrow2 = FancyArrowPatch(posA=(0, 0), posB=(1, 1), arrowstyle="-|>", arrow_transmuter=None, connectionstyle="arc3", connector=None, color="k", path_effects=path_effects, **kwargs) self.txt1 = Text(1, 1, txt1, rotation=0, rotation_mode="anchor", path_effects=path_effects, va="center", ha="center") self.txt2 = Text(2, 2, txt2, rotation=0, rotation_mode="anchor", path_effects=path_effects, va="center", ha="center") self._box.add_artist(self.arrow1) self._box.add_artist(self.arrow2) self._box.add_artist(self.txt1) self._box.add_artist(self.txt2) AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad, child=self._box, prop=prop, frameon=frameon) def _update_arrow(self, renderer): ax = self._ax x0, y0 = ax.viewLim.x0, ax.viewLim.y0 a1, a2 = 180 - self.ori, 180 - self.ori - 90 D = min(ax.viewLim.width, ax.viewLim.height) d = D * self.arrow_fraction x1, y1 = x0 + d * np.cos(a1 / 180. * np.pi), y0 + d * np.sin( a1 / 180. * np.pi) x2, y2 = x0 + d * np.cos(a2 / 180. * np.pi), y0 + d * np.sin( a2 / 180. * np.pi) self.arrow1.set_positions((x0, y0), (x1, y1)) self.arrow2.set_positions((x0, y0), (x2, y2)) d2 = d x1t, y1t = x0 + d2 * np.cos(a1 / 180. * np.pi), y0 + d2 * np.sin( a1 / 180. * np.pi) x2t, y2t = x0 + d2 * np.cos(a2 / 180. * np.pi), y0 + d2 * np.sin( a2 / 180. * np.pi) self.txt1.set_position((x1t, y1t)) self.txt1.set_rotation(0) # a1-180 self.txt2.set_position((x2t + 20, y2t)) self.txt2.set_rotation(0) # a2-90 def draw(self, renderer): self._update_arrow(renderer) super(AnchoredCompass, self).draw(renderer)
def main(): # Close any existing figure plt.close('all') # Obstacle Location Format [ox,oy,wd,ht]: # ox, oy specifies the bottom left corner of rectangle with width: wd and height: ht obstacleList = [(0.2, 1.2, 0.2, 0.5), (-0.9, 1.2, 0.25, 0.5), (0.2, 0.3, 0.2, 0.2), (-1.05, 0.2, 0.3, 0.4), (-0.6, 0.8, 0.6, 0.3)] start = [0, 0] randArea = [-1.2, 1.2, -0.1, 2.1] goalArea = [-1.2,-1.0,0.8,1.1] maxIter = 1300 # Start the timer startTime = time.time() # Create the DR_RRTStar Class Object by initizalizng the required data dr_rrtstar = DR_RRTStar(start, randArea, goalArea, maxIter) # Perform DR_RRTStar Tree Expansion NodeList = dr_rrtstar.ExpandTree() # Stop the Timer totalTime = time.time() - startTime print('Total time = ', totalTime) # Plot the environment with the obstacles and the starting position # Plot the Starting position fig = plt.figure(figsize = [16,9]) plt.plot(0, 0, "Xr",markersize=20) plt.axis([-1.3, 1.3, -0.3, 2.3]) # Plot the environment boundary xy, w, h = (-1.2, -0.2), 2.4, 2.2 r = Rectangle(xy, w, h, fc='none', ec='gold', lw=1) offsetbox = AuxTransformBox(plt.axes().transData) offsetbox.add_artist(r) ab = AnnotationBbox(offsetbox, (xy[0]+w/2.,xy[1]+w/2.), boxcoords="data", pad=0.52, fontsize=20, bboxprops=dict(facecolor = "none", edgecolor='k', lw = 20)) plt.axes().add_artist(ab) # Change ticklabel font size plt.xticks(fontsize=30) plt.yticks(fontsize=30) # Plot the rectangle obstacles obstacles = [Rectangle(xy = [ox, oy], width = wd, height = ht, angle = 0, color = "k", facecolor = "k",) for (ox, oy, wd, ht) in obstacleList] for obstacle in obstacles: plt.axes().add_artist(obstacle) # Data for plotting the shaded goal region goalHeight = goalArea[2] x = [-1.20,-1.15,-1.10,-1.05, -1.00] y1 = [goalHeight]*len(x) plt.text(-1.10, 1.0, 'GOAL', rotation=0, weight="bold", color='white', size=20,horizontalalignment='center', verticalalignment='top', multialignment='center') # Shade the area between y1 and line y=2.10 plt.fill_between(x, y1, goalArea[3], facecolor="#CAB8CB", # The fill color color='#CAB8CB') # The outline color def update(kk): ellipseNode = NodeList[kk] ellNodeShape = ellipseNode.means.shape xPlotValues = [] yPlotValues = [] xValues = [] yValues = [] widthValues = [] heightValues = [] angleValues = [] # Prepare the trajectory x and y vectors and plot them for k in range(ellNodeShape[0]): xPlotValues.append(ellipseNode.means[k,0,0]) yPlotValues.append(ellipseNode.means[k,1,0]) # Plotting the risk bounded trajectories lx, = plt.plot(xPlotValues, yPlotValues, "#636D97", linewidth=2.0) # Plot only the last ellipse in the trajectory alfa = math.atan2(ellipseNode.means[-1,1,0], ellipseNode.means[-1,0,0]) elcovar = np.asarray(ellipseNode.covar[-1,:,:]) elE, elV = LA.eig(elcovar[0:2,0:2]) xValues.append(ellipseNode.means[-1,0,0]) yValues.append(ellipseNode.means[-1,1,0]) widthValues.append(math.sqrt(elE[0])) heightValues.append(math.sqrt(elE[1])) angleValues.append(alfa*360) # Plot the Safe Ellipses XY = np.column_stack((xValues, yValues)) ec = EllipseCollection(widthValues, heightValues, angleValues, units='x', offsets=XY, facecolors="#C59434", transOffset=plt.axes().transData) ec.set_alpha(0.5) plt.axes().add_collection(ec) return lx, ec frameList = np.arange(len(NodeList)) ani = FuncAnimation(fig, update, frames=frameList, blit=True, repeat = False) ani.save('ccRRTstar.gif', writer='imagemagick', fps=40)
def draw(self, renderer, *args, **kwargs): if not self.get_visible(): return if self.dx == 0: return # Get parameters from matplotlib import rcParams # late import def _get_value(attr, default): value = getattr(self, attr) if value is None: value = rcParams.get('scalebar.' + attr, default) return value length_fraction = _get_value('length_fraction', 0.2) height_fraction = _get_value('height_fraction', 0.01) location = _get_value('location', 'upper right') if isinstance(location,six.string_types): location = self._LOCATIONS[location] pad = _get_value('pad', 0.2) border_pad = _get_value('border_pad', 0.1) sep = _get_value('sep', 5) frameon = _get_value('frameon', True) color = _get_value('color', 'k') box_color = _get_value('box_color', 'w') box_alpha = _get_value('box_alpha', 1.0) scale_loc = _get_value('scale_loc', 'bottom') label_loc = _get_value('label_loc', 'top') font_properties = self.font_properties if font_properties is None: textprops = {'color': color} else: textprops = {'color': color, 'fontproperties': font_properties} ax = self.axes xlim, ylim = ax.get_xlim(), ax.get_ylim() label = self.label # Create label if label: txtlabel = TextArea(label, minimumdescent=False, textprops=textprops) else: txtlabel = None # Create sizebar length_px = abs(xlim[1] - xlim[0]) * length_fraction length_px, scale_label = self._calculate_length(length_px) size_vertical = abs(ylim[1] - ylim[0]) * height_fraction sizebar = AuxTransformBox(ax.transData) sizebar.add_artist(Rectangle((0, 0), length_px, size_vertical, fill=True, facecolor=color, edgecolor=color)) txtscale = TextArea(scale_label, minimumdescent=False, textprops=textprops) if scale_loc in ['bottom', 'right']: children = [sizebar, txtscale] else: children = [txtscale, sizebar] if scale_loc in ['bottom', 'top']: Packer = VPacker else: Packer = HPacker boxsizebar = Packer(children=children, align='center', pad=0, sep=sep) # Create final offset box if txtlabel: if label_loc in ['bottom', 'right']: children = [boxsizebar, txtlabel] else: children = [txtlabel, boxsizebar] if label_loc in ['bottom', 'top']: Packer = VPacker else: Packer = HPacker child = Packer(children=children, align='center', pad=0, sep=sep) else: child = boxsizebar box = AnchoredOffsetbox(loc=location, pad=pad, borderpad=border_pad, child=child, frameon=frameon) box.axes = ax box.set_figure(self.get_figure()) box.patch.set_color(box_color) box.patch.set_alpha(box_alpha) box.draw(renderer)
def __init__(self, ax, transform, width, height, zorder, xlabel, fc, ylabels=None, loc=4, fontsize=5, pad=0.1, borderpad=0.1, sep=2, prop=None, add_ruler=False, ruler_unit='Km', ruler_unit_fontsize=7, ruler_fontweight='bold', tick_fontweight='light', **kwargs): """ Draw a horizontal and/or vertical bar with the size in data coordinate of the give axes. A label will be drawn underneath (center-aligned). - transform : the coordinate frame (typically axes.transData) - sizex,sizey : width of x,y bar, in data units. 0 to omit - labelx,labely : labels for x,y bars; None to omit - loc : position in containing axes - pad, borderpad : padding, in fraction of the legend font size (or prop) - sep : separation between labels and bars in points. - **kwargs : additional arguments passed to base class constructor """ if ruler_unit_fontsize is None: ruler_unit_fontsize = fontsize * 1.5 Rect = Rectangle( (0, 0), width, height, fc=fc, edgecolor='k', zorder=zorder, ) ATB = AuxTransformBox(transform) ATB.add_artist(Rect) Txt_xlabel = TextArea(xlabel, textprops=dict(fontsize=fontsize, fontweight=tick_fontweight), minimumdescent=True) # vertically packing a single stripe with respective label child = VPacker(children=[Txt_xlabel, ATB], align="right", pad=5, sep=0) if add_ruler: Text = TextArea(ruler_unit, textprops=dict(fontsize=ruler_unit_fontsize, fontweight=ruler_fontweight)) child = VPacker(children=[child, Text], align="center", pad=5, sep=0) else: Text = TextArea('', textprops=dict(fontsize=ruler_unit_fontsize)) child = VPacker(children=[child, Text], align="right", pad=5, sep=0) # horizontally packing all child packs in a single offsetBox AnchoredOffsetbox.__init__(self, loc='center left', borderpad=borderpad, child=child, prop=prop, frameon=False, **kwargs)
class AnchoredCompass(AnchoredOffsetbox): def __init__(self, ax, transSky2Pix, loc, arrow_fraction=0.15, txt1="E", txt2="N", delta_a1=0, delta_a2=0, pad=0.1, borderpad=0.5, prop=None, frameon=False, color=None): """ Draw an arrows pointing the directions of E & N arrow_fraction : length of the arrow as a fraction of axes size pad, borderpad in fraction of the legend font size (or prop) """ self._ax = ax self._transSky2Pix = transSky2Pix self._box = AuxTransformBox(ax.transData) self.delta_a1, self.delta_a2 = delta_a1, delta_a2 self.arrow_fraction = arrow_fraction kwargs = dict(mutation_scale=11, shrinkA=0, shrinkB=5) self.arrow1 = FancyArrowPatch(posA=(0, 0), posB=(1, 1), arrowstyle="->", arrow_transmuter=None, connectionstyle="arc3", connector=None, color=color, **kwargs) self.arrow2 = FancyArrowPatch(posA=(0, 0), posB=(1, 1), arrowstyle="->", arrow_transmuter=None, connectionstyle="arc3", connector=None, color=color, **kwargs) x1t, y1t, x2t, y2t = 1, 1, 1, 1 self.txt1 = Text(x1t, y1t, txt1, rotation=0, rotation_mode="anchor", va="center", ha="right", color=color, fontproperties=prop) self.txt2 = Text(x2t, y2t, txt2, rotation=0, rotation_mode="anchor", va="bottom", ha="center", color=color, fontproperties=prop) self._box.add_artist(self.arrow1) self._box.add_artist(self.arrow2) self._box.add_artist(self.txt1) self._box.add_artist(self.txt2) AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad, child=self._box, prop=prop, frameon=frameon) def set_path_effects(self, path_effects): for a in [self.arrow1, self.arrow2, self.txt1, self.txt2]: a.set_path_effects(path_effects) def _update_arrow(self, renderer): ax = self._ax x0, y0 = ax.viewLim.x0, ax.viewLim.y0 a1, a2 = estimate_angle_trans(self._transSky2Pix, x0, y0) a1, a2 = a1 + self.delta_a1, a2 + self.delta_a2 D = min(ax.viewLim.width, ax.viewLim.height) d = D * self.arrow_fraction x1, y1 = x0 + d * np.cos(a1 / 180. * np.pi), y0 + d * np.sin( a1 / 180. * np.pi) x2, y2 = x0 + d * np.cos(a2 / 180. * np.pi), y0 + d * np.sin( a2 / 180. * np.pi) self.arrow1.set_positions((x0, y0), (x1, y1)) self.arrow2.set_positions((x0, y0), (x2, y2)) d2 = d x1t, y1t = x0 + d2 * np.cos(a1 / 180. * np.pi), y0 + d2 * np.sin( a1 / 180. * np.pi) x2t, y2t = x0 + d2 * np.cos(a2 / 180. * np.pi), y0 + d2 * np.sin( a2 / 180. * np.pi) self.txt1.set_position((x1t, y1t)) self.txt1.set_rotation(a1 - 180) self.txt2.set_position((x2t, y2t)) self.txt2.set_rotation(a2 - 90) def draw(self, renderer): self._update_arrow(renderer) super(AnchoredCompass, self).draw(renderer)
def draw(self, renderer, *args, **kwargs): if not self.get_visible(): return if self.dx == 0: return # Late import from matplotlib import rcParams # Deprecation if rcParams.get("scalebar.height_fraction") is not None: warnings.warn( "The scalebar.height_fraction parameter in matplotlibrc is deprecated. " "Use scalebar.width_fraction instead.", DeprecationWarning, ) rcParams.setdefault("scalebar.width_fraction", rcParams["scalebar.height_fraction"]) # Get parameters def _get_value(attr, default): value = getattr(self, attr) if value is None: value = rcParams.get("scalebar." + attr, default) return value length_fraction = _get_value("length_fraction", 0.2) width_fraction = _get_value("width_fraction", 0.01) location = _get_value("location", "upper right") if isinstance(location, str): location = self._LOCATIONS[location.lower()] pad = _get_value("pad", 0.2) border_pad = _get_value("border_pad", 0.1) sep = _get_value("sep", 5) frameon = _get_value("frameon", True) color = _get_value("color", "k") box_color = _get_value("box_color", "w") box_alpha = _get_value("box_alpha", 1.0) scale_loc = _get_value("scale_loc", "bottom").lower() label_loc = _get_value("label_loc", "top").lower() font_properties = self.font_properties fixed_value = self.fixed_value fixed_units = self.fixed_units or self.units rotation = _get_value("rotation", "horizontal").lower() label = self.label # Create text properties textprops = {"color": color, "rotation": rotation} if font_properties is not None: textprops["fontproperties"] = font_properties # Calculate value, units and length ax = self.axes xlim = ax.get_xlim() ylim = ax.get_ylim() if rotation == "vertical": xlim, ylim = ylim, xlim # Mode 1: Auto if self.fixed_value is None: length_px = abs(xlim[1] - xlim[0]) * length_fraction length_px, value, units = self._calculate_best_length(length_px) # Mode 2: Fixed else: value = fixed_value units = fixed_units length_px = self._calculate_exact_length(value, units) scale_text = self.scale_formatter(value, self.dimension.to_latex(units)) width_px = abs(ylim[1] - ylim[0]) * width_fraction # Create scale bar if rotation == "horizontal": scale_rect = Rectangle( (0, 0), length_px, width_px, fill=True, facecolor=color, edgecolor="none", ) else: scale_rect = Rectangle( (0, 0), width_px, length_px, fill=True, facecolor=color, edgecolor="none", ) scale_bar_box = AuxTransformBox(ax.transData) scale_bar_box.add_artist(scale_rect) scale_text_box = TextArea(scale_text, textprops=textprops) if scale_loc in ["bottom", "right"]: children = [scale_bar_box, scale_text_box] else: children = [scale_text_box, scale_bar_box] if scale_loc in ["bottom", "top"]: Packer = VPacker else: Packer = HPacker scale_box = Packer(children=children, align="center", pad=0, sep=sep) # Create label if label: label_box = TextArea(label, textprops=textprops) else: label_box = None # Create final offset box if label_box: if label_loc in ["bottom", "right"]: children = [scale_box, label_box] else: children = [label_box, scale_box] if label_loc in ["bottom", "top"]: Packer = VPacker else: Packer = HPacker child = Packer(children=children, align="center", pad=0, sep=sep) else: child = scale_box box = AnchoredOffsetbox(loc=location, pad=pad, borderpad=border_pad, child=child, frameon=frameon) box.axes = ax box.set_figure(self.get_figure()) box.patch.set_color(box_color) box.patch.set_alpha(box_alpha) box.draw(renderer)
def draw(self, renderer, *args, **kwargs): if not self.get_visible(): return if not self.get_mappable(): return # Get parameters from matplotlib import rcParams # late import cmap = self.mappable.get_cmap() array = self.mappable.get_array() label = self.label orientation = self.orientation or \ rcParams.get('colorbar.orientation', 'vertical') nbins = self.nbins or rcParams.get('colorbar.nbins', 50) length_fraction = self.length_fraction or \ rcParams.get('colorbar.length_fraction', 0.2) width_fraction = self.width_fraction or \ rcParams.get('colorbar.width_fraction', 0.01) location = self.location or \ self._LOCATIONS[rcParams.get('colorbar.location', 'upper right')] pad = self.pad or rcParams.get('colorbar.pad', 0.2) border_pad = self.border_pad or \ rcParams.get('colorbar.border_pad', 0.1) sep = self.sep or rcParams.get('colorbar.sep', 5) frameon = self.frameon or rcParams.get('colorbar.frameon', True) color = self.color or rcParams.get('colorbar.color', 'k') box_color = self.box_color or rcParams.get('colorbar.box_color', 'w') box_alpha = self.box_alpha or rcParams.get('colorbar.box_alpha', 1.0) font_properties = self.font_properties ticks = self.ticks ticklabels = self.ticklabels ax = self.axes children = [] # Create colorbar colorbarbox = AuxTransformBox(ax.transData) xlim, ylim = ax.get_xlim(), ax.get_ylim() if orientation == 'horizontal': length = abs(xlim[1] - xlim[0]) * length_fraction width = abs(ylim[1] - ylim[0]) * width_fraction else: length = abs(ylim[1] - ylim[0]) * length_fraction width = abs(xlim[1] - xlim[0]) * width_fraction step_length = length / nbins patches = [] for x in np.arange(0, length, step_length): if orientation == 'horizontal': patch = Rectangle((x, 0), step_length, width) else: patch = Rectangle((0, x), width, step_length) patches.append(patch) values = np.linspace(np.min(array), np.max(array), nbins) minvalue, maxvalue = values[0], values[-1] col = PatchCollection(patches, cmap=cmap, edgecolors='none') col.set_array(values) colorbarbox.add_artist(col) if orientation == 'horizontal': patch = Rectangle((0, 0), length, width, fill=False, ec=color) else: patch = Rectangle((0, 0), width, length, fill=False, ec=color) colorbarbox.add_artist(patch) children.append(colorbarbox) # Create ticks tickbox = AuxTransformBox(ax.transData) if ticks is None: ticks = [minvalue, maxvalue] # default if not ticklabels: ticklabels = ticks[:] # tick label by default if minvalue not in ticks: # little hack to get right layout position ticks.append(minvalue) ticklabels.append('') # no label for this extra tick if maxvalue not in ticks: # little hack to get right layout position ticks.append(maxvalue) ticklabels.append('') # no label for this extra tick for itick, tick in enumerate(ticks): if tick > maxvalue or tick < minvalue: continue # ignore it # Fraction of colorbar depending of min and max values of colorbar a = 1 / (maxvalue - minvalue) b = -a * minvalue tickfrac = a * tick + b if orientation == 'horizontal': tickx = tickfrac * length ticky = 0 ha = 'center' va = 'top' else: tickx = width ticky = tickfrac * length ha = 'left' va = 'center' ticktext = Text(tickx, ticky, ticklabels[itick], color=color, fontproperties=font_properties, horizontalalignment=ha, verticalalignment=va) tickbox.add_artist(ticktext) children.append(tickbox) # Create label if label: labelbox = AuxTransformBox(ax.transData) va = 'baseline' if orientation == 'horizontal' else 'center' text = Text(0, 0, label, fontproperties=font_properties, verticalalignment=va, rotation=orientation) labelbox.add_artist(text) children.insert(0, labelbox) # Create final offset box Packer = VPacker if orientation == 'horizontal' else HPacker child = Packer(children=children, align="center", pad=0, sep=sep) box = AnchoredOffsetbox(loc=location, pad=pad, borderpad=border_pad, child=child, frameon=frameon) box.axes = ax box.set_figure(self.get_figure()) box.patch.set_color(box_color) box.patch.set_alpha(box_alpha) box.draw(renderer)
class AnchoredCompass(AnchoredOffsetbox): def __init__(self, ax, transSky2Pix, loc, arrow_fraction=0.15, txt1="E", txt2="N", delta_a1=0, delta_a2=0, pad=0.1, borderpad=0.5, prop=None, frameon=False, ): """ Draw an arrows pointing the directions of E & N arrow_fraction : length of the arrow as a fraction of axes size pad, borderpad in fraction of the legend font size (or prop) """ self._ax = ax self._transSky2Pix = transSky2Pix self._box = AuxTransformBox(ax.transData) self.delta_a1, self.delta_a2 = delta_a1, delta_a2 self.arrow_fraction = arrow_fraction kwargs = dict(mutation_scale=11, shrinkA=0, shrinkB=5) self.arrow1 = FancyArrowPatch(posA=(0, 0), posB=(1, 1), arrowstyle="->", arrow_transmuter=None, connectionstyle="arc3", connector=None, **kwargs) self.arrow2 = FancyArrowPatch(posA=(0, 0), posB=(1, 1), arrowstyle="->", arrow_transmuter=None, connectionstyle="arc3", connector=None, **kwargs) x1t, y1t, x2t, y2t = 1, 1, 1, 1 self.txt1 = Text(x1t, y1t, txt1, rotation=0, rotation_mode="anchor", va="center", ha="right") self.txt2 = Text(x2t, y2t, txt2, rotation=0, rotation_mode="anchor", va="bottom", ha="center") self._box.add_artist(self.arrow1) self._box.add_artist(self.arrow2) self._box.add_artist(self.txt1) self._box.add_artist(self.txt2) AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad, child=self._box, prop=prop, frameon=frameon) def set_path_effects(self, path_effects): for a in [self.arrow1, self.arrow2, self.txt1, self.txt2]: a.set_path_effects(path_effects) def _update_arrow(self, renderer): ax = self._ax x0, y0 = ax.viewLim.x0, ax.viewLim.y0 a1, a2 = estimate_angle(self._transSky2Pix, x0, y0) a1, a2 = a1+self.delta_a1, a2+self.delta_a2 D = min(ax.viewLim.width, ax.viewLim.height) d = D * self.arrow_fraction x1, y1 = x0+d*np.cos(a1/180.*np.pi), y0+d*np.sin(a1/180.*np.pi) x2, y2 = x0+d*np.cos(a2/180.*np.pi), y0+d*np.sin(a2/180.*np.pi) self.arrow1.set_positions((x0, y0), (x1, y1)) self.arrow2.set_positions((x0, y0), (x2, y2)) d2 = d x1t, y1t = x0+d2*np.cos(a1/180.*np.pi), y0+d2*np.sin(a1/180.*np.pi) x2t, y2t = x0+d2*np.cos(a2/180.*np.pi), y0+d2*np.sin(a2/180.*np.pi) self.txt1.set_position((x1t, y1t)) self.txt1.set_rotation(a1-180) self.txt2.set_position((x2t, y2t)) self.txt2.set_rotation(a2-90) def draw(self, renderer): self._update_arrow(renderer) super(AnchoredCompass, self).draw(renderer)
def draw(self, renderer, *args, **kwargs): if not self.get_visible(): return if not self.get_mappable(): return # Get parameters from matplotlib import rcParams # late import def _get_value(attr, default): value = getattr(self, attr) if value is None: value = rcParams.get('colorbar.' + attr, default) return value orientation = _get_value('orientation', 'vertical') length_fraction = _get_value('length_fraction', 0.2) width_fraction = _get_value('width_fraction', 0.01) location = _get_value('location', 'upper right') if is_string_like(location): location = self._LOCATIONS[location] pad = _get_value('pad', 0.2) border_pad = _get_value('border_pad', 0.1) sep = _get_value('sep', 5) frameon = _get_value('frameon', True) color = _get_value('color', 'k') box_color = _get_value('box_color', 'w') box_alpha = _get_value('box_alpha', 1.0) font_properties = self.font_properties ticklocation = _get_value('ticklocation', 'auto') if ticklocation == 'auto': ticklocation = 'bottom' if orientation == 'horizontal' else 'right' mappable = self.mappable cmap = self.mappable.cmap label = self.label ticks = self.ticks ticklabels = self.ticklabels ax = self.axes # Calculate calculator = ColorbarCalculator(mappable, ticks=ticks, ticklabels=ticklabels) X, Y, C = calculator.calculate_colorbar() X *= width_fraction Y *= length_fraction widths = np.diff(X, axis=1)[:, 0] heights = np.diff(Y[:, 0]) if orientation == 'horizontal': X, Y = Y, X widths, heights = heights, widths ticks, ticklabels, offset_string = calculator.calculate_ticks() ticks *= length_fraction # Create colorbar colorbarbox = AuxTransformBox(ax.transAxes) patches = [] for x0, y0, width, height in zip(X[:-1, 0], Y[:-1, 0], widths, heights): patch = Rectangle((x0, y0), width, height) patches.append(patch) edgecolors = 'none' #if self.drawedges else 'none' #FIXME: drawedge property #FIXME: Filled property col = PatchCollection(patches, cmap=cmap, edgecolors=edgecolors) col.set_array(C[:, 0]) colorbarbox.add_artist(col) # Create outline if orientation == 'horizontal': outline = Rectangle((0, 0), length_fraction, width_fraction, fill=False, ec=color) else: outline = Rectangle((0, 0), width_fraction, length_fraction, fill=False, ec=color) colorbarbox.add_artist(outline) # Create ticks and tick labels w10th = width_fraction / 10.0 ticklines = [] ticktexts = [] for tick, ticklabel in zip(ticks, ticklabels): if ticklocation == 'bottom': x0 = x1 = xtext = tick y0 = w10th y1 = -w10th ytext = -2 * w10th ha = 'center' va = 'top' elif ticklocation == 'top': x0 = x1 = xtext = tick y0 = width_fraction - w10th y1 = width_fraction + w10th ytext = width_fraction + 2 * w10th ha = 'center' va = 'bottom' elif ticklocation == 'left': x0 = w10th x1 = -w10th xtext = -2 * w10th y0 = y1 = ytext = tick ha = 'right' va = 'center' elif ticklocation == 'right': x0 = width_fraction - w10th x1 = width_fraction + w10th xtext = width_fraction + 2 * w10th y0 = y1 = ytext = tick ha = 'left' va = 'center' ticklines.append([(x0, y0), (x1, y1)]) ticklabel = offset_string + ticklabel ticktext = Text(xtext, ytext, ticklabel, color=color, fontproperties=font_properties, horizontalalignment=ha, verticalalignment=va) ticktexts.append(ticktext) col = LineCollection(ticklines, color=color) colorbarbox.add_artist(col) for ticktext in ticktexts: colorbarbox.add_artist(ticktext) # Create label if label: labelbox = AuxTransformBox(ax.transAxes) va = 'baseline' if orientation == 'horizontal' else 'center' text = Text(0, 0, label, fontproperties=font_properties, verticalalignment=va, rotation=orientation, color=color) labelbox.add_artist(text) else: labelbox = None # Create final offset box if ticklocation == 'bottom': children = [colorbarbox, labelbox] if labelbox else [colorbarbox] child = VPacker(children=children, align='center', pad=0, sep=sep) elif ticklocation == 'top': children = [labelbox, colorbarbox] if labelbox else [colorbarbox] child = VPacker(children=children, align='center', pad=0, sep=sep) elif ticklocation == 'left': children = [labelbox, colorbarbox] if labelbox else [colorbarbox] child = HPacker(children=children, align='center', pad=0, sep=sep) elif ticklocation == 'right': children = [colorbarbox, labelbox] if labelbox else [colorbarbox] child = HPacker(children=children, align='center', pad=0, sep=sep) # box = AnchoredOffsetbox(loc=location, pad=pad, borderpad=border_pad, child=child, frameon=frameon) box.axes = ax box.set_figure(self.get_figure()) box.patch.set_color(box_color) box.patch.set_alpha(box_alpha) box.draw(renderer)
def draw(self, renderer, *args, **kwargs): if not self.get_visible(): return if self.dx == 0: return # Get parameters from matplotlib import rcParams # late import def _get_value(attr, default): value = getattr(self, attr) if value is None: value = rcParams.get('scalebar.' + attr, default) return value length_fraction = _get_value('length_fraction', 0.2) height_fraction = _get_value('height_fraction', 0.01) location = _get_value('location', 'upper right') if is_string_like(location): location = self._LOCATIONS[location] pad = _get_value('pad', 0.2) border_pad = _get_value('border_pad', 0.1) sep = _get_value('sep', 5) frameon = _get_value('frameon', True) color = _get_value('color', 'k') box_color = _get_value('box_color', 'w') box_alpha = _get_value('box_alpha', 1.0) scale_loc = _get_value('scale_loc', 'bottom') label_loc = _get_value('label_loc', 'top') font_properties = self.font_properties if font_properties is None: textprops = {'color': color} else: textprops = {'color': color, 'fontproperties': font_properties} ax = self.axes xlim, ylim = ax.get_xlim(), ax.get_ylim() label = self.label # Create label if label: txtlabel = TextArea(label, minimumdescent=False, textprops=textprops) else: txtlabel = None # Create sizebar length_px = abs(xlim[1] - xlim[0]) * length_fraction length_px, scale_label = self._calculate_length(length_px) size_vertical = abs(ylim[1] - ylim[0]) * height_fraction sizebar = AuxTransformBox(ax.transData) sizebar.add_artist( Rectangle((0, 0), length_px, size_vertical, fill=True, facecolor=color, edgecolor=color)) txtscale = TextArea(scale_label, minimumdescent=False, textprops=textprops) if scale_loc in ['bottom', 'right']: children = [sizebar, txtscale] else: children = [txtscale, sizebar] if scale_loc in ['bottom', 'top']: Packer = VPacker else: Packer = HPacker boxsizebar = Packer(children=children, align='center', pad=0, sep=sep) # Create final offset box if txtlabel: if label_loc in ['bottom', 'right']: children = [boxsizebar, txtlabel] else: children = [txtlabel, boxsizebar] if label_loc in ['bottom', 'top']: Packer = VPacker else: Packer = HPacker child = Packer(children=children, align='center', pad=0, sep=sep) else: child = boxsizebar box = AnchoredOffsetbox(loc=location, pad=pad, borderpad=border_pad, child=child, frameon=frameon) box.axes = ax box.set_figure(self.get_figure()) box.patch.set_color(box_color) box.patch.set_alpha(box_alpha) box.draw(renderer)
class AnchoredEllipse(AnchoredOffsetbox): def __init__(self, transform, width, height, angle, loc, pad=0.1, borderpad=0.1, prop=None, frameon=True, **kwargs): """ Draw an anchored ellipse of a given size. Parameters ---------- transform : `matplotlib.transforms.Transform` The transformation object for the coordinate system in use, i.e., :attr:`matplotlib.axes.Axes.transData`. width, height : float Width and height of the ellipse, given in coordinates of *transform*. angle : float Rotation of the ellipse, in degrees, anti-clockwise. loc : int Location of this size bar. Valid location codes are:: 'upper right' : 1, 'upper left' : 2, 'lower left' : 3, 'lower right' : 4, 'right' : 5, 'center left' : 6, 'center right' : 7, 'lower center' : 8, 'upper center' : 9, 'center' : 10 pad : float, optional Padding around the ellipse, in fraction of the font size. Defaults to 0.1. borderpad : float, optional, default: 0.1 Border padding, in fraction of the font size. frameon : bool, optional, default: True If True, draw a box around the ellipse. prop : `matplotlib.font_manager.FontProperties`, optional Font property used as a reference for paddings. **kwargs Keyworded arguments to pass to :class:`matplotlib.offsetbox.AnchoredOffsetbox`. Attributes ---------- ellipse : `matplotlib.patches.Ellipse` Ellipse patch drawn. """ self._box = AuxTransformBox(transform) self.ellipse = Ellipse((0, 0), width, height, angle) self._box.add_artist(self.ellipse) AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad, child=self._box, prop=prop, frameon=frameon, **kwargs)
class AnchoredSizeBar(AnchoredOffsetbox): def __init__(self, transform, size, label, loc, pad=0.1, borderpad=0.1, sep=2, frameon=True, size_vertical=0, color='black', label_top=False, fontproperties=None, **kwargs): """ Draw a horizontal bar with the size in data coordinate of the given axes. A label will be drawn underneath (center-aligned). Parameters: ----------- transform : matplotlib transformation object size : int or float horizontal length of the size bar, given in data coordinates label : str loc : int pad : int or float, optional in fraction of the legend font size (or prop) borderpad : int or float, optional in fraction of the legend font size (or prop) sep : int or float, optional in points frameon : bool, optional if True, will draw a box around the horizontal bar and label size_vertical : int or float, optional vertical length of the size bar, given in data coordinates color : str, optional color for the size bar and label label_top : bool, optional if True, the label will be over the rectangle fontproperties: a matplotlib.font_manager.FontProperties instance, optional sets the font properties for the label text Returns: -------- AnchoredSizeBar object Example: -------- >>> import matplotlib.pyplot as plt >>> import numpy as np >>> from mpl_toolkits.axes_grid1.anchored_artists import AnchoredSizeBar >>> fig, ax = plt.subplots() >>> ax.imshow(np.random.random((10,10))) >>> bar = AnchoredSizeBar(ax.transData, 3, '3 units', 4) >>> ax.add_artist(bar) >>> fig.show() Using all the optional parameters >>> import matplotlib.font_manager as fm >>> fontprops = fm.FontProperties(size=14, family='monospace') >>> bar = AnchoredSizeBar(ax.transData, 3, '3 units', 4, pad=0.5, sep=5, borderpad=0.5, frameon=False, size_vertical=0.5, color='white', fontproperties=fontprops) # noqa """ self.size_bar = AuxTransformBox(transform) self.size_bar.add_artist(Rectangle((0, 0), size, size_vertical, fill=True, facecolor=color, edgecolor=color)) # if fontproperties is None, but `prop` is not, assume that # prop should be used to set the font properties. This is # questionable behavior if fontproperties is None and 'prop' in kwargs: fontproperties = kwargs.pop('prop') if fontproperties is None: textprops = {'color': color} else: textprops = {'color': color, 'fontproperties': fontproperties} self.txt_label = TextArea( label, minimumdescent=False, textprops=textprops) if label_top: _box_children = [self.txt_label, self.size_bar] else: _box_children = [self.size_bar, self.txt_label] self._box = VPacker(children=_box_children, align="center", pad=0, sep=sep) AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad, child=self._box, prop=fontproperties, frameon=frameon, **kwargs)
class AnchoredDirectionArrows(AnchoredOffsetbox): def __init__(self, transform, label_x, label_y, length=0.15, fontsize=0.08, loc=2, angle=0, aspect_ratio=1, pad=0.4, borderpad=0.4, frameon=False, color='w', alpha=1, sep_x=0.01, sep_y=0, fontproperties=None, back_length=0.15, head_width=10, head_length=15, tail_width=2, text_props=None, arrow_props=None, **kwargs): """ Draw two perpendicular arrows to indicate directions. Parameters ---------- transform : `matplotlib.transforms.Transform` The transformation object for the coordinate system in use, i.e., :attr:`matplotlib.axes.Axes.transAxes`. label_x, label_y : str Label text for the x and y arrows length : float, optional, default: 0.15 Length of the arrow, given in coordinates of *transform*. fontsize : float, optional, default: 0.08 Size of label strings, given in coordinates of *transform*. loc : int, optional, default: 2 Location of the direction arrows. Valid location codes are:: 'upper right' : 1, 'upper left' : 2, 'lower left' : 3, 'lower right' : 4, 'right' : 5, 'center left' : 6, 'center right' : 7, 'lower center' : 8, 'upper center' : 9, 'center' : 10 angle : float, optional, default: 0 The angle of the arrows in degrees. aspect_ratio : float, optional, default: 1 The ratio of the length of arrow_x and arrow_y. Negative numbers can be used to change the direction. pad : float, optional, default: 0.4 Padding around the labels and arrows, in fraction of the font size. borderpad : float, optional, default: 0.4 Border padding, in fraction of the font size. frameon : bool, optional, default: False If True, draw a box around the arrows and labels. color : str, optional, default: 'white' Color for the arrows and labels. alpha : float, optional, default: 1 Alpha values of the arrows and labels sep_x, sep_y : float, optional, default: 0.01 and 0 respectively Separation between the arrows and labels in coordinates of *transform*. fontproperties : `matplotlib.font_manager.FontProperties`, optional Font properties for the label text. back_length : float, optional, default: 0.15 Fraction of the arrow behind the arrow crossing. head_width : float, optional, default: 10 Width of arrow head, sent to ArrowStyle. head_length : float, optional, default: 15 Length of arrow head, sent to ArrowStyle. tail_width : float, optional, default: 2 Width of arrow tail, sent to ArrowStyle. text_props, arrow_props : dict Properties of the text and arrows, passed to `.textpath.TextPath` and `.patches.FancyArrowPatch`. **kwargs Keyworded arguments to pass to :class:`matplotlib.offsetbox.AnchoredOffsetbox`. Attributes ---------- arrow_x, arrow_y : `matplotlib.patches.FancyArrowPatch` Arrow x and y text_path_x, text_path_y : `matplotlib.textpath.TextPath` Path for arrow labels p_x, p_y : `matplotlib.patches.PathPatch` Patch for arrow labels box : `matplotlib.offsetbox.AuxTransformBox` Container for the arrows and labels. Notes ----- If *prop* is passed as a keyword argument, but *fontproperties* is not, then *prop* is be assumed to be the intended *fontproperties*. Using both *prop* and *fontproperties* is not supported. Examples -------- >>> import matplotlib.pyplot as plt >>> import numpy as np >>> from mpl_toolkits.axes_grid1.anchored_artists import ( ... AnchoredDirectionArrows) >>> fig, ax = plt.subplots() >>> ax.imshow(np.random.random((10, 10))) >>> arrows = AnchoredDirectionArrows(ax.transAxes, '111', '110') >>> ax.add_artist(arrows) >>> fig.show() Using several of the optional parameters, creating downward pointing arrow and high contrast text labels. >>> import matplotlib.font_manager as fm >>> fontprops = fm.FontProperties(family='monospace') >>> arrows = AnchoredDirectionArrows(ax.transAxes, 'East', 'South', ... loc='lower left', color='k', ... aspect_ratio=-1, sep_x=0.02, ... sep_y=-0.01, ... text_props={'ec':'w', 'fc':'k'}, ... fontproperties=fontprops) """ if arrow_props is None: arrow_props = {} if text_props is None: text_props = {} arrowstyle = ArrowStyle("Simple", head_width=head_width, head_length=head_length, tail_width=tail_width) if fontproperties is None and 'prop' in kwargs: fontproperties = kwargs.pop('prop') if 'color' not in arrow_props: arrow_props['color'] = color if 'alpha' not in arrow_props: arrow_props['alpha'] = alpha if 'color' not in text_props: text_props['color'] = color if 'alpha' not in text_props: text_props['alpha'] = alpha t_start = transform t_end = t_start + transforms.Affine2D().rotate_deg(angle) self.box = AuxTransformBox(t_end) length_x = length length_y = length * aspect_ratio self.arrow_x = FancyArrowPatch((0, back_length * length_y), (length_x, back_length * length_y), arrowstyle=arrowstyle, shrinkA=0.0, shrinkB=0.0, **arrow_props) self.arrow_y = FancyArrowPatch((back_length * length_x, 0), (back_length * length_x, length_y), arrowstyle=arrowstyle, shrinkA=0.0, shrinkB=0.0, **arrow_props) self.box.add_artist(self.arrow_x) self.box.add_artist(self.arrow_y) text_path_x = TextPath( (length_x + sep_x, back_length * length_y + sep_y), label_x, size=fontsize, prop=fontproperties) self.p_x = PathPatch(text_path_x, transform=t_start, **text_props) self.box.add_artist(self.p_x) text_path_y = TextPath((length_x * back_length + sep_x, length_y * (1 - back_length) + sep_y), label_y, size=fontsize, prop=fontproperties) self.p_y = PathPatch(text_path_y, **text_props) self.box.add_artist(self.p_y) AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad, child=self.box, frameon=frameon, **kwargs)
def draw(self, renderer, *args, **kwargs): if not self.get_visible(): return if not self.get_mappable(): return # Get parameters from matplotlib import rcParams # late import def _get_value(attr, default): value = getattr(self, attr) if value is None: value = rcParams.get('colorbar.' + attr, default) return value orientation = _get_value('orientation', 'vertical') length_fraction = _get_value('length_fraction', 0.2) width_fraction = _get_value('width_fraction', 0.01) location = _get_value('location', 'upper right') if isinstance(location, six.string_types): location = self._LOCATIONS[location] pad = _get_value('pad', 0.2) border_pad = _get_value('border_pad', 0.1) sep = _get_value('sep', 5) frameon = _get_value('frameon', True) color = _get_value('color', 'k') box_color = _get_value('box_color', 'w') box_alpha = _get_value('box_alpha', 1.0) font_properties = self.font_properties ticklocation = _get_value('ticklocation', 'auto') if ticklocation == 'auto': ticklocation = 'bottom' if orientation == 'horizontal' else 'right' mappable = self.mappable cmap = self.mappable.get_cmap() norm = self.mappable.norm label = self.label ticks = self.ticks ticklabels = self.ticklabels ax = self.axes # Calculate calculator = ColorbarCalculator(mappable, ticks=ticks, ticklabels=ticklabels) X, Y, C = calculator.calculate_colorbar() X *= width_fraction Y *= length_fraction widths = np.diff(X, axis=1)[:, 0] heights = np.diff(Y[:, 0]) if orientation == 'horizontal': X, Y = Y, X widths, heights = heights, widths ticks, ticklabels, offset_string = calculator.calculate_ticks() ticks *= length_fraction # Create colorbar colorbarbox = AuxTransformBox(ax.transAxes) patches = [] for x0, y0, width, height in zip(X[:-1, 0], Y[:-1, 0], widths, heights): patch = Rectangle((x0, y0), width, height) patches.append(patch) edgecolors = 'none' #if self.drawedges else 'none' #FIXME: drawedge property #FIXME: Filled property col = PatchCollection(patches, cmap=cmap, edgecolors=edgecolors, norm=norm) col.set_array(C[:, 0]) colorbarbox.add_artist(col) # Create outline if orientation == 'horizontal': outline = Rectangle((0, 0), length_fraction, width_fraction, fill=False, ec=color) else: outline = Rectangle((0, 0), width_fraction, length_fraction, fill=False, ec=color) colorbarbox.add_artist(outline) # Create ticks and tick labels w10th = width_fraction / 10.0 ticklines = [] ticktexts = [] for tick, ticklabel in zip(ticks, ticklabels): if ticklocation == 'bottom': x0 = x1 = xtext = tick y0 = w10th y1 = -w10th ytext = -2 * w10th ha = 'center' va = 'top' elif ticklocation == 'top': x0 = x1 = xtext = tick y0 = width_fraction - w10th y1 = width_fraction + w10th ytext = width_fraction + 2 * w10th ha = 'center' va = 'bottom' elif ticklocation == 'left': x0 = w10th x1 = -w10th xtext = -2 * w10th y0 = y1 = ytext = tick ha = 'right' va = 'center' elif ticklocation == 'right': x0 = width_fraction - w10th x1 = width_fraction + w10th xtext = width_fraction + 2 * w10th y0 = y1 = ytext = tick ha = 'left' va = 'center' ticklines.append([(x0, y0), (x1, y1)]) ticklabel = offset_string + ticklabel ticktext = Text(xtext, ytext, ticklabel, color=color, fontproperties=font_properties, horizontalalignment=ha, verticalalignment=va) ticktexts.append(ticktext) col = LineCollection(ticklines, color=color) colorbarbox.add_artist(col) for ticktext in ticktexts: colorbarbox.add_artist(ticktext) # Create label if label: labelbox = AuxTransformBox(ax.transAxes) va = 'baseline' if orientation == 'horizontal' else 'center' text = Text(0, 0, label, fontproperties=font_properties, verticalalignment=va, rotation=orientation, color=color) labelbox.add_artist(text) else: labelbox = None # Create final offset box if ticklocation == 'bottom': children = [colorbarbox, labelbox] if labelbox else [colorbarbox] child = VPacker(children=children, align='center', pad=0, sep=sep) elif ticklocation == 'top': children = [labelbox, colorbarbox] if labelbox else [colorbarbox] child = VPacker(children=children, align='center', pad=0, sep=sep) elif ticklocation == 'left': children = [labelbox, colorbarbox] if labelbox else [colorbarbox] child = HPacker(children=children, align='center', pad=0, sep=sep) elif ticklocation == 'right': children = [colorbarbox, labelbox] if labelbox else [colorbarbox] child = HPacker(children=children, align='center', pad=0, sep=sep) # box = AnchoredOffsetbox(loc=location, pad=pad, borderpad=border_pad, child=child, frameon=frameon) box.axes = ax box.set_figure(self.get_figure()) box.patch.set_color(box_color) box.patch.set_alpha(box_alpha) box.draw(renderer)
from matplotlib._png import read_png fn = get_sample_data("grace_hopper.png", asfileobj=False) arr = read_png(fn) text_path = TextPath((0, 0), "!?", size=150) p = PathClippedImagePatch(text_path, arr, ec="k", transform=IdentityTransform()) #p.set_clip_on(False) # make offset box offsetbox = AuxTransformBox(IdentityTransform()) offsetbox.add_artist(p) # make anchored offset box ao = AnchoredOffsetbox(loc=2, child=offsetbox, frameon=True, borderpad=0.2) ax.add_artist(ao) # another text from matplotlib.patches import PathPatch if usetex: r = r"\mbox{textpath supports mathtext \& \TeX}" else: r = r"textpath supports mathtext & TeX" text_path = TextPath((0, 0), r, size=20, usetex=usetex) p1 = PathPatch(text_path,
class AnchoredEllipse(AnchoredOffsetbox): def __init__(self, transform, width, height, angle, loc, pad=0.1, borderpad=0.1, prop=None, frameon=True, **kwargs): """ Draw an anchored ellipse of a given size. Parameters ---------- transform : `matplotlib.transforms.Transform` The transformation object for the coordinate system in use, i.e., :attr:`matplotlib.axes.Axes.transData`. width, height : int or float Width and height of the ellipse, given in coordinates of *transform*. angle : int or float Rotation of the ellipse, in degrees, anti-clockwise. loc : int Location of this size bar. Valid location codes are:: 'upper right' : 1, 'upper left' : 2, 'lower left' : 3, 'lower right' : 4, 'right' : 5, 'center left' : 6, 'center right' : 7, 'lower center' : 8, 'upper center' : 9, 'center' : 10 pad : int or float, optional Padding around the ellipse, in fraction of the font size. Defaults to 0.1. borderpad : int or float, optional Border padding, in fraction of the font size. Defaults to 0.1. frameon : bool, optional If True, draw a box around the ellipse. Defaults to True. prop : `matplotlib.font_manager.FontProperties`, optional Font property used as a reference for paddings. **kwargs Keyworded arguments to pass to :class:`matplotlib.offsetbox.AnchoredOffsetbox`. Attributes ---------- ellipse : `matplotlib.patches.Ellipse` Ellipse patch drawn. """ self._box = AuxTransformBox(transform) self.ellipse = Ellipse((0, 0), width, height, angle) self._box.add_artist(self.ellipse) AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad, child=self._box, prop=prop, frameon=frameon, **kwargs)