Example #1
0
    def plot(self, ax=None, sed_type="dnde", energy_power=0, **kwargs):
        """Plot flux points.

        Parameters
        ----------
        ax : `~matplotlib.axes.Axes`
            Axis object to plot on.
        sed_type : {"dnde", "flux", "eflux", "e2dnde"}
            Sed type
        energy_power : float
            Power of energy to multiply flux axis with
        **kwargs : dict
            Keyword arguments passed to `~RegionNDMap.plot`

        Returns
        -------
        ax : `~matplotlib.axes.Axes`
            Axis object
        """
        import matplotlib.pyplot as plt

        if not self.norm.geom.is_region:
            raise ValueError(
                "Plotting only supported for region based flux points")

        if ax is None:
            ax = plt.gca()

        flux_unit = DEFAULT_UNIT[sed_type]

        flux = getattr(self, sed_type)

        # get errors and ul
        y_errn, y_errp = self._plot_get_flux_err(sed_type=sed_type)

        is_ul = self.is_ul.data
        if np.isnan(is_ul.data).all() and y_errn and is_ul.any():
            flux_ul = getattr(self, sed_type + "_ul").quantity
            y_errn.data[is_ul] = 0.5 * flux_ul[is_ul].to_value(y_errn.unit)
            y_errp.data[is_ul] = 0
            flux.data[is_ul] = flux_ul[is_ul].to_value(flux.unit)

        # set flux points plotting defaults
        if y_errp:
            y_errp = scale_plot_flux(y_errp,
                                     energy_power=energy_power).quantity

        if y_errn:
            y_errn = scale_plot_flux(y_errn,
                                     energy_power=energy_power).quantity

        kwargs.setdefault("yerr", (y_errn, y_errp))
        kwargs.setdefault("uplims", is_ul)

        flux = scale_plot_flux(flux=flux.to_unit(flux_unit),
                               energy_power=energy_power)
        ax = flux.plot(ax=ax, **kwargs)
        ax.set_ylabel(f"{sed_type} ({ax.yaxis.units})")
        ax.set_yscale("log")
        return ax
Example #2
0
    def plot(self,
             ax=None,
             energy_unit="TeV",
             flux_unit=None,
             energy_power=0,
             sed_type="dnde",
             **kwargs):
        """Plot flux points.

        Parameters
        ----------
        ax : `~matplotlib.axes.Axes`
            Axis object to plot on.
        energy_unit : str, `~astropy.units.Unit`, optional
            Unit of the energy axis
        flux_unit : str, `~astropy.units.Unit`, optional
            Unit of the flux axis
        energy_power : int
            Power of energy to multiply y axis with
        sed_type : {"dnde", "flux", "eflux", "e2dnde"}
            Sed type
        kwargs : dict
            Keyword arguments passed to :func:`matplotlib.pyplot.errorbar`

        Returns
        -------
        ax : `~matplotlib.axes.Axes`
            Axis object
        """
        if not self.norm.geom.is_region:
            raise ValueError("Plotting only supported for flux points")

        import matplotlib.pyplot as plt

        if ax is None:
            ax = plt.gca()

        if flux_unit is None:
            flux_unit = DEFAULT_UNIT[sed_type]

        flux = getattr(self, sed_type).quantity[:, 0, 0]
        energy = self.energy_ref.to(energy_unit)

        # get errors and ul
        is_ul = self.is_ul.data.squeeze()
        x_err = self.energy_axis.as_xerr
        y_errn, y_errp = self._plot_get_flux_err(sed_type=sed_type)

        if y_errn:
            if is_ul.any():
                flux_ul = getattr(self, sed_type + "_ul").quantity[:, 0, 0]
                y_errn[is_ul] = 0.5 * flux_ul[is_ul]
                y_errp[is_ul] = 0
                flux[is_ul] = flux_ul[is_ul]

            y_errn = scale_plot_flux(energy=energy,
                                     flux=y_errn.to(flux_unit),
                                     energy_power=energy_power)
            y_errp = scale_plot_flux(energy=energy,
                                     flux=y_errp.to(flux_unit),
                                     energy_power=energy_power)

        # set flux points plotting defaults
        kwargs.setdefault("marker", "+")
        kwargs.setdefault("ls", "None")

        flux = scale_plot_flux(energy=energy,
                               flux=flux.to(flux_unit),
                               energy_power=energy_power)

        with quantity_support():
            ax.errorbar(energy,
                        flux,
                        yerr=(y_errn, y_errp),
                        xerr=x_err,
                        uplims=is_ul,
                        **kwargs)

        ax.set_xscale("log", nonpositive="clip")
        ax.set_yscale("log", nonpositive="clip")
        ax.set_xlabel(f"Energy ({energy_unit})")
        ax.set_ylabel(f"{sed_type} ({flux.unit})")
        return ax