예제 #1
0
    def plot_bboxes(self, ax: Axes, boxes: torch.Tensor,
                    class_idxs: torch.Tensor, color: str):
        """Add bboxes to the plot tied to `ax`"""
        for box, class_idx in zip(boxes, class_idxs):
            xmin, ymin, xmax, ymax = box
            width = xmax - xmin
            height = ymax - ymin

            rect = patches.Rectangle((xmin, ymin),
                                     width,
                                     height,
                                     fill=False,
                                     color=color,
                                     lw=1.5)
            ax.add_patch(rect)

            if isinstance(class_idx, torch.Tensor):
                class_idx = class_idx.item()

            class_name = self.categories[class_idx] if class_idx else None

            ax.text(xmin,
                    ymin,
                    class_name,
                    bbox={
                        'facecolor': 'white',
                        'alpha': 0.5,
                        'pad': 2
                    })
예제 #2
0
def draw_demand(ax: axes.Axes,
                coord: types.Coord2D,
                color: str,
                active: Optional[bool] = None) -> List[mpatches.Patch]:
    '''Draw a demand/arrivals source

    :param ax: matplotlib axes on which to draw
    :param coord: coordinate at which to place demand source (bottom left of it)
    :param color: color of the demand source
    :param active: whether demand is active (are items arriving)
    '''
    d_width = 1
    d_height = 1
    alpha = 0.3 if not active else .8

    centre = [coord[0] + d_width / 2 + 0.02, coord[1] + d_height / 2]

    p1 = mpatches.RegularPolygon(centre,
                                 7,
                                 radius=0.5,
                                 color=color,
                                 alpha=alpha)
    ax.add_patch(p1)
    p2 = mpatches.RegularPolygon(
        centre,
        7,
        radius=0.52,
        fill=False,
        color='k',
    )
    ax.add_patch(p2)
    return [p1, p2]
예제 #3
0
def plot_rect(axes: Axes, rect, highlight_corner=False, **kwargs):
    from matplotlib.patches import Rectangle, Polygon
    defaults = dict(fill=True, edgecolor='#929591', facecolor='#d8dcd6', highlight_fill=True,
                    highlight_facecolor='#d8dcd6')
    for k in defaults:
        if k not in kwargs:
            kwargs[k] = defaults[k]

    if 'alpha' in kwargs:
        from matplotlib.colors import to_rgba
        kwargs['edgecolor'] = to_rgba(kwargs['edgecolor'], kwargs['alpha'])
        kwargs['facecolor'] = to_rgba(kwargs['facecolor'], kwargs['alpha'])
        kwargs['highlight_facecolor'] = to_rgba(kwargs['highlight_facecolor'], kwargs['alpha'])

    highlight_facecolor = kwargs.pop('highlight_facecolor')
    highlight_fill = kwargs.pop('highlight_fill')

    x, y, theta = rect.get_pose()
    corner = rect.get_world_point((-rect.width / 2, -rect.height / 2))
    p1 = axes.add_patch(Rectangle(xy=corner, angle=math.degrees(theta),
                                  width=rect.width, height=rect.height, **kwargs))

    if highlight_corner:
        return p1, axes.add_patch(Polygon(xy=np.array(rect.vertices[0:3]), fill=highlight_fill,
                                          facecolor=highlight_facecolor))
    else:
        return p1
예제 #4
0
    def draw_rectangle_around_text(scene: Axes, origin: tuple, width: int,
                                   height: int, fill_color: tuple,
                                   line_color: tuple, line_width: int,
                                   rounded: int, text: str, font_size: int,
                                   font_family: str):

        if rounded > 0:
            box_style = 'round'
        else:
            box_style = 'square'

        scene.add_patch(
            FancyBboxPatch(
                origin,
                width,
                height,
                facecolor='#{0:02x}{1:02x}{2:02x}'.format(*fill_color),
                edgecolor='#{0:02x}{1:02x}{2:02x}'.format(*line_color),
                linewidth=line_width,
                boxstyle=box_style))

        # write label in the middle under
        labelx = origin[0] + width // 2
        labely = origin[
            1] + height // 2 + 4  # TODO: Should be drawn in the vertical center, so + 4 not needed!

        scene.text(labelx,
                   labely,
                   s=text,
                   fontsize=font_size,
                   color='#{0:02x}{1:02x}{2:02x}'.format(*line_color),
                   fontname=font_family)

        return origin[0], origin[1], width, height
예제 #5
0
 def render(self,
            axis: Axes,
            view: np.ndarray = np.eye(3),
            normalize: bool = False,
            colors: Tuple = ('b', 'r', 'k'),
            linewidth: float = 2) -> None:
     """
     Renders the box in the provided Matplotlib axis.
     :param axis: Axis onto which the box should be drawn.
     :param view: <np.array: 3, 3>. Define a projection in needed (e.g. for drawing projection in an image).
     :param normalize: Whether to normalize the remaining coordinate.
     :param colors: (<Matplotlib.colors>: 3). Valid Matplotlib colors (<str> or normalized RGB tuple) for front,
         back and sides.
     :param linewidth: Width in pixel of the box sides.
     """
     # corners = view_points(self.corners(), view, normalize=normalize)[:2, :]
     # def draw_rect(selected_corners, color):
     #     prev = selected_corners[-1]
     #     for corner in selected_corners:
     #         axis.plot([prev[0], corner[0]], [prev[1], corner[1]], color=color, linewidth=linewidth)
     #         prev = corner
     #
     # x = [corners.T[0][0], corners.T[4][0], corners.T[5][0], corners.T[1][0],corners.T[0][0]]
     # y = [corners.T[0][1], corners.T[4][1], corners.T[5][1], corners.T[1][1],corners.T[0][1]]
     # axis.plot(x,y,color=colors[2], linewidth=linewidth)
     # axis.add_patch(rect)
     corners = view_points(self.corners(), view, normalize=normalize)[:2, :]
     corners = corners.T
     corners = corners[(0, 4, 5, 1), :]
     axis.add_patch(Polygon(corners,
                    closed=True, facecolor=colors[0]))
