def draw(self, renderer, *args, **kwargs):
        if not self.get_visible():
            return
        if self.dx == 0:
            return

        # Get parameters
        from matplotlib import rcParams  # late import

        def _get_value(attr, default):
            value = getattr(self, attr)
            if value is None:
                value = rcParams.get('scalebar.' + attr, default)
            return value

        length_fraction = _get_value('length_fraction', 0.2)
        height_fraction = _get_value('height_fraction', 0.01)
        location = _get_value('location', 'upper right')
        if is_string_like(location):
            location = self._LOCATIONS[location]
        pad = _get_value('pad', 0.2)
        border_pad = _get_value('border_pad', 0.1)
        sep = _get_value('sep', 5)
        frameon = _get_value('frameon', True)
        color = _get_value('color', 'k')
        box_color = _get_value('box_color', 'w')
        box_alpha = _get_value('box_alpha', 1.0)
        scale_loc = _get_value('scale_loc', 'bottom')
        label_loc = _get_value('label_loc', 'top')
        font_properties = self.font_properties

        if font_properties is None:
            textprops = {'color': color}
        else:
            textprops = {'color': color, 'fontproperties': font_properties}

        ax = self.axes
        xlim, ylim = ax.get_xlim(), ax.get_ylim()
        label = self.label

        # Create label
        if label:
            txtlabel = TextArea(label,
                                minimumdescent=False,
                                textprops=textprops)
        else:
            txtlabel = None

        # Create sizebar
        length_px = abs(xlim[1] - xlim[0]) * length_fraction
        length_px, scale_label = self._calculate_length(length_px)

        size_vertical = abs(ylim[1] - ylim[0]) * height_fraction

        sizebar = AuxTransformBox(ax.transData)
        sizebar.add_artist(
            Rectangle((0, 0),
                      length_px,
                      size_vertical,
                      fill=True,
                      facecolor=color,
                      edgecolor=color))

        txtscale = TextArea(scale_label,
                            minimumdescent=False,
                            textprops=textprops)

        if scale_loc in ['bottom', 'right']:
            children = [sizebar, txtscale]
        else:
            children = [txtscale, sizebar]
        if scale_loc in ['bottom', 'top']:
            Packer = VPacker
        else:
            Packer = HPacker
        boxsizebar = Packer(children=children, align='center', pad=0, sep=sep)

        # Create final offset box
        if txtlabel:
            if label_loc in ['bottom', 'right']:
                children = [boxsizebar, txtlabel]
            else:
                children = [txtlabel, boxsizebar]
            if label_loc in ['bottom', 'top']:
                Packer = VPacker
            else:
                Packer = HPacker
            child = Packer(children=children, align='center', pad=0, sep=sep)
        else:
            child = boxsizebar

        box = AnchoredOffsetbox(loc=location,
                                pad=pad,
                                borderpad=border_pad,
                                child=child,
                                frameon=frameon)

        box.axes = ax
        box.set_figure(self.get_figure())
        box.patch.set_color(box_color)
        box.patch.set_alpha(box_alpha)
        box.draw(renderer)
