Exemple #1
0
def plot_image_scatter(data: DataFrame, ax_in: Axes, img: Image) -> list:
    """Creates a scatter plot using the images instead of points on ax_in.

    Arguments:
        data {DataFrame} -- Provides xCoordinate and yCoordinate
        ax_in {Axes} -- Target axes for the plot.
        img {Image} -- PIL Image already sized to be placed on plot.

    Returns:
        list -- List of created AnnotationBbox objects
    """
    img_boxes = []
    for _, row in data.iterrows():
        imagebox = OffsetImage(img)
        imagebox.image.axes = ax_in
        pos = (row['xCoordinate'], row['yCoordinate'])
        ab = AnnotationBbox(imagebox,
                            pos,
                            xycoords='data',
                            boxcoords="offset points",
                            box_alignment=(0.5, 0.5),
                            pad=0,
                            frameon=False)
        ax_in.add_artist(ab)
        ab.set_zorder(2)
        img_boxes.append(ab)

    return img_boxes
Exemple #2
0
    def plot_2d(self, ax_2d: Axes, **kwargs) -> None:
        """
        Plot the circle in 2D.

        Parameters
        ----------
        ax_2d : Axes
            Instance of :class:`~matplotlib.axes.Axes`.
        kwargs : dict, optional
            Additional keywords passed to :Class:`matplotlib.patches.Circle`.

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

            >>> import matplotlib.pyplot as plt

            >>> from skspatial.objects import Circle

            >>> circle = Circle([-2, 3], 3)

            >>> fig, ax = plt.subplots()
            >>> circle.plot_2d(ax, fill=False)
            >>> circle.point.plot_2d(ax)
            >>> limits = plt.axis([-10, 10, -10, 10])

        """
        circle = plt.Circle(self.point, self.radius, **kwargs)

        ax_2d.add_artist(circle)
Exemple #3
0
    def __init__(self, ax: Axes, numpages = 10, valinit=0, valfmt='%1d', **kwargs ):
        self.facecolor=kwargs.get('facecolor',"yellow")
        self.activecolor = kwargs.pop('activecolor',"blue" )
        self.stepcolor = kwargs.pop('stepcolor', "#ff6f6f" )
        self.on_animcolor = kwargs.pop('on-animcolor', "#006622")
        self.fontsize = kwargs.pop('fontsize', 10)
        self.maxIndexedPages = 24
        self.numpages = numpages
        self.axes = ax

        super(PageSlider, self).__init__(ax, "", 0, numpages, valinit=valinit, valfmt=valfmt, **kwargs)

        self.poly.set_visible(False)
        self.vline.set_visible(False)
        self.pageRects = []
        indexMod = math.ceil( self.numpages / self.maxIndexedPages )
        for i in range(numpages):
            facecolor = self.activecolor if i==valinit else self.facecolor
            r  = matplotlib.patches.Rectangle((float(i)/numpages, 0), 1./numpages, 1, transform=ax.transAxes, facecolor=facecolor)
            ax.add_artist(r)
            self.pageRects.append(r)
            if i % indexMod == 0:
                ax.text(float(i)/numpages+0.5/numpages, 0.5, str(i+1), ha="center", va="center", transform=ax.transAxes, fontsize=self.fontsize)
        self.valtext.set_visible(False)

        divider = make_axes_locatable(ax)
        bax = divider.append_axes("right", size="5%", pad=0.05)
        fax = divider.append_axes("right", size="5%", pad=0.05)
        self.button_back = matplotlib.widgets.Button(bax, label='$\u25C1$', color=self.stepcolor, hovercolor=self.activecolor)
        self.button_forward = matplotlib.widgets.Button(fax, label='$\u25B7$', color=self.stepcolor, hovercolor=self.activecolor)
        self.button_back.label.set_fontsize(self.fontsize)
        self.button_forward.label.set_fontsize(self.fontsize)
        self.button_back.on_clicked(self.backward)
        self.button_forward.on_clicked(self. forward)
