def file_vs_value_plot( a_x: Axis, field_name: str, row: pd.DataFrame, range_columns: List[str], fontsize: float, pad: float ) -> None: """Create a dot plot with one point per file""" assert field_name in ["rt_peak", "peak_height"] a_x.tick_params(direction="in", length=1, pad=pad, width=0.1, labelsize=fontsize) num_files = len(range_columns) a_x.scatter(range(num_files), row[:num_files], s=0.2) if field_name == "rt_peak": a_x.axhline(y=row["atlas RT peak"], color="r", linestyle="-", linewidth=0.2) range_columns += ["atlas RT peak"] a_x.set_ylim(np.nanmin(row.loc[range_columns]) - 0.12, np.nanmax(row.loc[range_columns]) + 0.12) else: a_x.set_yscale("log") a_x.set_ylim(bottom=1e4, top=1e10) a_x.set_xlim(-0.5, num_files + 0.5) a_x.xaxis.set_major_locator(mticker.FixedLocator(np.arange(0, num_files, 1.0))) _ = [s.set_linewidth(0.1) for s in a_x.spines.values()] # truncate name so it fits above a single subplot a_x.set_title(row.name[:33], pad=pad, fontsize=fontsize) a_x.set_xlabel("Files", labelpad=pad, fontsize=fontsize) ylabel = "Actual RTs" if field_name == "rt_peak" else "Peak Height" a_x.set_ylabel(ylabel, labelpad=pad, fontsize=fontsize)
def plot_data_and_fits( result: ResultLike, wavelength: float, axis: Axis, center_λ: float | None = None, main_irf_nr: int = 0, linlog: bool = False, linthresh: float = 1, divide_by_scale: bool = True, per_axis_legend: bool = False, y_label: str = "a.u.", cycler: Cycler | None = PlotStyle().data_cycler_solid, ) -> None: """Plot data and fits for a given ``wavelength`` on a given ``axis``. If the wavelength isn't part of a dataset, that dataset will be skipped. Parameters ---------- result : ResultLike Data structure which can be converted to a mapping. wavelength : float Wavelength to plot data and fits for. axis: Axis Axis to plot the data and fits on. center_λ: float | None Center wavelength (λ in nm) main_irf_nr : int Index of the main ``irf`` component when using an ``irf`` parametrized with multiple peaks. Defaults to 0. linlog : bool Whether to use 'symlog' scale or not. Defaults to False. linthresh : float A single float which defines the range (-x, x), within which the plot is linear. This avoids having the plot go to infinity around zero. Defaults to 1. divide_by_scale : bool Whether or not to divide the data by the dataset scale used for optimization. Defaults to True. per_axis_legend: bool Whether to use a legend per plot or for the whole figure. Defaults to False. y_label: str Label used for the y-axis of each subplot. cycler : Cycler | None Plot style cycler to use. Defaults to PlotStyle().data_cycler_solid. See Also -------- plot_fit_overview """ result_map = result_dataset_mapping(result) add_cycler_if_not_none(axis, cycler) for dataset_name in result_map.keys(): spectral_coords = result_map[dataset_name].coords["spectral"].values if spectral_coords.min() <= wavelength <= spectral_coords.max(): result_data = result_map[dataset_name].sel(spectral=[wavelength], method="nearest") scale = extract_dataset_scale(result_data, divide_by_scale) irf_loc = extract_irf_location(result_data, center_λ, main_irf_nr) result_data = result_data.assign_coords( time=result_data.coords["time"] - irf_loc) (result_data.data / scale).plot(x="time", ax=axis, label=f"{dataset_name}_data") (result_data.fitted_data / scale).plot(x="time", ax=axis, label=f"{dataset_name}_fit") else: [next(axis._get_lines.prop_cycler) for _ in range(2)] if linlog: axis.set_xscale("symlog", linthresh=linthresh) axis.set_ylabel(y_label) if per_axis_legend is True: axis.legend()