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

Skip to content

Commit 901562f

Browse files
authored
Merge pull request #7454 from anntzer/step-converters
PERF: Avoid temporaries when preparing step plots.
2 parents 048a7b4 + cd2608e commit 901562f

File tree

4 files changed

+78
-114
lines changed

4 files changed

+78
-114
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Functions removed from the `lines` module
2+
`````````````````````````````````````````
3+
4+
The `matplotlib.lines` module no longer imports the `pts_to_prestep`,
5+
`pts_to_midstep` and `pts_to_poststep` functions from the `matplotlib.cbook`
6+
module.

lib/matplotlib/cbook.py

Lines changed: 54 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -2302,147 +2302,112 @@ def get_instancemethod(self):
23022302
return getattr(self.parent_obj, self.instancemethod_name)
23032303

23042304

2305-
def _step_validation(x, *args):
2306-
"""
2307-
Helper function of `pts_to_*step` functions
2308-
2309-
This function does all of the normalization required to the
2310-
input and generate the template for output
2311-
2312-
2313-
"""
2314-
args = tuple(np.asanyarray(y) for y in args)
2315-
x = np.asanyarray(x)
2316-
if x.ndim != 1:
2317-
raise ValueError("x must be 1 dimensional")
2318-
if len(args) == 0:
2319-
raise ValueError("At least one Y value must be passed")
2320-
2321-
return np.vstack((x, ) + args)
2322-
2323-
23242305
def pts_to_prestep(x, *args):
23252306
"""
2326-
Covert continuous line to pre-steps
2307+
Convert continuous line to pre-steps.
23272308
2328-
Given a set of N points convert to 2 N -1 points
2329-
which when connected linearly give a step function
2330-
which changes values at the beginning of the intervals.
2309+
Given a set of ``N`` points, convert to ``2N - 1`` points, which when
2310+
connected linearly give a step function which changes values at the
2311+
beginning of the intervals.
23312312
23322313
Parameters
23332314
----------
23342315
x : array
2335-
The x location of the steps
2316+
The x location of the steps.
23362317
2337-
y1, y2, ... : array
2338-
Any number of y arrays to be turned into steps.
2339-
All must be the same length as ``x``
2318+
y1, ..., yp : array
2319+
y arrays to be turned into steps; all must be the same length as ``x``.
23402320
23412321
Returns
23422322
-------
2343-
x, y1, y2, .. : array
2344-
The x and y values converted to steps in the same order
2345-
as the input. If the input is length ``N``, each of these arrays
2346-
will be length ``2N + 1``
2347-
2323+
out : array
2324+
The x and y values converted to steps in the same order as the input;
2325+
can be unpacked as ``x_out, y1_out, ..., yp_out``. If the input is
2326+
length ``N``, each of these arrays will be length ``2N + 1``.
23482327
23492328
Examples
23502329
--------
23512330
>> x_s, y1_s, y2_s = pts_to_prestep(x, y1, y2)
23522331
"""
2353-
# do normalization
2354-
vertices = _step_validation(x, *args)
2355-
# create the output array
2356-
steps = np.zeros((vertices.shape[0], 2 * len(x) - 1), float)
2357-
# do the to step conversion logic
2358-
steps[0, 0::2], steps[0, 1::2] = vertices[0, :], vertices[0, :-1]
2359-
steps[1:, 0::2], steps[1:, 1:-1:2] = vertices[1:, :], vertices[1:, 1:]
2360-
# convert 2D array back to tuple
2361-
return tuple(steps)
2332+
steps = np.zeros((1 + len(args), 2 * len(x) - 1))
2333+
# In all `pts_to_*step` functions, only assign *once* using `x` and `args`,
2334+
# as converting to an array may be expensive.
2335+
steps[0, 0::2] = x
2336+
steps[0, 1::2] = steps[0, 0:-2:2]
2337+
steps[1:, 0::2] = args
2338+
steps[1:, 1::2] = steps[1:, 2::2]
2339+
return steps
23622340

23632341

23642342
def pts_to_poststep(x, *args):
23652343
"""
2366-
Covert continuous line to pre-steps
2344+
Convert continuous line to post-steps.
23672345
2368-
Given a set of N points convert to 2 N -1 points
2369-
which when connected linearly give a step function
2370-
which changes values at the end of the intervals.
2346+
Given a set of ``N`` points convert to ``2N + 1`` points, which when
2347+
connected linearly give a step function which changes values at the end of
2348+
the intervals.
23712349
23722350
Parameters
23732351
----------
23742352
x : array
2375-
The x location of the steps
2353+
The x location of the steps.
23762354
2377-
y1, y2, ... : array
2378-
Any number of y arrays to be turned into steps.
2379-
All must be the same length as ``x``
2355+
y1, ..., yp : array
2356+
y arrays to be turned into steps; all must be the same length as ``x``.
23802357
23812358
Returns
23822359
-------
2383-
x, y1, y2, .. : array
2384-
The x and y values converted to steps in the same order
2385-
as the input. If the input is length ``N``, each of these arrays
2386-
will be length ``2N + 1``
2387-
2360+
out : array
2361+
The x and y values converted to steps in the same order as the input;
2362+
can be unpacked as ``x_out, y1_out, ..., yp_out``. If the input is
2363+
length ``N``, each of these arrays will be length ``2N + 1``.
23882364
23892365
Examples
23902366
--------
23912367
>> x_s, y1_s, y2_s = pts_to_poststep(x, y1, y2)
23922368
"""
2393-
# do normalization
2394-
vertices = _step_validation(x, *args)
2395-
# create the output array
2396-
steps = np.zeros((vertices.shape[0], 2 * len(x) - 1), float)
2397-
# do the to step conversion logic
2398-
steps[0, ::2], steps[0, 1:-1:2] = vertices[0, :], vertices[0, 1:]
2399-
steps[1:, 0::2], steps[1:, 1::2] = vertices[1:, :], vertices[1:, :-1]
2400-
2401-
# convert 2D array back to tuple
2402-
return tuple(steps)
2369+
steps = np.zeros((1 + len(args), 2 * len(x) - 1))
2370+
steps[0, 0::2] = x
2371+
steps[0, 1::2] = steps[0, 2::2]
2372+
steps[1:, 0::2] = args
2373+
steps[1:, 1::2] = steps[1:, 0:-2:2]
2374+
return steps
24032375

24042376

24052377
def pts_to_midstep(x, *args):
24062378
"""
2407-
Covert continuous line to pre-steps
2379+
Convert continuous line to mid-steps.
24082380
2409-
Given a set of N points convert to 2 N -1 points
2410-
which when connected linearly give a step function
2411-
which changes values at the middle of the intervals.
2381+
Given a set of ``N`` points convert to ``2N`` points which when connected
2382+
linearly give a step function which changes values at the middle of the
2383+
intervals.
24122384
24132385
Parameters
24142386
----------
24152387
x : array
2416-
The x location of the steps
2388+
The x location of the steps.
24172389
2418-
y1, y2, ... : array
2419-
Any number of y arrays to be turned into steps.
2420-
All must be the same length as ``x``
2390+
y1, ..., yp : array
2391+
y arrays to be turned into steps; all must be the same length as ``x``.
24212392
24222393
Returns
24232394
-------
2424-
x, y1, y2, .. : array
2425-
The x and y values converted to steps in the same order
2426-
as the input. If the input is length ``N``, each of these arrays
2427-
will be length ``2N + 1``
2428-
2395+
out : array
2396+
The x and y values converted to steps in the same order as the input;
2397+
can be unpacked as ``x_out, y1_out, ..., yp_out``. If the input is
2398+
length ``N``, each of these arrays will be length ``2N``.
24292399
24302400
Examples
24312401
--------
24322402
>> x_s, y1_s, y2_s = pts_to_midstep(x, y1, y2)
24332403
"""
2434-
# do normalization
2435-
vertices = _step_validation(x, *args)
2436-
# create the output array
2437-
steps = np.zeros((vertices.shape[0], 2 * len(x)), float)
2438-
steps[0, 1:-1:2] = 0.5 * (vertices[0, :-1] + vertices[0, 1:])
2439-
steps[0, 2::2] = 0.5 * (vertices[0, :-1] + vertices[0, 1:])
2440-
steps[0, 0] = vertices[0, 0]
2441-
steps[0, -1] = vertices[0, -1]
2442-
steps[1:, 0::2], steps[1:, 1::2] = vertices[1:, :], vertices[1:, :]
2443-
2444-
# convert 2D array back to tuple
2445-
return tuple(steps)
2404+
steps = np.zeros((1 + len(args), 2 * len(x)))
2405+
x = np.asanyarray(x)
2406+
steps[0, 1:-1:2] = steps[0, 2::2] = (x[:-1] + x[1:]) / 2
2407+
steps[0, 0], steps[0, -1] = x[0], x[-1]
2408+
steps[1:, 0::2] = args
2409+
steps[1:, 1::2] = steps[1:, 0::2]
2410+
return steps
24462411

24472412

24482413
STEP_LOOKUP_MAP = {'default': lambda x, y: (x, y),

lib/matplotlib/lines.py

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,27 +12,24 @@
1212
import warnings
1313

1414
import numpy as np
15-
from numpy import ma
16-
from . import artist, colors as mcolors
17-
from .artist import Artist
18-
from .cbook import (iterable, is_string_like, is_numlike, ls_mapper_r,
19-
pts_to_prestep, pts_to_poststep, pts_to_midstep, ls_mapper,
20-
is_hashable, STEP_LOOKUP_MAP)
2115

16+
from . import artist, colors as mcolors, docstring, rcParams
17+
from .artist import Artist, allow_rasterization
18+
from .cbook import (
19+
iterable, is_string_like, is_numlike, ls_mapper, ls_mapper_r, is_hashable,
20+
STEP_LOOKUP_MAP)
21+
from .markers import MarkerStyle
2222
from .path import Path
2323
from .transforms import Bbox, TransformedPath, IdentityTransform
2424

25-
from matplotlib import rcParams
26-
from .artist import allow_rasterization
27-
from matplotlib import docstring
28-
from matplotlib.markers import MarkerStyle
2925
# Imported here for backward compatibility, even though they don't
3026
# really belong.
31-
from matplotlib.markers import TICKLEFT, TICKRIGHT, TICKUP, TICKDOWN
32-
from matplotlib.markers import (
27+
from numpy import ma
28+
from . import _path
29+
from .markers import (
3330
CARETLEFT, CARETRIGHT, CARETUP, CARETDOWN,
34-
CARETLEFTBASE, CARETRIGHTBASE, CARETUPBASE, CARETDOWNBASE)
35-
from matplotlib import _path
31+
CARETLEFTBASE, CARETRIGHTBASE, CARETUPBASE, CARETDOWNBASE,
32+
TICKLEFT, TICKRIGHT, TICKUP, TICKDOWN)
3633

3734

3835
def _get_dash_pattern(style):

lib/matplotlib/tests/test_cbook.py

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -460,18 +460,14 @@ def test_to_midstep():
460460
assert_array_equal(y1_target, y1s)
461461

462462

463-
def test_step_fails():
463+
@pytest.mark.parametrize(
464+
"args",
465+
[(np.arange(12).reshape(3, 4), 'a'),
466+
(np.arange(12), 'a'),
467+
(np.arange(12), np.arange(3))])
468+
def test_step_fails(args):
464469
with pytest.raises(ValueError):
465-
cbook._step_validation(np.arange(12).reshape(3, 4), 'a')
466-
467-
with pytest.raises(ValueError):
468-
cbook._step_validation(np.arange(12), 'a')
469-
470-
with pytest.raises(ValueError):
471-
cbook._step_validation(np.arange(12))
472-
473-
with pytest.raises(ValueError):
474-
cbook._step_validation(np.arange(12), np.arange(3))
470+
cbook.pts_to_prestep(*args)
475471

476472

477473
def test_grouper():

0 commit comments

Comments
 (0)