Пример #1
0
    def draw_boltzmann_actions(self, axis: Axes,
                               actions_value_fcn_dict: Dict[Tuple[int, int],
                                                            Dict[str, float]],
                               *args, **kwargs) -> None:
        arrow_half_length = GridWorld.ARROW_LENGTH / 2.0

        for state, actions_value_dict in actions_value_fcn_dict.items():
            x, y = state
            max_value = max(actions_value_dict.values())
            max_action = max(actions_value_dict, key=actions_value_dict.get)
            for action, value in actions_value_dict.items():
                delx, dely = GridWorld.ACTION_DELTA_XY_DICT[action]
                length = arrow_half_length * np.exp(value - max_value)

                kwargs_copied = kwargs.copy()

                if action == max_action:
                    kwargs_copied.update(color="r")

                axis.arrow(
                    x,
                    y,
                    length * delx,
                    length * dely,
                    head_width=0.3 * length,
                    length_includes_head=True,
                    *args,
                    **kwargs_copied,
                )

        self._draw_grid_world(axis)
Пример #2
0
def arrows_transitions(
    ax: Axes,
    X: np.ndarray,
    indices: Sequence[int],
    weight=None,
):
    """
    Plot arrows of transitions in data matrix.

    Parameters
    ----------
    ax
        Axis object from matplotlib.
    X
        Data array, any representation wished (X, psi, phi, etc).
    indices
        Indices storing the transitions.
    """
    step = 1
    width = axis_to_data(ax, 0.001)
    if X.shape[0] > 300:
        step = 5
        width = axis_to_data(ax, 0.0005)
    if X.shape[0] > 500:
        step = 30
        width = axis_to_data(ax, 0.0001)
    head_width = 10 * width
    for ix, x in enumerate(X):
        if ix % step != 0:
            continue
        X_step = X[indices[ix]] - x
        # don't plot arrow of length 0
        for itrans in range(X_step.shape[0]):
            alphai = 1
            widthi = width
            head_widthi = head_width
            if weight is not None:
                alphai *= weight[ix, itrans]
                widthi *= weight[ix, itrans]
            if not np.any(X_step[itrans, :1]):
                continue
            ax.arrow(
                x[0],
                x[1],
                X_step[itrans, 0],
                X_step[itrans, 1],
                length_includes_head=True,
                width=widthi,
                head_width=head_widthi,
                alpha=alphai,
                color='grey',
            )
Пример #3
0
    def plot_2d(self,
                ax_2d: Axes,
                point: array_like = (0, 0),
                scalar: float = 1,
                **kwargs) -> None:
        """
        Plot a 2D vector.

        The vector is plotted as an arrow.

        Parameters
        ----------
        ax_2d : Axes
            Instance of :class:`~matplotlib.axes.Axes`.
        point : array_like, optional
            Position of the vector tail (default is origin).
        scalar : {int, float}, optional
            Value used to scale the vector (default 1).
        kwargs : dict, optional
            Additional keywords passed to :meth:`~matplotlib.axes.Axes.arrow`.

        Examples
        --------
        .. plot::
            :include-source:

            >>> import matplotlib.pyplot as plt
            >>> from skspatial.objects import Vector

            >>> _, ax = plt.subplots()

            >>> Vector([1, 1]).plot_2d(ax, point=(-3, 5), scalar=2, head_width=0.5)

            >>> limits = ax.axis([-5, 5, 0, 10])

        """
        x, y = point
        dx, dy = scalar * self

        ax_2d.arrow(x, y, dx, dy, **kwargs)
Пример #4
0
    def draw_deterministic_actions(self, axis: Axes,
                                   actions_value_fcn_dict: Dict[Tuple[int,
                                                                      int],
                                                                Dict[str,
                                                                     float]],
                                   *args, **kwargs) -> None:
        arrow_length = GridWorld.ARROW_LENGTH
        arrow_half_length = arrow_length / 2.0
        for state, actions_value_dict in actions_value_fcn_dict.items():
            x, y = state
            best_action = max(actions_value_dict, key=actions_value_dict.get)
            delx, dely = GridWorld.ACTION_DELTA_XY_DICT[best_action]
            axis.arrow(
                x - arrow_half_length * delx,
                y - arrow_half_length * dely,
                arrow_length * delx,
                arrow_length * dely,
                head_width=0.1 * arrow_length,
                length_includes_head=True,
                *args,
                **kwargs,
            )

        self._draw_grid_world(axis)