예제 #6
0
def _draw_buildings(buildings: List[bl.Building], ax: maxs.Axes) -> None:
    for building in buildings:
        if isinstance(building.geometry, Polygon):
            patch = PolygonPatch(building.geometry,
                                 facecolor="black",
                                 edgecolor="black")
            ax.add_patch(patch)
예제 #7
0
def _draw_nodes_to_change(nodes_to_change: List[bl.NodeInRectifyBuilding],
                          ax: maxs.Axes) -> None:
    for node in nodes_to_change:
        ax.add_patch(
            pat.Circle((node.my_node.original_x, node.my_node.original_y),
                       radius=0.4,
                       linewidth=2,
                       color='green',
                       fill=False))
예제 #8
0
def add_list_of_polygons(ax: maxs.Axes, polygons: List[shg.Polygon],
                         face_color: str, edge_color: str) -> None:
    for poly in polygons:
        if poly is None or not poly.is_valid or not poly.is_valid:
            continue
        if isinstance(poly, shg.Polygon) or isinstance(poly, shg.MultiPolygon):
            patch = PolygonPatch(poly,
                                 facecolor=face_color,
                                 edgecolor=edge_color)
            ax.add_patch(patch)
예제 #9
0
파일: finance.py 프로젝트: dargor/dargor-py
def candlestick_chart(
    ax: Axes,
    df: DataFrame,
    *,
    heikin_ashi: bool = False,
    colorup: str = 'forestgreen',
    colordown: str = 'orangered',
    width: float = .6,
    alpha: float = 1.,
) -> None:
    # The area between the open and the close prices is called the body,
    # price excursions above and below the body are shadows (also called
    # wicks). Wicks illustrate the highest and lowest traded prices of an
    # asset during the time interval represented. The body illustrates the
    # opening and closing trades. This entire structure is called a candle.
    offset = width / 2.
    prev = None
    for t, row in df.iterrows():
        t = date2num(t)
        o0, h0, l0, c0 = row['Open'], row['High'], row['Low'], row['Close']
        if heikin_ashi:
            # pylint: disable=W8201
            if prev is None:
                oP, hP, lP, cP = o0, h0, l0, c0
            else:
                oP, hP, lP, cP = prev
            c = (o0 + h0 + l0 + c0) / 4.
            o = (oP + cP) / 2.
            h = max(h0, o, c)
            l = min(l0, o, c)
            prev = o, h, l, c
        else:
            o, h, l, c = o0, h0, l0, c0  # pylint: disable=W8201
        if c >= o:
            color = colorup
            lower = o
            upper = c
        else:
            color = colordown
            lower = c
            upper = o
        height = upper - lower
        ax.add_line(
            Line2D(xdata=(t, t), ydata=(lower, l), color=color, alpha=alpha))
        ax.add_line(
            Line2D(xdata=(t, t), ydata=(upper, h), color=color, alpha=alpha))
        ax.add_patch(
            Rectangle(xy=(t - offset, lower),
                      width=width,
                      height=height,
                      facecolor=color,
                      edgecolor=color,
                      alpha=alpha))
예제 #10
0
def _draw_city_blocks(building_zones: List[m.BuildingZone],
                      ax: maxs.Axes) -> None:
    for zone in building_zones:
        city_blocks = zone.linked_city_blocks
        for item in city_blocks:
            red = random.random()
            green = random.random()
            blue = random.random()
            patch = PolygonPatch(item.geometry,
                                 facecolor=(red, green, blue),
                                 edgecolor=(red, green, blue))
            ax.add_patch(patch)
예제 #11
0
def _add_patch_for_building_zone(building_zone: m.BuildingZone, face_color: str, edge_color: str, ax: maxs.Axes)  \
            -> None:
    if isinstance(building_zone.geometry, MultiPolygon):
        for polygon in building_zone.geometry.geoms:
            patch = PolygonPatch(polygon,
                                 facecolor=face_color,
                                 edgecolor=edge_color)
            ax.add_patch(patch)
    else:
        patch = PolygonPatch(building_zone.geometry,
                             facecolor=face_color,
                             edgecolor=edge_color)
        ax.add_patch(patch)
예제 #12
0
def axis_rectangle_labeling(axes: Axes,
                            coordinates,
                            colors,
                            lw=None,
                            fill=False):
    """ Labeling axes with given bounding boxes. """
    for (x, y, w, h), c in zip(coordinates, colors):
        rect = plt.Rectangle((x - w / 2, y - h / 2),
                             w,
                             h,
                             color=c,
                             fill=fill,
                             linewidth=lw)
        axes.add_patch(rect)
    return axes