Example #2
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 isinstance(location, six.string_types):
            location = self._LOCATIONS[location]
        pad = _get_value('pad', 0.2)
        border_pad = _get_value('border_pad', 0.1)
        sep = _get_value('sep', 5)
        frameon = _get_value('frameon', True)
        color = _get_value('color', 'k')
        box_color = _get_value('box_color', 'w')
        box_alpha = _get_value('box_alpha', 1.0)
        font_properties = self.font_properties
        ticklocation = _get_value('ticklocation', 'auto')
        if ticklocation == 'auto':
            ticklocation = 'bottom' if orientation == 'horizontal' else 'right'

        mappable = self.mappable
        cmap = self.mappable.get_cmap()
        norm = self.mappable.norm
        label = self.label
        ticks = self.ticks
        ticklabels = self.ticklabels

        ax = self.axes

        # Calculate
        calculator = ColorbarCalculator(mappable,
                                        ticks=ticks,
                                        ticklabels=ticklabels)

        X, Y, C = calculator.calculate_colorbar()
        X *= width_fraction
        Y *= length_fraction
        widths = np.diff(X, axis=1)[:, 0]
        heights = np.diff(Y[:, 0])
        if orientation == 'horizontal':
            X, Y = Y, X
            widths, heights = heights, widths

        ticks, ticklabels, offset_string = calculator.calculate_ticks()
        ticks *= length_fraction

        # Create colorbar
        colorbarbox = AuxTransformBox(ax.transAxes)

        patches = []
        for x0, y0, width, height in zip(X[:-1, 0], Y[:-1, 0], widths,
                                         heights):
            patch = Rectangle((x0, y0), width, height)
            patches.append(patch)

        edgecolors = 'none'  #if self.drawedges else 'none'
        #FIXME: drawedge property
        #FIXME: Filled property
        col = PatchCollection(patches,
                              cmap=cmap,
                              edgecolors=edgecolors,
                              norm=norm)
        col.set_array(C[:, 0])
        colorbarbox.add_artist(col)

        # Create outline
        if orientation == 'horizontal':
            outline = Rectangle((0, 0),
                                length_fraction,
                                width_fraction,
                                fill=False,
                                ec=color)
        else:
            outline = Rectangle((0, 0),
                                width_fraction,
                                length_fraction,
                                fill=False,
                                ec=color)
        colorbarbox.add_artist(outline)

        # Create ticks and tick labels
        w10th = width_fraction / 10.0
        ticklines = []
        ticktexts = []
        for tick, ticklabel in zip(ticks, ticklabels):
            if ticklocation == 'bottom':
                x0 = x1 = xtext = tick
                y0 = w10th
                y1 = -w10th
                ytext = -2 * w10th
                ha = 'center'
                va = 'top'
            elif ticklocation == 'top':
                x0 = x1 = xtext = tick
                y0 = width_fraction - w10th
                y1 = width_fraction + w10th
                ytext = width_fraction + 2 * w10th
                ha = 'center'
                va = 'bottom'
            elif ticklocation == 'left':
                x0 = w10th
                x1 = -w10th
                xtext = -2 * w10th
                y0 = y1 = ytext = tick
                ha = 'right'
                va = 'center'
            elif ticklocation == 'right':
                x0 = width_fraction - w10th
                x1 = width_fraction + w10th
                xtext = width_fraction + 2 * w10th
                y0 = y1 = ytext = tick
                ha = 'left'
                va = 'center'

            ticklines.append([(x0, y0), (x1, y1)])

            ticklabel = offset_string + ticklabel
            ticktext = Text(xtext,
                            ytext,
                            ticklabel,
                            color=color,
                            fontproperties=font_properties,
                            horizontalalignment=ha,
                            verticalalignment=va)
            ticktexts.append(ticktext)

        col = LineCollection(ticklines, color=color)
        colorbarbox.add_artist(col)

        for ticktext in ticktexts:
            colorbarbox.add_artist(ticktext)

        # Create label
        if label:
            labelbox = AuxTransformBox(ax.transAxes)

            va = 'baseline' if orientation == 'horizontal' else 'center'
            text = Text(0,
                        0,
                        label,
                        fontproperties=font_properties,
                        verticalalignment=va,
                        rotation=orientation,
                        color=color)
            labelbox.add_artist(text)
        else:
            labelbox = None

        # Create final offset box
        if ticklocation == 'bottom':
            children = [colorbarbox, labelbox] if labelbox else [colorbarbox]
            child = VPacker(children=children, align='center', pad=0, sep=sep)
        elif ticklocation == 'top':
            children = [labelbox, colorbarbox] if labelbox else [colorbarbox]
            child = VPacker(children=children, align='center', pad=0, sep=sep)
        elif ticklocation == 'left':
            children = [labelbox, colorbarbox] if labelbox else [colorbarbox]
            child = HPacker(children=children, align='center', pad=0, sep=sep)
        elif ticklocation == 'right':
            children = [colorbarbox, labelbox] if labelbox else [colorbarbox]
            child = HPacker(children=children, align='center', pad=0, sep=sep)


#
        box = AnchoredOffsetbox(loc=location,
                                pad=pad,
                                borderpad=border_pad,
                                child=child,
                                frameon=frameon)

        box.axes = ax
        box.set_figure(self.get_figure())
        box.patch.set_color(box_color)
        box.patch.set_alpha(box_alpha)
        box.draw(renderer)
