Visualization

This section documents the plotting helpers in hermes_rheo.visualization. They operate on the ExperimentSet / MeasurementSet objects produced by the readers and transforms.

All helpers work with the SciencePlots science + notebook style applied by use_science_style().

Rheology plots

Van Gurp–Palmen and Cole–Cole diagrams, colour-coded by temperature.

Plots of linear viscoelastic data: van Gurp-Palmen and Cole-Cole.

Both functions draw one trace per measurement, coloured by temperature, and read axis names and units from the datasets. They also work on a single measurement without temperature, such as simulated data from hermes_rheo.lve_models.

hermes_rheo.visualization.visualize.plot_cole_cole(experiment_set, ax: Axes | None = None, colormap=None, x_name: str = 'storage modulus', y_name: str = 'loss modulus', dataset_index: int = 0, legend: str | bool = 'auto', legend_max: int = 12, *, title: str | None = None, xlabel: str | None = None, ylabel: str | None = None, save: str | None = None, **kwargs) → tuple[Figure, Axes][source]

Plot the loss modulus against the storage modulus (Cole-Cole).

In this representation frequency is the implicit parameter. A single relaxation process (Maxwell model) gives a semicircle in linear axes, and curves from different temperatures superpose when time-temperature superposition holds. Both axes are logarithmic here.

Parameters:
  • experiment_set (ExperimentSet, MeasurementSet or Measurement) – One trace is drawn per measurement.

  • ax (matplotlib.axes.Axes, optional) – Axes to draw on. A new figure is created if omitted.

  • colormap (matplotlib colormap, optional) – Colormap for the temperature colours; coolwarm by default.

  • x_name (str) – Names of the data arrays on the x and y axes.

  • y_name (str) – Names of the data arrays on the x and y axes.

  • dataset_index (int, default 0) – Dataset to use within each measurement.

  • legend ({"auto", "legend", "colorbar", True, False}, default "auto") – Temperature key; see plot_vgp().

  • legend_max (int, default 12) – Largest number of distinct temperatures shown in a legend.

  • title (str, optional) – Override the default title and the labels read from the dataset.

  • xlabel (str, optional) – Override the default title and the labels read from the dataset.

  • ylabel (str, optional) – Override the default title and the labels read from the dataset.

  • save (str, optional) – Path to write the figure to.

  • **kwargs – Passed to matplotlib.axes.Axes.plot().

Returns:

  • fig (matplotlib.figure.Figure)

  • ax (matplotlib.axes.Axes)

Raises:

ValueError – If no measurement contains both x_name and y_name.

Examples

>>> fig, ax = plot_cole_cole(experiment_set)
hermes_rheo.visualization.visualize.plot_vgp(experiment_set, ax: Axes | None = None, colormap=None, x_name: str = 'complex modulus', y_name: str = 'tan(delta)', dataset_index: int = 0, legend: str | bool = 'auto', legend_max: int = 12, *, title: str | None = None, xlabel: str | None = None, ylabel: str | None = None, save: str | None = None, **kwargs) → tuple[Figure, Axes][source]

Plot the loss tangent against the complex modulus (van Gurp-Palmen).

The van Gurp-Palmen plot shows the phase angle, here as tan(delta), against |G*| with frequency as the implicit parameter. Because the plot does not contain frequency or temperature explicitly, curves measured at different temperatures overlap on a single curve when time-temperature superposition holds; vertical or horizontal gaps between them indicate that it fails.

Parameters:
  • experiment_set (ExperimentSet, MeasurementSet or Measurement) – One trace is drawn per measurement.

  • ax (matplotlib.axes.Axes, optional) – Axes to draw on. A new figure is created if omitted.

  • colormap (matplotlib colormap, optional) – Colormap for the temperature colours; coolwarm by default.

  • x_name (str) – Names of the data arrays on the x and y axes.

  • y_name (str) – Names of the data arrays on the x and y axes.

  • dataset_index (int, default 0) – Dataset to use within each measurement.

  • legend ({"auto", "legend", "colorbar", True, False}, default "auto") – Temperature key. "auto" uses a legend for up to legend_max distinct temperatures and a colorbar for more. True forces the legend; False forces the colorbar.

  • legend_max (int, default 12) – Largest number of distinct temperatures shown in a legend.

  • title (str, optional) – Override the default title and the labels read from the dataset.

  • xlabel (str, optional) – Override the default title and the labels read from the dataset.

  • ylabel (str, optional) – Override the default title and the labels read from the dataset.

  • save (str, optional) – Path to write the figure to.

  • **kwargs – Passed to matplotlib.axes.Axes.plot().

