• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

morganjwilliams / pyrolite / 5564819928

pending completion
5564819928

push

github

morganjwilliams
Merge branch 'release/0.3.3' into main

249 of 270 new or added lines in 48 files covered. (92.22%)

217 existing lines in 33 files now uncovered.

5971 of 6605 relevant lines covered (90.4%)

10.84 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.1
/pyrolite/util/lambdas/plot.py
1
"""
2
Functions for the visualisation of reconstructed and deconstructed parameterised REE
3
profiles based on parameterisations using 'lambdas' (and tetrad-equivalent weights
4
'taus').
5
"""
6
import numpy as np
12✔
7

8
from ... import plot
12✔
9
from ...geochem.ind import REE, get_ionic_radii
12✔
10
from ..log import Handle
12✔
11
from .eval import (
12✔
12
    get_function_components,
13
    get_lambda_poly_function,
14
    get_tetrads_function,
15
)
16
from .params import _get_params
12✔
17
from .transform import REE_radii_to_z, REE_z_to_radii
12✔
18

19
logger = Handle(__name__)
12✔
20

21

22
def plot_lambdas_components(lambdas, params=None, ax=None, **kwargs):
12✔
23
    """
24
    Plot a decomposed orthogonal polynomial from a single set of lambda coefficients.
25

26
    Parameters
27
    ----------
28
    lambdas
29
        1D array of lambdas.
30
    params : :class:`list`
31
        List of orthongonal polynomial parameters, if defaults are not used.
32
    ax : :class:`matplotlib.axes.Axes`
33
        Optionally specified axes to plot on.
34
    index : :class:`str`
35
        Index to use for the plot (one of :code:`"index", "radii", "z"`).
36

37
    Returns
38
    --------
39
    :class:`matplotlib.axes.Axes`
40
    """
41
    degree = lambdas.size
12✔
42
    params = _get_params(params=params, degree=degree)
12✔
43
    # check the degree and parameters are of consistent degree?
44
    reconstructed_func = get_lambda_poly_function(lambdas, params)
12✔
45

46
    ax = plot.spider.REE_v_radii(ax=ax)
12✔
47

48
    radii = np.array(get_ionic_radii(REE(), charge=3, coordination=8))
12✔
49
    xs = np.linspace(np.max(radii), np.min(radii), 100)
12✔
50
    ax.plot(xs, reconstructed_func(xs), label="Regression", color="k", **kwargs)
12✔
51
    for w, p in zip(lambdas, params):  # plot the components
12✔
52
        l_func = get_lambda_poly_function(
12✔
53
            [w], [p]
54
        )  # pasing singluar vaules and one tuple
55
        label = (
12✔
56
            r"$r^{}: \lambda_{}".format(len(p), len(p))
57
            + [r"\cdot f_{}".format(len(p)), ""][int(len(p) == 0)]
58
            + "$"
59
        )
60
        ax.plot(xs, l_func(xs), label=label, ls="--", **kwargs)  # plot the polynomials
12✔
61
    return ax
12✔
62

63

64
def plot_tetrads_components(
12✔
65
    taus, tetrad_params=None, ax=None, index="radii", logy=True, drop0=True, **kwargs
66
):
67
    """
68
    Individually plot the four tetrad components for one set of $\tau$s.
69

70
    Parameters
71
    ----------
72
    taus : :class:`numpy.ndarray`
73
        1D array of $\tau$ tetrad function coefficients.
74
    tetrad_params : :class:`list`
75
        List of tetrad parameters, if defaults are not used.
76
    ax : :class:`matplotlib.axes.Axes`
77
        Optionally specified axes to plot on.
78
    index : :class:`str`
79
        Index to use for the plot (one of :code:`"index", "radii", "z"`).
80
    logy : :class:`bool`
81
        Whether to log-scale the y-axis.
82
    drop0 : :class:`bool`
83
        Whether to remove zeroes from the outputs such that individual tetrad
84
        functions are shown only within their respective bounds (and not across the
85
        entire REE, where their effective values are zero).
86
    """
87
    # flat 1D array of ts
88
    f = get_tetrads_function(params=tetrad_params)
12✔
89

90
    z = np.arange(57, 72)  # marker
12✔
91
    linez = np.linspace(57, 71, 1000)  # line
12✔
92

93
    taus = taus.reshape(-1, 1)
12✔
94
    ys = (taus * f(z, sum_tetrads=False)).squeeze()
12✔
95
    liney = (taus * f(linez, sum_tetrads=False)).squeeze()
12✔
96

97
    xs = REE_z_to_radii(z)
12✔
98
    linex = REE_z_to_radii(linez)
12✔
99
    ####################################################################################
100
    if index in ["radii", "elements"]:
