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

morganjwilliams / pyrolite / 5460340654

pending completion
5460340654

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.

5967 of 6601 relevant lines covered (90.4%)

10.84 hits per line

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

97.3
/pyrolite/plot/biplot.py
1
import numpy as np
12✔
2

3
from ..comp import codata
12✔
4
from ..util.log import Handle
12✔
5
from ..util.plot.axes import init_axes
12✔
6

7
logger = Handle(__name__)
12✔
8

9

10
def compositional_SVD(X: np.ndarray):
12✔
11
    """
12
    Breakdown a set of compositions to vertexes and cases for adding to a
13
    compositional biplot.
14

15
    Parameters
16
    ----------
17
    X : :class:`numpy.ndarray`
18
        Compositional array.
19

20
    Returns
21
    ---------
22
    vertexes, cases : :class:`numpy.ndarray`, :class:`numpy.ndarray`
23
    """
24
    U, K, V = np.linalg.svd(codata.CLR(X))
12✔
25
    N = X.shape[1]  # dimensionality
12✔
26
    vertexes = K * V.T / (N - 1) ** 0.5
12✔
27
    cases = (N - 1) ** 0.5 * U.T
12✔
28
    return vertexes, cases
12✔
29

30

31
def plot_origin_to_points(
12✔
32
    xs,
33
    ys,
34
    labels=None,
35
    ax=None,
36
    origin=(0, 0),
37
    color="k",
38
    marker="o",
39
    pad=0.05,
40
    **kwargs
41
):
42
    """
43
    Plot lines radiating from a specific origin. Fornulated for creation of
44
    biplots (:func:`covariance_biplot`, :func:`compositional_biplot`).
45

46
    Parameters
47
    -----------
48
    xs, ys : :class:`numpy.ndarray`
49
        Coordinates for points to add.
50
    labels : :class:`list`
51
        Labels for verticies.
52
    ax : :class:`matplotlib.axes.Axes`
53
        Axes to plot on.
54
    origin : :class:`tuple`
55
        Origin to plot from.
56
    color : :class:`str`
57
        Line color to use.
58
    marker : :class:`str`
59
        Marker to use for ends of vectors and origin.
60
    pad : :class:`float`
61
        Fraction of vector to pad text label.
62

63
    Returns
64
    --------
65
    :class:`matplotlib.axes.Axes`
66
        Axes on which radial plot is added.
67
    """
68
    x0, y0 = origin
12✔
69
    ax = init_axes(ax=ax, **kwargs)
12✔
70
    _xs, _ys = (
12✔
71
        np.vstack([x0 * np.ones_like(xs), xs]),
72
        np.vstack([y0 * np.ones_like(ys), ys]),
73
    )
74
    ax.plot(_xs, _ys, color=color, marker=marker, **kwargs)
12✔
75

76
    if labels is not None:
12✔
77
        for ix, label in enumerate(labels):
12✔
78
            x, y = xs[ix], ys[ix]
12✔
79
            dx, dy = x - x0, y - y0
12✔
80
            theta = np.rad2deg(np.arctan(dy / dx))
12✔
81

82
            x += pad * dx
12✔
83
            y += pad * dy
12✔
84

85
            if np.abs(theta) > 60:
12✔
UNCOV
86
                ha = "center"
×
87
            else:
88
                ha = ["right" if x < x0 else "left"][0]
12✔
89

90
            if np.abs(theta) < 30:
12✔
91
                va = "center"
12✔
92
            else:
93
                va = ["top" if y < y0 else "bottom"][0]
12✔
94
            ax.annotate(label, (x, y), ha=ha, va=va, rotation=theta)
12✔
95

96
    return ax
12✔
97

98

99
def compositional_biplot(data, labels=None, ax=None, **kwargs):
12✔
100
    """
101
    Create a compositional biplot.
102

103
    Parameters
104
    -----------
105
    data : :class:`numpy.ndarray`
106
        Coordinates for points to add.
107
    labels : :class:`list`
108
        Labels for verticies.
109
    ax : :class:`matplotlib.axes.Axes`
110
        Axes to plot on.
111

112
    Returns
113
    --------
114
    :class:`matplotlib.axes.Axes`
115
        Axes on which biplot is added.
116
    """
117

118
    ax = init_axes(ax=ax, **kwargs)
12✔
119

120
    v, c = compositional_SVD(data)
12✔
121
    ax.scatter(*c[:, :2].T, **kwargs)
12✔
122
    plot_origin_to_points(
12✔
123
        *v[:, :2].T,
124
        ax=ax,
125
        marker=None,
126
        labels=labels,
127
        alpha=0.5,
128
        zorder=-1,
129
        label="Variables",
130
    )
131
    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