Returns:

  • fig (matplotlib.figure.Figure)

  • ax (matplotlib.axes.Axes)

Raises:

ValueError – If no measurement contains both x_name and y_name.

Examples

>>> fig, ax = plot_vgp(experiment_set)

Master curves

Measured data, Gaussian-process fits and shifted master curve of an AutomatedMasterCurve result, with one colour bar for the state.

Plot a time–temperature (or other state) superposition master curve.

hermes_rheo.visualization.mastercurve.plot_master_curve(master: Any, cmap: str | Colormap = 'coolwarm', show_gp: bool = True, markersize: float = 3.0, show: bool = False, *, lowest_on_top: bool = True, figsize: tuple[float, float] | None = None, save: str | PathLike | None = None) → tuple[Figure, ndarray][source]

Plot the measured data, the Gaussian-process fits and the master curve.

The panels show, side by side, the data before shifting, the data with the Gaussian-process interpolants (mean \(\pm\) one standard deviation) used by the superposition, and the shifted master curve against the reduced abscissa \(a\,x\). Each state is coloured by its value; a single colour bar labels the state range. Names and units are read from the master-curve dataset.

Parameters:
  • master (MasterCurveMeasurement) – Output of AutomatedMasterCurve, or one entry of a CompositeMasterCurve result.

  • cmap (str or Colormap, default "coolwarm") – Colormap mapping the state value to colour.

  • show_gp (bool, default True) – Include the Gaussian-process panel.

  • markersize (float, default 3.0) – Marker size of the data points.

  • show (bool, default False) – Call matplotlib.pyplot.show() before returning.

  • lowest_on_top (bool, default True) – Put the lowest state at the top of the colour bar (cold on top for temperature). Set False for the highest state on top.

  • figsize (tuple of float, optional) – Figure size. Scales with the number of panels by default.

  • save (str or path-like, optional) – Path to write the figure to.

Returns:

  • fig (matplotlib.figure.Figure)

  • axes (numpy.ndarray of matplotlib.axes.Axes) – The panels, left to right.

Examples

>>> master = AutomatedMasterCurve(y="storage modulus")(experiment)
>>> fig, axes = plot_master_curve(master)

Mutation number

Per-frequency and frequency-averaged mutation number against time, with the quasi-static threshold and optional colouring by temperature; also available as MutationNumberMeasurementSet.visualize.

Mutation number against time, per frequency and averaged over frequency.

hermes_rheo.visualization.mutation.plot_mutation_number(mutation: Any, *, show_all_frequencies: bool = False, color_by: str | None = None, cmap: str = 'viridis', threshold: float | None = 0.15, ylim: tuple[float, float] | None = None, logy: bool = False, figsize: tuple[float, float] | None = None, save: str | PathLike | None = None, show: bool = False) → tuple[Figure, Any][source]

Plot the mutation number against time.

Parameters:
  • mutation (MutationNumberMeasurementSet) – Output of MutationNumber.

  • show_all_frequencies (bool, default False) – Add a left panel with Mu at every frequency next to the panel of the frequency-averaged mean +/- standard deviation.

  • color_by (str, optional) – Data array that sets the marker colour, e.g. "temperature" for a TORCh ramp; a colour bar shows its range. Default: colour by time, without a colour bar.

  • cmap (str, default "viridis") – Matplotlib colormap.

  • threshold (float or None, default 0.15) – Quasi-static limit drawn as a dashed grey line; None to omit.

  • ylim (tuple of float, optional) – y-axis limits.

  • logy (bool, default False) – Logarithmic y-axis (useful with MutationNumber(absolute=True)).

  • figsize (tuple of float, optional) – Figure size; defaults to the style module sizes.

  • save (path-like, optional) – Save the figure to this path.

  • show (bool, default False) – Call plt.show().

