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
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
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)