예제 #13
0
def _draw_background_zones(building_zones, ax: maxs.Axes) -> None:
    for building_zone in building_zones:
        my_color = "lightgray"
        if isinstance(building_zone, m.GeneratedBuildingZone):
            my_color = "darkgray"
        if isinstance(building_zone.geometry, MultiPolygon):
            for polygon in building_zone.geometry.geoms:
                patch = PolygonPatch(polygon,
                                     facecolor=my_color,
                                     edgecolor="white")
                ax.add_patch(patch)
        else:
            patch = PolygonPatch(building_zone.geometry,
                                 facecolor=my_color,
                                 edgecolor="white")
            ax.add_patch(patch)
예제 #14
0
 def draw_line(scene: Axes, start: tuple, ctrl1: tuple, ctrl2: tuple,
               end: tuple, is_curved: bool, edge_color: tuple):
     if is_curved:  # cubic Bezier curve
         scene.add_patch(
             PathPatch(
                 Path([start, ctrl1, ctrl2, end],
                      [Path.MOVETO, Path.CURVE4, Path.CURVE4, Path.CURVE4]),
                 edgecolor='#{0:02x}{1:02x}{2:02x}'.format(*edge_color),
                 facecolor=(1, 1, 1, 0),  # Transparent...
                 linewidth=1))  # TODO: WIDTH!
     else:
         scene.add_patch(
             PathPatch(
                 Path([start, end], [Path.MOVETO, Path.LINETO]),
                 edgecolor='#{0:02x}{1:02x}{2:02x}'.format(*edge_color),
                 facecolor=(1, 1, 1, 0),  # Transparent...
                 linewidth=1))  # TODO: WIDTH!
예제 #15
0
def plot_spheres(ax: Axes, points: array_like, r: float):
    """
    Plot two-dimensional view of spheres centered on points.

    Parameters
    ----------
    ax: Axes
        Matplotlib Axes object.
    points : array_like
        Points in space.
    r : float
        Radius of spheres.

    """
    for point in points:
        circle = plt.Circle((point[0], point[1]), radius=r, color="black", fill=False)
        ax.add_patch(circle)
예제 #16
0
def plot_circle(axes: Axes, circle, **kwargs):
    from matplotlib.patches import Circle
    defaults = dict(fill=True, edgecolor='#929591', facecolor='#d8dcd6')
    for k in defaults:
        if k not in kwargs:
            kwargs[k] = defaults[k]

    return axes.add_patch(Circle(xy=circle.get_position(), radius=circle.get_radius(), **kwargs))
예제 #17
0
def draw_reset(ax: axes.Axes, width: float, height: float) -> None:
    """
    Fully reset a plot by deleting all annotations and patches, and drawing a
    blank background

    :param ax: matplotlib axes on which to draw
    :param width: the width of the plot
    :param height: the height of the plot
    """
    for child in ax.get_children():
        if isinstance(child, mtext.Annotation):
            child.remove()
    for p in reversed(ax.patches):
        p.remove()

    p1 = mpatches.Rectangle((0, 0), width, height, fill=True, color='w')
    ax.add_patch(p1)
예제 #18
0
def _draw_btg_building_zones(btg_building_zones, ax: maxs.Axes) -> None:
    for item in btg_building_zones:
        if item.type_ in [
                enu.BuildingZoneType.btg_builtupcover,
                enu.BuildingZoneType.btg_urban
        ]:
            my_color = "magenta"
        elif item.type_ in [
                enu.BuildingZoneType.btg_town,
                enu.BuildingZoneType.btg_suburban
        ]:
            my_color = "gold"
        else:
            my_color = "yellow"
        patch = PolygonPatch(item.geometry,
                             facecolor=my_color,
                             edgecolor=my_color)
        ax.add_patch(patch)
예제 #19
0
def draw_straight_arrows(ax: axes.Axes,
                         from_coord: types.Coord2D,
                         to_coord: types.Coord2D,
                         color: str,
                         active: bool,
                         effect: int,
                         do_annotations: bool,
                         no_head: bool = False) -> List[mpatches.Patch]:
    """Draw a straight arrow between two points, indicating an activity.

    :param ax: matplotlib axes on which to draw
    :param from_coord: point at the tail of the arrow (bottom left of it)
    :param to_coord: point at the head of the arrow (bottom left of it)
    :param color: color of the arrow when active
    :param active: whether arrow is active (are items arriving)
    :param effect: what value/no of items are being processed along the arrow
    :param do_annotations: whether to annotate the arrow with the no of items
        being processd
    :param no_head: whether do suppress a head to arrow
    """
    alpha = 0.3 if not active else 1
    color = 'k' if not active else color
    if no_head:
        a_style = '-'
        do_annotations = False
    else:
        a_style = mpatches.ArrowStyle("-|>", head_length=7, head_width=4)
    mid = 0.5
    mid_from_coord = [from_coord[0], from_coord[1] + mid]
    mid_to_coord = [to_coord[0], to_coord[1] + mid]
    p1 = mpatches.FancyArrowPatch(mid_from_coord,
                                  mid_to_coord,
                                  arrowstyle=a_style,
                                  alpha=alpha,
                                  color=color)
    ax.add_patch(p1)

    if do_annotations and active:
        msg = '{:.0f}'.format(abs(effect))
        text_coord = [(from_coord[0] + to_coord[0]) * .5 - 0.6,
                      to_coord[1] + 1.]
        ax.annotate(msg, from_coord, text_coord, size=14, color=color)

    return [p1]