Exemple #4
0
    def __init__(self, ax: Axes, numpages = 10, valinit=0, valfmt='%1d', **kwargs ):
        self.facecolor=kwargs.get('facecolor',"yellow")
        self.activecolor = kwargs.pop('activecolor',"blue" )
        self.stepcolor = kwargs.pop('stepcolor', "#ff6f6f" )
        self.animcolor = kwargs.pop('animcolor', "#6fff6f" )
        self.on_animcolor = kwargs.pop('on-animcolor', "#006622")
        self.fontsize = kwargs.pop('fontsize', 10)
        self.animation_controls = kwargs.pop('dynamic', True )
        self.maxIndexedPages = 24
        self.numpages = numpages
        self.init_anim_delay: float = 0.5   # time between timer events in seconds
        self.anim_delay: float = self.init_anim_delay
        self.anim_delay_multiplier = 1.5
        self.anim_state = ADirection.STOP
        self.axes = ax
        self.event_source = EventSource( self.step, delay = self.init_anim_delay )

        super(PageSlider, self).__init__(ax, "", 0, numpages, valinit=valinit, valfmt=valfmt, **kwargs)

        self.poly.set_visible(False)
        self.vline.set_visible(False)
        self.pageRects = []
        indexMod = math.ceil( self.numpages / self.maxIndexedPages )
        for i in range(numpages):
            facecolor = self.activecolor if i==valinit else self.facecolor
            r  = matplotlib.patches.Rectangle((float(i)/numpages, 0), 1./numpages, 1, transform=ax.transAxes, facecolor=facecolor)
            ax.add_artist(r)
            self.pageRects.append(r)
            if i % indexMod == 0:
                ax.text(float(i)/numpages+0.5/numpages, 0.5, str(i+1), ha="center", va="center", transform=ax.transAxes, fontsize=self.fontsize)
        self.valtext.set_visible(False)

        divider = make_axes_locatable(ax)
        bax = divider.append_axes("right", size="5%", pad=0.05)
        fax = divider.append_axes("right", size="5%", pad=0.05)
        self.button_back = matplotlib.widgets.Button(bax, label='$\u25C1$', color=self.stepcolor, hovercolor=self.activecolor)
        self.button_forward = matplotlib.widgets.Button(fax, label='$\u25B7$', color=self.stepcolor, hovercolor=self.activecolor)
        self.button_back.label.set_fontsize(self.fontsize)
        self.button_forward.label.set_fontsize(self.fontsize)
        self.button_back.on_clicked(self.step_backward)
        self.button_forward.on_clicked(self.step_forward)

        if self.animation_controls:
            afax = divider.append_axes("left", size="5%", pad=0.05)
            asax = divider.append_axes("left", size="5%", pad=0.05)
            abax = divider.append_axes("left", size="5%", pad=0.05)
            self.button_aback    = matplotlib.widgets.Button( abax, label='$\u25C0$', color=self.animcolor, hovercolor=self.activecolor)
            self.button_astop = matplotlib.widgets.Button( asax, label='$\u25FE$', color=self.animcolor, hovercolor=self.activecolor)
            self.button_aforward = matplotlib.widgets.Button( afax, label='$\u25B6$', color=self.animcolor, hovercolor=self.activecolor)

            self.button_aback.label.set_fontsize(self.fontsize)
            self.button_astop.label.set_fontsize(self.fontsize)
            self.button_aforward.label.set_fontsize(self.fontsize)
            self.button_aback.on_clicked(self.anim_backward)
            self.button_astop.on_clicked(self.anim_stop)
            self.button_aforward.on_clicked(self.anim_forward)
def _plot_color_wheel(ax: Axes,
                      font_size: int,
                      use_degrees: Optional[bool] = False) -> None:
    """Plots a color wheel on the given Axes object."""
    try:
        import seaborn as sns
    except ImportError:
        raise ImportError(
            'Must have seaborn installed to use plot_state_pixel or'
            ' plot_state_qpshere. To install, run "pip install seaborn".')
    n = 64
    theta = np.ones(n)
    ax.pie(theta, colors=sns.color_palette("hls", n), radius=0.75)
    ax.add_artist(Circle((0, 0), 0.5, color='white', zorder=1))
    offset = 0.95  # since radius of sphere is one.

    if use_degrees:
        labels = ['Phase\n(Deg)', '0', '90', '180   ', '270']
    else:
        labels = ['Phase', '$0$', '$\\pi/2$', '$\\pi$', '$3\\pi/2$']

    ax.text(0,
            0,
            labels[0],
            horizontalalignment='center',
            verticalalignment='center',
            fontsize=font_size)
    ax.text(offset,
            0,
            labels[1],
            horizontalalignment='center',
            verticalalignment='center',
            fontsize=font_size)
    ax.text(0,
            offset,
            labels[2],
            horizontalalignment='center',
            verticalalignment='center',
            fontsize=font_size)
    ax.text(-offset,
            0,
            labels[3],
            horizontalalignment='center',
            verticalalignment='center',
            fontsize=font_size)
    ax.text(0,
            -offset,
            labels[4],
            horizontalalignment='center',
            verticalalignment='center',
            fontsize=font_size)
Exemple #6
0
 def plot_cross_cut():
     #plot cut plane with crossection of cut fibers
     fig55 = figure(55)
     title('Cut fibers area (ellipses)')
     ax55 = Axes(fig55, [.1, .1, .8, .8])
     fig55.add_axes(ax55)
     for i in range(0, len(phi_x_cut)):
         sy_c = sy_cut[i] + (sec - sx_cut[i]) / cos(phi_x_cut[i]) * sin(phi_x_cut[i]) * cos(theta_cut[i])
         sz_c = sz_cut[i] + (sec - sx_cut[i]) / cos(phi_x_cut[i]) * sin(phi_x_cut[i]) * sin(theta_cut[i])
         if (0 < phi_x_cut[i] < arctan((fib.lf) / fib.df)) and (sx_cut[i] - fib.lf / 2. * cos(phi_x_cut[i]) + fib.df / 2. * sin(phi_x_cut[i]) < sec < sx_cut[i] + fib.lf / 2. * cos(phi_x_cut[i]) - fib.df / 2. * sin(phi_x_cut[i])):
             patch = Ellipse([ sy_c, sz_c ] , fib.df, fib.df / cos(phi_x_cut[i]), theta_cut[i] * 180 / pi , color = 'black')
             ax55.add_artist(patch)
     ax55.set_xlim(-spec.l_y / 2., spec.l_y / 2.)
     ax55.set_ylim(-spec.l_z / 2., spec.l_z / 2.)
Exemple #7
0
def preview(path, ext=0, width=None, minwidth=256, maxwidth=1024):
    """
    Preview FITS image as PNG
    """
    base = stdconf.get('basepath', '.')
    fullpath = os.path.join(base, path)

    # Optional parameters
    fmt = request.args.get('format', 'jpeg')
    quality = int(request.args.get('quality', 80))

    width = request.args.get('width', width)
    if width is not None:
        width = int(width)

    data = fits.getdata(fullpath, ext)

    figsize = [data.shape[1], data.shape[0]]

    if width is None:
        if figsize[0] < minwidth:
            width = minwidth
        elif figsize[0] > maxwidth:
            width = maxwidth

    if width is not None and figsize[0] != width:
        figsize[1] = width*figsize[1]/figsize[0]
        figsize[0] = width

    fig = Figure(facecolor='white', dpi=72, figsize=(figsize[0]/72, figsize[1]/72))
    ax = Axes(fig, [0., 0., 1., 1.])
    # ax.set_axis_off()
    fig.add_axes(ax)
    plots.imshow(data, ax=ax, show_axis=False, show_colorbar=False,
                 cmap=request.args.get('cmap', 'Blues_r'),
                 stretch=request.args.get('stretch', 'linear'),
                 qq=[float(request.args.get('qmin', 0.5)), float(request.args.get('qmax', 99.5))])

    if request.args.get('ra', None) is not None and request.args.get('dec', None) is not None:
        # Show the position of the object
        header = fits.getheader(fullpath, ext)
        wcs = WCS(header)
        x,y = wcs.all_world2pix(float(request.args.get('ra')), float(request.args.get('dec')), 0)
        ax.add_artist(Circle((x, y), 5.0, edgecolor='red', facecolor='none', ls='-', lw=2))

    buf = io.BytesIO()
    fig.savefig(buf, format=fmt, quality=quality)

    return Response(buf.getvalue(), mimetype='image/%s' % fmt)
def kpiPlot(title: str, info: Union[int, str], color: str, ax: Axes):
    ax.pie([1], colors=[color], labels=[""])
    centre_circle = plt.Circle((0, 0), 0.78, fc='white')

    ax.add_artist(centre_circle)
    ax.text(0, 1.45, title, va='top', ha='center', fontsize=18, weight='bold')
    ax.text(0,
            0,
            prettyNumber(info),
            va='top',
            ha='center',
            fontsize=16,
            weight='bold')

    return ax
Exemple #9
0
def add_mae_r2_box(
    xs: NDArray[np.float64],
    ys: NDArray[np.float64],
    ax: Axes = None,
    loc: str = "lower right",
    prefix: str = "",
    suffix: str = "",
    prec: int = 3,
    **kwargs: Any,
) -> AnchoredText:
    """Provide a set of x and y values of equal length and an optional Axes object
    on which to print the values' mean absolute error and R^2 coefficient of
    determination.

    Args:
        xs (array, optional): x values.
        ys (array, optional): y values.
        ax (Axes, optional): matplotlib Axes on which to add the box. Defaults to None.
        loc (str, optional): Where on the plot to place the AnchoredText object.
            Defaults to "lower right".
        prec (int, optional): # of decimal places in printed metrics. Defaults to 3.
        prefix (str, optional): Title or other string to prepend to metrics.
            Defaults to "".
        suffix (str, optional): Text to append after metrics. Defaults to "".

    Returns:
        AnchoredText: Instance containing the metrics.
    """
    if ax is None:
        ax = plt.gca()

    mask = ~np.isnan(xs) & ~np.isnan(ys)
    xs, ys = xs[mask], ys[mask]

    text = f"{prefix}$\\mathrm{{MAE}} = {np.abs(xs - ys).mean():.{prec}f}$"
    text += f"\n$R^2 = {r2_score(xs, ys):.{prec}f}${suffix}"

    frameon: bool = kwargs.pop("frameon", False)
    text_box = AnchoredText(text, loc=loc, frameon=frameon, **kwargs)
    ax.add_artist(text_box)

    return text_box
Exemple #10
0
def plot_ellipses(subplot: Axes,
                  x_avg: float,
                  y_avg: float,
                  x_std: float,
                  y_std: float,
                  ellipse_color: str = 'b') -> None:
    std_ellipse = Ellipse(xy=(x_avg, y_avg),
                          width=x_std * 2,
                          height=y_std * 2,
                          fill=False,
                          edgecolor=ellipse_color,
                          linestyle='dashed')
    double_std_ellipse = Ellipse(xy=(x_avg, y_avg),
                                 width=x_std * 4,
                                 height=y_std * 4,
                                 fill=False,
                                 edgecolor=ellipse_color)

    subplot.add_artist(std_ellipse)
    subplot.add_artist(double_std_ellipse)
Exemple #11
0
    def _plot(self, ax: Axes, position_kwargs: dict, heading_kwargs: dict):
        """ adds a representation of this critter to matplotlib axis object

        position_kwargs should likely have keys [radius, zorder, facecolor, edgecolor]
        heading_kwargs should likely have keys [color, linewidth, zorder]
        """

        # position
        p0 = self.location.position
        patch = CirclePolygon(p0, **position_kwargs)
        ax.add_artist(patch)

        # heading indicator
        if "hlen" not in heading_kwargs.keys():
            hlen = 0.08
        else:
            hlen = heading_kwargs["hlen"]

        p1 = (cos(self.location.heading) * hlen + p0[0],
              sin(self.location.heading) * hlen + p0[1])
        line = Line2D(p0, p1, **heading_kwargs)
        ax.add_line(line)
        return ax
    def add_artist(self, a, path_interpolation=None):
        '''
        Modified :meth:`matplotlib.axes.Axes.add_artist`. Enables the
        interpolation of a given artist, e.g. a line or rectangle

        Keyword arguments:

            *a*:
                Artist to be added
                Accepts: :class:`matplotlib.artist.Artist` instance

            *path_interpolation`:
                if set, the path of the artist will be interpolated with the
                given value. If set to 0, bezier arcs are used to connect.
        '''
        if path_interpolation is not None:
            if hasattr(a, "get_path"):
                a.get_path()._interpolation_steps = path_interpolation
            else:
                raise AttributeError("Artist has no Path")
        return Axes.add_artist(self, a)
