From de0848e480f303facead838b58b54a9ffaf6f2ca Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Tue, 3 Oct 2017 18:09:45 -0700 Subject: [PATCH] Update docstrings and allow infinite counts for plot_{surface,wireframe}. Docstrings: Emphasize the downsampling. Clarify when the defaults for rstride and cstride apply. Passing an infinite rcount and ccount is the easiest way to ensure the data does not get downsampled (which I still think is a misfeature, but that's a battle for another day), but would result in a stride of zero; instead, ensure that the stride is at least 1. --- lib/mpl_toolkits/mplot3d/axes3d.py | 171 +++++++++++++++-------------- 1 file changed, 91 insertions(+), 80 deletions(-) diff --git a/lib/mpl_toolkits/mplot3d/axes3d.py b/lib/mpl_toolkits/mplot3d/axes3d.py index b2a560288022..46cc540661a3 100644 --- a/lib/mpl_toolkits/mplot3d/axes3d.py +++ b/lib/mpl_toolkits/mplot3d/axes3d.py @@ -1560,49 +1560,60 @@ def plot(self, xs, ys, *args, **kwargs): plot3D = plot def plot_surface(self, X, Y, Z, *args, **kwargs): - ''' + """ Create a surface plot. - By default it will be colored in shades of a solid color, - but it also supports color mapping by supplying the *cmap* - argument. - - The `rstride` and `cstride` kwargs set the stride used to - sample the input data to generate the graph. If 1k by 1k - arrays are passed in, the default values for the strides will - result in a 100x100 grid being plotted. Defaults to 10. - Raises a ValueError if both stride and count kwargs - (see next section) are provided. - - The `rcount` and `ccount` kwargs supersedes `rstride` and - `cstride` for default sampling method for surface plotting. - These arguments will determine at most how many evenly spaced - samples will be taken from the input data to generate the graph. - This is the default sampling method unless using the 'classic' - style. Will raise ValueError if both stride and count are - specified. - Added in v2.0.0. + By default it will be colored in shades of a solid color, but it also + supports color mapping by supplying the *cmap* argument. - ============= ================================================ - Argument Description - ============= ================================================ - *X*, *Y*, *Z* Data values as 2D arrays - *rstride* Array row stride (step size) - *cstride* Array column stride (step size) - *rcount* Use at most this many rows, defaults to 50 - *ccount* Use at most this many columns, defaults to 50 - *color* Color of the surface patches - *cmap* A colormap for the surface patches. - *facecolors* Face colors for the individual 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 - ============= ================================================ + .. note:: - Other arguments are passed on to - :class:`~mpl_toolkits.mplot3d.art3d.Poly3DCollection` - ''' + The *rcount* and *ccount* kwargs, which both default to 50, + determine the maximum number of samples used in each direction. If + the input data is larger, it will be downsampled (by slicing) to + these numbers of points. + + Parameters + ---------- + X, Y, Z : 2d arrays + Data values. + + rcount, ccount : int + Maximum number of samples used in each direction. If the input + data is larger, it will be downsampled (by slicing) to these + numbers of points. Defaults to 50. + + .. versionadded:: 2.0 + + rstride, cstride : int + Downsampling stride in each direction. These arguments are + mutually exclusive with *rcount* and *ccount*. If only one of + *rstride* or *cstride* is set, the other defaults to 10. + + 'classic' mode uses a default of ``rstride = cstride = 10`` instead + of the new default of ``rcount = ccount = 50``. + + color : color-like + Color of the surface patches. + + cmap : Colormap + Colormap of the surface patches. + + facecolors : array-like of colors. + Colors of each individual patch. + + norm : Normalize + Normalization for the colormap. + + vmin, vmax : float + Bounds for the normalization. + + shade : bool + Whether to shade the face colors. + + **kwargs : + Other arguments are forwarded to `~.Poly3DCollection`. + """ had_data = self.has_data() @@ -1628,14 +1639,14 @@ def plot_surface(self, X, Y, Z, *args, **kwargs): # So, only compute strides from counts # if counts were explicitly given if has_count: - rstride = int(np.ceil(rows / rcount)) - cstride = int(np.ceil(cols / ccount)) + rstride = int(max(np.ceil(rows / rcount), 1)) + cstride = int(max(np.ceil(cols / ccount), 1)) else: # If the strides are provided then it has priority. # Otherwise, compute the strides from the counts. if not has_stride: - rstride = int(np.ceil(rows / rcount)) - cstride = int(np.ceil(cols / ccount)) + rstride = int(max(np.ceil(rows / rcount), 1)) + cstride = int(max(np.ceil(cols / ccount), 1)) if 'facecolors' in kwargs: fcolors = kwargs.pop('facecolors') @@ -1779,44 +1790,44 @@ def _shade_colors_lightsource(self, data, cmap, lightsource): return lightsource.shade(data, cmap) def plot_wireframe(self, X, Y, Z, *args, **kwargs): - ''' + """ Plot a 3D wireframe. - The `rstride` and `cstride` kwargs set the stride used to - sample the input data to generate the graph. If either is 0 - the input data in not sampled along this direction producing a - 3D line plot rather than a wireframe plot. The stride arguments - are only used by default if in the 'classic' mode. They are - now superseded by `rcount` and `ccount`. Will raise ValueError - if both stride and count are used. - -` The `rcount` and `ccount` kwargs supersedes `rstride` and - `cstride` for default sampling method for wireframe plotting. - These arguments will determine at most how many evenly spaced - samples will be taken from the input data to generate the graph. - This is the default sampling method unless using the 'classic' - style. Will raise ValueError if both stride and count are - specified. If either is zero, then the input data is not sampled - along this direction, producing a 3D line plot rather than a - wireframe plot. - Added in v2.0.0. + .. note:: - ========== ================================================ - Argument Description - ========== ================================================ - *X*, *Y*, Data values as 2D arrays - *Z* - *rstride* Array row stride (step size), defaults to 1 - *cstride* Array column stride (step size), defaults to 1 - *rcount* Use at most this many rows, defaults to 50 - *ccount* Use at most this many columns, defaults to 50 - ========== ================================================ + The *rcount* and *ccount* kwargs, which both default to 50, + determine the maximum number of samples used in each direction. If + the input data is larger, it will be downsampled (by slicing) to + these numbers of points. - Keyword arguments are passed on to - :class:`~matplotlib.collections.LineCollection`. + Parameters + ---------- + X, Y, Z : 2d arrays + Data values. - Returns a :class:`~mpl_toolkits.mplot3d.art3d.Line3DCollection` - ''' + rcount, ccount : int + Maximum number of samples used in each direction. If the input + data is larger, it will be downsampled (by slicing) to these + numbers of points. Setting a count to zero causes the data to be + not sampled in the corresponding direction, producing a 3D line + plot rather than a wireframe plot. Defaults to 50. + + .. versionadded:: 2.0 + + rstride, cstride : int + Downsampling stride in each direction. These arguments are + mutually exclusive with *rcount* and *ccount*. If only one of + *rstride* or *cstride* is set, the other defaults to 1. Setting a + stride to zero causes the data to be not sampled in the + corresponding direction, producing a 3D line plot rather than a + wireframe plot. + + 'classic' mode uses a default of ``rstride = cstride = 1`` instead + of the new default of ``rcount = ccount = 50``. + + **kwargs : + Other arguments are forwarded to `~.Line3DCollection`. + """ had_data = self.has_data() if Z.ndim != 2: @@ -1841,14 +1852,14 @@ def plot_wireframe(self, X, Y, Z, *args, **kwargs): # So, only compute strides from counts # if counts were explicitly given if has_count: - rstride = int(np.ceil(rows / rcount)) if rcount else 0 - cstride = int(np.ceil(cols / ccount)) if ccount else 0 + rstride = int(max(np.ceil(rows / rcount), 1)) if rcount else 0 + cstride = int(max(np.ceil(cols / ccount), 1)) if ccount else 0 else: # If the strides are provided then it has priority. # Otherwise, compute the strides from the counts. if not has_stride: - rstride = int(np.ceil(rows / rcount)) if rcount else 0 - cstride = int(np.ceil(cols / ccount)) if ccount else 0 + rstride = int(max(np.ceil(rows / rcount), 1)) if rcount else 0 + cstride = int(max(np.ceil(cols / ccount), 1)) if ccount else 0 # We want two sets of lines, one running along the "rows" of # Z and another set of lines running along the "columns" of Z.