Пример #1
0
    def plot(self, ax: matplotlib.axes.Axes):
        # individual points
        ax.scatter(self.mean, self.diff, s=20, alpha=0.6, color=self.color_points,
                   **self.point_kws)

        # mean difference and SD lines
        ax.axhline(self.mean_diff, color=self.color_mean, linestyle='-')
        ax.axhline(self.mean_diff + self.loa_sd, color=self.color_loa, linestyle='--')
        ax.axhline(self.mean_diff - self.loa_sd, color=self.color_loa, linestyle='--')

        if self.reference:
            ax.axhline(0, color='grey', linestyle='-', alpha=0.4)

        # confidence intervals (if requested)
        if self.CI is not None:
            ax.axhspan(self.CI_mean[0],  self.CI_mean[1], color=self.color_mean, alpha=0.2)
            ax.axhspan(self.CI_upper[0], self.CI_upper[1], color=self.color_loa, alpha=0.2)
            ax.axhspan(self.CI_lower[0], self.CI_lower[1], color=self.color_loa, alpha=0.2)

        # text in graph
        trans: matplotlib.transform = transforms.blended_transform_factory(
            ax.transAxes, ax.transData)
        offset: float = (((self.loa * self.sd_diff) * 2) / 100) * 1.2
        ax.text(0.98, self.mean_diff + offset, 'Mean', ha="right", va="bottom", transform=trans)
        ax.text(0.98, self.mean_diff - offset, f'{self.mean_diff:.2f}', ha="right", va="top", transform=trans)
        ax.text(0.98, self.mean_diff + self.loa_sd + offset,
                f'+{self.loa:.2f} SD', ha="right", va="bottom", transform=trans)
        ax.text(0.98, self.mean_diff + self.loa_sd - offset,
                f'{self.mean_diff + self.loa_sd:.2f}', ha="right", va="top", transform=trans)
        ax.text(0.98, self.mean_diff - self.loa_sd - offset,
                f'-{self.loa:.2f} SD', ha="right", va="top", transform=trans)
        ax.text(0.98, self.mean_diff - self.loa_sd + offset,
                f'{self.mean_diff - self.loa_sd:.2f}', ha="right", va="bottom", transform=trans)

        # transform graphs
        ax.spines['right'].set_visible(False)
        ax.spines['top'].set_visible(False)

        # set X and Y limits
        if self.xlim is not None:
            ax.set_xlim(self.xlim[0], self.xlim[1])
        if self.ylim is not None:
            ax.set_ylim(self.ylim[0], self.ylim[1])

        # graph labels
        ax.set_ylabel(self.y_title)
        ax.set_xlabel(self.x_title)
        if self.graph_title is not None:
            ax.set_title(self.graph_title)
