Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c5483f7

Browse files
committed
Consistently document shapes as (M, N), not MxN.
We already mostly use "(M, N)", but there were still quite a few instances of "MxN". Also add a helper to generate the error messages in extensions.
1 parent 1ad6cbf commit c5483f7

File tree

13 files changed

+90
-113
lines changed

13 files changed

+90
-113
lines changed

examples/lines_bars_and_markers/scatter_custom_symbol.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@
3535
# %%
3636
# Using a custom path
3737
# -------------------
38-
# Alternatively, one can also pass a custom path of N vertices as a Nx2 array
39-
# of x, y values as *marker*.
38+
# Alternatively, one can also pass a custom path of N vertices as a (N, 2)
39+
# array of x, y values as *marker*.
4040

4141
# unit area ellipse
4242
rx, ry = 3., 1.
@@ -45,7 +45,7 @@
4545
verts = np.column_stack([rx / area * np.cos(theta), ry / area * np.sin(theta)])
4646

4747
x, y, s, c = np.random.rand(4, 30)
48-
s *= 10**2.
48+
s *= 100
4949

5050
fig, ax = plt.subplots()
5151
ax.scatter(x, y, s, c, marker=verts)

lib/matplotlib/axes/_base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2495,7 +2495,7 @@ def update_datalim(self, xys, updatex=True, updatey=True):
24952495
----------
24962496
xys : 2D array-like
24972497
The points to include in the data limits Bbox. This can be either
2498-
a list of (x, y) tuples or a Nx2 array.
2498+
a list of (x, y) tuples or a (N, 2) array.
24992499
25002500
updatex, updatey : bool, default: True
25012501
Whether to update the x/y limits.

lib/matplotlib/colors.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,8 +1110,8 @@ class ListedColormap(Colormap):
11101110
Parameters
11111111
----------
11121112
colors : list, array
1113-
List of Matplotlib color specifications, or an equivalent Nx3 or Nx4
1114-
floating point array (*N* RGB or RGBA values).
1113+
Sequence of Matplotlib color specifications (color names or RGB(A)
1114+
values).
11151115
name : str, optional
11161116
String to identify the colormap.
11171117
N : int, optional
@@ -2370,8 +2370,8 @@ def shade(self, data, cmap, norm=None, blend_mode='overlay', vmin=None,
23702370
"overlay". Note that for most topographic surfaces,
23712371
"overlay" or "soft" appear more visually realistic. If a
23722372
user-defined function is supplied, it is expected to
2373-
combine an MxNx3 RGB array of floats (ranging 0 to 1) with
2374-
an MxNx1 hillshade array (also 0 to 1). (Call signature
2373+
combine an (M, N, 3) RGB array of floats (ranging 0 to 1) with
2374+
an (M, N, 1) hillshade array (also 0 to 1). (Call signature
23752375
``func(rgb, illum, **kwargs)``) Additional kwargs supplied
23762376
to this function will be passed on to the *blend_mode*
23772377
function.
@@ -2404,7 +2404,7 @@ def shade(self, data, cmap, norm=None, blend_mode='overlay', vmin=None,
24042404
Returns
24052405
-------
24062406
`~numpy.ndarray`
2407-
An MxNx4 array of floats ranging between 0-1.
2407+
An (M, N, 4) array of floats ranging between 0-1.
24082408
"""
24092409
if vmin is None:
24102410
vmin = data.min()
@@ -2445,8 +2445,8 @@ def shade_rgb(self, rgb, elevation, fraction=1., blend_mode='hsv',
24452445
defaults to "hsv". Note that for most topographic surfaces,
24462446
"overlay" or "soft" appear more visually realistic. If a
24472447
user-defined function is supplied, it is expected to combine an
2448-
MxNx3 RGB array of floats (ranging 0 to 1) with an MxNx1 hillshade
2449-
array (also 0 to 1). (Call signature
2448+
(M, N, 3) RGB array of floats (ranging 0 to 1) with an (M, N, 1)
2449+
hillshade array (also 0 to 1). (Call signature
24502450
``func(rgb, illum, **kwargs)``)
24512451
Additional kwargs supplied to this function will be passed on to
24522452
the *blend_mode* function.
@@ -2512,9 +2512,9 @@ def blend_hsv(self, rgb, intensity, hsv_max_sat=None, hsv_max_val=None,
25122512
Parameters
25132513
----------
25142514
rgb : `~numpy.ndarray`
2515-
An MxNx3 RGB array of floats ranging from 0 to 1 (color image).
2515+
An (M, N, 3) RGB array of floats ranging from 0 to 1 (color image).
25162516
intensity : `~numpy.ndarray`
2517-
An MxNx1 array of floats ranging from 0 to 1 (grayscale image).
2517+
An (M, N, 1) array of floats ranging from 0 to 1 (grayscale image).
25182518
hsv_max_sat : number, default: 1
25192519
The maximum saturation value that the *intensity* map can shift the
25202520
output image to.
@@ -2531,7 +2531,7 @@ def blend_hsv(self, rgb, intensity, hsv_max_sat=None, hsv_max_val=None,
25312531
Returns
25322532
-------
25332533
`~numpy.ndarray`
2534-
An MxNx3 RGB array representing the combined images.
2534+
An (M, N, 3) RGB array representing the combined images.
25352535
"""
25362536
# Backward compatibility...
25372537
if hsv_max_sat is None:
@@ -2574,14 +2574,14 @@ def blend_soft_light(self, rgb, intensity):
25742574
Parameters
25752575
----------
25762576
rgb : `~numpy.ndarray`
2577-
An MxNx3 RGB array of floats ranging from 0 to 1 (color image).
2577+
An (M, N, 3) RGB array of floats ranging from 0 to 1 (color image).
25782578
intensity : `~numpy.ndarray`
2579-
An MxNx1 array of floats ranging from 0 to 1 (grayscale image).
2579+
An (M, N, 1) array of floats ranging from 0 to 1 (grayscale image).
25802580
25812581
Returns
25822582
-------
25832583
`~numpy.ndarray`
2584-
An MxNx3 RGB array representing the combined images.
2584+
An (M, N, 3) RGB array representing the combined images.
25852585
"""
25862586
return 2 * intensity * rgb + (1 - 2 * intensity) * rgb**2
25872587

@@ -2592,14 +2592,14 @@ def blend_overlay(self, rgb, intensity):
25922592
Parameters
25932593
----------
25942594
rgb : `~numpy.ndarray`
2595-
An MxNx3 RGB array of floats ranging from 0 to 1 (color image).
2595+
An (M, N, 3) RGB array of floats ranging from 0 to 1 (color image).
25962596
intensity : `~numpy.ndarray`
2597-
An MxNx1 array of floats ranging from 0 to 1 (grayscale image).
2597+
An (M, N, 1) array of floats ranging from 0 to 1 (grayscale image).
25982598
25992599
Returns
26002600
-------
26012601
ndarray
2602-
An MxNx3 RGB array representing the combined images.
2602+
An (M, N, 3) RGB array representing the combined images.
26032603
"""
26042604
low = 2 * intensity * rgb
26052605
high = 1 - 2 * (1 - intensity) * (1 - rgb)

lib/matplotlib/lines.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,9 +1031,7 @@ def get_path(self):
10311031
return self._path
10321032

10331033
def get_xydata(self):
1034-
"""
1035-
Return the *xy* data as a Nx2 numpy array.
1036-
"""
1034+
"""Return the *xy* data as a (N, 2) array."""
10371035
if self._invalidy or self._invalidx:
10381036
self.recache()
10391037
return self._xy

lib/matplotlib/patches.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,14 +1081,16 @@ def __str__(self):
10811081
@_api.make_keyword_only("3.6", name="closed")
10821082
def __init__(self, xy, closed=True, **kwargs):
10831083
"""
1084-
*xy* is a numpy array with shape Nx2.
1085-
1086-
If *closed* is *True*, the polygon will be closed so the
1087-
starting and ending points are the same.
1084+
Parameters
1085+
----------
1086+
xy : (N, 2) array
10881087
1089-
Valid keyword arguments are:
1088+
closed : bool, default: True
1089+
Whether the polygon is closed (i.e., has identical start and end
1090+
points).
10901091
1091-
%(Patch:kwdoc)s
1092+
**kwargs
1093+
%(Patch:kwdoc)s
10921094
"""
10931095
super().__init__(**kwargs)
10941096
self._closed = closed

lib/matplotlib/path.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class Path:
2828
2929
The underlying storage is made up of two parallel numpy arrays:
3030
31-
- *vertices*: an Nx2 float array of vertices
31+
- *vertices*: an (N, 2) float array of vertices
3232
- *codes*: an N-length uint8 array of path codes, or None
3333
3434
These two arrays always have the same length in the first
@@ -210,9 +210,7 @@ def _update_values(self):
210210

211211
@property
212212
def vertices(self):
213-
"""
214-
The list of vertices in the `Path` as an Nx2 numpy array.
215-
"""
213+
"""The vertices of the `Path` as an (N, 2) array."""
216214
return self._vertices
217215

218216
@vertices.setter
@@ -684,7 +682,7 @@ def interpolated(self, steps):
684682
def to_polygons(self, transform=None, width=0, height=0, closed_only=True):
685683
"""
686684
Convert this path to a list of polygons or polylines. Each
687-
polygon/polyline is an Nx2 array of vertices. In other words,
685+
polygon/polyline is an (N, 2) array of vertices. In other words,
688686
each polygon has no ``MOVETO`` instructions or curves. This
689687
is useful for displaying in backends that do not support
690688
compound paths or Bézier curves.

lib/matplotlib/streamplot.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def streamplot(axes, x, y, u, v, density=1, linewidth=None, color=None,
5757
See `~matplotlib.patches.FancyArrowPatch`.
5858
minlength : float
5959
Minimum length of streamline in axes coordinates.
60-
start_points : Nx2 array
60+
start_points : (N, 2) array
6161
Coordinates of starting points for the streamlines in data coordinates
6262
(the same coordinates as the *x* and *y* arrays).
6363
zorder : float

lib/matplotlib/transforms.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@ def count_contains(self, vertices):
584584
585585
Parameters
586586
----------
587-
vertices : Nx2 Numpy array.
587+
vertices : (N, 2) array
588588
"""
589589
if len(vertices) == 0:
590590
return 0
@@ -769,7 +769,7 @@ def __init__(self, points, **kwargs):
769769
Parameters
770770
----------
771771
points : `~numpy.ndarray`
772-
A 2x2 numpy array of the form ``[[x0, y0], [x1, y1]]``.
772+
A (2, 2) array of the form ``[[x0, y0], [x1, y1]]``.
773773
"""
774774
super().__init__(**kwargs)
775775
points = np.asarray(points, float)
@@ -1485,13 +1485,13 @@ def transform(self, values):
14851485
----------
14861486
values : array
14871487
The input values as NumPy array of length :attr:`input_dims` or
1488-
shape (N x :attr:`input_dims`).
1488+
shape (N, :attr:`input_dims`).
14891489
14901490
Returns
14911491
-------
14921492
array
14931493
The output values as NumPy array of length :attr:`output_dims` or
1494-
shape (N x :attr:`output_dims`), depending on the input.
1494+
shape (N, :attr:`output_dims`), depending on the input.
14951495
"""
14961496
# Ensure that values is a 2d array (but remember whether
14971497
# we started with a 1d or 2d array).
@@ -1511,8 +1511,8 @@ def transform(self, values):
15111511
elif ndim == 2:
15121512
return res
15131513
raise ValueError(
1514-
"Input values must have shape (N x {dims}) "
1515-
"or ({dims}).".format(dims=self.input_dims))
1514+
"Input values must have shape (N, {dims}) or ({dims},)"
1515+
.format(dims=self.input_dims))
15161516

15171517
def transform_affine(self, values):
15181518
"""
@@ -1530,13 +1530,13 @@ def transform_affine(self, values):
15301530
----------
15311531
values : array
15321532
The input values as NumPy array of length :attr:`input_dims` or
1533-
shape (N x :attr:`input_dims`).
1533+
shape (N, :attr:`input_dims`).
15341534
15351535
Returns
15361536
-------
15371537
array
15381538
The output values as NumPy array of length :attr:`output_dims` or
1539-
shape (N x :attr:`output_dims`), depending on the input.
1539+
shape (N, :attr:`output_dims`), depending on the input.
15401540
"""
15411541
return self.get_affine().transform(values)
15421542

@@ -1555,13 +1555,13 @@ def transform_non_affine(self, values):
15551555
----------
15561556
values : array
15571557
The input values as NumPy array of length :attr:`input_dims` or
1558-
shape (N x :attr:`input_dims`).
1558+
shape (N, :attr:`input_dims`).
15591559
15601560
Returns
15611561
-------
15621562
array
15631563
The output values as NumPy array of length :attr:`output_dims` or
1564-
shape (N x :attr:`output_dims`), depending on the input.
1564+
shape (N, :attr:`output_dims`), depending on the input.
15651565
"""
15661566
return values
15671567

src/_backend_agg_wrapper.cpp

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -459,14 +459,16 @@ PyRendererAgg_draw_gouraud_triangle(PyRendererAgg *self, PyObject *args)
459459

460460
if (points.dim(0) != 3 || points.dim(1) != 2) {
461461
PyErr_Format(PyExc_ValueError,
462-
"points must be a 3x2 array, got %" NPY_INTP_FMT "x%" NPY_INTP_FMT,
462+
"points must have shape (3, 2), "
463+
"got (%" NPY_INTP_FMT ", %" NPY_INTP_FMT ")",
463464
points.dim(0), points.dim(1));
464465
return NULL;
465466
}
466467

467468
if (colors.dim(0) != 3 || colors.dim(1) != 4) {
468469
PyErr_Format(PyExc_ValueError,
469-
"colors must be a 3x4 array, got %" NPY_INTP_FMT "x%" NPY_INTP_FMT,
470+
"colors must have shape (3, 4), "
471+
"got (%" NPY_INTP_FMT ", %" NPY_INTP_FMT ")",
470472
colors.dim(0), colors.dim(1));
471473
return NULL;
472474
}
@@ -497,24 +499,16 @@ PyRendererAgg_draw_gouraud_triangles(PyRendererAgg *self, PyObject *args)
497499
&trans)) {
498500
return NULL;
499501
}
500-
501-
if (points.size() != 0 && (points.dim(1) != 3 || points.dim(2) != 2)) {
502-
PyErr_Format(PyExc_ValueError,
503-
"points must be a Nx3x2 array, got %" NPY_INTP_FMT "x%" NPY_INTP_FMT "x%" NPY_INTP_FMT,
504-
points.dim(0), points.dim(1), points.dim(2));
502+
if (points.size() && !check_trailing_shape(points, "points", 3, 2)) {
505503
return NULL;
506504
}
507-
508-
if (colors.size() != 0 && (colors.dim(1) != 3 || colors.dim(2) != 4)) {
509-
PyErr_Format(PyExc_ValueError,
510-
"colors must be a Nx3x4 array, got %" NPY_INTP_FMT "x%" NPY_INTP_FMT "x%" NPY_INTP_FMT,
511-
colors.dim(0), colors.dim(1), colors.dim(2));
505+
if (colors.size() && !check_trailing_shape(colors, "colors", 3, 4)) {
512506
return NULL;
513507
}
514-
515508
if (points.size() != colors.size()) {
516509
PyErr_Format(PyExc_ValueError,
517-
"points and colors arrays must be the same length, got %" NPY_INTP_FMT " and %" NPY_INTP_FMT,
510+
"points and colors arrays must be the same length, got "
511+
"%" NPY_INTP_FMT " points and %" NPY_INTP_FMT "colors",
518512
points.dim(0), colors.dim(0));
519513
return NULL;
520514
}

src/_path.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ void get_path_collection_extents(agg::trans_affine &master_transform,
394394
extent_limits &extent)
395395
{
396396
if (offsets.size() != 0 && offsets.dim(1) != 2) {
397-
throw std::runtime_error("Offsets array must be Nx2");
397+
throw std::runtime_error("Offsets array must have shape (N, 2)");
398398
}
399399

400400
size_t Npaths = paths.size();

src/mplutils.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,33 @@ inline int prepare_and_add_type(PyTypeObject *type, PyObject *module)
6262
return 0;
6363
}
6464

65+
#ifdef __cplusplus // not for macosx.m
66+
// Check that array has shape (N, d1) or (N, d1, d2). We cast d1, d2 to longs
67+
// so that we don't need to access the NPY_INTP_FMT macro here.
68+
69+
template<typename T>
70+
inline bool check_trailing_shape(T array, char const* name, long d1)
71+
{
72+
if (array.dim(1) != d1) {
73+
PyErr_Format(PyExc_ValueError,
74+
"%s must have shape (N, %ld), got (%ld, %ld)",
75+
name, d1, array.dim(0), array.dim(1));
76+
return false;
77+
}
78+
return true;
79+
}
80+
81+
template<typename T>
82+
inline bool check_trailing_shape(T array, char const* name, long d1, long d2)
83+
{
84+
if (array.dim(1) != d1 || array.dim(2) != d2) {
85+
PyErr_Format(PyExc_ValueError,
86+
"%s must have shape (N, %ld, %ld), got (%ld, %ld, %ld)",
87+
name, d1, d2, array.dim(0), array.dim(1), array.dim(2));
88+
return false;
89+
}
90+
return true;
91+
}
92+
#endif
93+
6594
#endif

0 commit comments

Comments
 (0)