Returns:

  • fig (matplotlib.figure.Figure)

  • axes (matplotlib.axes.Axes or tuple of matplotlib.axes.Axes) – (ax_all, ax_mean) if show_all_frequencies, else ax_mean.

Glass transition from the storage modulus

Construction of the onset Tg of a temperature ramp: G’ with the glassy and inflection tangents, and d log G’/dT; also available as TemperatureRampMeasurement.plot_onset.

Glass transition from the storage modulus of a temperature ramp.

hermes_rheo.visualization.temperature_ramp.plot_tg_onset(ramp: Any, *, figsize: tuple[float, float] = (5.5, 5.5), colors: tuple[str, str] = ('darkblue', 'k'), xlim: tuple[float, float] | None = None, save: str | PathLike | None = None, show: bool = False) → tuple[Figure, tuple[Any, Any]][source]

Plot how the onset Tg is obtained from the storage modulus.

Top: G’ with the smoothed curve, the tangent fitted to the glassy plateau (shaded range), the tangent at the inflection and their intersection, the onset Tg. Bottom: d log10 G’/dT, whose minimum is the inflection.

Parameters:
  • ramp (TemperatureRampMeasurement) – Output of TemperatureRampAnalysis(tg_method="storage_modulus") or tg_method="both".

  • figsize (tuple of float, default (5.5, 5.5)) – Figure size.

  • colors (tuple of str, default ("darkblue", "k")) – Colours of the data and of the fitted tangents; guide lines are gray.

  • xlim (tuple of float, optional) – Temperature limits, e.g. to zoom on the construction; default: the whole analysis range.

  • save (path-like, optional) – Save the figure to this path.

  • show (bool, default False) – Call plt.show().

Returns:

  • fig (matplotlib.figure.Figure)

  • axes (tuple of matplotlib.axes.Axes) – (ax_modulus, ax_slope).

OWChirp visualiser

A convenience object that wraps the per-wave extraction, plotting, PNG-frame saving, animation and Fourier-domain analysis of a processed OWChirp experiment (see OWChirpAnalysis).

Plots for processed OWChirp (optimally windowed chirp) experiments.

OWChirp probes a broad frequency range in one short arbitrary-wave step by applying a windowed chirp and Fourier-transforming the strain and stress signals to obtain G' and G'' [1].

After OWChirpAnalysis, each measurement holds two datasets:

  • datasets[0]: frequency domain (angular frequency, storage and loss modulus, complex modulus and viscosity, tan(delta), Fourier transforms of strain and stress);

  • datasets[1]: time domain (adjusted time, step time, adjusted strain, adjusted stress, temperature).

Axis labels and units are read from these datasets.

References

Examples

>>> from hermes_rheo.transforms.owchirp_analysis import OWChirpAnalysis
>>> from hermes_rheo.visualization import OWChirpVisualizer
>>> viz = OWChirpVisualizer(OWChirpAnalysis()(experiment))
>>> viz.plot_waves(steps=[0, 1, 2])
>>> viz.plot_fourier(step=10)
class hermes_rheo.visualization.owchirp.OWChirpVisualizer(processed_experiment: Any, moduli_ylim: tuple[float, float] | None = None)[source]

Bases: object

Plot the waves of a processed OWChirp experiment.

Parameters:
  • processed_experiment (ExperimentSet) – Output of OWChirpAnalysis.

  • moduli_ylim (tuple of float, optional) – (ymin, ymax) of the modulus axis in plot_wave(). Autoscaled if None.

Variables:

n_waves (int) – Number of waves (measurements).

property data: dict[str, list[ndarray]]

Arrays of every wave, computed once.

Returns:

Keys are angular_frequencies, storage_moduli, loss_moduli, complex_moduli, complex_viscosities, phase_angles, step_times, strains, stresses and temperatures; each list has n_waves entries. Arrays missing from a dataset are returned as empty arrays.

Return type:

dict of list of numpy.ndarray

plot_fourier(step: int = 0, figsize: tuple[float, float] = (10.0, 7.0)) → tuple[Figure, Sequence[Axes]][source]