Exemple #13
0
def imscatter(
    x: np.ndarray,
    y: np.ndarray,
    ax: Axes,
    imageData: torch.Tensor,
    unnormalize_fn: Optional[Callable] = None,
    zoom: int = 1,
) -> NoReturn:
    """Scatter plot with images instead of points on ax."""
    images = []
    for i in range(len(x)):
        x0, y0 = x[i], y[i]
        # Convert to image
        img = imageData[i]
        if unnormalize_fn is not None:
            img = unnormalize_fn(img)
        img *= 255.0
        img = img.permute([1, 2, 0]).numpy().astype(np.uint8)
        image = OffsetImage(img, zoom=zoom)
        ab = AnnotationBbox(image, (x0, y0), xycoords="data", frameon=False)
        images.append(ax.add_artist(ab))

    ax.update_datalim(np.column_stack([x, y]))
    ax.autoscale()
def plot_station_positions(directions_file_path: Path, stations: list, ax: Axes, grid_config: GridConfig=default_domains.bc_mh_044,
                           save_upstream_boundaries_to_shp=False):


    with Dataset(str(directions_file_path)) as ds:
        flow_dirs = ds.variables["flow_direction_value"][:]
        flow_acc_area = ds.variables["accumulation_area"][:]
        lons_2d, lats_2d = [ds.variables[k][:] for k in ["lon", "lat"]]



    basemap, reg_of_interest = grid_config.get_basemap_using_shape_with_polygons_of_interest(lons_2d, lats_2d,
                                                                                             shp_path=default_domains.MH_BASINS_PATH,
                                                                                             resolution="i")


    cell_manager = CellManager(flow_dirs, lons2d=lons_2d, lats2d=lats_2d, accumulation_area_km2=flow_acc_area)
    station_to_model_point = cell_manager.get_model_points_for_stations(station_list=stations, nneighbours=8)

    #####
    xx, yy = basemap(lons_2d, lats_2d)
    upstream_edges = cell_manager.get_upstream_polygons_for_points(
        model_point_list=list(station_to_model_point.values()), xx=xx, yy=yy)

    upstream_edges_latlon = cell_manager.get_upstream_polygons_for_points(
        model_point_list=list(station_to_model_point.values()), xx=lons_2d, yy=lats_2d)




    plot_utils.draw_upstream_area_bounds(ax, upstream_edges=upstream_edges, color="r", linewidth=0.6)

    if save_upstream_boundaries_to_shp:
        plot_utils.save_to_shape_file(upstream_edges_latlon, folder_path="mh/engage_report/upstream_stations_areas/mh_{}".format(grid_config.dx), in_proj=None)


    basemap.drawrivers(linewidth=0.2)
    basemap.drawstates(linewidth=0.1)
    basemap.drawcountries(linewidth=0.1)
    basemap.drawcoastlines(linewidth=0.2)


    pos_ids, lons_pos, lats_pos = [], [], []
    pos_labels = []
    legend_lines = []
    for i, (s, mp) in enumerate(sorted(station_to_model_point.items(), key=lambda p: p[0].latitude, reverse=True), start=1):
        pos_ids.append(s.id)
        pos_labels.append(i)
        lons_pos.append(mp.longitude)
        lats_pos.append(mp.latitude)

        legend_lines.append("{}: {}".format(i, s.id))

    xm, ym = basemap(lons_pos, lats_pos)
    ax.scatter(xm, ym, c="g", s=20)
    for txt, x1, y1, pos_label in zip(pos_ids, xm, ym, pos_labels):
        ax.annotate(pos_label, xy=(x1, y1))



    at = AnchoredText("\n".join(legend_lines), prop=dict(size=8), frameon=True, loc=1)

    at.patch.set_boxstyle("round,pad=0.,rounding_size=0.2")
    ax.add_artist(at)
    def plot(self,
             ax: Axes = None,
             show_image=True,
             labels=None,
             objects=None,
             alpha=0.6,
             ls='-'):
        # Reuse the current axis if none was passed in
        ax = ax or plt.gca()

        # I am now using this same class for the ENTIRE image as well
        # as for sub images of facades.
        if show_image:
            if self.extent:
                ax.imshow(self.image, zorder=-1, extent=self.extent)
            else:
                ax.imshow(self.image, zorder=-1)

        if self.extent:
            ax.set_xbound(self.extent[0], self.extent[1])
            ax.set_ybound(self.extent[2], self.extent[3])

        # If this is a subimage of a facade, use the JSON file to
        # determine the actual facade polygon
        if self.dat is not None and self.annotation is None:
            pts = array(self.dat.polygon)
            p = Polygon(pts,
                        color=[0, 0, 0],
                        zorder=self.z_orders['facade'],
                        fill=False,
                        alpha=alpha,
                        hatch='/')
            ax.add_patch(p)
            return

        if objects is None:
            objects = self.iter_objects(labels)
        else:
            objects = objects
        for o in objects:
            n = o.name
            z = self.z_orders[n]
            c = self.colors[z] / 255.

            pts = self.unrectified(o.polygon.pt)

            # Just in case -- I think I have pruned out deleted records but if
            # any remain, render them with a black crosshatch overlaid.
            if o.deleted:
                ax.add_patch(
                    Polygon(pts, color='k', hatch='+', fill=False, zorder=50))
            else:
                ax.add_patch(
                    Polygon(pts,
                            color=c,
                            edgecolor=None,
                            zorder=z,
                            linestyle=ls,
                            alpha=alpha))
                ax.add_patch(
                    Polygon(pts,
                            color=c,
                            lw=2,
                            linestyle=ls,
                            fill=False,
                            zorder=50))
            ax.add_artist(Text(*pts.mean(0), o.name, zorder=55))