12✔
101
        ax = plot.spider.REE_v_radii(logy=logy, index=index, ax=ax, **kwargs)
12✔
102
    else:
UNCOV
103
        index = "z"
×
UNCOV
104
        ax = plot.spider.spider(
×
105
            np.array([np.nan] * len(z)), indexes=z, logy=logy, ax=ax, **kwargs
106
        )
107
        ax.set_xticklabels(REE(dropPm=False))
×
108
        # xs = z
109
        # linex = linez
110

111
    if drop0:
12✔
112
        yfltr = np.isclose(ys, 0)
12✔
113
        # we can leave in markers which should actually be there at zero - 1/ea tetrad
114
        yfltr = yfltr * (
12✔
115
            1 - np.isclose(z[:, None] - np.array([57, 64, 64, 71]).T, 0).T
116
        ).astype(bool)
117
        ys[yfltr] = np.nan
12✔
118
        liney[np.isclose(liney, 0)] = np.nan
12✔
119
    return ax
12✔
120

121

122
def plot_profiles(
12✔
123
    coefficients,
124
    tetrads=False,
125
    params=None,
126
    tetrad_params=None,
127
    ax=None,
128
    index="radii",
129
    logy=False,
130
    **kwargs
131
):
132
    r"""
133
    Plot the reconstructed REE profiles of a 2D dataset of coefficients ($\lambda$s,
134
    and optionally $\tau$s).
135

136
    Parameters
137
    ----------
138
    coefficients : :class:`numpy.ndarray`
139
        2D array of $\lambda$ orthogonal polynomial coefficients, and optionally
140
        including $\tau$ tetrad function coefficients in the last four columns
141
        (where :code:`tetrads=True`).
142
    tetrads : :class:`bool`
143
        Whether the coefficient array contains tetrad coefficients ($\tau$s).
144
    params : :class:`list`
145
        List of orthongonal polynomial parameters, if defaults are not used.
146
    tetrad_params : :class:`list`
147
        List of tetrad parameters, if defaults are not used.
148
    ax : :class:`matplotlib.axes.Axes`
149
        Optionally specified axes to plot on.
150
    index : :class:`str`
151
        Index to use for the plot (one of :code:`"index", "radii", "z"`).
152
    logy : :class:`bool`
153
        Whether to log-scale the y-axis.
154

155
    Returns
156
    --------
157
    :class:`matplotlib.axes.Axes`
158
    """
159
    radii = get_ionic_radii(REE(), charge=3, coordination=8)
12✔
160
    # check the degree required for the lambda coefficients and get the OP parameters
161
    lambda_degree = coefficients.shape[1] - [0, 4][tetrads]
12✔
162
    params = _get_params(params or "full", degree=lambda_degree)
12✔
163

164
    # get the components and y values for the points/element locations
165
    _, x0, components = get_function_components(
12✔
166
        radii,
167
        params=params,
168
        fit_tetrads=tetrads,
169
        tetrad_params=tetrad_params,
170
    )
171
    ys = np.exp(coefficients @ components)
12✔
172
    # get the components and y values for the smooth lines
173
    lineradii = np.linspace(radii[0], radii[-1], 1000)
12✔
174

175
    _, x0, linecomponents = get_function_components(
12✔
176
        lineradii,
177
        params=params,
178
        fit_tetrads=tetrads,
179
        tetrad_params=tetrad_params,
180
    )
181
    liney = np.exp(coefficients @ linecomponents)
12✔
182
    z, linez = REE_radii_to_z(radii), REE_radii_to_z(lineradii)
12✔
183
    xs, linex = radii, lineradii
12✔
184
    ####################################################################################
185
    if index in ["radii", "elements"]:
12✔
186
        ax = plot.spider.REE_v_radii(ax=ax, logy=logy, index=index, **kwargs)
12✔
187
    else:
UNCOV
188
        index = "z"
×
UNCOV
189
        ax = plot.spider.spider(
×
190
            np.array([np.nan] * len(z)), ax=ax, indexes=z, logy=logy, **kwargs
191
        )
192
        ax.set_xticklabels(REE(dropPm=False))
×
UNCOV
193
        xs = z
×
UNCOV
194
        linex = linez
×
195

196
    # ys = np.exp(ys)
197
    # liney = np.exp(liney)
198
    # scatter-only spider
199
    plot.spider.spider(
12✔
200
        ys, ax=ax, indexes=xs, logy=logy, set_ticks=False, **{**kwargs, "linewidth": 0}
201
    )
202
    # line-only spider
203
    plot.spider.spider(
12✔
204
        liney,
205
        ax=ax,
206
        indexes=linex,
207
        logy=logy,
208
        set_ticks=False,
209
        **{**kwargs, "marker": ""}
210
    )
211

212
    return ax
12✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc