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

APN-Pucky / smpl / 28609932887

02 Jul 2026 05:40PM UTC coverage: 86.835% (-2.0%) from 88.798%
28609932887

Pull #358

github

web-flow
Merge 245f6c3af into 6042d4ac0
Pull Request #358: Add py3.14

5 of 6 new or added lines in 2 files covered. (83.33%)

34 existing lines in 2 files now uncovered.

1583 of 1823 relevant lines covered (86.83%)

1.74 hits per line

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

61.74
/smpl/plot2d.py
1
import matplotlib.pyplot as plt
2✔
2
import numpy as np
2✔
3
import smplr
2✔
4
from matplotlib import colors
2✔
5
from matplotlib.image import NonUniformImage
2✔
6

7
from smpl import doc, util
2✔
8
from smpl import plot as splot
2✔
9

10
default = {
2✔
11
    "title": [None, "Plot title"],
12
    "xlabel": [None, "."],
13
    "ylabel": [None, "."],
14
    "zlabel": [None, "."],
15
    "logz": [True, "Colorbar in logarithmic scale."],
16
    "style": [
17
        "pcolormesh",
18
        "Plot via an image ('image') or scatter ('scatter') or mesh ('pcolormesh').",
19
    ],
20
    "interpolation": [
21
        "nearest",
22
        "Only 'nearest' or 'bilinear' for nonuniformimage. Check https://matplotlib.org/stable/gallery/images_contours_and_fields/interpolation_methods.html#interpolations-for-imshow",
23
    ],
24
    "cmap": [
25
        "viridis",
26
        "Good default color map for missing datapoints since it does not include white.",
27
    ],
28
    # 'zscale' : [None,"Rescale z values."],
29
}
30

31
# @doc.insert_str("\tDefault kwargs\n\n\t")
32

33

34
@doc.append_str(doc.array_table(default, init=False))
2✔
35
@doc.append_str(
2✔
36
    doc.array_table({"plot2d_kwargs": ["default", "description"]}, bottom=False)
37
)
38
def plot2d_kwargs(kwargs):
2✔
39
    """Set default plot2d_kwargs if not set."""
40
    for k, v in default.items():
2✔
41
        if k not in kwargs:
2✔
42
            kwargs[k] = v[0]
2✔
43
    return kwargs
2✔
44

45

46
def plot2d(datax, datay, dataz, **kwargs):
2✔
47
    """
48
    Creates a 2D-Plot.
49

50
    Parameters
51
    ----------
52
    **kwargs : optional
53
        see :func:`plot2d_kwargs`.
54
    """
55
    kwargs = plot2d_kwargs(kwargs)
2✔
56
    if "xaxis" in kwargs and ("xlabel" not in kwargs or not kwargs["xlabel"]):
2✔
57
        # warnings.warn("xaxis is deprecated. Use xlabel instead.", DeprecationWarning, 2)
58
        kwargs["xlabel"] = kwargs["xaxis"]
×
59
    if "yaxis" in kwargs and ("ylabel" not in kwargs or not kwargs["ylabel"]):
2✔
60
        # warnings.warn("yaxis is deprecated. Use ylabel instead.", DeprecationWarning, 2)
61
        kwargs["ylabel"] = kwargs["yaxis"]
×
62
    if "zaxis" in kwargs and ("zlabel" not in kwargs or not kwargs["zlabel"]):
2✔
63
        # warnings.warn("zaxis is deprecated. Use zlabel instead.", DeprecationWarning, 2)
64
        kwargs["zlabel"] = kwargs["zaxis"]
×
65

66
    if util.has("axes", kwargs) and kwargs["axes"] is not None:
2✔
67
        plt.sca(kwargs["axes"])
×
68
    if kwargs["style"] == "pcolormesh":
2✔
69
        pcolormesh_vplot(datax, datay, dataz, **kwargs)
2✔
70
    elif kwargs["style"] == "image":
2✔
UNCOV
71
        map_vplot(datax, datay, dataz, **kwargs)
×
72
    elif kwargs["style"] == "scatter":
2✔
73
        scatter_vplot(datax, datay, dataz, **kwargs)
2✔
74

75

76
def sort_xyz(x, y, z):
2✔
77
    p1 = x.argsort(kind="stable")
2✔
78
    x = np.copy(x[p1])
2✔
79
    y = np.copy(y[p1])
2✔
80
    z = np.copy(z[p1])
2✔
81
    p2 = y.argsort(kind="stable")
2✔
82
    x = x[p2]
2✔
83
    y = y[p2]
2✔
84
    z = z[p2]
2✔
85
    return x, y, z
2✔
86

87

88
def pcolormesh_vplot(
2✔
89
    tvx,
90
    tvy,
91
    tvz,
92
    xlabel=None,
93
    ylabel=None,
94
    zlabel=None,
95
    logz=True,
96
    zscale=1.0,
97
    **kwargs,
98
):
99
    """
100
    Advantage over matplotlibs pcolor(mesh) is that does not require a meshgrid. Instead it uses the data points directly in three lists.
101
    """
102
    vx = np.copy(tvx)
2✔
103
    vy = np.copy(tvy)
2✔
104
    vz = np.copy(tvz)
2✔
105
    assert vx.shape == vy.shape == vz.shape
2✔
106

107
    if len(vz.shape) < 2:
2✔
108
        mesh = np.meshgrid(np.unique(vx), np.unique(vy))
2✔
109
        X, Y = mesh
2✔
110
        # set Z to values of vz on the meshgrid
111
        Z = np.empty(mesh[0].shape)
2✔
112
        Z[:] = np.nan
2✔
113
        for i, _ in enumerate(vx):
2✔
114
            Z[(mesh[0] == vx[i]) & (mesh[1] == vy[i])] = splot.unv(vz[i])
2✔
115
        Z[:] *= zscale
2✔
116
    else:
117
        X = vx
2✔
118
        Y = vy
2✔
119
        Z = vz * zscale
2✔
120

121
    plt.pcolormesh(
2✔
122
        X, Y, Z, norm=colors.LogNorm() if logz else None, cmap=kwargs["cmap"]
123
    )
124

125
    # ax.set_xlim(xl, xm)
126
    # ax.set_ylim(yl, ym)
127

128
    cb = plt.colorbar()
2✔
129
    cb.set_label(zlabel)
2✔
130
    smplr.style_plot2d(xlabel=xlabel, ylabel=ylabel, **kwargs)
2✔
131

132

133
def map_vplot(
2✔
134
    tvx,
135
    tvy,
136
    tvz,
137
    xlabel=None,
138
    ylabel=None,
139
    zlabel=None,
140
    logz=True,
141
    sort=True,
142
    fill_missing=True,
143
    zscale=1.0,
144
    **kwargs,
145
):
146
    """ """
UNCOV
147
    vx = np.copy(tvx)
×
UNCOV
148
    vy = np.copy(tvy)
×
UNCOV
149
    vz = np.copy(tvz)
×
UNCOV
150
    if fill_missing:
×
151
        # TODO speed up
UNCOV
152
        for x in vx:
×
UNCOV
153
            for y in vy:
×
UNCOV
154
                ex = np.any(np.logical_and((vx == x), (vy == y)))
×
UNCOV
155
                if not ex:
×
UNCOV
156
                    vx = np.append(vx, x)
×
UNCOV
157
                    vy = np.append(vy, y)
×
UNCOV
158
                    vz = np.append(vz, 0)
×
UNCOV
159
    if sort:
×
UNCOV
160
        vx, vy, vz = sort_xyz(vx, vy, vz)
×
161

UNCOV
162
    s = 1
×
UNCOV
163
    while vy[s] == vy[s - 1]:
×
UNCOV
164
        s = s + 1
×
UNCOV
165
    if s == 1:
×
166
        # print("flipped x y ")
167
        while vx[s] == vx[s - 1]:
×
168
            s = s + 1
×
169
        if s == 1:
×
170
            print("error too small map")
