diff --git a/doc/api/api_changes/2018-12-20-AL-deprecations.rst b/doc/api/api_changes/2018-12-20-AL-deprecations.rst new file mode 100644 index 000000000000..56bd23bc85dd --- /dev/null +++ b/doc/api/api_changes/2018-12-20-AL-deprecations.rst @@ -0,0 +1,30 @@ +Deprecations +```````````` + +Multiple internal functions that were exposed as part of the public API +of ``mpl_toolkits.mplot3d`` are deprecated, + +**mpl_toolkits.mplot3d.art3d** + +- :func:`mpl_toolkits.mplot3d.art3d.norm_angle` +- :func:`mpl_toolkits.mplot3d.art3d.norm_text_angle` +- :func:`mpl_toolkits.mplot3d.art3d.path_to_3d_segment` +- :func:`mpl_toolkits.mplot3d.art3d.paths_to_3d_segments` +- :func:`mpl_toolkits.mplot3d.art3d.path_to_3d_segment_with_codes` +- :func:`mpl_toolkits.mplot3d.art3d.paths_to_3d_segments_with_codes` +- :func:`mpl_toolkits.mplot3d.art3d.get_patch_verts` +- :func:`mpl_toolkits.mplot3d.art3d.get_colors` +- :func:`mpl_toolkits.mplot3d.art3d.zalpha` + +**mpl_toolkits.mplot3d.proj3d** + +- :func:`mpl_toolkits.mplot3d.proj3d.line2d` +- :func:`mpl_toolkits.mplot3d.proj3d.line2d_dist` +- :func:`mpl_toolkits.mplot3d.proj3d.line2d_seg_dist` +- :func:`mpl_toolkits.mplot3d.proj3d.mod` +- :func:`mpl_toolkits.mplot3d.proj3d.proj_transform_vec` +- :func:`mpl_toolkits.mplot3d.proj3d.proj_transform_vec_clip` +- :func:`mpl_toolkits.mplot3d.proj3d.vec_pad_ones` +- :func:`mpl_toolkits.mplot3d.proj3d.proj_trans_clip_points` + +If your project relies on these functions, consider vendoring them. diff --git a/lib/mpl_toolkits/mplot3d/art3d.py b/lib/mpl_toolkits/mplot3d/art3d.py index 808ee5a95f7c..d38fa862b69e 100644 --- a/lib/mpl_toolkits/mplot3d/art3d.py +++ b/lib/mpl_toolkits/mplot3d/art3d.py @@ -20,7 +20,7 @@ from . import proj3d -def norm_angle(a): +def _norm_angle(a): """Return the given angle normalized to -180 < *a* <= 180 degrees.""" a = (a + 360) % 360 if a > 180: @@ -28,7 +28,13 @@ def norm_angle(a): return a -def norm_text_angle(a): +@cbook.deprecated("3.1") +def norm_angle(a): + """Return the given angle normalized to -180 < *a* <= 180 degrees.""" + return _norm_angle(a) + + +def _norm_text_angle(a): """Return the given angle normalized to -90 < *a* <= 90 degrees.""" a = (a + 180) % 180 if a > 90: @@ -36,6 +42,12 @@ def norm_text_angle(a): return a +@cbook.deprecated("3.1") +def norm_text_angle(a): + """Return the given angle normalized to -90 < *a* <= 90 degrees.""" + return _norm_text_angle(a) + + def get_dir_vector(zdir): """ Return a direction vector. @@ -109,7 +121,7 @@ def draw(self, renderer): dy = proj[1][1] - proj[1][0] angle = math.degrees(math.atan2(dy, dx)) self.set_position((proj[0][0], proj[1][0])) - self.set_rotation(norm_text_angle(angle)) + self.set_rotation(_norm_text_angle(angle)) mtext.Text.draw(self, renderer) self.stale = False @@ -200,7 +212,7 @@ def line_2d_to_3d(line, zs=0, zdir='z'): line.set_3d_properties(zs, zdir) -def path_to_3d_segment(path, zs=0, zdir='z'): +def _path_to_3d_segment(path, zs=0, zdir='z'): """Convert a path to a 3D segment.""" zs = np.broadcast_to(zs, len(path)) @@ -210,16 +222,28 @@ def path_to_3d_segment(path, zs=0, zdir='z'): return seg3d -def paths_to_3d_segments(paths, zs=0, zdir='z'): +@cbook.deprecated("3.1") +def path_to_3d_segment(path, zs=0, zdir='z'): + """Convert a path to a 3D segment.""" + return _path_to_3d_segment(path, zs=zs, zdir=zdir) + + +def _paths_to_3d_segments(paths, zs=0, zdir='z'): """Convert paths from a collection object to 3D segments.""" zs = np.broadcast_to(zs, len(paths)) - segs = [path_to_3d_segment(path, pathz, zdir) + segs = [_path_to_3d_segment(path, pathz, zdir) for path, pathz in zip(paths, zs)] return segs -def path_to_3d_segment_with_codes(path, zs=0, zdir='z'): +@cbook.deprecated("3.1") +def paths_to_3d_segments(paths, zs=0, zdir='z'): + """Convert paths from a collection object to 3D segments.""" + return _paths_to_3d_segments(paths, zs=zs, zdir=zdir) + + +def _path_to_3d_segment_with_codes(path, zs=0, zdir='z'): """Convert a path to a 3D segment with path codes.""" zs = np.broadcast_to(zs, len(path)) @@ -234,13 +258,19 @@ def path_to_3d_segment_with_codes(path, zs=0, zdir='z'): return seg3d, list(codes) -def paths_to_3d_segments_with_codes(paths, zs=0, zdir='z'): +@cbook.deprecated("3.1") +def path_to_3d_segment_with_codes(path, zs=0, zdir='z'): + """Convert a path to a 3D segment with path codes.""" + return _path_to_3d_segment_with_codes(path, zs=zs, zdir=zdir) + + +def _paths_to_3d_segments_with_codes(paths, zs=0, zdir='z'): """ Convert paths from a collection object to 3D segments with path codes. """ zs = np.broadcast_to(zs, len(paths)) - segments_codes = [path_to_3d_segment_with_codes(path, pathz, zdir) + segments_codes = [_path_to_3d_segment_with_codes(path, pathz, zdir) for path, pathz in zip(paths, zs)] if segments_codes: segments, codes = zip(*segments_codes) @@ -249,6 +279,14 @@ def paths_to_3d_segments_with_codes(paths, zs=0, zdir='z'): return list(segments), list(codes) +@cbook.deprecated("3.1") +def paths_to_3d_segments_with_codes(paths, zs=0, zdir='z'): + """ + Convert paths from a collection object to 3D segments with path codes. + """ + return _paths_to_3d_segments_with_codes(paths, zs=zs, zdir=zdir) + + class Line3DCollection(LineCollection): """ A collection of 3D lines. @@ -291,7 +329,7 @@ def draw(self, renderer, project=False): def line_collection_2d_to_3d(col, zs=0, zdir='z'): """Convert a LineCollection to a Line3DCollection object.""" - segments3d = paths_to_3d_segments(col.get_paths(), zs, zdir) + segments3d = _paths_to_3d_segments(col.get_paths(), zs, zdir) col.__class__ = Line3DCollection col.set_segments(segments3d) @@ -350,7 +388,7 @@ def do_3d_projection(self, renderer): return min(vzs) -def get_patch_verts(patch): +def _get_patch_verts(patch): """Return a list of vertices for the path of a patch.""" trans = patch.get_patch_transform() path = patch.get_path() @@ -361,9 +399,15 @@ def get_patch_verts(patch): return [] +@cbook.deprecated("3.1") +def get_patch_verts(patch): + """Return a list of vertices for the path of a patch.""" + return _get_patch_verts(patch) + + def patch_2d_to_3d(patch, z=0, zdir='z'): """Convert a Patch to a Patch3D object.""" - verts = get_patch_verts(patch) + verts = _get_patch_verts(patch) patch.__class__ = Patch3D patch.set_3d_properties(verts, z, zdir) @@ -427,12 +471,12 @@ def do_3d_projection(self, renderer): xs, ys, zs = self._offsets3d vxs, vys, vzs, vis = proj3d.proj_transform_clip(xs, ys, zs, renderer.M) - fcs = (zalpha(self._facecolor3d, vzs) if self._depthshade else + fcs = (_zalpha(self._facecolor3d, vzs) if self._depthshade else self._facecolor3d) fcs = mcolors.to_rgba_array(fcs, self._alpha) self.set_facecolors(fcs) - ecs = (zalpha(self._edgecolor3d, vzs) if self._depthshade else + ecs = (_zalpha(self._edgecolor3d, vzs) if self._depthshade else self._edgecolor3d) ecs = mcolors.to_rgba_array(ecs, self._alpha) self.set_edgecolors(ecs) @@ -493,12 +537,12 @@ def do_3d_projection(self, renderer): xs, ys, zs = self._offsets3d vxs, vys, vzs, vis = proj3d.proj_transform_clip(xs, ys, zs, renderer.M) - fcs = (zalpha(self._facecolor3d, vzs) if self._depthshade else + fcs = (_zalpha(self._facecolor3d, vzs) if self._depthshade else self._facecolor3d) fcs = mcolors.to_rgba_array(fcs, self._alpha) self.set_facecolors(fcs) - ecs = (zalpha(self._edgecolor3d, vzs) if self._depthshade else + ecs = (_zalpha(self._edgecolor3d, vzs) if self._depthshade else self._edgecolor3d) ecs = mcolors.to_rgba_array(ecs, self._alpha) self.set_edgecolors(ecs) @@ -643,7 +687,7 @@ def do_3d_projection(self, renderer): self.update_scalarmappable() self._facecolors3d = self._facecolors - txs, tys, tzs = proj3d.proj_transform_vec(self._vec, renderer.M) + txs, tys, tzs = proj3d._proj_transform_vec(self._vec, renderer.M) xyzlist = [(txs[si:ei], tys[si:ei], tzs[si:ei]) for si, ei in self._segis] @@ -681,7 +725,7 @@ def do_3d_projection(self, renderer): # Return zorder value if self._sort_zpos is not None: zvec = np.array([[0], [0], [self._sort_zpos], [1]]) - ztrans = proj3d.proj_transform_vec(zvec, renderer.M) + ztrans = proj3d._proj_transform_vec(zvec, renderer.M) return ztrans[2][0] elif tzs.size > 0: # FIXME: Some results still don't look quite right. @@ -734,8 +778,8 @@ def get_edgecolor(self): def poly_collection_2d_to_3d(col, zs=0, zdir='z'): """Convert a PolyCollection to a Poly3DCollection object.""" - segments_3d, codes = paths_to_3d_segments_with_codes(col.get_paths(), - zs, zdir) + segments_3d, codes = _paths_to_3d_segments_with_codes( + col.get_paths(), zs, zdir) col.__class__ = Poly3DCollection col.set_verts_and_codes(segments_3d, codes) col.set_3d_properties() @@ -777,14 +821,20 @@ def rotate_axes(xs, ys, zs, zdir): return xs, ys, zs -def get_colors(c, num): +def _get_colors(c, num): """Stretch the color argument to provide the required number *num*.""" return np.broadcast_to( mcolors.to_rgba_array(c) if len(c) else [0, 0, 0, 0], (num, 4)) -def zalpha(colors, zs): +@cbook.deprecated("3.1") +def get_colors(c, num): + """Stretch the color argument to provide the required number *num*.""" + return _get_colors(c, num) + + +def _zalpha(colors, zs): """Modify the alphas of the color list according to depth.""" # FIXME: This only works well if the points for *zs* are well-spaced # in all three dimensions. Otherwise, at certain orientations, @@ -796,3 +846,9 @@ def zalpha(colors, zs): sats = 1 - norm(zs) * 0.7 rgba = np.broadcast_to(mcolors.to_rgba_array(colors), (len(zs), 4)) return np.column_stack([rgba[:, :3], rgba[:, 3] * sats]) + + +@cbook.deprecated("3.1") +def zalpha(colors, zs): + """Modify the alphas of the color list according to depth.""" + return _zalpha(colors, zs) diff --git a/lib/mpl_toolkits/mplot3d/axes3d.py b/lib/mpl_toolkits/mplot3d/axes3d.py index 8f2857ee4dfc..468b3aa4cc0e 100644 --- a/lib/mpl_toolkits/mplot3d/axes3d.py +++ b/lib/mpl_toolkits/mplot3d/axes3d.py @@ -1027,7 +1027,7 @@ def get_proj(self): self.eye = E self.vvec = R - E - self.vvec = self.vvec / proj3d.mod(self.vvec) + self.vvec = self.vvec / proj3d._mod(self.vvec) if abs(relev) > np.pi/2: # upside down @@ -1162,7 +1162,7 @@ def format_coord(self, xd, yd): # nearest edge p0, p1 = min(self.tunit_edges(), - key=lambda edge: proj3d.line2d_seg_dist( + key=lambda edge: proj3d._line2d_seg_dist( edge[0], edge[1], (xd, yd))) # scale the z value to match @@ -1209,8 +1209,8 @@ def _on_move(self, event): # get the x and y pixel coords if dx == 0 and dy == 0: return - self.elev = art3d.norm_angle(self.elev - (dy/h)*180) - self.azim = art3d.norm_angle(self.azim - (dx/w)*180) + self.elev = art3d._norm_angle(self.elev - (dy/h)*180) + self.azim = art3d._norm_angle(self.azim - (dx/w)*180) self.get_proj() self.stale = True self.figure.canvas.draw_idle() @@ -1762,8 +1762,8 @@ def _shade_colors(self, color, normals, lightsource=None): # chosen for backwards-compatibility lightsource = LightSource(azdeg=225, altdeg=19.4712) - shade = np.array([np.dot(n / proj3d.mod(n), lightsource.direction) - if proj3d.mod(n) else np.nan + shade = np.array([np.dot(n / proj3d._mod(n), lightsource.direction) + if proj3d._mod(n) else np.nan for n in normals]) mask = ~np.isnan(shade) @@ -2029,8 +2029,8 @@ def _3d_extend_contour(self, cset, stride=5): paths = linec.get_paths() if not paths: continue - topverts = art3d.paths_to_3d_segments(paths, z - dz) - botverts = art3d.paths_to_3d_segments(paths, z + dz) + topverts = art3d._paths_to_3d_segments(paths, z - dz) + botverts = art3d._paths_to_3d_segments(paths, z + dz) color = linec.get_color()[0] @@ -2394,7 +2394,7 @@ def bar(self, left, height, zs=0, zdir='z', *args, **kwargs): verts = [] verts_zs = [] for p, z in zip(patches, zs): - vs = art3d.get_patch_verts(p) + vs = art3d._get_patch_verts(p) verts += vs.tolist() verts_zs += [z] * len(vs) art3d.patch_2d_to_3d(p, z, zdir) diff --git a/lib/mpl_toolkits/mplot3d/axis3d.py b/lib/mpl_toolkits/mplot3d/axis3d.py index ba43685b2282..4fb5ad6ae68a 100644 --- a/lib/mpl_toolkits/mplot3d/axis3d.py +++ b/lib/mpl_toolkits/mplot3d/axis3d.py @@ -298,7 +298,7 @@ def draw(self, renderer): renderer.M) self.label.set_position((tlx, tly)) if self.get_rotate_label(self.label.get_text()): - angle = art3d.norm_text_angle(np.rad2deg(np.arctan2(dy, dx))) + angle = art3d._norm_text_angle(np.rad2deg(np.arctan2(dy, dx))) self.label.set_rotation(angle) self.label.set_va(info['label']['va']) self.label.set_ha(info['label']['ha']) @@ -321,7 +321,7 @@ def draw(self, renderer): pos[0], pos[1], pos[2], renderer.M) self.offsetText.set_text(self.major.formatter.get_offset()) self.offsetText.set_position((olx, oly)) - angle = art3d.norm_text_angle(np.rad2deg(np.arctan2(dy, dx))) + angle = art3d._norm_text_angle(np.rad2deg(np.arctan2(dy, dx))) self.offsetText.set_rotation(angle) # Must set rotation mode to "anchor" so that # the alignment point is used as the "fulcrum" for rotation. diff --git a/lib/mpl_toolkits/mplot3d/proj3d.py b/lib/mpl_toolkits/mplot3d/proj3d.py index 64df8db655f1..41a5df3845f8 100644 --- a/lib/mpl_toolkits/mplot3d/proj3d.py +++ b/lib/mpl_toolkits/mplot3d/proj3d.py @@ -6,7 +6,10 @@ import numpy as np import numpy.linalg as linalg +from matplotlib import cbook + +@cbook.deprecated("3.1") def line2d(p0, p1): """ Return 2D equation of line in the form ax+by+c = 0 @@ -30,6 +33,7 @@ def line2d(p0, p1): return a, b, c +@cbook.deprecated("3.1") def line2d_dist(l, p): """ Distance from line to point @@ -40,7 +44,7 @@ def line2d_dist(l, p): return abs((a*x0 + b*y0 + c) / np.hypot(a, b)) -def line2d_seg_dist(p1, p2, p0): +def _line2d_seg_dist(p1, p2, p0): """distance(s) from line defined by p1 - p2 to point(s) p0 p0[0] = x(s) @@ -62,11 +66,30 @@ def line2d_seg_dist(p1, p2, p0): return d -def mod(v): +@cbook.deprecated("3.1") +def line2d_seg_dist(p1, p2, p0): + """distance(s) from line defined by p1 - p2 to point(s) p0 + + p0[0] = x(s) + p0[1] = y(s) + + intersection point p = p1 + u*(p2-p1) + and intersection point lies within segment if u is between 0 and 1 + """ + return _line2d_seg_dist(p1, p2, p0) + + +def _mod(v): """3d vector length""" return np.sqrt(v[0]**2+v[1]**2+v[2]**2) +@cbook.deprecated("3.1") +def mod(v): + """3d vector length""" + return _mod(v) + + def world_transformation(xmin, xmax, ymin, ymax, zmin, zmax): @@ -91,9 +114,9 @@ def view_transformation(E, R, V): ## end new ## old - n = n / mod(n) + n = n / _mod(n) u = np.cross(V, n) - u = u / mod(u) + u = u / _mod(u) v = np.cross(n, u) Mr = [[u[0], u[1], u[2], 0], [v[0], v[1], v[2], 0], @@ -128,7 +151,7 @@ def ortho_transformation(zfront, zback): [0, 0, a, b]]) -def proj_transform_vec(vec, M): +def _proj_transform_vec(vec, M): vecw = np.dot(M, vec) w = vecw[3] # clip here.. @@ -136,7 +159,12 @@ def proj_transform_vec(vec, M): return txs, tys, tzs -def proj_transform_vec_clip(vec, M): +@cbook.deprecated("3.1") +def proj_transform_vec(vec, M): + return _proj_transform_vec(vec, M) + + +def _proj_transform_vec_clip(vec, M): vecw = np.dot(M, vec) w = vecw[3] # clip here. @@ -147,9 +175,14 @@ def proj_transform_vec_clip(vec, M): return txs, tys, tzs, tis +@cbook.deprecated("3.1") +def proj_transform_vec_clip(vec, M): + return _proj_transform_vec_clip(vec, M) + + def inv_transform(xs, ys, zs, M): iM = linalg.inv(M) - vec = vec_pad_ones(xs, ys, zs) + vec = _vec_pad_ones(xs, ys, zs) vecr = np.dot(iM, vec) try: vecr = vecr / vecr[3] @@ -158,16 +191,21 @@ def inv_transform(xs, ys, zs, M): return vecr[0], vecr[1], vecr[2] -def vec_pad_ones(xs, ys, zs): +def _vec_pad_ones(xs, ys, zs): return np.array([xs, ys, zs, np.ones_like(xs)]) +@cbook.deprecated("3.1") +def vec_pad_ones(xs, ys, zs): + return _vec_pad_ones(xs, ys, zs) + + def proj_transform(xs, ys, zs, M): """ Transform the points by the projection matrix """ - vec = vec_pad_ones(xs, ys, zs) - return proj_transform_vec(vec, M) + vec = _vec_pad_ones(xs, ys, zs) + return _proj_transform_vec(vec, M) transform = proj_transform @@ -179,8 +217,8 @@ def proj_transform_clip(xs, ys, zs, M): and return the clipping result returns txs,tys,tzs,tis """ - vec = vec_pad_ones(xs, ys, zs) - return proj_transform_vec_clip(vec, M) + vec = _vec_pad_ones(xs, ys, zs) + return _proj_transform_vec_clip(vec, M) def proj_points(points, M): @@ -192,6 +230,7 @@ def proj_trans_points(points, M): return proj_transform(xs, ys, zs, M) +@cbook.deprecated("3.1") def proj_trans_clip_points(points, M): xs, ys, zs = zip(*points) return proj_transform_clip(xs, ys, zs, M) diff --git a/lib/mpl_toolkits/tests/test_mplot3d.py b/lib/mpl_toolkits/tests/test_mplot3d.py index a1d3fd6653e9..23986f5b1ec3 100644 --- a/lib/mpl_toolkits/tests/test_mplot3d.py +++ b/lib/mpl_toolkits/tests/test_mplot3d.py @@ -2,7 +2,9 @@ from mpl_toolkits.mplot3d import Axes3D, axes3d, proj3d, art3d from matplotlib import cm +from matplotlib import path as mpath from matplotlib.testing.decorators import image_comparison, check_figures_equal +from matplotlib.cbook.deprecation import MatplotlibDeprecationWarning from matplotlib.collections import LineCollection, PolyCollection from matplotlib.patches import Circle import matplotlib.pyplot as plt @@ -618,8 +620,8 @@ def test_lines_dists(): ys = (100, 150, 30, 200) ax.scatter(xs, ys) - dist = proj3d.line2d_seg_dist(p0, p1, (xs[0], ys[0])) - dist = proj3d.line2d_seg_dist(p0, p1, np.array((xs, ys))) + dist = proj3d._line2d_seg_dist(p0, p1, (xs[0], ys[0])) + dist = proj3d._line2d_seg_dist(p0, p1, np.array((xs, ys))) for x, y, d in zip(xs, ys, dist): c = Circle((x, y), d, fill=0) ax.add_patch(c) @@ -842,3 +844,58 @@ def test_inverted_cla(): assert not ax.xaxis_inverted() assert not ax.yaxis_inverted() assert not ax.zaxis_inverted() + + +def test_art3d_deprecated(): + + with pytest.warns(MatplotlibDeprecationWarning): + art3d.norm_angle(0.0) + + with pytest.warns(MatplotlibDeprecationWarning): + art3d.norm_text_angle(0.0) + + path = mpath.Path(np.empty((0, 2))) + + with pytest.warns(MatplotlibDeprecationWarning): + art3d.path_to_3d_segment(path) + + with pytest.warns(MatplotlibDeprecationWarning): + art3d.paths_to_3d_segments([path]) + + with pytest.warns(MatplotlibDeprecationWarning): + art3d.path_to_3d_segment_with_codes(path) + + with pytest.warns(MatplotlibDeprecationWarning): + art3d.paths_to_3d_segments_with_codes([path]) + + with pytest.warns(MatplotlibDeprecationWarning): + art3d.get_colors([], 1) + + with pytest.warns(MatplotlibDeprecationWarning): + art3d.zalpha([], []) + + +def test_proj3d_deprecated(): + with pytest.warns(MatplotlibDeprecationWarning): + proj3d.line2d([0, 1], [0, 1]) + + with pytest.warns(MatplotlibDeprecationWarning): + proj3d.line2d_dist([0, 1, 3], [0, 1]) + + with pytest.warns(MatplotlibDeprecationWarning): + proj3d.mod([1, 1, 1]) + + vec = np.arange(4) + M = np.ones((4, 4)) + + with pytest.warns(MatplotlibDeprecationWarning): + proj3d.proj_transform_vec(vec, M) + + with pytest.warns(MatplotlibDeprecationWarning): + proj3d.proj_transform_vec_clip(vec, M) + + with pytest.warns(MatplotlibDeprecationWarning): + proj3d.vec_pad_ones(np.ones(3), np.ones(3), np.ones(3)) + + with pytest.warns(MatplotlibDeprecationWarning): + proj3d.proj_trans_clip_points(np.ones((4, 3)), M) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy