Skip to content

Commit bd3b975

Browse files
committed
Prefer concatenate to h/vstack in simple cases.
concatenate is (much) faster than hstack, while being essentially equivalent in the 1D case; when working on 2D arrays it can replace vstack too.
1 parent e6479bd commit bd3b975

File tree

5 files changed

+33
-31
lines changed

5 files changed

+33
-31
lines changed

lib/matplotlib/axes/_axes.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -4810,8 +4810,8 @@ def reduce_C_function(C: array) -> float
48104810
else:
48114811
lattice2[i, j] = np.nan
48124812

4813-
accum = np.hstack((lattice1.astype(float).ravel(),
4814-
lattice2.astype(float).ravel()))
4813+
accum = np.concatenate([lattice1.astype(float).ravel(),
4814+
lattice2.astype(float).ravel()])
48154815
good_idxs = ~np.isnan(accum)
48164816

48174817
offsets = np.zeros((n, 2), float)

lib/matplotlib/cbook/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1252,7 +1252,7 @@ def _compute_conf_interval(data, med, iqr, bootstrap):
12521252
stats['whislo'] = np.min(wisklo)
12531253

12541254
# compute a single array of outliers
1255-
stats['fliers'] = np.hstack([
1255+
stats['fliers'] = np.concatenate([
12561256
x[x < stats['whislo']],
12571257
x[x > stats['whishi']],
12581258
])

lib/matplotlib/markers.py

+14-13
Original file line numberDiff line numberDiff line change
@@ -608,10 +608,10 @@ def _set_star(self):
608608
else:
609609
verts = polypath.vertices
610610

611-
top = Path(np.vstack((verts[0:4, :], verts[7:10, :], verts[0])))
612-
bottom = Path(np.vstack((verts[3:8, :], verts[3])))
613-
left = Path(np.vstack((verts[0:6, :], verts[0])))
614-
right = Path(np.vstack((verts[0], verts[5:10, :], verts[0])))
611+
top = Path(np.concatenate([verts[0:4], verts[7:10], verts[0:1]]))
612+
bottom = Path(np.concatenate([verts[3:8], verts[3:4]]))
613+
left = Path(np.concatenate([verts[0:6], verts[0:1]]))
614+
right = Path(np.concatenate([verts[0:1], verts[5:10], verts[0:1]]))
615615

616616
if fs == 'top':
617617
mpath, mpath_alt = top, bottom
@@ -641,10 +641,10 @@ def _set_hexagon1(self):
641641

642642
# not drawing inside lines
643643
x = np.abs(np.cos(5 * np.pi / 6.))
644-
top = Path(np.vstack(([-x, 0], verts[(1, 0, 5), :], [x, 0])))
645-
bottom = Path(np.vstack(([-x, 0], verts[2:5, :], [x, 0])))
646-
left = Path(verts[(0, 1, 2, 3), :])
647-
right = Path(verts[(0, 5, 4, 3), :])
644+
top = Path(np.concatenate([[(-x, 0)], verts[[1, 0, 5]], [(x, 0)]]))
645+
bottom = Path(np.concatenate([[(-x, 0)], verts[2:5], [(x, 0)]]))
646+
left = Path(verts[0:4])
647+
right = Path(verts[[0, 5, 4, 3]])
648648

649649
if fs == 'top':
650650
mpath, mpath_alt = top, bottom
@@ -675,11 +675,12 @@ def _set_hexagon2(self):
675675

676676
# not drawing inside lines
677677
x, y = np.sqrt(3) / 4, 3 / 4.
678-
top = Path(verts[(1, 0, 5, 4, 1), :])
679-
bottom = Path(verts[(1, 2, 3, 4), :])
680-
left = Path(np.vstack(([x, y], verts[(0, 1, 2), :],
681-
[-x, -y], [x, y])))
682-
right = Path(np.vstack(([x, y], verts[(5, 4, 3), :], [-x, -y])))
678+
top = Path(verts[[1, 0, 5, 4, 1]])
679+
bottom = Path(verts[1:5])
680+
left = Path(np.concatenate([
681+
[(x, y)], verts[:3], [(-x, -y), (x, y)]]))
682+
right = Path(np.concatenate([
683+
[(x, y)], verts[5:2:-1], [(-x, -y)]]))
683684

684685
if fs == 'top':
685686
mpath, mpath_alt = top, bottom

lib/matplotlib/patches.py

+11-8
Original file line numberDiff line numberDiff line change
@@ -994,14 +994,14 @@ def _update_path(self):
994994
x = np.repeat(self._edges[idx0:idx1+1], 2)
995995
y = np.repeat(self._values[idx0:idx1], 2)
996996
if self._baseline is None:
997-
y = np.hstack((y[0], y, y[-1]))
997+
y = np.concatenate([y[:1], y, y[-1:]])
998998
elif self._baseline.ndim == 0: # single baseline value
999-
y = np.hstack((self._baseline, y, self._baseline))
999+
y = np.concatenate([[self._baseline], y, [self._baseline]])
10001000
elif self._baseline.ndim == 1: # baseline array
10011001
base = np.repeat(self._baseline[idx0:idx1], 2)[::-1]
10021002
x = np.concatenate([x, x[::-1]])
1003-
y = np.concatenate([np.hstack((base[-1], y, base[0],
1004-
base[0], base, base[-1]))])
1003+
y = np.concatenate([base[-1:], y, base[:1],
1004+
base[:1], base, base[-1:]])
10051005
else: # no baseline
10061006
raise ValueError('Invalid `baseline` specified')
10071007
if self.orientation == 'vertical':
@@ -1179,13 +1179,16 @@ def _recompute_path(self):
11791179
# followed by a reversed and scaled inner ring
11801180
v1 = arc.vertices
11811181
v2 = arc.vertices[::-1] * (self.r - self.width) / self.r
1182-
v = np.vstack([v1, v2, v1[0, :], (0, 0)])
1183-
c = np.hstack([arc.codes, arc.codes, connector, Path.CLOSEPOLY])
1182+
v = np.concatenate([v1, v2, [v1[0, :], (0, 0)]])
1183+
c = np.concatenate([
1184+
arc.codes, arc.codes, [connector, Path.CLOSEPOLY]])
11841185
c[len(arc.codes)] = connector
11851186
else:
11861187
# Wedge doesn't need an inner ring
1187-
v = np.vstack([arc.vertices, [(0, 0), arc.vertices[0, :], (0, 0)]])
1188-
c = np.hstack([arc.codes, [connector, connector, Path.CLOSEPOLY]])
1188+
v = np.concatenate([
1189+
arc.vertices, [(0, 0), arc.vertices[0, :], (0, 0)]])
1190+
c = np.concatenate([
1191+
arc.codes, [connector, connector, Path.CLOSEPOLY]])
11891192

11901193
# Shift and scale the wedge to the final location.
11911194
v *= self.r

lib/matplotlib/ticker.py

+5-7
Original file line numberDiff line numberDiff line change
@@ -2139,18 +2139,16 @@ def _validate_steps(steps):
21392139
raise ValueError('steps argument must be an increasing sequence '
21402140
'of numbers between 1 and 10 inclusive')
21412141
if steps[0] != 1:
2142-
steps = np.hstack((1, steps))
2142+
steps = np.concatenate([[1], steps])
21432143
if steps[-1] != 10:
2144-
steps = np.hstack((steps, 10))
2144+
steps = np.concatenate([steps, [10]])
21452145
return steps
21462146

21472147
@staticmethod
21482148
def _staircase(steps):
2149-
# Make an extended staircase within which the needed
2150-
# step will be found. This is probably much larger
2151-
# than necessary.
2152-
flights = (0.1 * steps[:-1], steps, 10 * steps[1])
2153-
return np.hstack(flights)
2149+
# Make an extended staircase within which the needed step will be
2150+
# found. This is probably much larger than necessary.
2151+
return np.concatenate([0.1 * steps[:-1], steps, [10 * steps[1]]])
21542152

21552153
def set_params(self, **kwargs):
21562154
"""

0 commit comments

Comments
 (0)