def style_figure(fig: matplotlib.figure.Figure, title: str, bottom: float = 0.2) -> None: """Stylize the supplied matplotlib Figure instance.""" fig.tight_layout() if bottom is not None: fig.subplots_adjust(bottom=bottom) fig.suptitle(title) fig.legend(ncol=10, handlelength=0.75, handletextpad=0.25, columnspacing=0.5, loc='lower left')
def multi_nyquist_title(fig: matplotlib.figure.Figure, params: paramsTup, settings) -> matplotlib.figure.Figure: # plt.figure(fig) # make sure fig is focus (filename_strip, solv, elec, ref_elec, work_elec, voltage) = params elec = "TBFTFB" fig.suptitle( f"Nyquist plots of {work_elec} in {elec} ({solv}) vs {ref_elec} reference", y=0.98) # xmin, xmax = plt.xlim() # pylint: disable=W0612 # expt_vars = f"WE = {work_elec} \nRE = {ref_elec} \nElectrolyte = {elec} \nSolvent = {solv}" # fig.text(xmax * 1.1, 0, expt_vars, fontdict=settings, withdash=False) return fig
def add_metric_description_title(df_plot: pd.DataFrame, fig: mpl.figure.Figure, y: float = 1.0): """Adds a suptitle to the figure, describing the metric used.""" assert df_plot.Metric.nunique() == 1, "More than one metric in DataFrame." binning_scheme = utils.assert_and_get_constant(df_plot.binning_scheme) num_bins = utils.assert_and_get_constant(df_plot.num_bins) norm = utils.assert_and_get_constant(df_plot.norm) title = (f"ECE variant: {binning_scheme} binning, " f"{num_bins:.0f} bins, " f"{norm} norm") display_names = { "adaptive": "equal-mass", "even": "equal-width", "l1": "L1", "l2": "L2", } for old, new in display_names.items(): title = title.replace(old, new) fig.suptitle(title, y=y, verticalalignment="bottom")
def plot_avg_decay_data(t_sol: Union[np.ndarray, List[np.array]], list_sim_data: List[np.array], list_exp_data: List[np.array] = None, state_labels: List[str] = None, concentration: Conc = None, atol: float = A_TOL, colors: Union[str, Tuple[ColorMap, ColorMap]] = 'rk', fig: mpl.figure.Figure = None, title: str = '') -> None: ''' Plot the list of simulated and experimental data (optional) against time in t_sol. If concentration is given, the legend will show the concentrations. colors is a string with two chars. The first is the sim color, the second the exp data color. ''' num_plots = len(list_sim_data) num_rows = 3 num_cols = int(np.ceil(num_plots / 3)) # optional lists default to list of None list_exp_data = list_exp_data or [None] * num_plots state_labels = state_labels or [''] * num_plots list_t_sim = t_sol if len( t_sol) == num_plots else [t_sol] * num_plots # type: List[np.array] if concentration: conc_str = '_' + str(concentration.S_conc) + 'S_' + str( concentration.A_conc) + 'A' # state_labels = [label+conc_str for label in state_labels] else: conc_str = '' sim_color = colors[0] exp_color = colors[1] exp_size = 2 # marker size exp_marker = '.' if fig is None: fig = plt.figure() fig.suptitle(title + '. Time in ms.') list_axes = fig.get_axes() # type: List if not list_axes: for num in range(num_plots): fig.add_subplot(num_rows, num_cols, num + 1) list_axes = fig.get_axes() for sim_data, t_sim, exp_data, state_label, axes\ in zip(list_sim_data, list_t_sim, list_exp_data, state_labels, list_axes): if state_label: axes.set_title( state_label.replace('_', ' '), { 'horizontalalignment': 'center', 'verticalalignment': 'center', 'fontweight': 'bold', 'fontsize': 10 }) if sim_data is None or np.isnan(sim_data).any() or not np.any( sim_data > 0): continue # no exp data: either a GS or simply no exp data available if exp_data is 0 or exp_data is None: # nonposy='clip': clip non positive values to a very small positive number axes.semilogy(t_sim * 1000, sim_data, color=sim_color, label=state_label + conc_str) axes.axis('tight') axes.set_xlim(left=t_sim[0] * 1000.0) # add some white space above and below margin_factor = np.array([0.7, 1.3]) axes.set_ylim(*np.array(axes.get_ylim()) * margin_factor) if axes.set_ylim()[0] < atol: axes.set_ylim(bottom=atol) # don't show noise below atol # detect when the simulation goes above and below atol above = sim_data > atol change_indices = np.where(np.roll(above, 1) != above)[0] # make sure change_indices[-1] happens when the population is going BELOW atol if change_indices.size > 1 and sim_data[ change_indices[-1]] < atol: # pragma: no cover # last time it changes max_index = change_indices[-1] # show simData until it falls below atol axes.set_xlim(right=t_sim[max_index] * 1000) min_y = min(*axes.get_ylim()) max_y = max(*axes.get_ylim()) axes.set_ylim(bottom=min_y, top=max_y) else: # exp data available sim_handle, = axes.semilogy(t_sim * 1000, sim_data, color=sim_color, label=state_label + conc_str, zorder=10) # convert exp_data time to ms exp_handle, = axes.semilogy(exp_data[:, 0] * 1000, exp_data[:, 1] * np.max(sim_data), color=exp_color, marker=exp_marker, linewidth=0, markersize=exp_size, zorder=1) axes.axis('tight') axes.set_ylim(top=axes.get_ylim()[1] * 1.2) # add some white space on top tmin = min(exp_data[-1, 0], t_sim[0]) axes.set_xlim(left=tmin * 1000.0, right=exp_data[-1, 0] * 1000) # don't show beyond expData if conc_str: list_axes[0].legend(loc="best", fontsize='small') curr_handles, curr_labels = list_axes[0].get_legend_handles_labels() new_labels = [ label.replace(state_labels[0] + '_', '').replace('_', ', ') for label in curr_labels ] list_axes[0].legend(curr_handles, new_labels, markerscale=5, loc="best", fontsize='small') fig.subplots_adjust(top=0.918, bottom=0.041, left=0.034, right=0.99, hspace=0.275, wspace=0.12)