예제 #20
0
def _draw_blocked_areas(building_zones, ax: maxs.Axes) -> None:
    for my_building_zone in building_zones:
        for blocked in my_building_zone.linked_blocked_areas:
            if m.BlockedAreaType.open_space == blocked.type_:
                my_facecolor = 'darkgreen'
                my_edgecolor = 'darkgreen'
            elif m.BlockedAreaType.gen_building == blocked.type_:
                my_facecolor = 'yellow'
                my_edgecolor = 'yellow'
            elif m.BlockedAreaType.osm_building == blocked.type_:
                my_facecolor = 'blue'
                my_edgecolor = 'blue'
            else:
                my_facecolor = 'orange'
                my_edgecolor = 'orange'
            patch = PolygonPatch(blocked.polygon,
                                 facecolor=my_facecolor,
                                 edgecolor=my_edgecolor)
            ax.add_patch(patch)
예제 #21
0
def draw_polygon(ax: Axes, polygon: Polygon, size: int = size, ticks: int = ticks, font_size: int = font_size) -> None:
    """Plot a polygon to the current matplotlib figure."""
    max_x, min_x = ceil(max(p.x for p in polygon.points)), floor(min(p.x for p in polygon.points))
    max_y, min_y = ceil(max(p.y for p in polygon.points)), floor(min(p.y for p in polygon.points))
    size_x = max_x - min_x
    size_y = max_y - min_y
    ax.set_aspect('equal')
    ax.set_xlim(min_x - size_x * 0.05, max_x + size_x * 0.05)
    ax.set_ylim(min_y - size_y * 0.05, max_y + size_y * 0.05)
    ticks -= 1
    ax.xaxis.set_major_locator(ticker.MultipleLocator(base=round(size_x / ticks)))
    ax.yaxis.set_major_locator(ticker.MultipleLocator(base=round(size_y / ticks)))
    ax.grid(color='grey')

    polygon_points = list(polygon.points_as_tuples())

    plt_polygon = pyplot.Polygon(polygon_points, fill=None, color='0.25', linewidth=.5)
    ax.add_patch(plt_polygon)
    pyplot.plot(list([x[0] for x in polygon_points]), list([x[1] for x in polygon_points]),
                color='black', linestyle='None', marker='.', markersize=3)

    if isinstance(polygon, TriangulatedPolygon):
        edges = set()
        for triangle in polygon.triangles:
            for edge in triangle.edges:
                if (edge.a.index, edge.b.index) in edges:
                    # The edge was already plotted
                    continue
                if edge.a.index in ((edge.b.index - 1) % len(polygon), (edge.b.index + 1) % len(polygon)):
                    # The edge is a polygon edge, thus we ignore it
                    continue

                pyplot.plot([edge.a.x, edge.b.x], [edge.a.y, edge.b.y], color='0.5', linestyle='--', alpha=0.5)
                edges.add((edge.a.index, edge.b.index))
                edges.add((edge.b.index, edge.a.index))

    for i in range(0, len(polygon), 2):
        ax.annotate(str(i), xy=polygon_points[i],
                    xytext=(
                        polygon_points[i][0] + round(size_x / ticks) / 20,
                        polygon_points[i][1] + round(size_y / ticks) / 20),
                    fontsize=font_size, color='0.3', alpha=.8)
예제 #22
0
    def plot(self, ax: Axes) -> Axes:
        """Plot the curve."""
        xmin, xmax = ax.get_xlim()
        ymin, ymax = ax.get_ylim()
        if not self.x_data or not self.y_data or not _between_limits(
                self.x_data, self.y_data, xmin, xmax, ymin, ymax):
            self._print_err(
                '{} (label:{}) Not between limits ([{}, {}, {}, {}]) '
                '-> x:{}, y:{}'.format(self._type_curve, self._label, xmin,
                                       xmax, ymin, ymax, self.x_data,
                                       self.y_data))
            return ax

        if self._is_patch and self.y_data is not None:
            assert len(self.y_data) > 2
            verts = list(zip(self.x_data, self.y_data))
            codes = ([Path.MOVETO] + [Path.LINETO] * (len(self.y_data) - 2) +
                     [Path.CLOSEPOLY])
            path = Path(verts, codes)
            patch = patches.PathPatch(path, **self.style)
            ax.add_patch(patch)

            if self._label is not None:
                bbox_p = path.get_extents()
                text_x = .5 * (bbox_p.x0 + bbox_p.x1)
                text_y = .5 * (bbox_p.y0 + bbox_p.y1)
                style = {
                    'ha': 'center',
                    'va': 'center',
                    "backgroundcolor": [1, 1, 1, .4]
                }
                if 'edgecolor' in self.style:
                    style['color'] = mod_color(self.style['edgecolor'], -25)
                self._annotate_label(ax, self._label, text_x, text_y, 0, style)
        else:
            ax.plot(self.x_data, self.y_data, **self.style)
            if self._label is not None:
                self.add_label(ax)

        return ax
