From 833543dc97746dc03d633105419e133bd9141069 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Sat, 15 Jul 2017 17:14:09 +0100 Subject: [PATCH 1/5] BUG: Respect the lightsource argument in plot_surface and plot_trisurf --- lib/mpl_toolkits/mplot3d/axes3d.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/mpl_toolkits/mplot3d/axes3d.py b/lib/mpl_toolkits/mplot3d/axes3d.py index 211c807eb8c6..f28d1e4ff6f2 100644 --- a/lib/mpl_toolkits/mplot3d/axes3d.py +++ b/lib/mpl_toolkits/mplot3d/axes3d.py @@ -1688,7 +1688,7 @@ def get_normals(polygons): if fcolors is not None: if shade: - colset = self._shade_colors(colset, get_normals(polys)) + colset = self._shade_colors(colset, get_normals(polys), lightsource) polyc.set_facecolors(colset) polyc.set_edgecolors(colset) elif cmap: @@ -1701,7 +1701,7 @@ def get_normals(polygons): polyc.set_norm(norm) else: if shade: - colset = self._shade_colors(color, get_normals(polys)) + colset = self._shade_colors(color, get_normals(polys), lightsource) else: colset = color polyc.set_facecolors(colset) @@ -1725,13 +1725,16 @@ def _generate_normals(self, polygons): normals.append(np.cross(v1, v2)) return normals - def _shade_colors(self, color, normals): + def _shade_colors(self, color, normals, lightsource=None): ''' Shade *color* using normal vectors given by *normals*. *color* can also be an array of the same length as *normals*. ''' + if lightsource is None: + # chosen for backwards-compatibility + lightsource = LightSource(azdeg=225, altdeg=19.4712) - shade = np.array([np.dot(n / proj3d.mod(n), [-1, -1, 0.5]) + 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) @@ -1965,7 +1968,7 @@ def plot_trisurf(self, *args, color=None, norm=None, vmin=None, vmax=None, v1 = verts[:, 0, :] - verts[:, 1, :] v2 = verts[:, 1, :] - verts[:, 2, :] normals = np.cross(v1, v2) - colset = self._shade_colors(color, normals) + colset = self._shade_colors(color, normals, lightsource) else: colset = color polyc.set_facecolors(colset) From 9e73e2591ad90498d51ffb74688488eb6aaa0c5b Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Sat, 15 Jul 2017 17:38:22 +0100 Subject: [PATCH 2/5] DOC: Add documentation for lightsource parameter --- lib/mpl_toolkits/mplot3d/axes3d.py | 38 ++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/lib/mpl_toolkits/mplot3d/axes3d.py b/lib/mpl_toolkits/mplot3d/axes3d.py index f28d1e4ff6f2..87879e0eea0b 100644 --- a/lib/mpl_toolkits/mplot3d/axes3d.py +++ b/lib/mpl_toolkits/mplot3d/axes3d.py @@ -1593,7 +1593,11 @@ def plot_surface(self, X, Y, Z, *args, norm=None, vmin=None, Bounds for the normalization. shade : bool - Whether to shade the face colors. + Whether to shade the facecolors. Defaults to True. Shading is + always disabled when `cmap` is specified. + + lightsource : LightSource + The lightsource to use when `shade` is True. **kwargs : Other arguments are forwarded to `.Poly3DCollection`. @@ -1882,17 +1886,24 @@ def plot_wireframe(self, X, Y, Z, *args, **kwargs): def plot_trisurf(self, *args, color=None, norm=None, vmin=None, vmax=None, lightsource=None, **kwargs): """ - ============= ================================================ - Argument Description - ============= ================================================ - *X*, *Y*, *Z* Data values as 1D arrays - *color* Color of the surface patches - *cmap* A colormap for the surface patches. - *norm* An instance of Normalize to map values to colors - *vmin* Minimum value to map - *vmax* Maximum value to map - *shade* Whether to shade the facecolors - ============= ================================================ + + Parameters + ---------- + X, Y, Z : array-like + Data values as 1D arrays + color + Color of the surface patches + cmap + A colormap for the surface patches. + norm : Normalize + An instance of Normalize to map values to colors. + vmin, vmax : scalar, optional, default: None + Minimum and maximum value to map. + shade : bool + Whether to shade the facecolors. Defaults to True. Shading is + always disabled when `cmap` is specified. + lightsource : LightSource + The lightsource to use when `shade` is True. The (optional) triangulation can be specified in one of two ways; either:: @@ -1920,7 +1931,8 @@ def plot_trisurf(self, *args, color=None, norm=None, vmin=None, vmax=None, Other arguments are passed on to :class:`~mpl_toolkits.mplot3d.art3d.Poly3DCollection` - **Examples:** + Examples + -------- .. plot:: gallery/mplot3d/trisurf3d.py .. plot:: gallery/mplot3d/trisurf3d_2.py From ec18ea9592fbaae855efe491ed88d680be3f5ee1 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Sat, 15 Jul 2017 17:46:43 +0100 Subject: [PATCH 3/5] BUG: remove broken shading in plot_surface This didn't respect the x and y coordinates, so plotting `x{::-1], y{::-1], z[::-1,::-1]` would result in different shading to `x, y, z`. It also looked super screwy, and could only be triggered if `facecolors="do something wacky"` was passed --- lib/mpl_toolkits/mplot3d/axes3d.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/lib/mpl_toolkits/mplot3d/axes3d.py b/lib/mpl_toolkits/mplot3d/axes3d.py index 87879e0eea0b..b1afb56440d0 100644 --- a/lib/mpl_toolkits/mplot3d/axes3d.py +++ b/lib/mpl_toolkits/mplot3d/axes3d.py @@ -1648,10 +1648,6 @@ def plot_surface(self, X, Y, Z, *args, norm=None, vmin=None, cmap = kwargs.get('cmap', None) shade = kwargs.pop('shade', cmap is None) - # Shade the data - if shade and cmap is not None and fcolors is not None: - fcolors = self._shade_colors_lightsource(Z, cmap, lightsource) - # evenly spaced, and including both endpoints row_inds = list(range(0, rows-1, rstride)) + [rows-1] col_inds = list(range(0, cols-1, cstride)) + [cols-1] @@ -1758,11 +1754,6 @@ def _shade_colors(self, color, normals, lightsource=None): return colors - def _shade_colors_lightsource(self, data, cmap, lightsource): - if lightsource is None: - lightsource = LightSource(azdeg=135, altdeg=55) - return lightsource.shade(data, cmap) - def plot_wireframe(self, X, Y, Z, *args, **kwargs): """ Plot a 3D wireframe. From 4749752669113308155a5ff475d5b35dba9cd474 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Sun, 19 Aug 2018 11:35:39 -0700 Subject: [PATCH 4/5] DOC: Add sphinx links to the LightSource class --- lib/mpl_toolkits/mplot3d/axes3d.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/mpl_toolkits/mplot3d/axes3d.py b/lib/mpl_toolkits/mplot3d/axes3d.py index b1afb56440d0..ece0a8845398 100644 --- a/lib/mpl_toolkits/mplot3d/axes3d.py +++ b/lib/mpl_toolkits/mplot3d/axes3d.py @@ -1596,7 +1596,7 @@ def plot_surface(self, X, Y, Z, *args, norm=None, vmin=None, Whether to shade the facecolors. Defaults to True. Shading is always disabled when `cmap` is specified. - lightsource : LightSource + lightsource : `~matplotlib.colors.LightSource` The lightsource to use when `shade` is True. **kwargs : @@ -1893,7 +1893,7 @@ def plot_trisurf(self, *args, color=None, norm=None, vmin=None, vmax=None, shade : bool Whether to shade the facecolors. Defaults to True. Shading is always disabled when `cmap` is specified. - lightsource : LightSource + lightsource : `~matplotlib.colors.LightSource` The lightsource to use when `shade` is True. The (optional) triangulation can be specified in one of two ways; From b0561071d3a0c60257cb53e08b2f68cf292c4a0b Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Wed, 5 Sep 2018 22:37:42 -0700 Subject: [PATCH 5/5] DOC: Use emphasis for other parameters, fix parameters section to render correctly --- lib/mpl_toolkits/mplot3d/axes3d.py | 41 +++++++++++++++--------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/lib/mpl_toolkits/mplot3d/axes3d.py b/lib/mpl_toolkits/mplot3d/axes3d.py index ece0a8845398..27a88cbc6342 100644 --- a/lib/mpl_toolkits/mplot3d/axes3d.py +++ b/lib/mpl_toolkits/mplot3d/axes3d.py @@ -1877,24 +1877,7 @@ def plot_wireframe(self, X, Y, Z, *args, **kwargs): def plot_trisurf(self, *args, color=None, norm=None, vmin=None, vmax=None, lightsource=None, **kwargs): """ - - Parameters - ---------- - X, Y, Z : array-like - Data values as 1D arrays - color - Color of the surface patches - cmap - A colormap for the surface patches. - norm : Normalize - An instance of Normalize to map values to colors. - vmin, vmax : scalar, optional, default: None - Minimum and maximum value to map. - shade : bool - Whether to shade the facecolors. Defaults to True. Shading is - always disabled when `cmap` is specified. - lightsource : `~matplotlib.colors.LightSource` - The lightsource to use when `shade` is True. + Plot a triangulated surface. The (optional) triangulation can be specified in one of two ways; either:: @@ -1919,8 +1902,26 @@ def plot_trisurf(self, *args, color=None, norm=None, vmin=None, vmax=None, where *Z* is the array of values to contour, one per point in the triangulation. - Other arguments are passed on to - :class:`~mpl_toolkits.mplot3d.art3d.Poly3DCollection` + Parameters + ---------- + X, Y, Z : array-like + Data values as 1D arrays. + color + Color of the surface patches. + cmap + A colormap for the surface patches. + norm : Normalize + An instance of Normalize to map values to colors. + vmin, vmax : scalar, optional, default: None + Minimum and maximum value to map. + shade : bool + Whether to shade the facecolors. Defaults to True. Shading is + always disabled when *cmap* is specified. + lightsource : `~matplotlib.colors.LightSource` + The lightsource to use when *shade* is True. + **kwargs + All other arguments are passed on to + :class:`~mpl_toolkits.mplot3d.art3d.Poly3DCollection` Examples --------