コード例 #1
0
    def get_plot(
        self,
        plot_fd_tols: bool = False,
        plot_total_rate: bool = False,
        ymin: float = None,
        ymax: float = None,
        xmin: float = None,
        xmax: float = None,
        normalize_energy: bool = True,
        separate_rates: bool = True,
        doping_idx=0,
        temperature_idx=0,
        legend=True,
        total_color=None,
        show_dfde=False,
        plot_type="rate",
        title=True,
        axes=None,
        style=None,
        no_base_style=False,
        fonts=None,
    ):
        if normalize_energy and self.is_metal:
            norm_e = self.fermi_levels[0][0]
        elif normalize_energy:
            cb_idx = {s: v + 1 for s, v in self.vb_idx.items()}
            norm_e = np.max([self.energies[s][: cb_idx[s]] for s in self.spins])
        else:
            norm_e = 0

        if doping_idx is None and len(self.doping) == 1:
            doping_idx = 0

        if temperature_idx is None and len(self.temperatures) == 1:
            temperature_idx = 0

        if doping_idx is None and temperature_idx is None:
            ny = len(self.doping)
            nx = len(self.temperatures)
            p_idx = [[(x, y) for y in range(nx)] for x in range(ny)]
        elif doping_idx is None:
            nx = len(self.doping)
            ny = 1
            p_idx = [[(x, temperature_idx) for x in range(nx)]]
        elif temperature_idx is None:
            nx = len(self.temperatures)
            ny = 1
            p_idx = [[(doping_idx, x) for x in range(nx)]]
        else:
            nx = 1
            ny = 1
            p_idx = [[(doping_idx, temperature_idx)]]

        if axes is None:
            _, axes = plt.subplots(ny, nx, figsize=get_figsize(ny, nx))

        for y_idx, p_x_idx in enumerate(p_idx):
            for x_idx, (n, t) in enumerate(p_x_idx):
                if nx == 1 and ny == 1:
                    ax = axes
                elif ny == 1:
                    ax = axes[x_idx]
                else:
                    ax = axes[y_idx, x_idx]

                if x_idx == nx - 1 and y_idx == ny - 1 and legend:
                    show_legend = True
                else:
                    show_legend = False

                doping_fmt = fancy_format_doping(self.doping[n])
                temp_fmt = fancy_format_temp(self.temperatures[t])
                title_str = f"{doping_fmt}    {temp_fmt}"

                self.plot_rates_to_axis(
                    ax,
                    n,
                    t,
                    plot_type=plot_type,
                    separate_rates=separate_rates,
                    plot_total_rate=plot_total_rate,
                    plot_fd_tols=plot_fd_tols,
                    ymin=ymin,
                    ymax=ymax,
                    xmin=xmin,
                    xmax=xmax,
                    show_legend=show_legend,
                    legend_kwargs=_legend_kwargs,
                    normalize_energy=norm_e,
                    total_color=total_color,
                    show_dfde=show_dfde,
                )
                if title:
                    ax.set(title=title_str)

        return plt