Пример #5
0
    def render_sample_data(self,
                           sample_data_token: str,
                           with_anns: bool = True,
                           box_vis_level: BoxVisibility = BoxVisibility.ANY,
                           axes_limit: float = 40,
                           ax: Axes = None,
                           nsweeps: int = 1) -> None:
        """
        Render sample data onto axis.
        :param sample_data_token: Sample_data token.
        :param with_anns: Whether to draw annotations.
        :param box_vis_level: If sample_data is an image, this sets required visibility for boxes.
        :param axes_limit: Axes limit for lidar and radar (measured in meters).
        :param ax: Axes onto which to render.
        :param nsweeps: Number of sweeps for lidar and radar.
        """

        # Get sensor modality.
        sd_record = self.nusc.get('sample_data', sample_data_token)
        sensor_modality = sd_record['sensor_modality']

        if sensor_modality == 'lidar':
            # Get boxes in lidar frame.
            _, boxes, _ = self.nusc.get_sample_data(sample_data_token, box_vis_level=box_vis_level)

            # Get aggregated point cloud in lidar frame.
            sample_rec = self.nusc.get('sample', sd_record['sample_token'])
            chan = sd_record['channel']
            ref_chan = 'LIDAR_TOP'
            pc, times = LidarPointCloud.from_file_multisweep(self.nusc, sample_rec, chan, ref_chan, nsweeps=nsweeps)

            # Init axes.
            if ax is None:
                _, ax = plt.subplots(1, 1, figsize=(9, 9))

            # Show point cloud.
            points = view_points(pc.points[:3, :], np.eye(4), normalize=False)
            dists = np.sqrt(np.sum(pc.points[:2, :] ** 2, axis=0))
            colors = np.minimum(1, dists/axes_limit/np.sqrt(2))
            ax.scatter(points[0, :], points[1, :], c=colors, s=0.2)

            # Show ego vehicle.
            ax.plot(0, 0, 'x', color='black')

            # Show boxes.
            if with_anns:
                for box in boxes:
                    c = np.array(self.get_color(box.name)) / 255.0
                    box.render(ax, view=np.eye(4), colors=(c, c, c))

            # Limit visible range.
            ax.set_xlim(-axes_limit, axes_limit)
            ax.set_ylim(-axes_limit, axes_limit)

        elif sensor_modality == 'radar':
            # Get boxes in lidar frame.
            sample_rec = self.nusc.get('sample', sd_record['sample_token'])
            lidar_token = sample_rec['data']['LIDAR_TOP']
            _, boxes, _ = self.nusc.get_sample_data(lidar_token, box_vis_level=box_vis_level)

            # Get aggregated point cloud in lidar frame.
            # The point cloud is transformed to the lidar frame for visualization purposes.
            chan = sd_record['channel']
            ref_chan = 'LIDAR_TOP'
            pc, times = RadarPointCloud.from_file_multisweep(self.nusc, sample_rec, chan, ref_chan, nsweeps=nsweeps)

            # Transform radar velocities (x is front, y is left), as these are not transformed when loading the point
            # cloud.
            radar_cs_record = self.nusc.get('calibrated_sensor', sd_record['calibrated_sensor_token'])
            lidar_sd_record = self.nusc.get('sample_data', lidar_token)
            lidar_cs_record = self.nusc.get('calibrated_sensor', lidar_sd_record['calibrated_sensor_token'])
            velocities = pc.points[8:10, :]  # Compensated velocity
            velocities = np.vstack((velocities, np.zeros(pc.points.shape[1])))
            velocities = np.dot(Quaternion(radar_cs_record['rotation']).rotation_matrix, velocities)
            velocities = np.dot(Quaternion(lidar_cs_record['rotation']).rotation_matrix.T, velocities)
            velocities[2, :] = np.zeros(pc.points.shape[1])

            # Init axes.
            if ax is None:
                _, ax = plt.subplots(1, 1, figsize=(9, 9))

            # Show point cloud.
            points = view_points(pc.points[:3, :], np.eye(4), normalize=False)
            dists = np.sqrt(np.sum(pc.points[:2, :] ** 2, axis=0))
            colors = np.minimum(1, dists / axes_limit / np.sqrt(2))
            sc = ax.scatter(points[0, :], points[1, :], c=colors, s=3)

            # Show velocities.
            points_vel = view_points(pc.points[:3, :] + velocities, np.eye(4), normalize=False)
            max_delta = 10
            deltas_vel = points_vel - points
            deltas_vel = 3 * deltas_vel  # Arbitrary scaling
            deltas_vel = np.clip(deltas_vel, -max_delta, max_delta)  # Arbitrary clipping
            colors_rgba = sc.to_rgba(colors)
            for i in range(points.shape[1]):
                ax.arrow(points[0, i], points[1, i], deltas_vel[0, i], deltas_vel[1, i], color=colors_rgba[i])

            # Show ego vehicle.
            ax.plot(0, 0, 'x', color='black')

            # Show boxes.
            if with_anns:
                for box in boxes:
                    c = np.array(self.get_color(box.name)) / 255.0
                    box.render(ax, view=np.eye(4), colors=(c, c, c))

            # Limit visible range.
            ax.set_xlim(-axes_limit, axes_limit)
            ax.set_ylim(-axes_limit, axes_limit)

        elif sensor_modality == 'camera':
            # Load boxes and image.
            data_path, boxes, camera_intrinsic = self.nusc.get_sample_data(sample_data_token,
                                                                           box_vis_level=box_vis_level)
            data = Image.open(data_path)

            # Init axes.
            if ax is None:
                _, ax = plt.subplots(1, 1, figsize=(9, 16))

            # Show image.
            ax.imshow(data)

            # Show boxes.
            if with_anns:
                for box in boxes:
                    c = np.array(self.get_color(box.name)) / 255.0
                    box.render(ax, view=camera_intrinsic, normalize=True, colors=(c, c, c))

            # Limit visible range.
            ax.set_xlim(0, data.size[0])
            ax.set_ylim(data.size[1], 0)

        else:
            raise ValueError("Error: Unknown sensor modality!")

        ax.axis('off')
        ax.set_title(sd_record['channel'])
        ax.set_aspect('equal')
