Example #1
0
    def get_plot(
        self,
        properties=("conductivity", "seebeck", "thermal conductivity"),
        x_property=None,
        doping_idx=None,
        temperature_idx=None,
        grid=None,
        height=None,
        width=None,
        doping_type=None,
        conductivity_label=None,
        conductivity_min=None,
        conductivity_max=None,
        log_conductivity=None,
        seebeck_label=None,
        seebeck_min=None,
        seebeck_max=None,
        log_seebeck=None,
        mobility_label=None,
        mobility_min=None,
        mobility_max=None,
        log_mobility=None,
        thermal_conductivity_label=None,
        thermal_conductivity_min=None,
        thermal_conductivity_max=None,
        log_thermal_conductivity=None,
        power_factor_label=None,
        power_factor_min=None,
        power_factor_max=None,
        log_power_factor=None,
        xlabel=None,
        xmin=None,
        xmax=None,
        logx=None,
        legend=True,
        axes=None,
        return_plot_data=False,
        plt=None,
        style=None,
        no_base_style=False,
        fonts=None,
    ):

        if axes is None:
            if grid is None or len(grid) == 0:
                grid = (1, len(properties))

            if np.product(grid) < len(properties):
                raise ValueError(
                    "Grid is not large enough to plot all properties")

            width, height = get_figsize(*grid, width=width, height=height)
            _, axes = pretty_subplot(*grid, width=width, height=height)
        else:
            if not isinstance(axes, (list, tuple, np.ndarray)):
                # single axis given
                grid = (1, 1)
            else:
                axes = np.array(axes)
                if grid is None:
                    grid = axes.shape
                    if len(grid) == 1:
                        grid = (1, grid[0])

            if np.product(grid) < len(properties):
                raise ValueError("Not enough axes to plot all properties")

        if doping_type is not None and doping_idx is not None:
            warnings.warn(
                "Both doping type and doping indexes have been set. This can cause "
                "unexpected behaviour.")

        prop_dict = {
            "conductivity": {
                "ylabel": conductivity_label,
                "ymin": conductivity_min,
                "ymax": conductivity_max,
                "logy": log_conductivity,
            },
            "mobility": {
                "ylabel": mobility_label,
                "ymin": mobility_min,
                "ymax": mobility_max,
                "logy": log_mobility,
            },
            "seebeck": {
                "ylabel": seebeck_label,
                "ymin": seebeck_min,
                "ymax": seebeck_max,
                "logy": log_seebeck,
            },
            "thermal conductivity": {
                "ylabel": thermal_conductivity_label,
                "ymin": thermal_conductivity_min,
                "ymax": thermal_conductivity_max,
                "logy": log_thermal_conductivity,
            },
            "power factor": {
                "ylabel": power_factor_label,
                "ymin": power_factor_min,
                "ymax": power_factor_max,
                "logy": log_power_factor,
            },
        }

        if np.product(grid) > len(properties):
            n_missing = np.product(grid) - len(properties)
            properties = list(properties) + [None] * n_missing

        plot_data = []
        for (x, y), prop in zip(np.ndindex(grid), properties):
            if grid[0] == 1 and grid[1] == 1:
                ax = axes
            elif grid[0] == 1:
                ax = axes[y]
            elif grid[1] == 1:
                ax = axes[x]
            else:
                ax = axes[x, y]

            if prop is None:
                ax.axis("off")

            else:
                prop_data = self.plot_property(
                    ax,
                    prop,
                    x_property=x_property,
                    temperature_idx=temperature_idx,
                    doping_idx=doping_idx,
                    doping_type=doping_type,
                    xmin=xmin,
                    xmax=xmax,
                    xlabel=xlabel,
                    logx=logx,
                    **prop_dict[prop],
                )
                plot_data.append(prop_data)

        if legend:
            if grid[0] == 1 and grid[1] == 1:
                ax = axes
            elif grid[0] == 1:
                ax = axes[-1]
            elif grid[1] == 1:
                ax = axes[0]
            else:
                ax = axes[0, -1]
            ax.legend(loc="upper left", bbox_to_anchor=(1.01, 1), ncol=1)

        if return_plot_data:
            return matplotlib.pyplot, plot_data

        return matplotlib.pyplot
Example #2
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
Example #3
0
    def get_plot(
        self,
        doping_idx=None,
        temperature_idx=None,
        properties=("conductivity", "seebeck", "thermal conductivity"),
        labels=None,
        x_property=None,
        grid=None,
        height=None,
        width=None,
        doping_type=None,
        conductivity_label=None,
        conductivity_min=None,
        conductivity_max=None,
        log_conductivity=None,
        seebeck_label=None,
        seebeck_min=None,
        seebeck_max=None,
        log_seebeck=None,
        mobility_label=None,
        mobility_min=None,
        mobility_max=None,
        log_mobility=None,
        thermal_conductivity_label=None,
        thermal_conductivity_min=None,
        thermal_conductivity_max=None,
        log_thermal_conductivity=None,
        power_factor_label=None,
        power_factor_min=None,
        power_factor_max=None,
        log_power_factor=None,
        xlabel=None,
        xmin=None,
        xmax=None,
        logx=None,
        legend=True,
        axes=None,
        plt=None,
        style=None,
        no_base_style=False,
        fonts=None,
    ):
        if axes is None:
            if grid is None or len(grid) == 0:
                grid = (1, len(properties))

            if np.product(grid) < len(properties):
                raise ValueError(
                    "Grid is not large enough to plot all properties")

            width, height = get_figsize(*grid, width=width, height=height)
            _, axes = pretty_subplot(*grid, width=width, height=height)
        else:
            if not isinstance(axes, (list, tuple, np.ndarray)):
                # single axis given
                grid = (1, 1)
            else:
                axes = np.array(axes)
                if grid is None:
                    grid = axes.shape
                    if len(grid) == 1:
                        grid = (1, grid[0])

            if np.product(grid) < len(properties):
                raise ValueError("Not enough axes to plot all properties")

        if doping_type is not None and doping_idx is not None:
            warnings.warn(
                "Both doping type and doping indexes have been set. This can cause "
                "unexpected behaviour.")

        if temperature_idx is None and doping_idx is None:
            if len(self.doping) == 1 or x_property == "temperature":
                warnings.warn(
                    "Either one of temperature-idx or doping-idx should be "
                    "set. Using doping-idx of 0")
                if doping_type:
                    if doping_type == "n":
                        doping_idx = [
                            i for i, d in enumerate(self.doping) if d <= 0
                        ]
                    else:
                        doping_idx = [
                            i for i, d in enumerate(self.doping) if d >= 0
                        ]
                    if len(doping_idx) == 0:
                        raise ValueError(
                            f"{doping_type}-type doping specified but no doping "
                            f"concentrations of this type are in the calculations"
                        )
                    else:
                        doping_idx = doping_idx[0]
                else:
                    doping_idx = [0]
            else:
                warnings.warn(
                    "Either one of temperature-idx or doping-idx should be "
                    "set. Using temperature-idx of 0")
                temperature_idx = [0]

        prop_dict = {
            "conductivity": {
                "ylabel": conductivity_label,
                "ymin": conductivity_min,
                "ymax": conductivity_max,
                "logy": log_conductivity,
            },
            "mobility": {
                "ylabel": mobility_label,
                "ymin": mobility_min,
                "ymax": mobility_max,
                "logy": log_mobility,
            },
            "seebeck": {
                "ylabel": seebeck_label,
                "ymin": seebeck_min,
                "ymax": seebeck_max,
                "logy": log_seebeck,
            },
            "thermal conductivity": {
                "ylabel": thermal_conductivity_label,
                "ymin": thermal_conductivity_min,
                "ymax": thermal_conductivity_max,
                "logy": log_thermal_conductivity,
            },
            "power factor": {
                "ylabel": power_factor_label,
                "ymin": power_factor_min,
                "ymax": power_factor_max,
                "logy": log_power_factor,
            },
        }

        title = None
        for (x, y), prop in zip(np.ndindex(grid), properties):
            if grid[0] == 1 and grid[1] == 1:
                ax = axes
            elif grid[0] == 1:
                ax = axes[y]
            elif grid[1] == 1:
                ax = axes[x]
            else:
                ax = axes[x, y]

            title = self.plot_property(
                ax,
                prop,
                x_property=x_property,
                doping_type=doping_type,
                temperature_idx=temperature_idx,
                doping_idx=doping_idx,
                xmin=xmin,
                xmax=xmax,
                xlabel=xlabel,
                logx=logx,
                labels=labels,
                **prop_dict[prop],
            )

        if legend:
            if grid[0] == 1 and grid[1] == 1:
                ax = axes
            elif grid[0] == 1:
                ax = axes[-1]
            elif grid[1] == 1:
                ax = axes[0]
            else:
                ax = axes[0, -1]
            ax.legend(loc="upper left",
                      bbox_to_anchor=(1.01, 1),
                      ncol=1,
                      title=title)

        return matplotlib.pyplot