Example #3
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)
Example #4
0
    def draw(self, renderer, *args, **kwargs):
        if not self.get_visible():
            return
        if self.dx == 0:
            return

        # Late import
        from matplotlib import rcParams

        # Deprecation
        if rcParams.get("scalebar.height_fraction") is not None:
            warnings.warn(
                "The scalebar.height_fraction parameter in matplotlibrc is deprecated. "
                "Use scalebar.width_fraction instead.",
                DeprecationWarning,
            )
            rcParams.setdefault("scalebar.width_fraction",
                                rcParams["scalebar.height_fraction"])

        # Get parameters
        def _get_value(attr, default):
            value = getattr(self, attr)
            if value is None:
                value = rcParams.get("scalebar." + attr, default)
            return value

        length_fraction = _get_value("length_fraction", 0.2)
        width_fraction = _get_value("width_fraction", 0.01)
        location = _get_value("location", "upper right")
        if isinstance(location, str):
            location = self._LOCATIONS[location.lower()]
        pad = _get_value("pad", 0.2)
        border_pad = _get_value("border_pad", 0.1)
        sep = _get_value("sep", 5)
        frameon = _get_value("frameon", True)
        color = _get_value("color", "k")
        box_color = _get_value("box_color", "w")
        box_alpha = _get_value("box_alpha", 1.0)
        scale_loc = _get_value("scale_loc", "bottom").lower()
        label_loc = _get_value("label_loc", "top").lower()
        font_properties = self.font_properties
        fixed_value = self.fixed_value
        fixed_units = self.fixed_units or self.units
        rotation = _get_value("rotation", "horizontal").lower()
        label = self.label

        # Create text properties
        textprops = {"color": color, "rotation": rotation}
        if font_properties is not None:
            textprops["fontproperties"] = font_properties

        # Calculate value, units and length
        ax = self.axes
        xlim = ax.get_xlim()
        ylim = ax.get_ylim()
        if rotation == "vertical":
            xlim, ylim = ylim, xlim

        # Mode 1: Auto
        if self.fixed_value is None:
            length_px = abs(xlim[1] - xlim[0]) * length_fraction
            length_px, value, units = self._calculate_best_length(length_px)

        # Mode 2: Fixed
        else:
            value = fixed_value
            units = fixed_units
            length_px = self._calculate_exact_length(value, units)

        scale_text = self.scale_formatter(value,
                                          self.dimension.to_latex(units))

        width_px = abs(ylim[1] - ylim[0]) * width_fraction

        # Create scale bar
        if rotation == "horizontal":
            scale_rect = Rectangle(
                (0, 0),
                length_px,
                width_px,
                fill=True,
                facecolor=color,
                edgecolor="none",
            )
        else:
            scale_rect = Rectangle(
                (0, 0),
                width_px,
                length_px,
                fill=True,
                facecolor=color,
                edgecolor="none",
            )

        scale_bar_box = AuxTransformBox(ax.transData)
        scale_bar_box.add_artist(scale_rect)

        scale_text_box = TextArea(scale_text, textprops=textprops)

        if scale_loc in ["bottom", "right"]:
            children = [scale_bar_box, scale_text_box]
        else:
            children = [scale_text_box, scale_bar_box]

        if scale_loc in ["bottom", "top"]:
            Packer = VPacker
        else:
            Packer = HPacker

        scale_box = Packer(children=children, align="center", pad=0, sep=sep)

        # Create label
        if label:
            label_box = TextArea(label, textprops=textprops)
        else:
            label_box = None

        # Create final offset box
        if label_box:
            if label_loc in ["bottom", "right"]:
                children = [scale_box, label_box]
            else:
                children = [label_box, scale_box]

            if label_loc in ["bottom", "top"]:
                Packer = VPacker
            else:
                Packer = HPacker

            child = Packer(children=children, align="center", pad=0, sep=sep)
        else:
            child = scale_box

        box = AnchoredOffsetbox(loc=location,
                                pad=pad,
                                borderpad=border_pad,
                                child=child,
                                frameon=frameon)

        box.axes = ax
        box.set_figure(self.get_figure())
        box.patch.set_color(box_color)
        box.patch.set_alpha(box_alpha)
        box.draw(renderer)
