Beispiel #1
0
    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
        )
Beispiel #3
0
    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,
        )
Beispiel #4
0
    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)
Beispiel #5
0
    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)
Beispiel #6
0
    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)
Beispiel #7
0
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
Beispiel #8
0
    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)
Beispiel #9
0
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)
Beispiel #11
0
 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)
Beispiel #12
0
    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)
Beispiel #13
0
    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
        )
Beispiel #15
0
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)
Beispiel #16
0
 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
Beispiel #18
0
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)
Beispiel #19
0
    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)
Beispiel #20
0
    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
Beispiel #21
0
    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)
Beispiel #22
0
   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)
Beispiel #23
0
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)
Beispiel #24
0
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
Beispiel #25
0
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))
Beispiel #26
0
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
Beispiel #27
0
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
Beispiel #28
0
    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)
Beispiel #29
0
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)
Beispiel #31
0
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)
Beispiel #32
0
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)
Beispiel #33
0
  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)
Beispiel #34
0
    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)
Beispiel #35
0
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,
            ))
Beispiel #36
0
 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)
Beispiel #37
0
    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)
Beispiel #38
0
    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)
Beispiel #39
0
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)
Beispiel #40
0
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
Beispiel #41
0
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()
Beispiel #42
0
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)
Beispiel #44
0
    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)
Beispiel #46
0
    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)
Beispiel #47
0
    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)
Beispiel #48
0
    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)
Beispiel #49
0
    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)
Beispiel #50
0
    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)
Beispiel #51
0
    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)
Beispiel #52
0
    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)