From 5a1e7b3b996487983eef939599c36a67b620bb8c Mon Sep 17 00:00:00 2001 From: Roman Yurchak Date: Wed, 3 Oct 2018 10:39:00 +0200 Subject: [PATCH 1/6] Avoid memory copies with np.full --- lib/matplotlib/axes/_axes.py | 2 +- lib/matplotlib/hatch.py | 2 +- lib/matplotlib/legend_handler.py | 2 +- lib/matplotlib/path.py | 10 +++++----- lib/matplotlib/tri/triinterpolate.py | 2 +- lib/matplotlib/tri/trirefine.py | 4 ++-- lib/matplotlib/tri/tritools.py | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index 70472e05758a..a4172a4780fc 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -4000,7 +4000,7 @@ def dopatch(xs, ys, **kwargs): # maybe draw the fliers if showfliers: # fliers coords - flier_x = np.ones(len(stats['fliers'])) * pos + flier_x = np.full(len(stats['fliers']), pos) flier_y = stats['fliers'] fliers.extend(doplot( diff --git a/lib/matplotlib/hatch.py b/lib/matplotlib/hatch.py index 532840624d26..61e4a9a4ed64 100644 --- a/lib/matplotlib/hatch.py +++ b/lib/matplotlib/hatch.py @@ -169,7 +169,7 @@ def __init__(self, hatch, density): self.num_rows = (hatch.count('*')) * density path = Path.unit_regular_star(5) self.shape_vertices = path.vertices - self.shape_codes = np.ones(len(self.shape_vertices)) * Path.LINETO + self.shape_codes = np.full(len(self.shape_vertices), Path.LINETO) self.shape_codes[0] = Path.MOVETO Shapes.__init__(self, hatch, density) diff --git a/lib/matplotlib/legend_handler.py b/lib/matplotlib/legend_handler.py index 5d4e55a351da..bad493f662b4 100644 --- a/lib/matplotlib/legend_handler.py +++ b/lib/matplotlib/legend_handler.py @@ -231,7 +231,7 @@ def create_artists(self, legend, orig_handle, xdata, xdata_marker = self.get_xdata(legend, xdescent, ydescent, width, height, fontsize) - ydata = ((height - ydescent) / 2.) * np.ones(xdata.shape, float) + ydata = np.full(xdata.shape, ((height - ydescent) / 2.), float) legline = Line2D(xdata, ydata) self.update_prop(legline, orig_handle, legend) diff --git a/lib/matplotlib/path.py b/lib/matplotlib/path.py index 24dee6e58071..ccc15a89f4a5 100644 --- a/lib/matplotlib/path.py +++ b/lib/matplotlib/path.py @@ -312,7 +312,7 @@ def make_compound_path_from_polys(cls, XY): stride = numsides + 1 nverts = numpolys * stride verts = np.zeros((nverts, 2)) - codes = np.ones(nverts, int) * cls.LINETO + codes = np.full(nverts, cls.LINETO, dtype=int) codes[0::stride] = cls.MOVETO codes[numsides::stride] = cls.CLOSEPOLY for i in range(numsides): @@ -552,7 +552,7 @@ def interpolated(self, steps): vertices = simple_linear_interpolation(self.vertices, steps) codes = self.codes if codes is not None: - new_codes = Path.LINETO * np.ones(((len(codes) - 1) * steps + 1, )) + new_codes = np.full(((len(codes) - 1) * steps + 1, ), Path.LINETO) new_codes[0::steps] = codes else: new_codes = None @@ -802,7 +802,7 @@ def unit_circle_righthalf(cls): float) - codes = cls.CURVE4 * np.ones(14) + codes = np.full(14, cls.CURVE4) codes[0] = cls.MOVETO codes[-1] = cls.CLOSEPOLY @@ -864,7 +864,7 @@ def arc(cls, theta1, theta2, n=None, is_wedge=False): if is_wedge: length = n * 3 + 4 vertices = np.zeros((length, 2), float) - codes = cls.CURVE4 * np.ones((length, ), cls.code_type) + codes = np.full((length, ), cls.CURVE4, dtype=cls.code_type) vertices[1] = [xA[0], yA[0]] codes[0:2] = [cls.MOVETO, cls.LINETO] codes[-2:] = [cls.LINETO, cls.CLOSEPOLY] @@ -873,7 +873,7 @@ def arc(cls, theta1, theta2, n=None, is_wedge=False): else: length = n * 3 + 1 vertices = np.empty((length, 2), float) - codes = cls.CURVE4 * np.ones((length, ), cls.code_type) + codes = np.full((length, ), cls.CURVE4, dtype=cls.code_type) vertices[0] = [xA[0], yA[0]] codes[0] = cls.MOVETO vertex_offset = 1 diff --git a/lib/matplotlib/tri/triinterpolate.py b/lib/matplotlib/tri/triinterpolate.py index 070bd85700c9..2e235580508c 100644 --- a/lib/matplotlib/tri/triinterpolate.py +++ b/lib/matplotlib/tri/triinterpolate.py @@ -959,7 +959,7 @@ def get_Kff_and_Ff(self, J, ecc, triangles, Uc): """ ntri = np.size(ecc, 0) vec_range = np.arange(ntri, dtype=np.int32) - c_indices = -np.ones(ntri, dtype=np.int32) # for unused dofs, -1 + c_indices = np.full(ntri, -1, dtype=np.int32) # for unused dofs, -1 f_dof = [1, 2, 4, 5, 7, 8] c_dof = [0, 3, 6] diff --git a/lib/matplotlib/tri/trirefine.py b/lib/matplotlib/tri/trirefine.py index 4f55c1fa94b3..fed6d8c0f215 100644 --- a/lib/matplotlib/tri/trirefine.py +++ b/lib/matplotlib/tri/trirefine.py @@ -111,7 +111,7 @@ def refine_triangulation(self, return_tri_index=False, subdiv=3): # We have to initialize found_index with -1 because some nodes # may very well belong to no triangle at all, e.g., in case of # Delaunay Triangulation with DuplicatePointWarning. - found_index = - np.ones(refi_npts, dtype=np.int32) + found_index = np.full(refi_npts, -1, dtype=np.int32) tri_mask = self._triangulation.mask if tri_mask is None: found_index[refi_triangles] = np.repeat(ancestors, @@ -243,7 +243,7 @@ def _refine_triangulation_once(triangulation, ancestors=None): np.arange(ntri, dtype=np.int32)])) edge_apexes = np.ravel(np.vstack([np.zeros(ntri, dtype=np.int32), np.ones(ntri, dtype=np.int32), - np.ones(ntri, dtype=np.int32)*2])) + np.full(ntri, 2, dtype=np.int32)])) edge_neighbors = neighbors[edge_elems, edge_apexes] mask_masters = (edge_elems > edge_neighbors) diff --git a/lib/matplotlib/tri/tritools.py b/lib/matplotlib/tri/tritools.py index 94da837a1f5d..af5f75dbba75 100644 --- a/lib/matplotlib/tri/tritools.py +++ b/lib/matplotlib/tri/tritools.py @@ -292,7 +292,7 @@ def _total_to_compress_renum(mask, n=None): if n is None: n = np.size(mask) if mask is not None: - renum = -np.ones(n, dtype=np.int32) # Default num is -1 + renum = np.full(n, -1, dtype=np.int32) # Default num is -1 valid = np.arange(n, dtype=np.int32).compress(~mask, axis=0) renum[valid] = np.arange(np.size(valid, 0), dtype=np.int32) return renum From de37bc581a92654bf9bae49d52527b53ddfc74b6 Mon Sep 17 00:00:00 2001 From: Roman Yurchak Date: Wed, 3 Oct 2018 15:36:37 +0200 Subject: [PATCH 2/6] Explicitly specify the dtype in np.full --- lib/matplotlib/axes/_axes.py | 2 +- lib/matplotlib/hatch.py | 3 ++- lib/matplotlib/path.py | 5 +++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index a4172a4780fc..16dbb5ca6805 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -4000,7 +4000,7 @@ def dopatch(xs, ys, **kwargs): # maybe draw the fliers if showfliers: # fliers coords - flier_x = np.full(len(stats['fliers']), pos) + flier_x = np.full(len(stats['fliers']), pos, dtype='float64') flier_y = stats['fliers'] fliers.extend(doplot( diff --git a/lib/matplotlib/hatch.py b/lib/matplotlib/hatch.py index 61e4a9a4ed64..16a04bacb732 100644 --- a/lib/matplotlib/hatch.py +++ b/lib/matplotlib/hatch.py @@ -169,7 +169,8 @@ def __init__(self, hatch, density): self.num_rows = (hatch.count('*')) * density path = Path.unit_regular_star(5) self.shape_vertices = path.vertices - self.shape_codes = np.full(len(self.shape_vertices), Path.LINETO) + self.shape_codes = np.full(len(self.shape_vertices), Path.LINETO, + dtype='float64') self.shape_codes[0] = Path.MOVETO Shapes.__init__(self, hatch, density) diff --git a/lib/matplotlib/path.py b/lib/matplotlib/path.py index ccc15a89f4a5..74325f50259a 100644 --- a/lib/matplotlib/path.py +++ b/lib/matplotlib/path.py @@ -552,7 +552,8 @@ def interpolated(self, steps): vertices = simple_linear_interpolation(self.vertices, steps) codes = self.codes if codes is not None: - new_codes = np.full(((len(codes) - 1) * steps + 1, ), Path.LINETO) + new_codes = np.full(((len(codes) - 1) * steps + 1, ), Path.LINETO, + dtype='float64') new_codes[0::steps] = codes else: new_codes = None @@ -802,7 +803,7 @@ def unit_circle_righthalf(cls): float) - codes = np.full(14, cls.CURVE4) + codes = np.full(14, cls.CURVE4, dtype='float64') codes[0] = cls.MOVETO codes[-1] = cls.CLOSEPOLY From 2da85621bc01d234ae59c449c564929a945da4e2 Mon Sep 17 00:00:00 2001 From: Roman Yurchak Date: Thu, 4 Oct 2018 18:23:19 +0200 Subject: [PATCH 3/6] Address review comments --- lib/matplotlib/hatch.py | 2 +- lib/matplotlib/legend_handler.py | 2 +- lib/matplotlib/path.py | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/matplotlib/hatch.py b/lib/matplotlib/hatch.py index 16a04bacb732..90b33fada706 100644 --- a/lib/matplotlib/hatch.py +++ b/lib/matplotlib/hatch.py @@ -170,7 +170,7 @@ def __init__(self, hatch, density): path = Path.unit_regular_star(5) self.shape_vertices = path.vertices self.shape_codes = np.full(len(self.shape_vertices), Path.LINETO, - dtype='float64') + dtype='int32') self.shape_codes[0] = Path.MOVETO Shapes.__init__(self, hatch, density) diff --git a/lib/matplotlib/legend_handler.py b/lib/matplotlib/legend_handler.py index bad493f662b4..e693137914c7 100644 --- a/lib/matplotlib/legend_handler.py +++ b/lib/matplotlib/legend_handler.py @@ -231,7 +231,7 @@ def create_artists(self, legend, orig_handle, xdata, xdata_marker = self.get_xdata(legend, xdescent, ydescent, width, height, fontsize) - ydata = np.full(xdata.shape, ((height - ydescent) / 2.), float) + ydata = np.full(xdata.shape, ((height - ydescent) / 2), float) legline = Line2D(xdata, ydata) self.update_prop(legline, orig_handle, legend) diff --git a/lib/matplotlib/path.py b/lib/matplotlib/path.py index 74325f50259a..609e46066a16 100644 --- a/lib/matplotlib/path.py +++ b/lib/matplotlib/path.py @@ -312,7 +312,7 @@ def make_compound_path_from_polys(cls, XY): stride = numsides + 1 nverts = numpolys * stride verts = np.zeros((nverts, 2)) - codes = np.full(nverts, cls.LINETO, dtype=int) + codes = np.full(nverts, cls.LINETO, dtype=cls.code_type) codes[0::stride] = cls.MOVETO codes[numsides::stride] = cls.CLOSEPOLY for i in range(numsides): @@ -553,7 +553,7 @@ def interpolated(self, steps): codes = self.codes if codes is not None: new_codes = np.full(((len(codes) - 1) * steps + 1, ), Path.LINETO, - dtype='float64') + dtype=self.code_type) new_codes[0::steps] = codes else: new_codes = None @@ -803,7 +803,7 @@ def unit_circle_righthalf(cls): float) - codes = np.full(14, cls.CURVE4, dtype='float64') + codes = np.full(14, cls.CURVE4, dtype=cls.code_type) codes[0] = cls.MOVETO codes[-1] = cls.CLOSEPOLY From 95fa27f928f352fce859bf5457660ad0a0972c33 Mon Sep 17 00:00:00 2001 From: Roman Yurchak Date: Tue, 22 Jan 2019 14:26:28 +0100 Subject: [PATCH 4/6] Don't specify dtype as str --- lib/matplotlib/axes/_axes.py | 2 +- lib/matplotlib/hatch.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index 16dbb5ca6805..1548df33d97c 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -4000,7 +4000,7 @@ def dopatch(xs, ys, **kwargs): # maybe draw the fliers if showfliers: # fliers coords - flier_x = np.full(len(stats['fliers']), pos, dtype='float64') + flier_x = np.full(len(stats['fliers']), pos, dtype=np.float64) flier_y = stats['fliers'] fliers.extend(doplot( diff --git a/lib/matplotlib/hatch.py b/lib/matplotlib/hatch.py index 90b33fada706..abb83985c43a 100644 --- a/lib/matplotlib/hatch.py +++ b/lib/matplotlib/hatch.py @@ -170,7 +170,7 @@ def __init__(self, hatch, density): path = Path.unit_regular_star(5) self.shape_vertices = path.vertices self.shape_codes = np.full(len(self.shape_vertices), Path.LINETO, - dtype='int32') + dtype=np.int32) self.shape_codes[0] = Path.MOVETO Shapes.__init__(self, hatch, density) From d376dad7dc1ceda0b01544e02db5fa05ad793163 Mon Sep 17 00:00:00 2001 From: Roman Yurchak Date: Tue, 22 Jan 2019 16:42:00 +0100 Subject: [PATCH 5/6] More review comments --- lib/matplotlib/hatch.py | 2 +- lib/matplotlib/legend_handler.py | 2 +- lib/matplotlib/path.py | 6 +++--- lib/matplotlib/tri/trirefine.py | 8 ++------ 4 files changed, 7 insertions(+), 11 deletions(-) diff --git a/lib/matplotlib/hatch.py b/lib/matplotlib/hatch.py index abb83985c43a..f52c03c36fb2 100644 --- a/lib/matplotlib/hatch.py +++ b/lib/matplotlib/hatch.py @@ -170,7 +170,7 @@ def __init__(self, hatch, density): path = Path.unit_regular_star(5) self.shape_vertices = path.vertices self.shape_codes = np.full(len(self.shape_vertices), Path.LINETO, - dtype=np.int32) + dtype=Path.code_type) self.shape_codes[0] = Path.MOVETO Shapes.__init__(self, hatch, density) diff --git a/lib/matplotlib/legend_handler.py b/lib/matplotlib/legend_handler.py index e693137914c7..b2cd85d4677f 100644 --- a/lib/matplotlib/legend_handler.py +++ b/lib/matplotlib/legend_handler.py @@ -231,7 +231,7 @@ def create_artists(self, legend, orig_handle, xdata, xdata_marker = self.get_xdata(legend, xdescent, ydescent, width, height, fontsize) - ydata = np.full(xdata.shape, ((height - ydescent) / 2), float) + ydata = np.full_like(xdata, ((height - ydescent) / 2)) legline = Line2D(xdata, ydata) self.update_prop(legline, orig_handle, legend) diff --git a/lib/matplotlib/path.py b/lib/matplotlib/path.py index 609e46066a16..f8a4b9e05d53 100644 --- a/lib/matplotlib/path.py +++ b/lib/matplotlib/path.py @@ -552,7 +552,7 @@ def interpolated(self, steps): vertices = simple_linear_interpolation(self.vertices, steps) codes = self.codes if codes is not None: - new_codes = np.full(((len(codes) - 1) * steps + 1, ), Path.LINETO, + new_codes = np.full((len(codes) - 1) * steps + 1, Path.LINETO, dtype=self.code_type) new_codes[0::steps] = codes else: @@ -865,7 +865,7 @@ def arc(cls, theta1, theta2, n=None, is_wedge=False): if is_wedge: length = n * 3 + 4 vertices = np.zeros((length, 2), float) - codes = np.full((length, ), cls.CURVE4, dtype=cls.code_type) + codes = np.full(length, cls.CURVE4, dtype=cls.code_type) vertices[1] = [xA[0], yA[0]] codes[0:2] = [cls.MOVETO, cls.LINETO] codes[-2:] = [cls.LINETO, cls.CLOSEPOLY] @@ -874,7 +874,7 @@ def arc(cls, theta1, theta2, n=None, is_wedge=False): else: length = n * 3 + 1 vertices = np.empty((length, 2), float) - codes = np.full((length, ), cls.CURVE4, dtype=cls.code_type) + codes = np.full(length, cls.CURVE4, dtype=cls.code_type) vertices[0] = [xA[0], yA[0]] codes[0] = cls.MOVETO vertex_offset = 1 diff --git a/lib/matplotlib/tri/trirefine.py b/lib/matplotlib/tri/trirefine.py index fed6d8c0f215..cbee328c07f2 100644 --- a/lib/matplotlib/tri/trirefine.py +++ b/lib/matplotlib/tri/trirefine.py @@ -238,12 +238,8 @@ def _refine_triangulation_once(triangulation, ancestors=None): # (can be -1 if border edge) # For slave and master we will identify the apex pointing to the edge # start - edge_elems = np.ravel(np.vstack([np.arange(ntri, dtype=np.int32), - np.arange(ntri, dtype=np.int32), - np.arange(ntri, dtype=np.int32)])) - edge_apexes = np.ravel(np.vstack([np.zeros(ntri, dtype=np.int32), - np.ones(ntri, dtype=np.int32), - np.full(ntri, 2, dtype=np.int32)])) + edge_elems = np.tile(np.arange(3, dtype=np.int32), ntri) + edge_apexes = np.repeat(np.arange(3, dtype=np.int32), ntri) edge_neighbors = neighbors[edge_elems, edge_apexes] mask_masters = (edge_elems > edge_neighbors) From fec1fa075fa44451a6356ea4391f46b0419d34c3 Mon Sep 17 00:00:00 2001 From: Roman Yurchak Date: Tue, 22 Jan 2019 16:49:49 +0100 Subject: [PATCH 6/6] Fix tiling in trirefine.py --- lib/matplotlib/tri/trirefine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/tri/trirefine.py b/lib/matplotlib/tri/trirefine.py index cbee328c07f2..2ca862114731 100644 --- a/lib/matplotlib/tri/trirefine.py +++ b/lib/matplotlib/tri/trirefine.py @@ -238,7 +238,7 @@ def _refine_triangulation_once(triangulation, ancestors=None): # (can be -1 if border edge) # For slave and master we will identify the apex pointing to the edge # start - edge_elems = np.tile(np.arange(3, dtype=np.int32), ntri) + edge_elems = np.tile(np.arange(ntri, dtype=np.int32), 3) edge_apexes = np.repeat(np.arange(3, dtype=np.int32), ntri) edge_neighbors = neighbors[edge_elems, edge_apexes] mask_masters = (edge_elems > edge_neighbors)