Plot strain and stress in the time and Fourier domains.

The left column shows the strain (top) and stress (bottom) versus time. The right column shows the real part, imaginary part and magnitude of their Fourier transforms versus angular frequency.

Parameters:
  • step (int, optional) – Wave index (0-based).

  • figsize (tuple of float, optional) – Figure size.

Returns:

  • fig (matplotlib.figure.Figure)

  • axes (tuple of matplotlib.axes.Axes) – (strain_time, strain_fourier, stress_time, stress_fourier).

plot_wave(step: int, figsize: tuple[float, float] = (12.0, 4.8), save_dir: str | None = None) → tuple[Figure, Sequence[Axes]][source]

Plot the moduli, strain and stress of one wave.

The moduli versus angular frequency are on the left; the strain and stress versus time are stacked on the right.

Parameters:
  • step (int) – Wave index (0-based).

  • figsize (tuple of float, optional) – Figure size.

  • save_dir (str, optional) – If given, write the figure to <save_dir>/plot_<step+1>.png.

Returns:

  • fig (matplotlib.figure.Figure)

  • axes (tuple of matplotlib.axes.Axes) – (moduli_ax, strain_ax, stress_ax).

plot_waves(steps: int | str | Sequence[int] | None = 'first-middle-last', figsize: tuple[float, float] = (12.0, 4.8), save_dir: str | None = None) → tuple[list[Figure], list[Sequence[Axes]]][source]

Plot several waves with plot_wave().

Parameters:
  • steps (None, str, int or sequence of int, optional) – Waves to plot; see _resolve_steps().

  • figsize (tuple of float, optional) – Size of each figure.

  • save_dir (str, optional) – If given, write each figure to <save_dir>/plot_<step+1>.png.

Returns:

  • figs (list of matplotlib.figure.Figure)

  • axes (list of tuple of matplotlib.axes.Axes)

save_frames(output_dir: str) → list[str][source]

Save every wave as plot_<n>.png without showing it.

Parameters:

output_dir (str) – Output directory, created if needed.

Returns:

Paths of the PNG files, in wave order.

Return type:

list of str

to_video(output_dir: str, filename: str = 'plot_video.avi', fps: int = 2, codec: str = 'DIVX') → str[source]

Combine the plot_<n>.png frames into a video.

Frames are created with save_frames() if output_dir has none.

Parameters:
  • output_dir (str) – Directory of the frames and the output video.

  • filename (str, optional) – Video file name.

  • fps (int, optional) – Frames per second.

  • codec (str, optional) – FourCC codec code.

Returns:

Path of the video file.

Return type:

str

Raises:

ImportError – If opencv-python is not installed.

Relaxation-spectrum plots

Helpers for the pyReSpect-based RelaxationSpectrum transform:

Plots for the relaxation spectrum of RelaxationSpectrum.

The relaxation spectrum \(h(s)\) is the distribution of relaxation strengths over relaxation time \(s\), with the relaxation modulus \(G(t) = \int h(s)\, e^{-t/s}\, d\ln s\). The continuous spectrum is obtained by regularised inversion of the data with the regularisation parameter \(\lambda\) chosen by Bayesian evidence, and a discrete set of Maxwell modes \((g_i, \tau_i)\) is selected with the Akaike criterion (pyReSpect; Takeh and Shanbhag, Appl. Rheol. 23, 24628 (2013); Shanbhag, Macromol. Theory Simul. 28, 1900005 (2019)).

Examples

>>> from hermes_rheo.transforms.relaxation_spectrum import RelaxationSpectrum
>>> out = RelaxationSpectrum(domain="frequency")(measurement)
>>> fig, ax = plot_relaxation_spectrum(
...     out.details["relaxation_spectrum_result"], source=out
... )
hermes_rheo.visualization.spectrum.plot_relaxation_spectrum(result: Any, ax: Axes | None = None, *, show_discrete: bool = True, show_continuous: bool = True, show_uncertainty: bool = True, source: Any | None = None, label_continuous: str | None = None, label_discrete: str | None = None, color_continuous: str = 'tab:blue', color_discrete: str = 'tab:red', unit_style: str = 'paren', legend_loc: str = 'best', title: str | None = None, xlabel: str | None = None, ylabel: str | None = None, save: str | None = None) → tuple[Figure, Axes][source]