×
171
            return
×
172
        # x, y = y, x
173
        xlabel, ylabel = ylabel, xlabel
×
174
        vx, vy = vy, vx
×
175

UNCOV
176
    grid = splot.unv(vz).reshape((int(np.rint(np.size(vx) / s)), s)) * zscale
×
177

UNCOV
178
    _, ax = plt.subplots(nrows=1, ncols=1, constrained_layout=True)
×
UNCOV
179
    im = None
×
UNCOV
180
    xl = vx.min() + (vx.min() / 2) - vx[vx != vx.min()].min() / 2
×
UNCOV
181
    xm = vx.max() + (vx.max() / 2) - vx[vx != vx.max()].max() / 2
×
UNCOV
182
    yl = vy.min() + (vy.min() / 2) - vy[vy != vy.min()].min() / 2
×
UNCOV
183
    ym = vy.max() + (vy.max() / 2) - vy[vy != vy.max()].max() / 2
×
UNCOV
184
    im = NonUniformImage(
×
185
        ax,
186
        origin="lower",
187
        cmap=kwargs["cmap"],
188
        interpolation=kwargs["interpolation"],
189
        extent=(xl, xm, yl, ym),
190
        norm=colors.LogNorm() if logz else None,
191
    )
192

UNCOV
193
    im.set_data(np.unique(vx), np.unique(vy), grid)
×
UNCOV
194
    ax.add_image(im)
×
195
    # ax.images.append(im)
UNCOV
196
    ax.set_xlim(xl, xm)
×
UNCOV
197
    ax.set_ylim(yl, ym)
×
198

UNCOV
199
    cb = plt.colorbar(im)
×
UNCOV
200
    cb.set_label(zlabel)
×
UNCOV
201
    smplr.style_plot2d(xlabel=xlabel, ylabel=ylabel, **kwargs)
×
202

203

204
def scatter_vplot(
2✔
205
    vx,
206
    vy,
207
    vz,
208
    xlabel=None,
209
    ylabel=None,
210
    zlabel=None,
211
    logz=True,
212
    sort=True,
213
    **kwargs,
214
):
215
    if sort:
2✔
216
        vx, vy, vz = sort_xyz(vx, vy, vz)
2✔
217

218
    _, ax = plt.subplots(nrows=1, ncols=1, constrained_layout=True)
2✔
219
    xl = vx.min() + (vx.min() / 2) - vx[vx != vx.min()].min() / 2
2✔
220
    xm = vx.max() + (vx.max() / 2) - vx[vx != vx.max()].max() / 2
2✔
221
    yl = vy.min() + (vy.min() / 2) - vy[vy != vy.min()].min() / 2
2✔
222
    ym = vy.max() + (vy.max() / 2) - vy[vy != vy.max()].max() / 2
2✔
223

224
    s = plt.scatter(
2✔
225
        np.concatenate((vx, vx, vx)),
226
        np.concatenate((vy, vy, vy)),
227
        c=np.concatenate(
228
            (
229
                splot.unv(vz) + splot.usd(vz),
230
                splot.unv(vz) - splot.usd(vz),
231
                splot.unv(vz),
232
            )
233
        ),
234
        s=np.concatenate(
235
            (
236
                [(3 * plt.rcParams["lines.markersize"]) ** 2 for i in range(len(vx))],
237
                [(2 * plt.rcParams["lines.markersize"]) ** 2 for i in range(len(vx))],
238
                [(plt.rcParams["lines.markersize"]) ** 2 for i in range(len(vx))],
239
            )
240
        ),
241
        norm=colors.LogNorm() if logz else None,
242
        cmap=kwargs["cmap"],
243
    )
244

245
    ax.set_xlim(xl, xm)
2✔
246
    ax.set_ylim(yl, ym)
2✔
247

248
    cb = plt.colorbar(s)
2✔
249
    cb.set_label(zlabel)
2✔
250
    smplr.style_plot2d(xlabel=xlabel, ylabel=ylabel, **kwargs)
2✔
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