Example #5
0
    def draw(self, renderer, *args, **kwargs):
        if not self.get_visible():
            return
        if self.dx == 0:
            return

        # Get parameters
        from matplotlib import rcParams # late import

        def _get_value(attr, default):
            value = getattr(self, attr)
            if value is None:
                value = rcParams.get('scalebar.' + attr, default)
            return value

        length_fraction = _get_value('length_fraction', 0.2)
        height_fraction = _get_value('height_fraction', 0.01)
        location = _get_value('location', 'upper right')
        if isinstance(location,six.string_types):
            location = self._LOCATIONS[location]
        pad = _get_value('pad', 0.2)
        border_pad = _get_value('border_pad', 0.1)
        sep = _get_value('sep', 5)
        frameon = _get_value('frameon', True)
        color = _get_value('color', 'k')
        box_color = _get_value('box_color', 'w')
        box_alpha = _get_value('box_alpha', 1.0)
        scale_loc = _get_value('scale_loc', 'bottom')
        label_loc = _get_value('label_loc', 'top')
        font_properties = self.font_properties

        if font_properties is None:
            textprops = {'color': color}
        else:
            textprops = {'color': color, 'fontproperties': font_properties}

        ax = self.axes
        xlim, ylim = ax.get_xlim(), ax.get_ylim()
        label = self.label

        # Create label
        if label:
            txtlabel = TextArea(label, minimumdescent=False, textprops=textprops)
        else:
            txtlabel = None

        # Create sizebar
        length_px = abs(xlim[1] - xlim[0]) * length_fraction
        length_px, scale_label = self._calculate_length(length_px)

        size_vertical = abs(ylim[1] - ylim[0]) * height_fraction

        sizebar = AuxTransformBox(ax.transData)
        sizebar.add_artist(Rectangle((0, 0), length_px, size_vertical,
                                     fill=True, facecolor=color,
                                     edgecolor=color))

        txtscale = TextArea(scale_label, minimumdescent=False, textprops=textprops)

        if scale_loc in ['bottom', 'right']:
            children = [sizebar, txtscale]
        else:
            children = [txtscale, sizebar]
        if scale_loc in ['bottom', 'top']:
            Packer = VPacker
        else:
            Packer = HPacker
        boxsizebar = Packer(children=children, align='center', pad=0, sep=sep)

        # Create final offset box
        if txtlabel:
            if label_loc in ['bottom', 'right']:
                children = [boxsizebar, txtlabel]
            else:
                children = [txtlabel, boxsizebar]
            if label_loc in ['bottom', 'top']:
                Packer = VPacker
            else:
                Packer = HPacker
            child = Packer(children=children, align='center', pad=0, sep=sep)
        else:
            child = boxsizebar

        box = AnchoredOffsetbox(loc=location,
                                pad=pad,
                                borderpad=border_pad,
                                child=child,
                                frameon=frameon)

        box.axes = ax
        box.set_figure(self.get_figure())
        box.patch.set_color(box_color)
        box.patch.set_alpha(box_alpha)
        box.draw(renderer)
    def scalebar_based_on_planar_distance(
        ax,
        x_planar_size=1,
        rounding_value_for_xsize=0,
        bar_height=0.015,
        decimal_separator=',',
        fill_bar=True,
        fill_bar_color='k',
        fontproperties=None,
        label_top=True,
        loc='center',
        pad=0,
        borderpad=0,
        background_facecolor='k',
        face_alpha=1,
        length_unit='m',
        unit_transformation_function=None,
        background_edgecolor='k',
        background_linewidth=1,
        background_edgealpha=1,
        background_facealpha=1,
        sep=0,
        x0=0.91,
        y0=0.02,
        x1=1,
        y1=0.08,
    ):
        """
            Function description:
                This function adds a sizebar in the axes. 
                This sizebar is an artist of matplotlib. 
                This artist x_size automatically dilates or contracts acoording to the zooming (in/out) \
                of its parent axes.

            --------------------------------------------------------------------------------------------------------------    

            Parameters:

                ax: the parent axes that will be used to measure the distance for the sizebar
                

                --------------------------------------------------------------------------------------------------------------    

                x_planar_size (float): the planar longitudinal size to create the scalebar. Units in data coordinates transform.
                     Standard = 200 (units)

                --------------------------------------------------------------------------------------------------------------    

                rounding_value_for_xsize: the rounding decimal cases to be used in the scalebar label.

                --------------------------------------------------------------------------------------------------------------    

                bar_height (float): the relative height of the scalebar in figure units
                    Standard = 0.015

                --------------------------------------------------------------------------------------------------------------    

                fill_bar (bool): this sets whether to fill or not the bar. The filling color is setted by the color attribute
                    Standard = True

                --------------------------------------------------------------------------------------------------------------    

                fill_bar_color ('string' or Tuple): sets the color to be used in the filling process of the scalebar

                --------------------------------------------------------------------------------------------------------------    

                fontproperties (matplotlib.font_manager.FontProperties): sets the fontproperties to be used in the label of the scalebar

                    Example:

                        from matplotlib.font_manager import FontProperties

                        fontproperties = FontProperties(family='calibri', weight='light', style='normal', size=10)

                --------------------------------------------------------------------------------------------------------------    

                label_top (Bool): sets the label vertical position relative to the scalebar. For standard, the legend is above the scalebar
                    Standard = True

                --------------------------------------------------------------------------------------------------------------    

                loc (string): this attribute sets the label position relative to the bounding box
                    Standard = 'upper right'
                    Options available: [upper right, upper left, 
                                        lower left, lower right,
                                        right, center left,
                                        center right, lower center,
                                        upper center, center]

                --------------------------------------------------------------------------------------------------------------    

                pad (float): sets the vertical distance from the scalebar and its background Bbox in fraction of the font \
                             size
                    Standard = 0.1

                --------------------------------------------------------------------------------------------------------------    

                background_facecolor = sets the color to the background color'k'

                --------------------------------------------------------------------------------------------------------------    

                face_alpha (string): sets the color to the background alpha
                    Standard = 'grey'

                --------------------------------------------------------------------------------------------------------------    

                length_unit (string): The distance unit measurement that will be used in the scalebar. Available options: ['m', 'Km']
                    If other distance unit measurements are required, add a transformation function from meters to the required unit 
                    in the attr: "unit_transformation_function"

                    Standard: 'Km'
                
                
                --------------------------------------------------------------------------------------------------------------    

                
                unit_transformation_function: the function to convert the scale unit into the desired distance measurement unit.
                    If unit_transformation_function is provided, the returned value will be the transformation of the planar distance by this given function

                    Example of converting a meter to mile: unit_transformation_function = lambda x: x*0,00062137

                    Standard: None (so that no transformation is applied)
                    
                --------------------------------------------------------------------------------------------------------------    

                background_padding=100

                --------------------------------------------------------------------------------------------------------------    

                background_edgecolor (string; or tuple(RGB); or tuple(RGBA) ): sets the color to be used in the edgecolor of the bbox 
                    Standard = 'k'

                --------------------------------------------------------------------------------------------------------------    

                background_linewidth (float): the width of the line surrounding the Bbox
                    Standard = 1

                --------------------------------------------------------------------------------------------------------------    

                sep (int): Separation between the label and the size bar, in points
                    Standard = 5
                --------------------------------------------------------------------------------------------------------------    

                x0 (float): the relative longitudinal position to be placed the scalebar in figure units.
                    Standard = 0.8

                --------------------------------------------------------------------------------------------------------------    

                y0 (float): the relative latitudinal position to be placed the scalebar in figure units.
                    Standard = 0.1


                --------------------------------------------------------------------------------------------------------------    
                --------------------------------------------------------------------------------------------------------------    


            Returns (tuple):
                1) The extent of the colorbar in rendered window units

                2) The extent of the colorbar in figure window units

        """

        # the x coords of this transformation are data, and the
        # y coord are axes
        trans = transforms.blended_transform_factory(ax.transData,
                                                     ax.figure.transFigure)

        if not isinstance(fontproperties,
                          matplotlib.font_manager.FontProperties):

            fontproperties = FontProperties(family='calibri',
                                            weight='light',
                                            style='normal',
                                            size=10)

        if unit_transformation_function != None:
            converted_string = round(
                unit_transformation_function(x_planar_size),
                rounding_value_for_xsize)

        else:
            converted_string = round(
                unit_transformation_function(x_planar_size),
                rounding_value_for_xsize)

        if rounding_value_for_xsize == 0:
            converted_string = int(converted_string)

        else:

            converted_string = str(converted_string).replace(
                '.', decimal_separator)

        Formatted_Label = '{0} {1}'.format(converted_string, length_unit)

        Bbox_bar = scale_bar_class.add_anchored_size_bar(
            ax=ax,
            transform=trans,
            loc=loc,
            color='k',
            horizontal_size=x_planar_size,
            label=Formatted_Label,
            label_top=label_top,
            pad=pad,
            bar_height=bar_height,
            fontproperties=fontproperties,
            borderpad=borderpad,
            sep=sep,
            frameon=True,
            fill_bar=fill_bar,
            bbox_to_anchor=(x0, y0, x1, y1),
            bbox_transform=ax.figure.transFigure)

        child = HPacker(pad=0.2,
                        sep=0.2,
                        width=0.2,
                        height=0.2,
                        align='baseline',
                        mode='fixed',
                        children=[Bbox_bar])

        box = AnchoredOffsetbox(loc='center',
                                pad=pad,
                                borderpad=0.5,
                                child=child,
                                frameon=False,
                                bbox_to_anchor=(x0, y0, x1, y1),
                                bbox_transform=ax.figure.transFigure)

        box.patch.set_color(background_facecolor)
        box.patch.set_alpha(background_facealpha)
        box.patch.set_edgecolor(background_edgecolor)

        box.axes = ax
        box.set_figure(ax.get_figure())

        return box
    def scalebar_based_on_degree_distance(ax,
                                          distance_measuring_method='geopy',
                                          ellipsoid='WGS-84',
                                          distance_method='geodesic',
                                          x_size_in_degrees=1,
                                          rounding_value_for_xsize=0,
                                          decimal_separator=',',
                                          bar_height=0.015,
                                          fill_bar=True,
                                          fill_bar_color='k',
                                          fontproperties=None,
                                          label_top=True,
                                          loc='center',
                                          pad=0.3,
                                          borderpad=0,
                                          background_facecolor='white',
                                          face_alpha=1,
                                          length_unit='km',
                                          unit_transformation_function=None,
                                          background_edgecolor='k',
                                          background_linewidth=1,
                                          background_edgealpha=1,
                                          background_facealpha=1,
                                          sep=0,
                                          x0=0.91,
                                          y0=0.02,
                                          x1=1,
                                          y1=0.08,
                                          over_write_distance_metric=False):
        """
            Function description:
                This function adds a sizebar in the axes. 
                This sizebar is an artist of matplotlib. 
                This artist x_size automatically dilates or contracts acoording to the zooming (in/out) \
                of its parent axes.

            --------------------------------------------------------------------------------------------------------------    

            Parameters:

                ax: the parent axes that will be used to measure the distance for the sizebar
                
                --------------------------------------------------------------------------------------------------------------    

                distance_measuring_method (string): sets the type of distance measuring system over geodetic (degree) distances
                    Available options: ['geopy', 'Transverse_mercator_projection']
                    
                        Geopy option requires extra parameters for its evaluation which are set by the ellipsoid and distance_method parameters
                        
                
                    Standard: 'geopy'
                --------------------------------------------------------------------------------------------------------------    

                ellipsoid (string or (3d-tuple)): sets the ellipsoid that will be used for the distance measuring system. WGS-84 garantees standard error distance for all the globe. 
                                                  Better precision can be acchieved by local specific Ellipsoid
                
                    Standard: 'WGS-84'
                    
                    Observation: this parameter is only applicable for distance_measuring_method == 'geopy'
                --------------------------------------------------------------------------------------------------------------    

                distance_method (string): sets the type of distance measuring system that will be applied over the scalebar. It will convert
                                          degree distance into planar distance.
                                          
                    
                    Available options: ['vincety': most precise
                                        'geodetic/geodesic': will converge always
                                        'great_circle': commonly used in the literature
                                        ]
                                        
                    Standard: 'vincenty'
                
                    Observation: this parameter is only applicable for distance_measuring_method == 'geopy'
                --------------------------------------------------------------------------------------------------------------    

                x_size_in_degrees (float): the longitudinal size to create the scalebar. Units in longitudinal data coordinates transform.
                     Standard = 0.2

                --------------------------------------------------------------------------------------------------------------    

                rounding_value_for_xsize: the rounding decimal cases to be used in the scalebar label.

                --------------------------------------------------------------------------------------------------------------    

                bar_height (float): the relative height of the scalebar in figure units
                    Standard = 0.015

                --------------------------------------------------------------------------------------------------------------    

                fill_bar (bool): this sets whether to fill or not the bar. The filling color is setted by the color attribute
                    Standard = True

                --------------------------------------------------------------------------------------------------------------    

                fill_bar_color ('string' or Tuple): sets the color to be used in the filling process of the scalebar

                --------------------------------------------------------------------------------------------------------------    

                fontproperties (matplotlib.font_manager.FontProperties): sets the fontproperties to be used in the label of the scalebar

                    Example:

                        from matplotlib.font_manager import FontProperties

                        fontproperties = FontProperties(family='calibri', weight='light', style='normal', size=10)

                --------------------------------------------------------------------------------------------------------------    

                label_top (Bool): sets the label vertical position relative to the scalebar. For standard, the legend is above the scalebar
                    Standard = True

                --------------------------------------------------------------------------------------------------------------    

                loc (string): this attribute sets the label position relative to the bounding box
                    Standard = 'upper right'
                    Options available: [upper right, upper left, 
                                        lower left, lower right,
                                        right, center left,
                                        center right, lower center,
                                        upper center, center]

                --------------------------------------------------------------------------------------------------------------    

                pad (float): sets the vertical distance from the scalebar and its background Bbox in fraction of the font \
                             size
                    Standard = 0.1

                --------------------------------------------------------------------------------------------------------------    

                background_facecolor = sets the color to the background color'k'

                --------------------------------------------------------------------------------------------------------------    

                face_alpha (string): sets the color to the background alpha
                    Standard = 'grey'

                --------------------------------------------------------------------------------------------------------------    

                length_unit (string): The distance unit measurement that will be used in the scalebar. Available options: ['m', 'Km']
                    If other distance unit measurements are required, add a transformation function from meters to the required unit 
                    in the attr: "unit_transformation_function"

                    Standard: 'Km'
                
                
                --------------------------------------------------------------------------------------------------------------    

                
                unit_transformation_function: the function to convert the scale unit into the desired distance measurement unit, 
                    in case that measurement unit is not "km" or 'm'. This passed function must convert meters to the desired unit, 
                    and return the converted value in the desired unit.

                    Example of converting a meter to mile: unit_transformation_function = lambda x: x*0,00062137

                    Standard: None (so that no transformation is applied)
                    
                    Observation: this parameter is only applicable for distance_measuring_method == 'Transverse_mercator_projection'
                --------------------------------------------------------------------------------------------------------------    


                background_padding=100,

                --------------------------------------------------------------------------------------------------------------    

                background_edgecolor (string; or tuple(RGB); or tuple(RGBA) ): sets the color to be used in the edgecolor of the bbox 
                    Standard = 'k'

                --------------------------------------------------------------------------------------------------------------    

                background_linewidth (float): the width of the line surrounding the Bbox
                    Standard = 1

                --------------------------------------------------------------------------------------------------------------    

                sep (int): Separation between the label and the size bar, in points
                    Standard = 5
                --------------------------------------------------------------------------------------------------------------    

                x0 (float): the relative longitudinal position to be placed the scalebar in figure units.
                    Standard = 0.8

                --------------------------------------------------------------------------------------------------------------    

                y0 (float): the relative latitudinal position to be placed the scalebar in figure units.
                    Standard = 0.1


                --------------------------------------------------------------------------------------------------------------    
                --------------------------------------------------------------------------------------------------------------    


            Returns:
                box that encompasses the scalebar

        """

        if ax.projection.is_geodetic() == True:
            raise ValueError(
                "The axes projection must be the ccrs.PlateCarree() projection in order for this algorithm to work."
            )

        # the x coords of this transformation are data, and the
        # y coord are axes
        trans = transforms.blended_transform_factory(ax.transData,
                                                     ax.figure.transFigure)

        if not isinstance(fontproperties,
                          matplotlib.font_manager.FontProperties):

            fontproperties = FontProperties(family='calibri',
                                            weight='light',
                                            style='normal',
                                            size=10)

        if distance_measuring_method == 'geopy':

            get_distancer = getattr(scale_bar_class,
                                    'distance_from_degrees_using_geopy')

            Distance = get_distancer(
                ax=ax,
                longitudinal_distance_in_degrees=x_size_in_degrees,
                ellipsoid=ellipsoid,
                distance_method=distance_method,
                length_unit=length_unit,
                rounding_value_for_xsize=rounding_value_for_xsize)

            if rounding_value_for_xsize == 0:
                converted_string = int(Distance)

            else:

                converted_string = str(Distance).replace(
                    '.', decimal_separator)

            Formatted_Label = '{0} {1}'.format(converted_string, length_unit)

        else:

            if (length_unit.lower() not in [
                    'km', 'm', 'meter', 'kilometer'
            ]) and unit_transformation_function == None:
                raise Exception(
                    """If length_unit is not Km or meter unit, a transformation function must be supplied for the attribute \
                                unit_transformation_function """)

            get_distancer = getattr(
                scale_bar_class,
                'calculate_distance_based_on_Transverse_mercator_projection')

            Distance = get_distancer(
                ax=ax,
                x_size_in_degrees=x_size_in_degrees,
                rounding_value_for_xsize=rounding_value_for_xsize,
                length_unit=length_unit,
                unit_transformation_function=unit_transformation_function)

            if rounding_value_for_xsize == 0:
                converted_string = int(Distance)

            else:

                converted_string = str(Distance).replace(
                    '.', decimal_separator)

            Formatted_Label = '{0} {1}'.format(converted_string, length_unit)

        if over_write_distance_metric is not False:
            Formatted_Label = '{0} {1}'.format(over_write_distance_metric,
                                               length_unit)

            print(Formatted_Label)

        from functools import partial

        P_scale_bar_c = partial(scale_bar_class.add_anchored_size_bar,
                                ax=ax,
                                transform=trans,
                                loc=loc,
                                color='k',
                                horizontal_size=x_size_in_degrees,
                                label=Formatted_Label,
                                label_top=label_top,
                                pad=pad,
                                bar_height=bar_height,
                                fontproperties=fontproperties,
                                borderpad=borderpad,
                                sep=sep,
                                frameon=True,
                                bbox_to_anchor=(x0, y0, x1, y1),
                                bbox_transform=ax.figure.transFigure)

        Bbox_bar = P_scale_bar_c(fill_bar=True)

        child = HPacker(pad=0.2,
                        sep=0,
                        width=0.2,
                        height=0.2,
                        align='baseline',
                        mode='fixed',
                        children=[Bbox_bar])

        box = AnchoredOffsetbox(loc='center',
                                pad=pad,
                                borderpad=0.5,
                                child=child,
                                frameon=False,
                                bbox_to_anchor=(x0, y0, x1, y1),
                                bbox_transform=ax.figure.transFigure)

        box.patch.set_color(background_facecolor)
        box.patch.set_alpha(background_facealpha)
        box.patch.set_edgecolor(background_edgecolor)

        box.axes = ax
        box.set_figure(ax.get_figure())

        return box
