def __init__(self, transform, sizex=0, sizey=0, labelx=None, labely=None, loc=4, pad=0.1, borderpad=0.1, sep=2, thickness=0, prop=None, **kwargs): """ Draw a horizontal and/or vertical bar with the size in data coordinate of the given 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 bars = AuxTransformBox(transform) if sizex: bars.add_artist(Rectangle((0,0), sizex, thickness, fc="k")) if sizey: bars.add_artist(Rectangle((0,0), thickness, sizey, fc="k")) 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 __init__(self, transform, loc, pad=0.4, borderpad=0.5, prop=None, frameon=True, **kwargs): self.drawing_area = AuxTransformBox(transform) AnchoredOffsetbox.__init__( self, loc, pad=pad, borderpad=borderpad, child=self.drawing_area, prop=prop, frameon=frameon, **kwargs )
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, label_kwa={}, **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). 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 """ from matplotlib.offsetbox import AuxTransformBox, HPacker, TextArea, VPacker from matplotlib.patches import Rectangle bars = AuxTransformBox(transform) rect_kwa = {"ec": barcolor, "lw": barwidth, "fc": "none"} if sizex: bars.add_artist(Rectangle((0, 0), sizex, 0, **rect_kwa)) if sizey: bars.add_artist(Rectangle((0, 0), 0, sizey, **rect_kwa)) vpacker_kwa = {"align": "center", "pad": 0, "sep": sep} if sizex and labelx: self.xlabel = TextArea(labelx, minimumdescent=False, **label_kwa) bars = VPacker(children=[bars, self.xlabel], **vpacker_kwa) if sizey and labely: self.ylabel = TextArea(labely, **label_kwa) bars = HPacker(children=[self.ylabel, bars], **vpacker_kwa) AnchoredOffsetbox.__init__( self, loc, pad=pad, borderpad=borderpad, child=bars, prop=prop, frameon=False, **kwargs, )
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, 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. """ 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)
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)
def draw_legend(ax, legend, legend_type, legend_title, ith_legend): children = [] children.append(make_title(legend_title)) viz_handler = legend_viz[legend_type] legend_items = sorted(legend.items(), key=operator.itemgetter(1)) children += [viz_handler(str(lab), col) for col, lab in legend_items] box = VPacker(children=children, align="left", pad=0, sep=5) # TODO: The vertical spacing between the legends isn't consistent. Should be # padded consistently anchored_box = AnchoredOffsetbox( loc=6, child=box, pad=0., frameon=False, #bbox_to_anchor=(0., 1.02), # Spacing goes here bbox_to_anchor=(1, 0.8 - 0.35 * ith_legend), bbox_transform=ax.transAxes, borderpad=1., ) # Workaround for a bug in matplotlib up to 1.3.1 # https://github.com/matplotlib/matplotlib/issues/2530 anchored_box.set_clip_on(False) return anchored_box
def __init__(self, transform, width, height, angle, loc, pad=0.1, borderpad=0.1, prop=None, frameon=True, facecolor='White', alpha=1.0, **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, facecolor=facecolor, alpha=alpha, **kwargs)) self._box.add_artist(self.ellipse) AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad, child=self._box, prop=prop, frameon=frameon)
def make_gui(img, dataset_name, **kwargs): global alphabet fig = plt.figure(figsize=kwargs["figsize"]) from matplotlib import rcParams rcParams['axes.linewidth'] = 2 rcParams['axes.edgecolor'] = 'k' plt.imshow(img) label_category = cv_label_category if dataset_name == "camvid" else voc_label_category alphabet = alphabet_cv if dataset_name == "camvid" else alphabet_voc vpacker_children = [TextArea("{} - {}".format(alphabet[l], cat), textprops={"weight": 'bold', "size": 10}) for l, cat in sorted(label_category.items(), key=lambda x: x[1])] box = VPacker(children=vpacker_children, align="left", pad=5, sep=5) # display the texts on the right side of image anchored_box = AnchoredOffsetbox(loc="center left", child=box, pad=0., frameon=True, bbox_to_anchor=(1.04, 0.5), bbox_transform=plt.gca().transAxes, borderpad=0.) anchored_box.patch.set_linewidth(2) anchored_box.patch.set_facecolor('gray') anchored_box.patch.set_alpha(0.2) anchored_box.patch.set_boxstyle("round,pad=0.5, rounding_size=0.2") plt.gca().add_artist(anchored_box) # create texts for "Enter a label for the current marker" box1 = TextArea("Enter a label for the current marker", textprops={"weight": 'bold', "size": 12}) box2 = DrawingArea(5, 10, 0, 0) box2.add_artist(mpatches.Circle((5, 5), radius=5, fc=np.array((1, 0, 0)), edgecolor="k", lw=1.5)) box = HPacker(children=[box1, box2], align="center", pad=5, sep=5) # anchored_box creates the text box outside of the plot anchored_box = AnchoredOffsetbox(loc="lower center", child=box, pad=0., frameon=False, bbox_to_anchor=(0.5, -0.1), # ( 0.5, -0.1) bbox_transform=plt.gca().transAxes, borderpad=0.) plt.gca().add_artist(anchored_box) plt.xticks([]) plt.yticks([]) plt.tight_layout(pad=2) buf = io.BytesIO() fig.savefig(buf, format="jpg", dpi=80) buf.seek(0) img_arr = np.frombuffer(buf.getvalue(), dtype=np.uint8) buf.close() im = cv2.imdecode(img_arr, 1) plt.close() return im
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)
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, 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 __init__(self, transform, loc, pad=0.4, borderpad=0.5, prop=None, frameon=True, **kwargs): self.drawing_area = AuxTransformBox(transform) AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad, child=self.drawing_area, prop=prop, frameon=frameon, **kwargs)
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 anchor_legend(ax, box, row, col): anchored = AnchoredOffsetbox(loc=2, child=box, pad=0., frameon=False, bbox_to_anchor=(1 + 0.25*col, 1 - 0.054*row), bbox_transform=ax.transAxes, ) # Workaround for a bug in matplotlib up to 1.3.1 # https://github.com/matplotlib/matplotlib/issues/2530 anchored.set_clip_on(False) ax.add_artist(anchored)
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)
def multicolor_ylabel(ax, list_of_strings, list_of_colors, axis='x', anchorpad=0, **kw): """this function creates axes labels with multiple colors ax specifies the axes object where the labels should be drawn list_of_strings is a list of all of the text items list_if_colors is a corresponding list of colors for the strings axis='x', 'y', or 'both' and specifies which label(s) should be drawn""" from matplotlib.offsetbox import AnchoredOffsetbox, TextArea, HPacker, VPacker # x-axis label if axis == 'x' or axis == 'both': boxes = [ TextArea(text, textprops=dict(color=color, ha='left', va='bottom', **kw)) for text, color in zip(list_of_strings, list_of_colors) ] xbox = HPacker(children=boxes, align="center", pad=0, sep=5) anchored_xbox = AnchoredOffsetbox(loc=3, child=xbox, pad=anchorpad, frameon=False, bbox_to_anchor=(0.2, -0.09), bbox_transform=ax.transAxes, borderpad=0.) ax.add_artist(anchored_xbox) # y-axis label if axis == 'y' or axis == 'both': boxes = [ TextArea(text, textprops=dict(color=color, ha='left', va='bottom', rotation=90, **kw)) for text, color in zip(list_of_strings[::-1], list_of_colors[::-1]) ] ybox = VPacker(children=boxes, align="center", pad=0, sep=5) anchored_ybox = AnchoredOffsetbox(loc=3, child=ybox, pad=anchorpad, frameon=False, bbox_to_anchor=(-0.25, 0.2), bbox_transform=ax.transAxes, borderpad=0.) ax.add_artist(anchored_ybox) return
def anchor_legend(ax, box, row, col): anchored = AnchoredOffsetbox( loc=2, child=box, pad=0., frameon=False, bbox_to_anchor=(1 + 0.25 * col, 1 - 0.054 * row), bbox_transform=ax.transAxes, ) # Workaround for a bug in matplotlib up to 1.3.1 # https://github.com/matplotlib/matplotlib/issues/2530 anchored.set_clip_on(False) ax.add_artist(anchored)
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 draw(self, x=None, y=None): """ Docstring """ # https://stackoverflow.com/questions/33159134/matplotlib-y-axis-label-with-multiple-colors if x is None: x = self.x if y is None: y = self.y if (x is None) and (y is None): raise Exception('No x,y arguments passed!') xy_px = self._get_xy_px(x, y) y_incr_px = self._get_y_increment() boxes = self.boxes for box in boxes[::-1]: x, y = self.transform.inverted().transform(xy_px) anchored_xbox = AnchoredOffsetbox(loc=3, child=box, pad=0, frameon=False, bbox_to_anchor=(x, y), bbox_transform=self.transform, borderpad=0) self.parent.add_artist(anchored_xbox) xy_px[1] += y_incr_px self.children = [ textarea.get_children() for box in boxes for textarea in box.get_children() ] return self.children
def add_image_inset(self, filename, loc=4, zoom=1, transpose=False): """ Add a raster image to the plot, according to the legend location loc. :param filename: image's file name :param loc: an integer specifying the location. The 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, :param zoom: scaling factor of the image :param transpose: Transpose the image. """ arr_eps = plt.imread(filename) if transpose: arr_eps = arr_eps.transpose((1, 0, 2)) imagebox = OffsetImage(arr_eps, zoom=zoom) ab = AnchoredOffsetbox(loc=loc, child=imagebox, frameon=False) self._ax.add_artist(ab)
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)
def set_ylabel_multicolor( ax, strings, colors, anchorpad=0., **kwargs, ): """Use multiple colors in the ylabel :ax: (matplotlib.axes) axis to set ylabel :strings: (list of strings) strings for the label :colors: (list of strings) name of colors for the label :ancharpad: (float) Pad between the text and the frame as fraction of the font size """ from matplotlib.offsetbox import AnchoredOffsetbox, TextArea, HPacker, VPacker boxes = [ TextArea(text, textprops=dict(color=color, ha='left', va='bottom', rotation=90, **kwargs)) for text, color in zip(strings[::-1], colors[::-1]) ] ybox = VPacker(children=boxes, align="center", pad=0, sep=5) anchored_ybox = AnchoredOffsetbox(loc=3, child=ybox, pad=anchorpad, frameon=False, bbox_to_anchor=(-0.15, -0.05), bbox_transform=ax.transAxes, borderpad=0.) ax.add_artist(anchored_ybox)
def add_offsetboxes(ax, size=10, margin=.1, color='black'): """ Surround ax with OffsetBoxes """ m, mp = margin, 1 + margin anchor_points = [(-m, -m), (-m, .5), (-m, mp), (mp, .5), (.5, mp), (mp, mp), (.5, -m), (mp, -m), (.5, -m)] for point in anchor_points: da = DrawingArea(size, size) background = Rectangle((0, 0), width=size, height=size, facecolor=color, edgecolor='None', linewidth=0, antialiased=False) da.add_artist(background) anchored_box = AnchoredOffsetbox(loc='center', child=da, pad=0., frameon=False, bbox_to_anchor=point, bbox_transform=ax.transAxes, borderpad=0.) ax.add_artist(anchored_box) return anchored_box
def test_offsetbox_clipping(): # - create a plot # - put an AnchoredOffsetbox with a child DrawingArea # at the center of the axes # - give the DrawingArea a gray background # - put a black line across the bounds of the DrawingArea # - see that the black line is clipped to the edges of # the DrawingArea. fig, ax = plt.subplots() size = 100 da = DrawingArea(size, size, clip=True) bg = mpatches.Rectangle((0, 0), size, size, facecolor='#CCCCCC', edgecolor='None', linewidth=0) line = mlines.Line2D([-size * .5, size * 1.5], [size / 2, size / 2], color='black', linewidth=10) anchored_box = AnchoredOffsetbox(loc=10, child=da, pad=0., frameon=False, bbox_to_anchor=(.5, .5), bbox_transform=ax.transAxes, borderpad=0.) da.add_artist(bg) da.add_artist(line) ax.add_artist(anchored_box) ax.set_xlim((0, 1)) ax.set_ylim((0, 1))
def logo_box(x, y): logo_offset_image = OffsetImage(read_png( get_sample_data(logo_location, asfileobj=False)), zoom=0.25, resample=1, dpi_cor=1) text_box = TextArea(logo_text, textprops=dict(color='#444444', fontsize=50, weight='bold')) logo_and_text_box = HPacker(children=[logo_offset_image, text_box], align="center", pad=0, sep=25) anchored_box = AnchoredOffsetbox(loc=2, child=logo_and_text_box, pad=0.8, frameon=False, borderpad=0., bbox_to_anchor=[x, y], bbox_transform=plt.gcf().transFigure) return anchored_box
def generate_title(d_min, d_max, ax): '''This generates the title box artist to be added to the top of the map. If the title needs to be changed, this is where to do it. The dates d_min and d_max should be years. If the title location needs to be adjusted, this is where that happens (bbox_to_anchor). ''' title = TextArea("Cruises for the U.S. Global Ocean Carbon and Repeat " "Hydrography Program, {0}-{1}".format(d_min, d_max), textprops=dict(size=9)) subtitle_size = 8 subt1 = TextArea("(", textprops=dict(size=subtitle_size)) subt2 = TextArea("red italic", textprops=dict(color="r",style="italic",size=subtitle_size)) subt3 = TextArea("indicates pending cruise;", textprops=dict(size=subtitle_size)) subt4 = TextArea("grey", textprops=dict(color="grey",size=subtitle_size)) subt5 = TextArea("indicates completed cruises; black indicates funded cruises)", textprops=dict(size=subtitle_size)) subt = HPacker(children=[subt1,subt2,subt3,subt4,subt5], align="center", pad=0, sep=2) title = VPacker(children=[title,subt], align="center", pad=0, sep=8) t = AnchoredOffsetbox(loc=3, child=title, pad=0, bbox_to_anchor=(-0.02, 1.02), bbox_transform=ax.transAxes, borderpad=0, frameon=False) return t
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)
def draw_circles(ax): """Draw circles in axes coordinates.""" area = DrawingArea(40, 20, 0, 0) area.add_artist(Circle((10, 10), 10, fc="tab:blue")) area.add_artist(Circle((30, 10), 5, fc="tab:red")) box = AnchoredOffsetbox( child=area, loc="upper right", pad=0, frameon=False) ax.add_artist(box)
def draw_figure(popularity, data): # init figure fig, ax = plt.subplots(constrained_layout=True, figsize=(7,7)) # pie plot wedges,_,texts = ax.pie([p for p,_ in data], startangle=90, counterclock=False, autopct="", pctdistance=0.75, wedgeprops={'width':0.5,'linewidth':1,'edgecolor':'k','antialiased': True}, colors="w") # matrix plot nbMen, nbWomen = popularity.shape """ axmat = inset_axes(ax, "20%", "20%", loc="center") axmat.xaxis.tick_top() xticks, yticks = list(range(1,1+nbWomen)), list(range(1,1+nbMen)) axmat.set_xticks(xticks) axmat.set_yticks(yticks) axmat.set_xticklabels("$w_{%d}$" % i for i in xticks) axmat.set_yticklabels("$m_{%d}$" % i for i in yticks) axmat.imshow(popularity, norm=LogNorm(vmin=0.01,vmax=1000), cmap="gray_r", extent=(0.5, nbWomen+0.5, nbMen+0.5, 0.5)) for idMan in range(nbMen): for idWoman in range(nbWomen): axmat.text(1+idWoman, 1+idMan, str(popularity[idMan, idWoman])) """ # angles anglesB = [(w.theta2 - w.theta1)/2. + w.theta1 for w in wedges] anglesA = best_angles(anglesB) # plot matchings plt.rc('mathtext', fontset='stix') ax.set_xlim(-1.6, 1.6) ax.set_ylim(-1.6, 1.6) matchings = [ (p,m,w,t) for (p,m),w,t in zip(data, wedges, texts)] for i, (p, m, w, t) in enumerate(matchings): radius = 1.25 if abs(w.theta2 - w.theta1) >= 10: t.set_text("$\\frac{%d}{%d}$" % (p.numerator, p.denominator)) t.set_size(22) angA, angB = anglesA[i], anglesB[i] xA = radius * np.cos(np.deg2rad(angA)) yA = radius * np.sin(np.deg2rad(angA)) xB = np.cos(np.deg2rad(angB)) yB = np.sin(np.deg2rad(angB)) box = AnchoredOffsetbox( child=draw_matching(m, nbMen, nbWomen), loc='center', frameon=True, bbox_to_anchor=(xA, yA), bbox_transform=ax.transData, pad=0., borderpad=0.) ax.add_artist(box) con = ConnectionPatch( xyA = (xA,yA), xyB = (xB,yB), coordsA="data", coordsB="data") ax.add_artist(con)
def export_panel(plitem, ax): """ export_panel recreates the contents of one pyqtgraph PlotItem into a specified matplotlib axis item. Handles PlotItem types of PlotCurveItem, PlotDataItem, BarGraphItem, and ScatterPlotItem :param plitem: The PlotItem holding a single plot :param ax: the matplotlib axis to put the result into :return: Nothing """ # get labels from the pyqtgraph PlotItems xlabel = plitem.axes['bottom']['item'].label.toPlainText() ylabel = plitem.axes['left']['item'].label.toPlainText() title = remove_html_markup(plitem.titleLabel.text) label = remove_html_markup(plitem.plotLabel.text) fontsize = 12 fn = pg.functions ax.clear() cleanAxes(ax) # make a "nice" plot ax.set_title(title) # add the plot title here for item in plitem.items: # was .curves, but let's handle all items # dispatch do different routines depending on what we need to plot if isinstance(item, pg.graphicsItems.PlotCurveItem.PlotCurveItem): export_curve(fn, ax, item) elif isinstance(item, pg.graphicsItems.PlotDataItem.PlotDataItem): export_curve(fn, ax, item) elif isinstance(item, pg.graphicsItems.BarGraphItem.BarGraphItem): export_bargraph(fn, ax, item) elif isinstance(item, pg.graphicsItems.ScatterPlotItem.ScatterPlotItem): export_scatterplot(fn, ax, item) else: print 'unknown item encountered : ', item continue xr, yr = plitem.viewRange() # now clean up the matplotlib/pylab plot and annotations ax.set_xbound(*xr) ax.set_ybound(*yr) at = TextArea(label, textprops=dict(color="k", verticalalignment='bottom', weight='bold', horizontalalignment='right', fontsize=fontsize, family='sans-serif')) box = HPacker(children=[at], align="left", pad=0, sep=2) ab = AnchoredOffsetbox(loc=3, child=box, pad=0., frameon=False, bbox_to_anchor=(-0.08, 1.1), bbox_transform=ax.transAxes, borderpad=0.) ax.add_artist(ab) ax.set_xlabel(xlabel) # place the axis labels. ax.set_ylabel(ylabel)
def multicolor_label(ax, list_of_strings, list_of_colors, axis='x', anchorpad=0, bbox_to_anchor=(0, 0), **kw): from matplotlib.offsetbox import AnchoredOffsetbox, TextArea, HPacker, VPacker # x-axis label if axis == 'x' or axis == 'both': boxes = [ TextArea(text, textprops=dict(color=color, ha='left', va='bottom', **kw)) for text, color in zip(list_of_strings, list_of_colors) ] xbox = HPacker(children=boxes, align="center", pad=0, sep=5) anchored_xbox = AnchoredOffsetbox(loc='center left', child=xbox, pad=anchorpad, frameon=False, bbox_to_anchor=bbox_to_anchor, bbox_transform=ax.transAxes, borderpad=0.) ax.add_artist(anchored_xbox) # y-axis label if axis == 'y' or axis == 'both': boxes = [ TextArea(text, textprops=dict(color=color, ha='left', va='center', **kw)) for text, color in zip(list_of_strings[::-1], list_of_colors) ] ybox = VPacker(children=boxes, align='center', pad=0, sep=5) anchored_ybox = AnchoredOffsetbox(loc='center left', child=ybox, pad=anchorpad, frameon=False, bbox_to_anchor=bbox_to_anchor, bbox_transform=ax.transAxes, borderpad=0.) ax.add_artist(anchored_ybox)
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, 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)
def plot_twiss( ax, twiss, *, twiss_functions=("beta_x", "beta_y", "eta_x"), scales={ "eta_x": 10, "eta_x_dds": 10 }, line_style="solid", line_width=1.3, alpha=1.0, show_ylabels=False, ): if scales is None: scales = {} text_areas = [] for i, function in enumerate(twiss_functions): value = getattr(twiss, function) label, color = OPTICAL_FUNCTIONS[function] scale = scales.get(function) if scale is not None: label = f"{scale} {label}" value = scale * value ax.plot( twiss.s, value, color=color, linewidth=line_width, linestyle=line_style, alpha=alpha, zorder=10 - i, label=label, ) text_areas.insert( 0, TextArea(label, textprops=dict(color=color, rotation=90))) ax.set_xlabel("Orbit Position $s$ / m") if show_ylabels: ax.add_artist( AnchoredOffsetbox( child=VPacker(children=text_areas, align="bottom", pad=0, sep=20), loc="center left", bbox_to_anchor=(-0.125, 0, 1.125, 1), bbox_transform=ax.transAxes, frameon=False, ))
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 __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 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: linewidth=0.70 #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')) #TODO capstyle 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 draw_legend(ax, legend, legend_type, legend_title, ith_legend): children = [] children.append(make_title(legend_title)) viz_handler = legend_viz[legend_type] legend_items = sorted(legend.items(), key=operator.itemgetter(1)) children += [viz_handler(str(lab), col) for col, lab in legend_items] box = VPacker(children=children, align="left", pad=0, sep=5) # TODO: The vertical spacing between the legends isn't consistent. Should be # padded consistently anchored_box = AnchoredOffsetbox(loc=6, child=box, pad=0., frameon=False, #bbox_to_anchor=(0., 1.02), # Spacing goes here bbox_to_anchor=(1, 0.8 - 0.35 * ith_legend), bbox_transform=ax.transAxes, borderpad=1., ) # Workaround for a bug in matplotlib up to 1.3.1 # https://github.com/matplotlib/matplotlib/issues/2530 anchored_box.set_clip_on(False) return anchored_box
def _plot_val_sens_specif_auc(validation_aucs, validation_recalls, validation_specifs): """ Plots training and validation auc roc score in same figure. Args: validation_aucs (list) validation_recalls (list) validation_specifs (list) """ color = 'tab:red' num_val_aucs = np.arange(0, len(validation_aucs), 1) fig, ax1 = plt.subplots() fig.set_size_inches(12, 6) ax1.set_xlabel('Epochs') ax1.set_ylabel('Validation AUC', color=color) ax1.plot(num_val_aucs, validation_aucs, color=color) ax1.tick_params(axis='y', labelcolor=color) ax1.set_ylim([0.0, 1.1]) ax2 = ax1.twinx() ax2.set_ylim([0.0, 1.1]) ybox1 = TextArea("Sensitivity ", textprops=dict(color='tab:blue', rotation=90, ha='left', va='bottom')) ybox2 = TextArea("and ", textprops=dict(color="k", rotation=90, ha='left', va='bottom')) ybox3 = TextArea("Specificity ", textprops=dict(color='xkcd:azure', rotation=90, ha='left', va='bottom')) ybox = VPacker(children=[ybox1, ybox2, ybox3], align="bottom", pad=0, sep=5) anchored_ybox = AnchoredOffsetbox(loc=8, child=ybox, pad=0., frameon=False, bbox_to_anchor=(1.13, 0.25), bbox_transform=ax2.transAxes, borderpad=0.) ax2.add_artist(anchored_ybox) color = 'tab:blue' ax2.plot(num_val_aucs, validation_recalls, color=color) ax2.plot(num_val_aucs, validation_specifs, color='xkcd:azure') ax2.tick_params(axis='y', labelcolor=color) fig.tight_layout() plt.show()
def watermark(fig, ax, loc=2, downscale=8): # print(os.getcwd()) img = Image.open('../references/tu_delft_logo.png') width, height = ax.figure.get_size_inches() * fig.dpi wm_width = int(width / downscale) # make the watermark 1/4 of the figure size scaling = (wm_width / float(img.size[0])) wm_height = int(float(img.size[1]) * float(scaling)) img = img.resize((wm_width, wm_height), Image.ANTIALIAS) imagebox = OffsetImage(img, zoom=1, alpha=0.5) imagebox.image.axes = ax ao = AnchoredOffsetbox(loc=loc, pad=0.01, borderpad=0, child=imagebox) ao.patch.set_alpha(0) ax.add_artist(ao)
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)
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 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, transform, loc, pad=0.4, borderpad=0.5, prop=None, frameon=True, **kwargs): """ An anchored container with transformed coordinates. Artists added to the *drawing_area* are scaled according to the coordinates of the transformation used. The dimensions of this artist will scale to contain the artists added. Parameters ---------- transform : `matplotlib.transforms.Transform` The transformation object for the coordinate system in use, i.e., :attr:`matplotlib.axes.Axes.transData`. loc : int Location of this artist. 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 child objects, 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.5. prop : `matplotlib.font_manager.FontProperties`, optional Font property used as a reference for paddings. frameon : bool, optional If True, draw a box around this artists. Defaults to True. **kwargs Keyworded arguments to pass to :class:`matplotlib.offsetbox.AnchoredOffsetbox`. Attributes ---------- drawing_area : `matplotlib.offsetbox.AuxTransformBox` A container for artists to display. Examples -------- To display an ellipse in the upper left, with a width of 0.1 and height of 0.4 in data coordinates: >>> box = AnchoredAuxTransformBox(ax.transData, loc='upper left') >>> el = Ellipse((0,0), width=0.1, height=0.4, angle=30) >>> box.drawing_area.add_artist(el) >>> ax.add_artist(box) """ self.drawing_area = AuxTransformBox(transform) AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad, child=self.drawing_area, prop=prop, frameon=frameon, **kwargs)
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)
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)
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)
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)
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)
def _draw_legend(self): """ Draw legend onto the figure """ legend_box = self.guides.build(self) if not legend_box: return figure = self.figure left = figure.subplotpars.left right = figure.subplotpars.right top = figure.subplotpars.top bottom = figure.subplotpars.bottom W, H = figure.get_size_inches() position = self.guides.position get_property = self.theme.themeables.property # defaults spacing = 0.1 strip_margin_x = 0 strip_margin_y = 0 with suppress(KeyError): spacing = get_property('legend_box_spacing') with suppress(KeyError): strip_margin_x = get_property('strip_margin_x') with suppress(KeyError): strip_margin_y = get_property('strip_margin_y') right_strip_width = self.facet.strip_size('right') top_strip_height = self.facet.strip_size('top') # Other than when the legend is on the right the rest of # the computed x, y locations are not gauranteed not to # overlap with the axes or the labels. The user must then # use the legend_margin theme parameter to adjust the # location. This should get fixed when MPL has a better # layout manager. if position == 'right': loc = 6 pad = right_strip_width*(1+strip_margin_x) + spacing x = right + pad/W y = 0.5 elif position == 'left': loc = 7 x = left - spacing/W y = 0.5 elif position == 'top': loc = 8 x = 0.5 pad = top_strip_height*(1+strip_margin_y) + spacing y = top + pad/H elif position == 'bottom': loc = 9 x = 0.5 y = bottom - spacing/H else: loc = 10 x, y = position anchored_box = AnchoredOffsetbox( loc=loc, child=legend_box, pad=0., frameon=False, bbox_to_anchor=(x, y), bbox_transform=figure.transFigure, borderpad=0.) anchored_box.set_zorder(90.1) self.figure._themeable['legend_background'] = anchored_box ax = self.axs[0] ax.add_artist(anchored_box)