• 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

67.74
/pyrolite/util/plot/interpolation.py
1
"""
2
Line interpolation for matplotlib lines and paths.
3
"""
4
import matplotlib.collections
12✔
5
import matplotlib.path
12✔
6
import numpy as np
12✔
7
import scipy.interpolate
12✔
8

9
from ..log import Handle
12✔
10

11
logger = Handle(__name__)
12✔
12

13

14
def interpolate_path(
12✔
15
    path, resolution=100, periodic=False, aspath=True, closefirst=False, **kwargs
16
):
17
    """
18
    Obtain the interpolation of an existing path at a given
19
    resolution. Keyword arguments are forwarded to
20
    :func:`scipy.interpolate.splprep`.
21

22
    Parameters
23
    -----------
24
    path : :class:`matplotlib.path.Path`
25
        Path to interpolate.
26
    resolution :class:`int`
27
        Resolution at which to obtain the new path. The verticies of
28
        the new path will have shape (`resolution`, 2).
29
    periodic : :class:`bool`
30
        Whether to use a periodic spline.
31
    periodic : :class:`bool`
32
        Whether to return a :code:`matplotlib.path.Path`, or simply
33
        a tuple of x-y arrays.
34
    closefirst : :class:`bool`
35
        Whether to first close the path by appending the first point again.
36

37
    Returns
38
    --------
39
    :class:`matplotlib.path.Path` | :class:`tuple`
40
        Interpolated :class:`~matplotlib.path.Path` object, if
41
        `aspath` is :code:`True`, else a tuple of x-y arrays.
42
    """
43
    x, y = path.vertices.T
12✔
44
    if closefirst:
12✔
45
        x = np.append(x, x[0])
×
46
        y = np.append(y, y[0])
×
47
    # s=0 forces the interpolation to go through every point
48
    tck, _ = scipy.interpolate.splprep([x[:-1], y[:-1]], s=0, per=periodic, **kwargs)
12✔
49
    xi, yi = scipy.interpolate.splev(np.linspace(0.0, 1.0, resolution), tck)
12✔
50
    # could get control points for path and construct codes here
51
    codes = None
12✔
52
    pth = matplotlib.path.Path(np.vstack([xi, yi]).T, codes=codes)
12✔
53
    if aspath:
12✔
54
        return pth
12✔
55
    else:
56
        return pth.vertices.T
×
57

58

59
def interpolated_patch_path(patch, resolution=100, **kwargs):
12✔
60
    """
61
    Obtain the periodic interpolation of the existing path of a patch at a
62
    given resolution.
63

64
    Parameters
65
    -----------
66
    patch : :class:`matplotlib.patches.Patch`
67
        Patch to obtain the original path from.
68
    resolution :class:`int`
69
        Resolution at which to obtain the new path. The verticies of the new path
70
        will have shape (`resolution`, 2).
71

72
    Returns
73
    --------
74
    :class:`matplotlib.path.Path`
75
        Interpolated :class:`~matplotlib.path.Path` object.
76
    """
77
    pth = patch.get_path()
12✔
78
    tfm = patch.get_transform()
12✔
79
    pathtfm = tfm.transform_path(pth)
12✔
80
    return interpolate_path(
12✔
81
        pathtfm, resolution=resolution, aspath=True, periodic=True, **kwargs
82
    )
83

84

85
def get_contour_paths(ax, resolution=100):
12✔
86
    """
87
    Extract the paths of contours from a contour plot.
88

89
    Parameters
90
    ------------
91
    ax : :class:`matplotlib.axes.Axes`
92
        Axes to extract contours from.
93
    resolution : :class:`int`
94
        Resolution of interpolated splines to return.
95

96
    Returns
97
    --------
98
    contourspaths : :class:`list` (:class:`list`)
99
        List of lists, each represnting one line collection (a single contour). In the
100
        case where this contour is multimodal, there will be multiple paths for each
101
        contour.
102
    contournames : :class:`list`
103
        List of names for contours, where they have been labelled, and there are no
104
        other text artists on the figure.
105
    contourstyles : :class:`list`
106
        List of styles for contours.
107

108
    Notes
109
    ------
110
        This method assumes that contours are the only
111
        :code:`matplotlib.collections.LineCollection` objects within an axes;
112
        and when this is not the case, additional non-contour objects will be returned.
113
    """
114
    linecolls = [
×
115
        c
116
        for c in ax.collections
117
        # contours/default lines don't have markers - allows distinguishing scatter
118
        if (
119
            isinstance(c, matplotlib.collections.PathCollection)
120
            and c.get_sizes().size == 0
121
        )
122
        or isinstance(c, matplotlib.collections.LineCollection)
123
    ]
NEW
124
    rgba = [lc.get_edgecolors() for lc in linecolls]
×
UNCOV
125
    styles = [{"color": c} for c in rgba]
×
UNCOV
126
    names = [None for lc in linecolls]
×
NEW
127
    if (len(ax.texts) == len(linecolls)) and all(
×
128
        [a.get_text() != "" for a in ax.texts]
129
    ):
NEW
130
        names = [a.get_text() for a in ax.texts]
×
131
    return (
×
132
        [
133
            [
134
                interpolate_path(p, resolution=resolution, periodic=True, aspath=False)
135
                for p in lc.get_paths()
136
            ]
137
            for lc in linecolls
138
        ],
139
        names,
140
        styles,
141
    )
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