Exemple #16
0
    def plot_z_trend_histogram(self,
                               axis: Axes = None,
                               polar: bool = True,
                               normed: bool = True) -> None:

        if axis is None:
            axis = self.figure.add_subplot(111)

        cluster = Cluster(simulation_name=self.simulation.simulation_name,
                          clusterID=0,
                          redshift='z000p000')
        aperture_float = self.get_apertures(cluster)[
            self.aperture_id] / cluster.r200

        if not os.path.isfile(
                os.path.join(
                    self.path,
                    f'redshift_rot0rot4_histogram_aperture_{self.aperture_id}.npy'
                )):
            warnings.warn(
                f"File redshift_rot0rot4_histogram_aperture_{self.aperture_id}.npy not found."
            )
            print("self.make_simhist() activated.")
            self.make_simhist()

        print(
            f"Retrieving npy files: redshift_rot0rot4_histogram_aperture_{self.aperture_id}.npy"
        )
        sim_hist = np.load(os.path.join(
            self.path,
            f'redshift_rot0rot4_histogram_aperture_{self.aperture_id}.npy'),
                           allow_pickle=True)
        sim_hist = np.asarray(sim_hist)

        if normed:
            norm_factor = np.sum(self.simulation.sample_completeness)
            sim_hist[2] /= norm_factor
            sim_hist[3] /= norm_factor
            y_label = r"Sample fraction"
        else:
            y_label = r"Number of samples"

        items_labels = f""" REDSHIFT TRENDS - HISTOGRAM
							Number of clusters: {self.simulation.totalClusters:d}
							$z$ = 0.0 - 1.8
							Total samples: {np.sum(self.simulation.sample_completeness):d} $\equiv N_\mathrm{{clusters}} \cdot N_\mathrm{{redshifts}}$
							Aperture radius = {aperture_float:.2f} $R_{{200\ true}}$"""
        print(items_labels)

        sim_colors = {
            'ceagle': 'pink',
            'celr_e': 'lime',
            'celr_b': 'orange',
            'macsis': 'aqua',
        }

        axis.axvline(90, linestyle='--', color='k', alpha=0.5, linewidth=2)
        axis.step(sim_hist[0],
                  sim_hist[2],
                  color=sim_colors[self.simulation.simulation_name],
                  where='mid')
        axis.fill_between(sim_hist[0],
                          sim_hist[2] + sim_hist[3],
                          sim_hist[2] - sim_hist[3],
                          step='mid',
                          color=sim_colors[self.simulation.simulation_name],
                          alpha=0.2,
                          edgecolor='none',
                          linewidth=0)

        axis.set_ylabel(y_label, size=25)
        axis.set_xlabel(
            r"$\Delta \theta \equiv (\mathbf{L}_\mathrm{gas},\mathrm{\widehat{CoP}},\mathbf{L}_\mathrm{stars})$\quad[degrees]",
            size=25)
        axis.set_xlim(0, 180)
        axis.set_ylim(0, 0.1)
        axis.text(0.03,
                  0.97,
                  items_labels,
                  horizontalalignment='left',
                  verticalalignment='top',
                  transform=axis.transAxes,
                  size=15)

        if polar:
            inset_axis = self.figure.add_axes([0.75, 0.65, 0.25, 0.25],
                                              projection='polar')
            inset_axis.patch.set_alpha(0)  # Transparent background
            inset_axis.set_theta_zero_location('N')
            inset_axis.set_thetamin(0)
            inset_axis.set_thetamax(180)
            inset_axis.set_xticks(np.pi / 180. *
                                  np.linspace(0, 180, 5, endpoint=True))
            inset_axis.set_yticks([])
            inset_axis.step(sim_hist[0] / 180 * np.pi,
                            sim_hist[2],
                            color=sim_colors[self.simulation.simulation_name],
                            where='mid')
            inset_axis.fill_between(
                sim_hist[0] / 180 * np.pi,
                sim_hist[2] + sim_hist[3],
                sim_hist[2] - sim_hist[3],
                step='mid',
                color=sim_colors[self.simulation.simulation_name],
                alpha=0.2,
                edgecolor='none',
                linewidth=0)

        patch_ceagle = Patch(facecolor=sim_colors['ceagle'],
                             label='C-EAGLE',
                             edgecolor='k',
                             linewidth=1)
        patch_celre = Patch(facecolor=sim_colors['celr_e'],
                            label='CELR-E',
                            edgecolor='k',
                            linewidth=1)
        patch_celrb = Patch(facecolor=sim_colors['celr_b'],
                            label='CELR-B',
                            edgecolor='k',
                            linewidth=1)
        patch_macsis = Patch(facecolor=sim_colors['macsis'],
                             label='MACSIS',
                             edgecolor='k',
                             linewidth=1)

        leg2 = axis.legend(
            handles=[patch_ceagle, patch_celre, patch_celrb, patch_macsis],
            loc='lower center',
            handlelength=1,
            fontsize=20)
        axis.add_artist(leg2)