def gauge(ax: Axes, bounds: Tuple[float, float], arrow: float, labels=('A', 'B', 'C'), colors='plasma', title: str = '',
          bounds_check: bool = False):
    """
    some sanity checks first

    """

    n = len(labels)

    if bounds_check and not (bounds[0] <= arrow <= bounds[1]):
        raise ValueError('Arrow position out of range')
    arrow = np.clip(arrow, *bounds)

    """
    if colors is a string, we assume it's a matplotlib colormap
    and we discretize in n discrete colors 
    """

    if isinstance(colors, str):
        cmap = cm.get_cmap(colors, n)
        cmap = cmap(np.arange(n))
        colors = cmap[::, :].tolist()
    if isinstance(colors, list):
        if len(colors) == n:
            colors = colors[::-1]
        else:
            raise Exception("\n\nnumber of colors {} not equal \
            to number of categories{}\n".format(len(colors), n))

    """
    begins the plotting
    """

    ang_range, mid_points = _degree_range(n)

    labels = labels[::-1]

    """
    plots the sectors and the arcs
    """
    patches = []
    for ang, c in zip(ang_range, colors):
        # sectors
        patches.append(Wedge((0., 0.), .4, *ang, facecolor='w', lw=2))
        # arcs
        patches.append(Wedge((0., 0.), .4, *ang, width=0.10, facecolor=c, lw=2, alpha=1.0))

    [ax.add_patch(p) for p in patches]

    """
    set the autolabel_service 
    """

    for mid, lab in zip(mid_points, labels):
        ax.text(0.35 * np.cos(np.radians(mid)), 0.35 * np.sin(np.radians(mid)), lab,
                horizontalalignment='center', verticalalignment='center', fontsize=14,
                fontweight='bold', rotation=_rot_text(mid))

    """
    set the bottom banner and the title
    """
    r = Rectangle((-0.4, -0.1), 0.8, 0.1, facecolor='w', lw=2)
    ax.add_patch(r)

    if "{}" in title:
        title = title.format(arrow)
    ax.text(0, -0.05, title, horizontalalignment='center',
            verticalalignment='center', fontsize=22, fontweight='bold')

    """
    plots the arrow now
    """

    tile = 180 / n / 2
    swing = 180 - 2 * tile
    pos = tile + swing - (arrow - bounds[0]) / (bounds[1] - bounds[0]) * swing

    ax.arrow(0, 0, 0.225 * np.cos(np.radians(pos)), 0.225 * np.sin(np.radians(pos)),
             width=0.04, head_width=0.09, head_length=0.1, fc='k', ec='k')

    ax.add_patch(Circle((0, 0), radius=0.02, facecolor='k'))
    ax.add_patch(Circle((0, 0), radius=0.01, facecolor='w', zorder=11))

    """
    removes frame and ticks, and makes axis equal and tight
    """
    ax.set_frame_on(False)
    ax.axes.set_xticks([])
    ax.axes.set_yticks([])
    ax.axis('equal')