Example #4
0
    def get_plot(
        self,
        x_property=None,
        doping_idx=None,
        temperature_idx=None,
        doping_type=None,
        grid=None,
        height=None,
        width=None,
        ylabel=None,
        ymin=None,
        ymax=None,
        logy=None,
        xlabel=None,
        xmin=None,
        xmax=None,
        logx=None,
        legend=True,
        title=True,
        total_color=None,
        axes=None,
        style=None,
        no_base_style=False,
        fonts=None,
    ):
        if doping_type is not None and doping_idx is not None:
            warnings.warn(
                "Both doping type and doping indexes have been set. This can cause "
                "unexpected behaviour.")

        if temperature_idx is None:
            temperature_idx = np.arange(self.temperatures.shape[0])
        elif isinstance(temperature_idx, int):
            temperature_idx = [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]

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

        if x_property == "doping":
            if grid is None or len(grid) == 0:
                grid = (1, len(temperature_idx))
            primary_idxs = temperature_idx
            secondary_idxs = doping_idx
        elif x_property == "temperature":
            if grid is None or len(grid) == 0:
                grid = (1, len(doping_idx))
            primary_idxs = doping_idx
            secondary_idxs = temperature_idx
        else:
            raise ValueError(f"Unrecognised x_property: {x_property}")

        if axes is None:
            width, height = get_figsize(*grid, width=width, height=height)
            _, axes = pretty_subplot(*grid, width=width, height=height)
        else:
            if not isinstance(axes, (list, tuple, np.ndarray)):
                # single axis given
                grid = (1, 1)
            else:
                axes = np.array(axes)
                if grid is None:
                    grid = axes.shape
                    if len(grid) == 1:
                        grid = (1, grid[0])

            if len(primary_idxs) > np.product(grid):
                raise ValueError(
                    "Axes array not commensurate with doping_idx and temperature_idx"
                )

        for (x, y), primary_idx in zip(np.ndindex(grid), primary_idxs):
            if grid[0] == 1 and grid[1] == 1:
                ax = axes
            elif grid[0] == 1:
                ax = axes[y]
            elif grid[1] == 1:
                ax = axes[x]
            else:
                ax = axes[x, y]

            self.plot_mobility(
                ax,
                x_property,
                primary_idx,
                secondary_idxs,
                xlabel=xlabel,
                xmin=xmin,
                xmax=xmax,
                logx=logx,
                ylabel=ylabel,
                ymin=ymin,
                ymax=ymax,
                logy=logy,
                title=title,
                total_color=total_color,
            )
            ax.set()

        if legend and (self.separate_mobility or not self.average):
            if grid[0] == 1 and grid[1] == 1:
                ax = axes
            elif grid[0] == 1:
                ax = axes[-1]
            elif grid[1] == 1:
                ax = axes[0]
            else:
                ax = axes[0, -1]
            ax.legend(loc="upper left", bbox_to_anchor=(1.01, 1), ncol=1)

        return matplotlib.pyplot