예제 #23
0
def _draw_settlement_zones(building_zones: List[m.BuildingZone],
                           ax: maxs.Axes) -> None:
    for building_zone in building_zones:
        colour = 'grey'
        if building_zone.type_ is enu.BuildingZoneType.farmyard:
            colour = 'brown'
        _add_patch_for_building_zone(building_zone, colour, colour, ax)
        for block in building_zone.linked_city_blocks:
            if block.settlement_type is enu.SettlementType.centre:
                colour = 'blue'
            elif block.settlement_type is enu.SettlementType.block:
                colour = 'green'
            elif block.settlement_type is enu.SettlementType.dense:
                colour = 'magenta'
            elif block.settlement_type is enu.SettlementType.periphery:
                colour = 'yellow'
            patch = PolygonPatch(block.geometry,
                                 facecolor=colour,
                                 edgecolor=colour)
            if block.settlement_type_changed:
                patch.set_hatch('/')
            ax.add_patch(patch)
예제 #24
0
    def plot(self, ax: Axes) -> Axes:
        """Plot the curve."""
        xmin, xmax = ax.get_xlim()
        ymin, ymax = ax.get_ylim()
        if (self.x_data is None or self.y_data is None or not _between_limits(
                self.x_data, self.y_data, xmin, xmax, ymin, ymax)):
            logging.info(
                f"{self._type_curve} (label:{self._label}) Not between limits "
                f"([{xmin}, {xmax}, {ymin}, {ymax}]) "
                f"-> x:{self.x_data}, y:{self.y_data}")
            return ax

        if self._is_patch and self.y_data is not None:
            assert len(self.y_data) > 2
            verts = list(zip(self.x_data, self.y_data))
            codes = ([Path.MOVETO] + [Path.LINETO] * (len(self.y_data) - 2) +
                     [Path.CLOSEPOLY])
            path = Path(verts, codes)
            patch = patches.PathPatch(path, **self.style)
            ax.add_patch(patch)

            if self._label is not None:
                bbox_p = path.get_extents()
                text_x = 0.5 * (bbox_p.x0 + bbox_p.x1)
                text_y = 0.5 * (bbox_p.y0 + bbox_p.y1)
                style = {
                    "ha": "center",
                    "va": "center",
                    "backgroundcolor": [1, 1, 1, 0.4],
                }
                if "edgecolor" in self.style:
                    style["color"] = mod_color(self.style["edgecolor"], -25)
                self._annotate_label(ax, self._label, text_x, text_y, 0, style)
        else:
            ax.plot(self.x_data, self.y_data, **self.style)
            if self._label is not None:
                self.add_label(ax)

        return ax
예제 #25
0
    def plot(self, ax: Axes):
        """
        Plots the lens into the passed matplotlib axes
        Args:
            ax: (Axes) the axes to plot the lens into

        Returns:
            (tuple) plotted objects
        """

        plotted_objects = Element.plot(self, ax)
        plotted_objects += plotting.plot_aperture(ax, self)

        if plot_blockers:
            plotted_objects += plotting.plot_blocker(ax, self,
                                                     self.blocker_diameter)

        if self.draw_arcs:
            arc_ratio = 0.02
            arc_radius_factor = (0.5 * arc_ratio + 0.125 * 1. / arc_ratio)
            m = np.array(
                [[self.diameter * (arc_radius_factor - arc_ratio), 0],
                 [-self.diameter * (arc_radius_factor - arc_ratio), 0]])

            m = self.points_to_global_frame_of_reference(m)

            r = arc_radius_factor * self.diameter
            a = 2 * np.arctan(2. * arc_ratio) * 180. / np.pi
            arc = Arc(m[0, :], 2 * r, 2 * r, self.theta, 180. - a, 180. + a,
                      **plotting.outline_properties.copy())
            ax.add_patch(arc)
            plotted_objects += (arc, )
            arc = Arc(m[1, :], 2 * r, 2 * r, self.theta, -a, +a,
                      **plotting.outline_properties.copy())
            ax.add_patch(arc)
            plotted_objects += (arc, )

        return plotted_objects
예제 #26
0
def _draw_blocked_nodes(blocked_nodes: List[bl.NodeInRectifyBuilding],
                        ax: maxs.Axes) -> None:
    for node in blocked_nodes:
        if bl.RectifyBlockedType.ninety_degrees in node.blocked_types:
            my_color = 'blue'
        else:
            my_color = 'red'
        if bl.RectifyBlockedType.corner_to_bow in node.blocked_types:
            my_fill = True
        else:
            my_fill = False
        if bl.RectifyBlockedType.multiple_buildings in node.blocked_types:
            my_alpha = 0.3
        else:
            my_alpha = 1.0

        my_circle = pat.Circle(
            (node.my_node.original_x, node.my_node.original_y),
            radius=0.4,
            linewidth=2,
            color=my_color,
            fill=my_fill,
            alpha=my_alpha)
        ax.add_patch(my_circle)
예제 #27
0
def plot_polygon(axes: Axes, polygon, **kwargs):
    from matplotlib.patches import Polygon
    defaults = dict(fill=True,
                    # edgecolor='#929591',
                    facecolor='#d8dcd6')
    for k in defaults:
        if k not in kwargs:
            kwargs[k] = defaults[k]

    if 'alpha' in kwargs:
        from matplotlib.colors import to_rgba
        # kwargs['edgecolor'] = to_rgba(kwargs['edgecolor'], kwargs['alpha'])
        kwargs['facecolor'] = to_rgba(kwargs['facecolor'], kwargs['alpha'])

    artist = axes.add_patch(Polygon(xy=np.array(polygon.plot_vertices), **kwargs))

    return artist