Example #8
0
    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, str):
            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
        fixed_value = self.fixed_value
        fixed_units = self.fixed_units or self.units

        if font_properties is None:
            textprops = {"color": color}
        else:
            textprops = {"color": color, "fontproperties": font_properties}

        ax = self.axes
        xlim = ax.get_xlim()
        ylim = ax.get_ylim()
        label = self.label

        # Calculate value, units and length
        # Mode 1: Auto
        if self.fixed_value is None:
            length_px = abs(xlim[1] - xlim[0]) * length_fraction
            length_px, value, units = self._calculate_best_length(length_px)

        # Mode 2: Fixed
        else:
            value = fixed_value
            units = fixed_units
            length_px = self._calculate_exact_length(value, units)

        scale_label = self.label_formatter(value,
                                           self.dimension.to_latex(units))

        size_vertical = abs(ylim[1] - ylim[0]) * height_fraction

        # Create size bar
        sizebar = AuxTransformBox(ax.transData)
        sizebar.add_artist(
            Rectangle(
                (0, 0),
                length_px,
                size_vertical,
                fill=True,
                facecolor=color,
                edgecolor="none",
            ))

        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 text area
        if label:
            txtlabel = TextArea(label,
                                minimumdescent=False,
                                textprops=textprops)
        else:
            txtlabel = None

        # 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)
Example #9
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)