Exemple #17
0
def qq_gaussian(
    y_true: NumArray,
    y_pred: NumArray,
    y_std: NumArray | dict[str, NumArray],
    ax: Axes = None,
) -> Axes:
    """Plot the Gaussian quantile-quantile (Q-Q) plot of one (passed as array)
    or multiple (passed as dict) sets of uncertainty estimates for a single
    pair of ground truth targets `y_true` and model predictions `y_pred`.

    Overconfidence relative to a Gaussian distribution is visualized as shaded
    areas below the parity line, underconfidence (oversized uncertainties) as
    shaded areas above the parity line.

    The measure of calibration is how well the uncertainty percentiles conform
    to those of a normal distribution.

    Inspired by https://git.io/JufOz.
    Info on Q-Q plots: https://wikipedia.org/wiki/Q-Q_plot

    Args:
        y_true (array): ground truth targets
        y_pred (array): model predictions
        y_std (array | dict[str, array]): model uncertainties
        ax (Axes): matplotlib Axes on which to plot. Defaults to None.

    Returns:
        ax: The plot's matplotlib Axes.
    """
    if ax is None:
        ax = plt.gca()

    if isinstance(y_std, np.ndarray):
        y_std = {"std": y_std}

    res = np.abs(y_pred - y_true)
    resolution = 100

    lines = []  # collect plotted lines to show second legend with miscalibration areas
    for key, std in y_std.items():

        z_scored = (np.array(res) / std).reshape(-1, 1)

        exp_proportions = np.linspace(0, 1, resolution)
        gaussian_upper_bound = norm.ppf(0.5 + exp_proportions / 2)
        obs_proportions = np.mean(z_scored <= gaussian_upper_bound, axis=0)

        [line] = ax.plot(
            exp_proportions, obs_proportions, linewidth=2, alpha=0.8, label=key
        )
        ax.fill_between(
            exp_proportions, y1=obs_proportions, y2=exp_proportions, alpha=0.2
        )
        miscal_area = np.trapz(
            np.abs(obs_proportions - exp_proportions), dx=1 / resolution
        )
        lines.append([line, miscal_area])

    # identity line
    ax.axline((0, 0), (1, 1), alpha=0.5, zorder=0, linestyle="dashed", color="black")

    ax.set(xlim=(0, 1), ylim=(0, 1))
    ax.set(xlabel="Theoretical Quantile", ylabel="Observed Quantile")

    legend1 = ax.legend(loc="upper left", frameon=False)
    # Multiple legends on the same axes:
    # https://matplotlib.org/3.3.3/tutorials/intermediate/legend_guide.html#multiple-legends-on-the-same-axes
    ax.add_artist(legend1)

    lines, areas = zip(*lines)

    if len(lines) > 1:
        legend2 = ax.legend(
            lines,
            [f"{area:.2f}" for area in areas],
            title="Miscalibration areas",
            loc="lower right",
            ncol=2,
            frameon=False,
        )
        legend2._legend_box.align = "left"  # https://stackoverflow.com/a/44620643
    else:
        ax.legend(
            lines,
            [f"Miscalibration area: {areas[0]:.2f}"],
            loc="lower right",
            frameon=False,
        )

    return ax