예제 #28
0
def draw_buffer(ax: axes.Axes,
                coord: types.Coord2D,
                num_items: int,
                max_capacity: int,
                color: str,
                do_annotations: bool,
                do_reverse: bool = False,
                is_extra_high: Optional[bool] = False) -> List[mpatches.Patch]:
    """Draw a horizontal buffer diagram on axes, at a certain coordinate,
    with items added from the left ('top' is on the left.)

    :param ax: matplotlib axes on which to draw
    :param coord: coordinate at which to place buffer (bottom left of it)
    :param num_items: number of items in the buffer (state)
    :param max_capacity: max capacity of the buffer
    :param color: color of the buffer
    :param do_annotations: whether to annotate the buffer with the current state
    :param do_reverse: if true, draw the buffer in reverse (items added from right)
    :param is_extra_high: if true, draw a buffer that is twice the height of the default option
    """

    b_width = 3
    if is_extra_high:
        b_height = 2
    else:
        b_height = 1
    p1 = mpatches.Rectangle(coord, b_width, b_height, color=color)
    fill_fraction = num_items / max_capacity
    f_width = (1 - fill_fraction) * b_width
    ax.add_patch(p1)

    if do_reverse:
        white_coord = (coord[0] + b_width - f_width, coord[1])
        p2 = mpatches.Rectangle(white_coord, f_width, b_height, color='w')
    else:
        p2 = mpatches.Rectangle(coord, f_width, b_height, color='w')
    ax.add_patch(p2)

    p3 = mpatches.Rectangle(coord, b_width, b_height, fill=False, color='k')
    ax.add_patch(p3)

    if do_annotations:
        msg = '{:.0f}'.format(num_items)
        text_coord = [coord[0] + .2, coord[1] + b_height + 0.2]
        ax.annotate(msg, coord, text_coord, size=14)

    return [p1, p2, p3]
예제 #29
0
def draw_station(ax: axes.Axes,
                 coord: types.Coord2D,
                 buffers: int,
                 color: str,
                 active_b: Optional[int] = None) -> List[mpatches.Patch]:
    """Draw a vertical station which holds a resource.

    :param ax: matplotlib axes on which to draw
    :param coord: coordinate at which to place station (bottom left of it)
    :param buffers: number of buffers attached to the station
    :param color: color of the station
    :param active_b: which buffer/action is active (where the resource should be)
    """
    s_width = 1
    s_height = buffers + (buffers - 1) * 2

    margin_height = 0.5

    rec_coord = [coord[0], coord[1] - margin_height]
    p1 = mpatches.Rectangle(rec_coord,
                            s_width,
                            s_height + 2 * margin_height,
                            fill=False,
                            color='k')
    ax.add_patch(p1)

    if active_b is None:
        centre = [coord[0] + s_width / 2 + 0.02, coord[1] + s_height / 2]
    else:
        b = active_b - 1
        centre = [coord[0] + s_width / 2 + 0.02, coord[1] + 0.5 + 3 * b]

    p2 = mpatches.Circle(centre, s_width * .42, fill=False, color='k')
    ax.add_patch(p2)
    p3 = mpatches.Circle(centre, s_width * .4, color=color, alpha=0.4)
    ax.add_patch(p3)
    return [p1, p2, p3]