コード例 #2
0
    def plot_property(
        self,
        ax,
        prop,
        x_property=None,
        doping_type=None,
        temperature_idx=None,
        doping_idx=None,
        ylabel=None,
        ymin=None,
        ymax=None,
        logy=None,
        xlabel=None,
        xmin=None,
        xmax=None,
        logx=None,
        labels=None,
    ):
        if temperature_idx is None and doping_idx is None:
            raise ValueError(
                "Either one of temperature-idx or doping-idx must be set")

        if temperature_idx is None:
            temperature_idx = np.arange(self.temperatures.shape[0])
        elif isinstance(temperature_idx, int):
            temperature_idx = [temperature_idx]
        temperatures = self.temperatures[temperature_idx]

        if doping_idx is None:
            doping_idx = np.arange(self.doping.shape[0])
        elif isinstance(doping_idx, int):
            doping_idx = [doping_idx]

        if doping_type == "n":
            doping_idx = [i for i in doping_idx if self.doping[i] <= 0]
        elif doping_type == "p":
            doping_idx = [i for i in doping_idx if self.doping[i] >= 0]
        doping = self.doping[doping_idx]

        if len(doping_idx) != 1 and len(temperature_idx) != 1:
            raise ValueError(
                "A specific temperature or doping index must be chosen")

        data = self._get_data(prop)

        if x_property is None and len(temperatures) == 1:
            x_property = "doping"
        elif x_property is None:
            x_property = "temperature"

        y = np.squeeze(data[:, doping_idx][:, :, temperature_idx])

        if x_property == "doping":
            annotation = fancy_format_temp(temperatures[0])
            x = doping
        elif x_property == "temperature":
            annotation = fancy_format_doping(doping[0])
            x = temperatures
            y = y
        else:
            raise ValueError(f"Unknown x_property: {x_property}")

        if np.any((x > 0) & (x < 0)):
            raise ValueError(
                "Cannot plot n- and p- type properties on the same figure."
                "Use doping-idx to select doping indices")
        x = np.abs(x)

        if labels is None:
            labels = [str(i) for i in range(self.n)]
        elif len(labels) != self.n:
            raise ValueError("Number of labels does not match number of data")

        cmap = cm.get_cmap("viridis_r")
        colors = cmap(np.linspace(0.05, 1, len(y)))

        for yi, label, color in zip(y, labels, colors):
            ax.plot(x, yi, label=label, c=color)

        ylabel = ylabel if ylabel else property_data[prop][self.label_key]
        xlabel = xlabel if xlabel else property_data[x_property][
            self.label_key]
        logy = logy if logy is not None else property_data[prop]["log"]
        logx = logx if logx is not None else property_data[x_property]["log"]
        ylim = get_lim(y, ymin, ymax, logy, self.pad)
        xlim = get_lim(x, xmin, xmax, logx, self.pad)

        if logy:
            ax.semilogy()
        if logx:
            ax.semilogx()
        ax.set(ylabel=ylabel, xlabel=xlabel, ylim=ylim, xlim=xlim)
        return annotation
コード例 #3
0
    def plot_mobility(
        self,
        ax,
        x_property,
        primary_idx,
        secondary_idxs,
        xlabel=None,
        xmin=None,
        xmax=None,
        logx=None,
        ylabel=None,
        ymin=None,
        ymax=None,
        logy=None,
        title=True,
        total_color=None,
    ):
        if x_property == "temperature":
            labels, y = self._get_data(primary_idx, secondary_idxs)
            x = self.temperatures[secondary_idxs]
            title_str = fancy_format_doping(self.doping[primary_idx])
        elif x_property == "doping":
            labels, y = self._get_data(secondary_idxs, primary_idx)
            x = self.doping[secondary_idxs]
            if np.any(x < 0) and np.any(x > 0):
                warnings.warn(
                    "You are plotting both n- and p-type carrier concentrations on the "
                    "same figure. Try using the --n-type and --p-type options instead."
                )
            x = np.abs(self.doping[secondary_idxs])
            title_str = fancy_format_temp(self.temperatures[primary_idx])
        else:
            raise ValueError(f"Unrecognised x_property: {x_property}")

        for i, (yi, label) in enumerate(zip(y, labels)):
            label = label.replace("overall", "total")
            if label == "total":
                color = base_total_color if total_color is None else total_color
            else:
                color = f"C{i}"

            if self.average:
                ax.plot(x, yi, label=label, c=color)
            else:
                for j in range(3):
                    ax.plot(
                        x,
                        yi[:, j],
                        label=f"{dir_mapping[j]} {label}",
                        c=color,
                        ls=ls_mapping[j],
                    )

        ylabel = ylabel if ylabel else _property_data["mobility"][
            self.label_key]
        xlabel = xlabel if xlabel else _property_data[x_property][
            self.label_key]
        logy = logy if logy is not None else _property_data["mobility"]["log"]
        logx = logx if logx is not None else _property_data[x_property]["log"]
        ylim = get_lim(y, ymin, ymax, logy, self.pad)
        xlim = get_lim(x, xmin, xmax, logx, self.pad)

        if logy:
            ax.semilogy()
        if logx:
            ax.semilogx()

        if not title:
            title_str = None

        ax.set(ylabel=ylabel,
               xlabel=xlabel,
               ylim=ylim,
               xlim=xlim,
               title=title_str)