Exemple #18
0
    def plot_z_trends(self, axis: Axes = None) -> None:

        if axis is None:
            axis = self.figure.add_subplot(111)

        cluster = Cluster(simulation_name=self.simulation.simulation_name,
                          clusterID=0,
                          redshift='z000p000')
        aperture_float = self.get_apertures(cluster)[
            self.aperture_id] / cluster.r200

        if not os.path.isfile(
                os.path.join(
                    self.path,
                    f'redshift_rot0rot4_bootstrap_aperture_{self.aperture_id}.npy'
                )):
            warnings.warn(
                f"File redshift_rot0rot4_bootstrap_aperture_{self.aperture_id}.npy not found."
            )
            print("self.make_simbootstrap() activated.")
            self.make_simbootstrap()

        print(
            f"Retrieving npy files: redshift_rot0rot4_bootstrap_aperture_{self.aperture_id}.npy"
        )
        sim_bootstrap = np.load(os.path.join(
            self.path, f'redshift_rot0rot4_bootstrap_aperture_'
            f'{self.aperture_id}.npy'),
                                allow_pickle=True)
        sim_bootstrap = np.asarray(sim_bootstrap)

        items_labels = f""" REDSHIFT TRENDS
							Number of clusters: {self.simulation.totalClusters:d}
							$z$ = 0.0 - 1.8
							Aperture radius = {aperture_float:.2f} $R_{{200\ true}}$"""
        print(items_labels)

        sim_colors = {
            'ceagle': 'pink',
            'celr_e': 'lime',
            'celr_b': 'orange',
            'macsis': 'aqua',
        }

        axis.axhline(90, linestyle='--', color='k', alpha=0.5, linewidth=2)

        axis.plot(sim_bootstrap[0, 0],
                  sim_bootstrap[3, 0],
                  color=sim_colors[self.simulation.simulation_name],
                  alpha=1,
                  linestyle='none',
                  marker='^',
                  markersize=10)
        axis.plot(sim_bootstrap[0, 0],
                  sim_bootstrap[2, 0],
                  color=sim_colors[self.simulation.simulation_name],
                  alpha=1,
                  linestyle='none',
                  marker='o',
                  markersize=10)
        axis.plot(sim_bootstrap[0, 0],
                  sim_bootstrap[1, 0],
                  color=sim_colors[self.simulation.simulation_name],
                  alpha=1,
                  linestyle='none',
                  marker='v',
                  markersize=10)

        for marker_index in range(len(sim_bootstrap[0, 0])):

            if marker_index is 0:
                align_toggle = 'edge'
                x_edge_left = sim_bootstrap[0, 0][marker_index]
                x_edge_right = sim_bootstrap[
                    0, 0][marker_index] + sim_bootstrap[0, 1][marker_index]
            else:
                align_toggle = 'center'
                x_edge_left = sim_bootstrap[
                    0, 0][marker_index] - sim_bootstrap[0, 1][marker_index] / 2
                x_edge_right = sim_bootstrap[
                    0, 0][marker_index] + sim_bootstrap[0, 1][marker_index] / 2

            axis.plot([x_edge_left, x_edge_right], [
                sim_bootstrap[3, 0][marker_index],
                sim_bootstrap[3, 0][marker_index]
            ],
                      color=sim_colors[self.simulation.simulation_name],
                      alpha=0.8,
                      linestyle='--',
                      lw=1.5)

            axis.plot([x_edge_left, x_edge_right], [
                sim_bootstrap[2, 0][marker_index],
                sim_bootstrap[2, 0][marker_index]
            ],
                      color=sim_colors[self.simulation.simulation_name],
                      alpha=0.8,
                      linestyle='-',
                      lw=1.5)

            axis.plot([x_edge_left, x_edge_right], [
                sim_bootstrap[1, 0][marker_index],
                sim_bootstrap[1, 0][marker_index]
            ],
                      color=sim_colors[self.simulation.simulation_name],
                      alpha=0.8,
                      linestyle='-.',
                      lw=1.5)

            axis.bar(sim_bootstrap[0, 0][marker_index],
                     2 * sim_bootstrap[3, 1][marker_index],
                     bottom=sim_bootstrap[3, 0][marker_index] -
                     sim_bootstrap[3, 1][marker_index],
                     width=sim_bootstrap[0, 1][marker_index],
                     align=align_toggle,
                     color=sim_colors[self.simulation.simulation_name],
                     alpha=0.2,
                     edgecolor='none',
                     linewidth=0)
            axis.bar(sim_bootstrap[0, 0][marker_index],
                     2 * sim_bootstrap[2, 1][marker_index],
                     bottom=sim_bootstrap[2, 0][marker_index] -
                     sim_bootstrap[2, 1][marker_index],
                     width=sim_bootstrap[0, 1][marker_index],
                     align=align_toggle,
                     color=sim_colors[self.simulation.simulation_name],
                     alpha=0.2,
                     edgecolor='none',
                     linewidth=0)
            axis.bar(sim_bootstrap[0, 0][marker_index],
                     2 * sim_bootstrap[1, 1][marker_index],
                     bottom=sim_bootstrap[1, 0][marker_index] -
                     sim_bootstrap[1, 1][marker_index],
                     width=sim_bootstrap[0, 1][marker_index],
                     align=align_toggle,
                     color=sim_colors[self.simulation.simulation_name],
                     alpha=0.2,
                     edgecolor='none',
                     linewidth=0)

        perc84 = Line2D([], [],
                        color='k',
                        marker='^',
                        linestyle='--',
                        markersize=10,
                        label=r'$84^{th}$ percentile')
        perc50 = Line2D([], [],
                        color='k',
                        marker='o',
                        linestyle='-',
                        markersize=10,
                        label=r'median')
        perc16 = Line2D([], [],
                        color='k',
                        marker='v',
                        linestyle='-.',
                        markersize=10,
                        label=r'$16^{th}$ percentile')
        patch_ceagle = Patch(facecolor=sim_colors['ceagle'],
                             label='C-EAGLE',
                             edgecolor='k',
                             linewidth=1)
        patch_celre = Patch(facecolor=sim_colors['celr_e'],
                            label='CELR-E',
                            edgecolor='k',
                            linewidth=1)
        patch_celrb = Patch(facecolor=sim_colors['celr_b'],
                            label='CELR-B',
                            edgecolor='k',
                            linewidth=1)
        patch_macsis = Patch(facecolor=sim_colors['macsis'],
                             label='MACSIS',
                             edgecolor='k',
                             linewidth=1)

        leg1 = axis.legend(handles=[perc84, perc50, perc16],
                           loc='lower right',
                           handlelength=3,
                           fontsize=20)
        leg2 = axis.legend(
            handles=[patch_ceagle, patch_celre, patch_celrb, patch_macsis],
            loc='lower left',
            handlelength=1,
            fontsize=20)
        axis.add_artist(leg1)
        axis.add_artist(leg2)
        axis.text(0.03,
                  0.97,
                  items_labels,
                  horizontalalignment='left',
                  verticalalignment='top',
                  transform=axis.transAxes,
                  size=15)

        axis.set_xlabel(r"$z$", size=25)
        axis.set_ylabel(
            r"$\Delta \theta \equiv (\mathbf{L},\mathrm{\widehat{CoP}},\mathbf{v_{pec}})$\quad[degrees]",
            size=25)
        axis.set_ylim(0, 180)
