Source code for ta.plotter

"""Matplotlib routines for thermal-analysis figure generation.

The main entry point is :func:`plot_ta_figure`, which produces a
two-panel plot:

* **Panel A** — DTA (left Y), TGA and DTG (twin right Y-axes) vs.
  temperature.
* **Panel B** — MS ion intensities (log scale) vs. temperature.
"""

from __future__ import annotations

import matplotlib.pyplot as plt
import numpy as np


[docs] def plot_ta_figure( temperature_C: np.ndarray, tga: np.ndarray, dtg: np.ndarray, dta: np.ndarray, ms_dict: dict[str, np.ndarray], *, figsize: tuple[float, float] = (10, 8), dta_label: str = r"DTA ($\mu$V/mg)", tga_label: str = "TGA (mass %)", dtg_label: str = "DTG (%/min)", ms_label: str = "Ion intensity (a.u.)", title: str = "Thermal Analysis", ) -> tuple[plt.Figure, tuple[plt.Axes, plt.Axes, plt.Axes, plt.Axes]]: """Create a two-panel thermal-analysis figure. Parameters ---------- temperature_C : np.ndarray Temperature [deg C] (shared X-axis for both panels). tga, dtg, dta : np.ndarray Signals computed by :mod:`ta.signals`. ms_dict : dict[str, np.ndarray] Species name -> mole-fraction array for the MS panel. figsize : tuple[float, float] Figure dimensions in inches. dta_label, tga_label, dtg_label, ms_label : str Y-axis labels. title : str Figure super-title. Returns ------- fig : matplotlib.figure.Figure axes : tuple[Axes, Axes, Axes, Axes] ``(ax_dta, ax_tga, ax_dtg, ax_ms)`` """ fig, (ax_top, ax_ms) = plt.subplots( 2, 1, figsize=figsize, sharex=True, ) # ---- colours ---- c_dta = "tab:blue" c_tga = "tab:red" c_dtg = "tab:green" # ==== Panel A: DTA / TGA / DTG ==== ax_dta: plt.Axes = ax_top # DTA — left axis ax_dta.plot(temperature_C, dta, color=c_dta, label="DTA") ax_dta.set_ylabel(dta_label, color=c_dta) ax_dta.tick_params(axis="y", labelcolor=c_dta) # TGA — first right axis ax_tga: plt.Axes = ax_dta.twinx() ax_tga.plot(temperature_C, tga, color=c_tga, label="TGA") ax_tga.set_ylabel(tga_label, color=c_tga) ax_tga.tick_params(axis="y", labelcolor=c_tga) # DTG — second right axis (offset outward) ax_dtg: plt.Axes = ax_dta.twinx() ax_dtg.spines["right"].set_position(("outward", 60)) ax_dtg.plot(temperature_C, dtg, color=c_dtg, label="DTG") ax_dtg.set_ylabel(dtg_label, color=c_dtg) ax_dtg.tick_params(axis="y", labelcolor=c_dtg) # combined legend all_lines = ( ax_dta.get_lines() + ax_tga.get_lines() + ax_dtg.get_lines() ) all_labels = [ln.get_label() for ln in all_lines] ax_dta.legend(all_lines, all_labels, loc="best") ax_dta.set_title(title) # ==== Panel B: MS ==== if ms_dict: for name, intensity in ms_dict.items(): ax_ms.plot(temperature_C, intensity, label=name) ax_ms.set_yscale("log") ax_ms.set_ylim(1e-2, 1e2) ax_ms.legend(loc="best", fontsize="small", ncol=2) ax_ms.set_xlabel(r"Temperature ($\degree$C)") ax_ms.set_ylabel(ms_label) fig.tight_layout() return fig, (ax_dta, ax_tga, ax_dtg, ax_ms)