Plot the continuous and discrete relaxation spectra on log-log axes.

Parameters:
  • result (RelaxationSpectrumResult) – Result of RelaxationSpectrum, stored in details["relaxation_spectrum_result"].

  • ax (matplotlib.axes.Axes, optional) – Axes to draw on. A new figure is created if omitted.

  • show_discrete (bool, default True) – Draw the discrete modes \((\tau_i, g_i)\) as stems.

  • show_continuous (bool, default True) – Draw the continuous spectrum \(h(s)\).

  • show_uncertainty (bool, default True) – Shade the band \(\exp(\ln h \pm dH)\). Only available for frequency-domain results; skipped if result.dH is None.

  • source (Measurement, ExperimentSet or dataset, optional) – Object whose data array units label the axes. Defaults to s for time and Pa for modulus.

  • label_continuous (str, optional) – Legend labels.

  • label_discrete (str, optional) – Legend labels.

  • color_continuous (str) – Colours of the continuous and discrete spectra.

  • color_discrete (str) – Colours of the continuous and discrete spectra.

  • unit_style ({"paren", "bracket"}, default "paren") – Brackets around the unit in axis labels.

  • legend_loc (str, default "best") – Legend location.

  • title (str, optional) – Override the default title and labels.

  • xlabel (str, optional) – Override the default title and labels.

  • ylabel (str, optional) – Override the default title and labels.

  • save (str, optional) – Path to write the figure to.

Returns:

  • fig (matplotlib.figure.Figure)

  • ax (matplotlib.axes.Axes)

hermes_rheo.visualization.spectrum.plot_spectrum_diagnostics(result: Any, axes: ndarray | None = None, *, save: str | None = None) → tuple[Figure, ndarray][source]

Plot the three regularisation diagnostics of a spectrum fit.

The panels are, from left to right:

  1. L-curve: residual norm \(\rho(\lambda)\) against solution norm \(\eta(\lambda)\), with the selected \(\lambda_C\) marked.

  2. Log evidence \(\log p(\lambda)\) against \(\lambda\).

  3. Akaike criterion against the base-weight distance of the discrete modes, with the optimum number of modes \(N_\mathrm{opt}\).

Panels whose diagnostics are missing from result are left blank.

Parameters:
  • result (RelaxationSpectrumResult) – Result of RelaxationSpectrum.

  • axes (array of matplotlib.axes.Axes, optional) – Three axes. A new 1x3 figure is created if omitted.

  • save (str, optional) – Path to write the figure to.

Returns:

  • fig (matplotlib.figure.Figure)

  • axes (numpy.ndarray of matplotlib.axes.Axes, shape (3,))

Style helpers

Apply or reset the publication-quality Matplotlib style used throughout the tutorials.

Matplotlib style and shared layout constants for hermes-rheo plots.

The layout constants (figure sizes, font sizes, line widths, markers and colours) are used by every plot_* function so that figures look the same regardless of which one produced them. use_science_style() additionally applies the SciencePlots style sheets; it is optional and a no-op when scienceplots is missing.

Examples

>>> from hermes_rheo.visualization import use_science_style
>>> use_science_style()
['science', 'notebook', 'no-latex']
hermes_rheo.visualization.style.reset_style() → None[source]

Restore the Matplotlib default style and piblin’s axes styling.

hermes_rheo.visualization.style.use_science_style(latex: bool = False, extras: Iterable[str] | None = None) → list[str][source]

Apply the SciencePlots science and notebook styles globally.

Axes are boxed, with ticks pointing inward on all four sides and minor ticks shown. piblin’s Dataset.visualize normally hides the top and right spines; while this style is active it follows these settings instead, so piblin and hermes-rheo plots look the same.

Parameters:
  • latex (bool, default False) – Render text with LaTeX. Requires latex and dvipng on the PATH.

  • extras (iterable of str, optional) – Further SciencePlots style names, for example ["grid"] or ["ieee"].

Returns:

The style names applied; empty if scienceplots is not installed.

Return type:

list of str