예제 #30
0
class InteractiveGraph(object):
    def __init__(self, ax):

        self.ax = Axes(ax.get_figure(), ax.get_position(original=True))
        self.ax.set_aspect("equal")
        self.ax.set_anchor("NE")

        self._visible_vertices, self._visible_edges = {}, {}
        self._hidden_vertices, self._hidden_edges = {}, {}

        self._press_action = "move"
        self._press_actions = {
            "move": None,
        }

    @property
    def press_actions(self):
        return self._press_actions.keys()

    def add_press_action(self, name, handler):
        self._press_actions[name] = handler

    def remove_press_action(self, name):
        del self._press_actions[name]

    def set_press_action(self, name):

        if name not in self._press_actions:
            raise Exception("Invalid action")
        self._press_action = name

    def do_press_action(self, vxid):

        self._press_actions[self._press_action](vxid)

    def add_vertex(self, vxid, xy, label, redraw=True, **props):

        if self.vertex_exists(vxid):
            raise DuplicateVertexError(vxid)

        circle = plt.Circle(xy, **props)
        self.ax.add_patch(circle)
        vx = Vertex(vxid, self, circle, label, props)
        vx._connect()
        self._visible_vertices[vxid] = vx

        if redraw:
            self.ax.figure.canvas.draw()

    def update_vertex_props(self, vxid, redraw=True, **props):

        vx = self.get_vertex(vxid)
        vx.update_circle_props(**props)
        if redraw:
            self.ax.figure.canvas.draw()

    def restore_vertex_props(self, vxid, redraw=True):

        vx = self.get_vertex(vxid)
        vx.restore_circle_props()
        if redraw:
            self.ax.figure.canvas.draw()

    def add_edge(self, edge_id, src_id, tgt_id, redraw=True, **props):

        if not self.vertex_exists(src_id):
            raise NonexistentVertexError(src_id, "add edge")
        elif not self.vertex_exists(tgt_id):
            raise NonexistentVertexError(tgt_id, "add edge")

        if self.edge_exists(edge_id):
            edge = self.get_edge(edge_id)
            src, tgt = edge.source, edge.target
            raise DuplicateEdgeError(edge_id, src, tgt, "add edge",
                                     "edge id already exists")

        if src_id == tgt_id:
            src = self.get_vertex(src_id)
            src.add_loop(edge_id)
        else:
            src, tgt = self.get_vertex(src_id), self.get_vertex(tgt_id)
            src.add_out_edge(edge_id)
            tgt.add_in_edge(edge_id)

        edge = Edge(edge_id, self, src_id, tgt_id, **props)

        if self.vertex_visible(src_id) and self.vertex_visible(tgt_id):
            self._visible_edges[edge_id] = edge
        else:
            self._hidden_edges[edge_id] = edge

    def hide_vertex(self, vxid, redraw=True):

        if not self.vertex_exists(vxid):
            raise NonexistentVertexError(vxid, "hide")
        elif not self.vertex_visible(vxid):
            raise VertexActionError(vxid, "hide", "vertex already hidden")

        vertex = self.get_vertex(vxid)
        self._hidden_vertices[vxid] = self._visible_vertices.pop(vxid)

        for edge_id in vertex.loops & self.visible_edges:
            self._hidden_edges[edge_id] = self._visible_edges.pop(edge_id)
        for edge_id in vertex.in_edges & self.visible_edges:
            self._hidden_edges[edge_id] = self._visible_edges.pop(edge_id)
            self.get_edge(edge_id).hide()
        for edge_id in vertex.out_edges & self.visible_edges:
            self._hidden_edges[edge_id] = self._visible_edges.pop(edge_id)
            self.get_edge(edge_id).hide()

        vertex.hide()

        if redraw:
            self.ax.figure.canvas.draw()

    def hide_edge(self, edge_id, redraw=True):

        if not self.edge_exists(edge_id):
            raise NonexistentEdgeError(edge_id, None, None, "hide")
        elif not self.edge_visible(edge_id):
            raise EdgeActionError(edge_id, "hide", "edge already hidden")

        self._hidden_edges[edge_id] = self._visible_edges.pop(edge_id)
        edge = self.get_edge(edge_id)
        if edge.source != edge.target:
            edge.hide()

        if redraw:
            self.ax.figure.canvas.draw()

    def restore_vertex(self, vxid, redraw=True):

        if not self.vertex_exists(vxid):
            raise NonexistentVertexError(vxid, "restore")
        if self.vertex_visible(vxid):
            raise VertexActionError(vxid, "restore", "vertex already visible")

        vertex = self.get_vertex(vxid)

        for edge_id in vertex.in_edges:
            edge = self.get_edge(edge_id)
            if self.vertex_visible(edge.source):
                self._visible_edges[edge_id] = self._hidden_edges.pop(edge_id)
                edge.restore(self.ax)

        for edge_id in vertex.out_edges:
            edge = self.get_edge(edge_id)
            if self.vertex_visible(edge.target):
                self._visible_edges[edge_id] = self._hidden_edges.pop(edge_id)
                edge.restore(self.ax)

        for edge_id in vertex.loops:
            self._visible_edges[edge_id] = self._hidden_edges.pop(edge_id)

        self._visible_vertices[vxid] = self._hidden_vertices.pop(vxid)
        vertex.restore(self.ax)

        if redraw:
            self.ax.figure.canvas.draw()

    def restore_edge(self, edge_id, redraw=True):

        if not self.edge_exists(edge_id):
            raise NonexistentEdgeError(edge_id, None, None, "restore")
        elif self.edge_visible(edge_id):
            edge = self.get_edge(edge_id)
            src_id, tgt_id = edge.source, edge.target
            raise EdgeActionError(edge_id, src_id, tgt_id, "restore",
                                  "edge already visible")

        edge = self.get_edge(edge_id)
        src_id, tgt_id = edge.source, edge.target

        if not self.vertex_visible(src_id):
            raise EdgeActionError(edge_id, src_id, tgt_id, "restore",
                                  "source vertex is hidden")
        if not self.vertex_visible(tgt_id):
            raise EdgeActionError(edge_id, src_id, tgt_id, "restore",
                                  "target vertex is hidden")

        self._visible_edges[edge_id] = self._hidden_edges.pop(edge_id)
        if src_id != tgt_id:
            edge.restore(self.ax)

        if redraw:
            self.ax.figure.canvas.draw()

    def remove_vertex(self, vxid, redraw=True):

        if not self.vertex_exists(vxid):
            raise NonexistentVertexError(vxid, "remove")

        vertex = self._visible_vertices[vxid]

        for edge_id in vertex.loops & self.visible_edges:
            edge = self._visible_edges.pop(edge_id)
        for edge_id in vertex.loops & self.hidden_edges:
            edge = self._hidden_edges.pop(edge_id)

        for edge_id in (vertex.in_edges
                        | vertex.out_edges) & self.visible_edges:
            edge = self._visible_edges.pop(edge_id)
            edge.hide()

        for edge_id in (vertex.in_edges
                        | vertex.out_edges) & self.hidden_edges:
            edge = self._hidden_edges.pop(edge_id)
            edge.hide()

        if self.vertex_visible:
            self._visible_vertices.pop(vxid)
        else:
            self._hidden_vertices.pop(vxid)

        vertex.remove()

        if redraw:
            self.ax.figure.canvas.draw()

    def remove_edge(self, edge_id, redraw=True):

        if not self.edge_exists(edge_id):
            raise NonexistentEdgeError(edge_id, "remove")

        if self.edge_visible(edge_id):
            edge = self._visible_edges.pop(edge_id)
        else:
            edge = self._hidden_edges.pop(edge_id)

        src_id, tgt_id = edge.source, edge.target
        src, tgt = self.get_vertex(src_id), self.get_vertex(tgt_id)

        if src_id == tgt_id:
            src.remove_loop(edge_id)
        else:
            src.remove_out_edge(edge_id)
            tgt.remove_in_edge(edge_id)
            edge.hide()

        if redraw:
            self.ax.figure.canvas.draw()

    def redraw(action):
        def f(self, *args, **kwargs):
            result = action(self, *args, **kwargs)
            self.ax.figure.canvas.draw()
            return result

        return f

    @redraw
    def add_vertices(self, vertices, **props):
        return filter(
            lambda v: v is not None,
            [self.add_vertex(*vx, redraw=False, **props) for vx in vertices])

    @redraw
    def update_vertices_props(self, vertices, **props):
        return filter(lambda v: v is not None, [
            self.update_vertex_props(vx, redraw=False, **props)
            for vx in vertices
        ])

    @redraw
    def restore_vertices_props(self, vertices):
        return filter(
            lambda v: v is not None,
            [self.restore_vertex_props(vx, redraw=False) for vx in vertices])

    @redraw
    def add_edges(self, edges, **props):
        return filter(
            lambda v: v is not None,
            [self.add_edge(*e, redraw=False, **props) for e in edges])

    @redraw
    def hide_vertices(self, vertices):
        return filter(lambda v: v is not None,
                      [self.hide_vertex(vx, False) for vx in vertices])

    @redraw
    def hide_edges(self, edge_ids):
        return filter(lambda v: v is not None,
                      [self.hide_edge(e, False) for e in edge_ids])

    @redraw
    def restore_vertices(self, vertices):
        return filter(lambda v: v is not None,
                      [self.restore_vertex(vx, False) for vx in vertices])

    @redraw
    def restore_edges(self, edge_ids):
        return filter(lambda v: v is not None,
                      [self.restore_edge(e, False) for e in edge_ids])

    @redraw
    def remove_vertices(self, vertices):
        return filter(lambda v: v is not None,
                      [self.remove_vertex(vx, False) for vx in vertices])

    @redraw
    def remove_edges(self, edge_ids):
        return filter(lambda v: v is not None,
                      [self.remove_edge(e, False) for e in edge_ids])

    @redraw
    def restore_all(self):
        return filter(
            lambda v: v is not None,
            [self.restore_vertex(vx, False) for vx in self.hidden_vertices] +
            [self.restore_edge(e, False) for e in self.hidden_edges])

    @redraw
    def clear(self):
        return filter(lambda v: v is not None, [
            self.remove_vertex(vx, False)
            for vx in self._hidden_vertices.keys() +
            self._visible_vertices.keys()
        ] + [
            self.remove_edge(e, False)
            for e in self._hidden_edges.keys() + self._visible_edges.keys()
        ])

    @property
    def vertices(self):
        return set(self._visible_vertices.keys()) | set(
            self._hidden_vertices.keys())

    @property
    def edges(self):
        return set(self._visible_edges.keys()) | set(self._hidden_edges.keys())

    @property
    def visible_vertices(self):
        return set(self._visible_vertices.keys())

    @property
    def visible_edges(self):
        return set(self._visible_edges.keys())

    @property
    def hidden_vertices(self):
        return set(self._hidden_vertices.keys())

    @property
    def hidden_edges(self):
        return set(self._hidden_edges.keys())

    def vertex_exists(self, vxid):
        return vxid in self.vertices

    def edge_exists(self, edge_id):
        return edge_id in self.edges

    def vertex_visible(self, vxid):
        return vxid in self.visible_vertices

    def edge_visible(self, edge_id):
        return edge_id in self.visible_edges

    def get_vertex(self, vxid):

        if vxid in self._visible_vertices:
            return self._visible_vertices[vxid]
        elif vxid in self._hidden_vertices:
            return self._hidden_vertices[vxid]
        else:
            raise NonexistentVertexError(vxid, "get")

    def get_edge(self, edge_id):

        if edge_id in self._visible_edges:
            return self._visible_edges[edge_id]
        elif edge_id in self._hidden_edges:
            return self._hidden_edges[edge_id]
        else:
            raise NonexistentVertexError(vxid, "get")

    def get_edges(self, vertices):

        edges = set()
        for vxid in vertices:
            vertex = self.get_vertex(vxid)
            for edge_id in vertex.out_edges:
                edge = self.get_edge(edge_id)
                if edge.target in vertices:
                    edges.add(edge_id)
        return edges

    def filter_edges(self, vxid, vertices):

        edges = set()
        vertex = self.get_vertex(vxid)
        for edge_id in vertex.edges:
            edge = self.get_edges(edge_id)
            if edge.source in vertices or edge.target in vertices:
                edges.add(edge_id)
        return edges

    def reset_view(self):

        self.ax.set_autoscale_on(True)
        self.ax.relim()
        self.ax.autoscale_view()
        self.ax.figure.canvas.toolbar.update()