Exemple #19
0
    def _draw_grid_world(self, axis: Axes) -> None:

        draw_kwargs: Dict[str, Any] = dict(linestyle="-", color="k", alpha=0.5)

        col: int
        for col in range(self.width):
            axis.plot((col - 0.5) * np.ones(2), [-0.5, self.height - 0.5],
                      **draw_kwargs)

        axis.plot((self.width - 0.5) * np.ones(2), [-0.5, self.height - 0.5],
                  **draw_kwargs)

        row: int
        for row in range(self.height):
            axis.plot([-0.5, self.width - 0.5], (row - 0.5) * np.ones(2),
                      **draw_kwargs)

        axis.plot([-0.5, self.width - 0.5], (self.height - 0.5) * np.ones(2),
                  **draw_kwargs)

        axis.add_artist(
            plt.Circle(
                self.get_start_state(),
                radius=GridWorld.ARROW_LENGTH * 0.5 * 1.1,
                color="b",
                fill=False,
            ))

        for terminal_state in self.get_terminal_states():
            axis.add_artist(
                plt.Circle(
                    terminal_state,
                    radius=GridWorld.ARROW_LENGTH * 0.5 * 1.1,
                    color="k",
                    fill=True,
                ))

        xlim: Tuple[int, int] = [-1.0, self.width]
        ylim: Tuple[int, int] = [-1.0, self.height]
        # TODO adding typing from here

        if self.upward_wind_list:
            for col in range(self.width):
                axis.text(
                    col,
                    -1.0,
                    f"{self.upward_wind_list[col]:.1f}",
                    ha="center",
                    va="top",
                )
                ylim[0] = -1.5

        if self.rightward_wind_list:
            for row in range(self.height):
                axis.text(-1.0, row, f"{self.rightward_wind_list[row]:.1f}")
                xlim[0] = -1.5

        axis.set_xlim(xlim)
        axis.set_ylim(ylim)

        axis.axis("equal")
        axis.axis("off")
Exemple #20
0
def draw_regions1d(regions: RegionSet, plot: Axes, **kwargs):
    """
  Draws the Regions on a 1D plot, to visualize the
  overlapping or intersecting Regions (or intervals).

  Args:
    regions:  The set of 1D Regions to draw.
    plot:     The matplotlib plot to draw on.
    kwargs:   Additional arguments and options.

  Keyword Args:
    colored:
      Boolean flag for colored output or greyscale.
      If True, color codes the Regions based on the
      Region's stored 'color' data property. Otherwise,
      all Regions have black edges with transparent faces.
    communities:
      Boolean flag for whether or not to show the
      connected communities (or Regions with same color).
      Requires colored to be True.
    tightbounds:
      Boolean flag for whether or not to reduce the
      bounding size to the minimum bounding Region,
      instead of the defined bounds.
  """
    assert regions.dimension == 1

    black = (0, 0, 0)
    groups = {}

    colored = kwargs.get('colored', False)
    communities = kwargs.get('communities', False)
    tightbounds = kwargs.get('tightbounds', False)

    bbox = regions.bbox if tightbounds else regions.minbounds
    spacing = max(bbox[0].length / len(regions), 10)

    if colored and communities:
        for region in regions:
            color = region.getdata('color')
            if color is not None:
                group = groups.setdefault(tuple(color), RegionSet(dimension=1))
                group.add(region)

        for color, group in groups.items():
            gbbox = group.bbox[0]
            lows = (gbbox.lower, 0)
            w, h = (gbbox.length, spacing * (len(regions) + 2))

            rectangle = Rectangle(lows,
                                  w,
                                  h,
                                  facecolor=(*color, 0.05),
                                  edgecolor='none')
            rectangle.set_clip_box(plot)
            plot.add_artist(rectangle)

    for i, region in enumerate(regions):
        color = region.getdata('color', black) if colored else black
        plot.plot(list(astuple(region[0])), [spacing * (i + 1)] * 2,
                  color=color)

    plot.set_xlim(astuple(bbox[0]))
    plot.yaxis.set_visible(False)
Exemple #21
0
def draw_regions2d(regions: RegionSet, plot: Axes, **kwargs):
    """
  Draws the Regions on a 2D plot, to visualize the
  overlapping or intersecting Regions (or rectangles).

  Args:
    regions:  The set of 2D Regions to draw.
    plot:     The matplotlib plot to draw on.
    kwargs:   Additional arguments and options.

  Keyword Args:
    colored:
      Boolean flag for colored output or greyscale.
      If True, color codes the Regions based on the
      Region's stored 'color' data property. Otherwise,
      all Regions have black edges with transparent faces.
    communities:
      Boolean flag for whether or not to show the
      connected communities (or Regions with same color).
      Requires colored to be True.
    tightbounds:
      Boolean flag for whether or not to reduce the
      bounding size to the minimum bounding Region,
      instead of the defined bounds.
  """
    assert regions.dimension == 2

    black = (0, 0, 0)
    groups = {}

    colored = kwargs.get('colored', False)
    communities = kwargs.get('communities', False)
    tightbounds = kwargs.get('tightbounds', False)

    bbox = regions.bbox if tightbounds else regions.minbounds

    def mkrectangle(region: Region):
        lower = tuple(region[d].lower for d in range(2))
        w, h = tuple(region[d].length for d in range(2))

        return lower, w, h

    if colored and communities:
        for region in regions:
            color = region.getdata('color')
            if color is not None:
                group = groups.setdefault(tuple(color), RegionSet(dimension=2))
                group.add(region)

        for color, group in groups.items():
            rectangle = Rectangle(*mkrectangle(group.bbox),
                                  facecolor=(*color, 0.05),
                                  edgecolor='none')
            rectangle.set_clip_box(plot)
            plot.add_artist(rectangle)

    for region in regions:
        color = region.getdata('color', black) if colored else black
        rectangle = Rectangle(*mkrectangle(region),
                              facecolor=(*color, 0.1),
                              edgecolor=color)
        rectangle.set_clip_box(plot)
        plot.add_artist(rectangle)

    plot.set_xlim(astuple(bbox[0]))
    plot.set_ylim(astuple(bbox[1]))