Пример #2
0
    def plot(
        self,
        x_label: str = "Mean of methods",
        y_label: str = "Difference between methods",
        graph_title: str = None,
        reference: bool = False,
        xlim: Tuple = None,
        ylim: Tuple = None,
        color_mean: str = "#008bff",
        color_loa: str = "#FF7000",
        color_points: str = "#000000",
        point_kws: Dict = None,
        ci_alpha: float = 0.2,
        loa_linestyle: str = "--",
        ax: matplotlib.axes.Axes = None,
    ):
        """Provide a method comparison using Bland-Altman plotting.
        This is an Axis-level function which will draw the Bland-Altman plot
        onto the current active Axis object unless ``ax`` is provided.
        Parameters
        ----------
        x_label : str, optional
            The label which is added to the X-axis. If None is provided, a standard
            label will be added.
        y_label : str, optional
            The label which is added to the Y-axis. If None is provided, a standard
            label will be added.
        graph_title : str, optional
            Title of the Bland-Altman plot.
            If None is provided, no title will be plotted.
        reference : bool, optional
            If True, a grey reference line at y=0 will be plotted in the Bland-Altman.
        xlim : list, optional
            Minimum and maximum limits for X-axis. Should be provided as list or tuple.
            If not set, matplotlib will decide its own bounds.
        ylim : list, optional
            Minimum and maximum limits for Y-axis. Should be provided as list or tuple.
            If not set, matplotlib will decide its own bounds.
        color_mean : str, optional
            Color of the mean difference line that will be plotted.
        color_loa : str, optional
            Color of the limit of agreement lines that will be plotted.
        color_points : str, optional
            Color of the individual differences that will be plotted.
        point_kws : dict of key, value mappings, optional
            Additional keyword arguments for `plt.scatter`.
        ci_alpha: float, optional
            Alpha value of the confidence interval.
        loa_linestyle: str, optional
            Linestyle of the limit of agreement lines.
        ax : matplotlib Axes, optional
            Axes in which to draw the plot, otherwise use the currently-active
            Axes.

        Returns
        -------
        ax : matplotlib Axes
            Axes object with the Bland-Altman plot.
        """

        ax = ax or plt.gca()

        pkws = self.DEFAULT_POINTS_KWS.copy()
        pkws.update(point_kws or {})

        # Get parameters
        mean, mean_CI = self.result["mean"], self.result["mean_CI"]
        loa_upper, loa_upper_CI = self.result["loa_upper"], self.result[
            "loa_upper_CI"]
        loa_lower, loa_lower_CI = self.result["loa_lower"], self.result[
            "loa_lower_CI"]
        sd_diff = self.result["sd_diff"]

        # individual points
        ax.scatter(self.mean, self.diff, **pkws)

        # mean difference and SD lines
        ax.axhline(mean, color=color_mean, linestyle=loa_linestyle)
        ax.axhline(loa_upper, color=color_loa, linestyle=loa_linestyle)
        ax.axhline(loa_lower, color=color_loa, linestyle=loa_linestyle)

        if reference:
            ax.axhline(0, color="grey", linestyle="-", alpha=0.4)

        # confidence intervals (if requested)
        if self.CI is not None:
            ax.axhspan(*mean_CI, color=color_mean, alpha=ci_alpha)
            ax.axhspan(*loa_upper_CI, color=color_loa, alpha=ci_alpha)
            ax.axhspan(*loa_lower_CI, color=color_loa, alpha=ci_alpha)

        # text in graph
        trans: matplotlib.transform = transforms.blended_transform_factory(
            ax.transAxes, ax.transData)
        offset: float = (((self.loa * sd_diff) * 2) / 100) * 1.2
        ax.text(
            0.98,
            mean + offset,
            "Mean",
            ha="right",
            va="bottom",
            transform=trans,
        )
        ax.text(
            0.98,
            mean - offset,
            f"{mean:.2f}",
            ha="right",
            va="top",
            transform=trans,
        )
        ax.text(
            0.98,
            loa_upper + offset,
            f"+{self.loa:.2f} SD",
            ha="right",
            va="bottom",
            transform=trans,
        )
        ax.text(
            0.98,
            loa_upper - offset,
            f"{loa_upper:.2f}",
            ha="right",
            va="top",
            transform=trans,
        )
        ax.text(
            0.98,
            loa_lower - offset,
            f"-{self.loa:.2f} SD",
            ha="right",
            va="top",
            transform=trans,
        )
        ax.text(
            0.98,
            loa_lower + offset,
            f"{loa_lower:.2f}",
            ha="right",
            va="bottom",
            transform=trans,
        )

        # transform graphs
        ax.spines["right"].set_visible(False)
        ax.spines["top"].set_visible(False)

        # set X and Y limits
        if xlim is not None:
            ax.set_xlim(xlim[0], xlim[1])
        if ylim is not None:
            ax.set_ylim(ylim[0], ylim[1])

        # graph labels
        ax.set(xlabel=x_label, ylabel=y_label, title=graph_title)

        return ax