From a68784fdd5f97d90e80c86a17551b19c0a466dbc Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Tue, 20 Feb 2018 01:29:47 -0800 Subject: [PATCH] Change manual kwargs popping to kwonly arguments. Only simple cases (no mutable defaults, no defaults depending on other args) are handled so far. --- examples/api/radar_chart.py | 3 +- .../contour_demo.py | 3 +- examples/scales/custom_scale.py | 5 +- .../custom_figure_class.py | 5 +- .../usetex_baseline_test.py | 21 ++---- .../user_interfaces/toolmanager_sgskip.py | 6 +- lib/matplotlib/__init__.py | 4 +- lib/matplotlib/axes/_axes.py | 24 +++---- lib/matplotlib/axes/_base.py | 13 ++-- lib/matplotlib/axis.py | 3 +- lib/matplotlib/backends/backend_agg.py | 8 +-- lib/matplotlib/backends/backend_pdf.py | 15 +++-- lib/matplotlib/backends/backend_pgf.py | 8 +-- lib/matplotlib/backends/backend_ps.py | 25 +++---- lib/matplotlib/backends/backend_svg.py | 11 ++- lib/matplotlib/backends/backend_template.py | 3 +- lib/matplotlib/backends/backend_webagg.py | 14 ++-- lib/matplotlib/contour.py | 37 +++++----- lib/matplotlib/figure.py | 5 +- lib/matplotlib/image.py | 5 +- lib/matplotlib/legend.py | 14 ++-- lib/matplotlib/projections/__init__.py | 25 ++++--- lib/matplotlib/projections/geo.py | 8 +-- lib/matplotlib/projections/polar.py | 13 ++-- lib/matplotlib/table.py | 6 +- lib/matplotlib/tests/test_figure.py | 5 +- lib/mpl_toolkits/axes_grid/axes_grid.py | 14 ++-- lib/mpl_toolkits/axes_grid1/axes_divider.py | 12 +--- lib/mpl_toolkits/axes_grid1/axes_grid.py | 11 +-- lib/mpl_toolkits/axes_grid1/axes_rgb.py | 6 +- lib/mpl_toolkits/axes_grid1/parasite_axes.py | 24 +++---- lib/mpl_toolkits/axisartist/axes_grid.py | 14 ++-- lib/mpl_toolkits/axisartist/axis_artist.py | 24 +++---- lib/mpl_toolkits/axisartist/axislines.py | 16 ++--- lib/mpl_toolkits/mplot3d/art3d.py | 21 +++--- lib/mpl_toolkits/mplot3d/axes3d.py | 67 ++++++------------- lib/mpl_toolkits/mplot3d/axis3d.py | 5 +- 37 files changed, 199 insertions(+), 304 deletions(-) diff --git a/examples/api/radar_chart.py b/examples/api/radar_chart.py index 814f79425405..c9b4c31340ef 100644 --- a/examples/api/radar_chart.py +++ b/examples/api/radar_chart.py @@ -64,9 +64,8 @@ def __init__(self, *args, **kwargs): # rotate plot such that the first axis is at the top self.set_theta_zero_location('N') - def fill(self, *args, **kwargs): + def fill(self, *args, closed=True, **kwargs): """Override fill so that line is closed by default""" - closed = kwargs.pop('closed', True) return super().fill(closed=closed, *args, **kwargs) def plot(self, *args, **kwargs): diff --git a/examples/images_contours_and_fields/contour_demo.py b/examples/images_contours_and_fields/contour_demo.py index a3366c88979a..510767501628 100644 --- a/examples/images_contours_and_fields/contour_demo.py +++ b/examples/images_contours_and_fields/contour_demo.py @@ -98,8 +98,7 @@ plt.setp(zc, linewidth=4) ax.clabel(CS, levels[1::2], # label every second level - inline=1, fmt='%1.1f', - cmap='flag', fontsize=14) + inline=1, fmt='%1.1f', fontsize=14) # make a colorbar for the contour lines CB = fig.colorbar(CS, shrink=0.8, extend='both') diff --git a/examples/scales/custom_scale.py b/examples/scales/custom_scale.py index 8150a5b2101c..b19025e4c0d4 100644 --- a/examples/scales/custom_scale.py +++ b/examples/scales/custom_scale.py @@ -44,7 +44,7 @@ class MercatorLatitudeScale(mscale.ScaleBase): # scale. name = 'mercator' - def __init__(self, axis, **kwargs): + def __init__(self, axis, *, thresh=np.deg2rad(85), **kwargs): """ Any keyword arguments passed to ``set_xscale`` and ``set_yscale`` will be passed along to the scale's @@ -53,8 +53,7 @@ def __init__(self, axis, **kwargs): thresh: The degree above which to crop the data. """ mscale.ScaleBase.__init__(self) - thresh = kwargs.pop("thresh", np.radians(85)) - if thresh >= np.pi / 2.0: + if thresh >= np.pi / 2: raise ValueError("thresh must be less than pi/2") self.thresh = thresh diff --git a/examples/subplots_axes_and_figures/custom_figure_class.py b/examples/subplots_axes_and_figures/custom_figure_class.py index 7e7b92721739..db1315f1f590 100644 --- a/examples/subplots_axes_and_figures/custom_figure_class.py +++ b/examples/subplots_axes_and_figures/custom_figure_class.py @@ -12,12 +12,11 @@ class MyFigure(Figure): - def __init__(self, *args, **kwargs): + def __init__(self, *args, figtitle='hi mom', **kwargs): """ custom kwarg figtitle is a figure title """ - figtitle = kwargs.pop('figtitle', 'hi mom') - Figure.__init__(self, *args, **kwargs) + super().__init__(*args, **kwargs) self.text(0.5, 0.95, figtitle, ha='center') diff --git a/examples/text_labels_and_annotations/usetex_baseline_test.py b/examples/text_labels_and_annotations/usetex_baseline_test.py index 1a222b61a912..6d8b79177d17 100644 --- a/examples/text_labels_and_annotations/usetex_baseline_test.py +++ b/examples/text_labels_and_annotations/usetex_baseline_test.py @@ -20,22 +20,15 @@ class Axes(maxes.Axes): usetex=False in the same figure. It does not work in the ps backend. """ - def __init__(self, *kl, **kw): - self.usetex = kw.pop("usetex", "False") - self.preview = kw.pop("preview", "False") - - maxes.Axes.__init__(self, *kl, **kw) + def __init__(self, *args, usetex=False, preview=False, **kwargs): + self.usetex = usetex + self.preview = preview + super().__init__(*args, **kwargs) def draw(self, renderer): - usetex = plt.rcParams["text.usetex"] - preview = plt.rcParams["text.latex.preview"] - plt.rcParams["text.usetex"] = self.usetex - plt.rcParams["text.latex.preview"] = self.preview - - maxes.Axes.draw(self, renderer) - - plt.rcParams["text.usetex"] = usetex - plt.rcParams["text.latex.preview"] = preview + with plt.rc_context({"text.usetex": self.usetex, + "text.latex.preview": self.preview}): + super().draw(renderer) subplot = maxes.subplot_class_factory(Axes) diff --git a/examples/user_interfaces/toolmanager_sgskip.py b/examples/user_interfaces/toolmanager_sgskip.py index 7c2eeae5b845..6ae0fc3d88e9 100644 --- a/examples/user_interfaces/toolmanager_sgskip.py +++ b/examples/user_interfaces/toolmanager_sgskip.py @@ -56,9 +56,9 @@ class GroupHideTool(ToolToggleBase): description = 'Show by gid' default_toggled = True - def __init__(self, *args, **kwargs): - self.gid = kwargs.pop('gid') - ToolToggleBase.__init__(self, *args, **kwargs) + def __init__(self, *args, gid, **kwargs): + self.gid = gid + super().__init__(*args, **kwargs) def enable(self, *args): self.set_lines_visibility(True) diff --git a/lib/matplotlib/__init__.py b/lib/matplotlib/__init__.py index 0a3b20a15269..869ce0354272 100644 --- a/lib/matplotlib/__init__.py +++ b/lib/matplotlib/__init__.py @@ -1703,7 +1703,7 @@ def param(func): pass @functools.wraps(func) - def inner(ax, *args, **kwargs): + def inner(ax, *args, data=None, **kwargs): # this is needed because we want to change these values if # arg_names_at_runtime==True, but python does not allow assigning # to a variable in a outer scope. So use some new local ones and @@ -1714,8 +1714,6 @@ def inner(ax, *args, **kwargs): label = None - data = kwargs.pop('data', None) - if data is None: # data validation args = tuple(sanitize_sequence(a) for a in args) else: diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index 1e1b4347bb22..33a749e34871 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -5243,20 +5243,14 @@ def imshow(self, X, cmap=None, norm=None, aspect=None, return im @staticmethod - def _pcolorargs(funcname, *args, **kw): - # This takes one kwarg, allmatch. - # If allmatch is True, then the incoming X, Y, C must - # have matching dimensions, taking into account that - # X and Y can be 1-D rather than 2-D. This perfect - # match is required for Gouroud shading. For flat - # shading, X and Y specify boundaries, so we need - # one more boundary than color in each direction. - # For convenience, and consistent with Matlab, we - # discard the last row and/or column of C if necessary - # to meet this condition. This is done if allmatch - # is False. - - allmatch = kw.pop("allmatch", False) + def _pcolorargs(funcname, *args, allmatch=False): + # If allmatch is True, then the incoming X, Y, C must have matching + # dimensions, taking into account that X and Y can be 1-D rather than + # 2-D. This perfect match is required for Gouroud shading. For flat + # shading, X and Y specify boundaries, so we need one more boundary + # than color in each direction. For convenience, and consistent with + # Matlab, we discard the last row and/or column of C if necessary to + # meet this condition. This is done if allmatch is False. if len(args) == 1: C = np.asanyarray(args[0]) @@ -5303,7 +5297,7 @@ def _pcolorargs(funcname, *args, **kw): 'Incompatible X, Y inputs to %s; see help(%s)' % ( funcname, funcname)) if allmatch: - if not (Nx == numCols and Ny == numRows): + if (Nx, Ny) != (numCols, numRows): raise TypeError('Dimensions of C %s are incompatible with' ' X (%d) and/or Y (%d); see help(%s)' % ( C.shape, Nx, Ny, funcname)) diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py index 2bedc1e724e7..ecce9837a9aa 100644 --- a/lib/matplotlib/axes/_base.py +++ b/lib/matplotlib/axes/_base.py @@ -2683,7 +2683,8 @@ def grid(self, b=None, which='major', axis='both', **kwargs): if axis == 'y' or axis == 'both': self.yaxis.grid(b, which=which, **kwargs) - def ticklabel_format(self, **kwargs): + def ticklabel_format(self, *, axis='both', style='', scilimits=None, + useOffset=None, useLocale=None, useMathText=None): """ Change the `~matplotlib.ticker.ScalarFormatter` used by default for linear axes. @@ -2693,6 +2694,7 @@ def ticklabel_format(self, **kwargs): ============== ========================================= Keyword Description ============== ========================================= + *axis* [ 'x' | 'y' | 'both' ] *style* [ 'sci' (or 'scientific') | 'plain' ] plain turns off scientific notation *scilimits* (m, n), pair of integers; if *style* @@ -2705,7 +2707,6 @@ def ticklabel_format(self, **kwargs): if False, no offset will be used; if a numeric offset is specified, it will be used. - *axis* [ 'x' | 'y' | 'both' ] *useLocale* If True, format the number according to the current locale. This affects things such as the character used for the @@ -2724,12 +2725,8 @@ def ticklabel_format(self, **kwargs): :exc:`AttributeError` will be raised. """ - style = kwargs.pop('style', '').lower() - scilimits = kwargs.pop('scilimits', None) - useOffset = kwargs.pop('useOffset', None) - useLocale = kwargs.pop('useLocale', None) - useMathText = kwargs.pop('useMathText', None) - axis = kwargs.pop('axis', 'both').lower() + style = style.lower() + axis = axis.lower() if scilimits is not None: try: m, n = scilimits diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index b3a7ffcc3ca3..ba591fe15912 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -1616,7 +1616,7 @@ def set_pickradius(self, pickradius): """ self.pickradius = pickradius - def set_ticklabels(self, ticklabels, *args, **kwargs): + def set_ticklabels(self, ticklabels, *args, minor=False, **kwargs): """ Set the text values of the tick labels. Return a list of Text instances. Use *kwarg* *minor=True* to select minor ticks. @@ -1645,7 +1645,6 @@ def set_ticklabels(self, ticklabels, *args, **kwargs): # replace the ticklabels list with the processed one ticklabels = get_labels - minor = kwargs.pop('minor', False) if minor: self.set_minor_formatter(mticker.FixedFormatter(ticklabels)) ticks = self.get_minor_ticks() diff --git a/lib/matplotlib/backends/backend_agg.py b/lib/matplotlib/backends/backend_agg.py index b17ab46ca27d..bf4b85032a80 100644 --- a/lib/matplotlib/backends/backend_agg.py +++ b/lib/matplotlib/backends/backend_agg.py @@ -516,7 +516,7 @@ def print_to_buffer(self): if _has_pil: # add JPEG support - def print_jpg(self, filename_or_obj, *args, **kwargs): + def print_jpg(self, filename_or_obj, *args, dryrun=False, **kwargs): """ Other Parameters ---------------- @@ -536,7 +536,7 @@ def print_jpg(self, filename_or_obj, *args, **kwargs): should be stored as a progressive JPEG file. """ buf, size = self.print_to_buffer() - if kwargs.pop("dryrun", False): + if dryrun: return # The image is "pasted" onto a white background image to safely # handle any transparency @@ -557,9 +557,9 @@ def print_jpg(self, filename_or_obj, *args, **kwargs): print_jpeg = print_jpg # add TIFF support - def print_tif(self, filename_or_obj, *args, **kwargs): + def print_tif(self, filename_or_obj, *args, dryrun=False, **kwargs): buf, size = self.print_to_buffer() - if kwargs.pop("dryrun", False): + if dryrun: return image = Image.frombuffer('RGBA', size, buf, 'raw', 'RGBA', 0, 1) dpi = (self.figure.dpi, self.figure.dpi) diff --git a/lib/matplotlib/backends/backend_pdf.py b/lib/matplotlib/backends/backend_pdf.py index ca0e797411f7..32a825f171bf 100644 --- a/lib/matplotlib/backends/backend_pdf.py +++ b/lib/matplotlib/backends/backend_pdf.py @@ -2560,21 +2560,22 @@ def draw(self): def get_default_filetype(self): return 'pdf' - def print_pdf(self, filename, **kwargs): - image_dpi = kwargs.get('dpi', 72) # dpi to use for images + def print_pdf(self, filename, *, + dpi=72, # dpi to use for images + bbox_inches_restore=None, metadata=None, + **kwargs): self.figure.set_dpi(72) # there are 72 pdf points to an inch width, height = self.figure.get_size_inches() if isinstance(filename, PdfPages): file = filename._file else: - file = PdfFile(filename, metadata=kwargs.pop("metadata", None)) + file = PdfFile(filename, metadata=metadata) try: file.newPage(width, height) - _bbox_inches_restore = kwargs.pop("bbox_inches_restore", None) renderer = MixedModeRenderer( - self.figure, width, height, image_dpi, - RendererPdf(file, image_dpi, height, width), - bbox_inches_restore=_bbox_inches_restore) + self.figure, width, height, dpi, + RendererPdf(file, dpi, height, width), + bbox_inches_restore=bbox_inches_restore) self.figure.draw(renderer) renderer.finalize() if not isinstance(filename, PdfPages): diff --git a/lib/matplotlib/backends/backend_pgf.py b/lib/matplotlib/backends/backend_pgf.py index eaa243203ad3..817cc0e93e79 100644 --- a/lib/matplotlib/backends/backend_pgf.py +++ b/lib/matplotlib/backends/backend_pgf.py @@ -802,8 +802,9 @@ class FigureCanvasPgf(FigureCanvasBase): def get_default_filetype(self): return 'pdf' - def _print_pgf_to_fh(self, fh, *args, **kwargs): - if kwargs.get("dryrun", False): + def _print_pgf_to_fh(self, fh, *args, + dryrun=False, bbox_inches_restore=None, **kwargs): + if dryrun: renderer = RendererPgf(self.figure, None, dummy=True) self.figure.draw(renderer) return @@ -849,10 +850,9 @@ def _print_pgf_to_fh(self, fh, *args, **kwargs): r"\pgfpathrectangle{\pgfpointorigin}{\pgfqpoint{%fin}{%fin}}" % (w, h)) writeln(fh, r"\pgfusepath{use as bounding box, clip}") - _bbox_inches_restore = kwargs.pop("bbox_inches_restore", None) renderer = MixedModeRenderer(self.figure, w, h, dpi, RendererPgf(self.figure, fh), - bbox_inches_restore=_bbox_inches_restore) + bbox_inches_restore=bbox_inches_restore) self.figure.draw(renderer) # end the pgfpicture environment diff --git a/lib/matplotlib/backends/backend_ps.py b/lib/matplotlib/backends/backend_ps.py index d3bc8814545e..4025cb90a14d 100644 --- a/lib/matplotlib/backends/backend_ps.py +++ b/lib/matplotlib/backends/backend_ps.py @@ -959,9 +959,11 @@ def _print_ps(self, outfile, format, *args, **kwargs): orientation, isLandscape, papertype, **kwargs) - def _print_figure(self, outfile, format, dpi=72, facecolor='w', edgecolor='w', - orientation='portrait', isLandscape=False, papertype=None, - metadata=None, **kwargs): + def _print_figure( + self, outfile, format, dpi=72, facecolor='w', edgecolor='w', + orientation='portrait', isLandscape=False, papertype=None, + metadata=None, *, + dryrun=False, bbox_inches_restore=None, **kwargs): """ Render the figure to hardcopy. Set the figure patch face and edge colors. This is useful because some of the GUIs have a @@ -1031,8 +1033,6 @@ def _print_figure(self, outfile, format, dpi=72, facecolor='w', edgecolor='w', self.figure.set_facecolor(facecolor) self.figure.set_edgecolor(edgecolor) - - dryrun = kwargs.get("dryrun", False) if dryrun: class NullWriter(object): def write(self, *kl, **kwargs): @@ -1042,14 +1042,12 @@ def write(self, *kl, **kwargs): else: self._pswriter = io.StringIO() - # mixed mode rendering - _bbox_inches_restore = kwargs.pop("bbox_inches_restore", None) ps_renderer = self._renderer_class(width, height, self._pswriter, imagedpi=dpi) renderer = MixedModeRenderer(self.figure, width, height, dpi, ps_renderer, - bbox_inches_restore=_bbox_inches_restore) + bbox_inches_restore=bbox_inches_restore) self.figure.draw(renderer) @@ -1199,9 +1197,10 @@ def do_nothing(): with io.open(outfile, 'w', encoding='latin-1') as fh: print_figure_impl(fh) - def _print_figure_tex(self, outfile, format, dpi, facecolor, edgecolor, - orientation, isLandscape, papertype, metadata=None, - **kwargs): + def _print_figure_tex( + self, outfile, format, dpi, facecolor, edgecolor, + orientation, isLandscape, papertype, metadata=None, *, + dryrun=False, bbox_inches_restore=None, **kwargs): """ If text.usetex is True in rc, a temporary pair of tex/eps files are created to allow tex to manage the text layout via the PSFrags @@ -1236,7 +1235,6 @@ def _print_figure_tex(self, outfile, format, dpi, facecolor, edgecolor, self.figure.set_facecolor(facecolor) self.figure.set_edgecolor(edgecolor) - dryrun = kwargs.get("dryrun", False) if dryrun: class NullWriter(object): def write(self, *kl, **kwargs): @@ -1247,12 +1245,11 @@ def write(self, *kl, **kwargs): self._pswriter = io.StringIO() # mixed mode rendering - _bbox_inches_restore = kwargs.pop("bbox_inches_restore", None) ps_renderer = self._renderer_class(width, height, self._pswriter, imagedpi=dpi) renderer = MixedModeRenderer(self.figure, width, height, dpi, ps_renderer, - bbox_inches_restore=_bbox_inches_restore) + bbox_inches_restore=bbox_inches_restore) self.figure.draw(renderer) diff --git a/lib/matplotlib/backends/backend_svg.py b/lib/matplotlib/backends/backend_svg.py index 7aa0b39e309b..3c8326905486 100644 --- a/lib/matplotlib/backends/backend_svg.py +++ b/lib/matplotlib/backends/backend_svg.py @@ -1215,17 +1215,16 @@ def print_svgz(self, filename, *args, **kwargs): gzip.GzipFile(mode='w', fileobj=fh) as gzipwriter: return self.print_svg(gzipwriter) - def _print_svg(self, filename, fh, **kwargs): - image_dpi = kwargs.pop("dpi", 72) + def _print_svg( + self, filename, fh, *, dpi=72, bbox_inches_restore=None, **kwargs): self.figure.set_dpi(72.0) width, height = self.figure.get_size_inches() w, h = width * 72, height * 72 - _bbox_inches_restore = kwargs.pop("bbox_inches_restore", None) renderer = MixedModeRenderer( - self.figure, width, height, image_dpi, - RendererSVG(w, h, fh, filename, image_dpi), - bbox_inches_restore=_bbox_inches_restore) + self.figure, width, height, dpi, + RendererSVG(w, h, fh, filename, dpi), + bbox_inches_restore=bbox_inches_restore) self.figure.draw(renderer) renderer.finalize() diff --git a/lib/matplotlib/backends/backend_template.py b/lib/matplotlib/backends/backend_template.py index af5637efc37f..384a69850230 100644 --- a/lib/matplotlib/backends/backend_template.py +++ b/lib/matplotlib/backends/backend_template.py @@ -185,7 +185,7 @@ def show(block=None): pass -def new_figure_manager(num, *args, **kwargs): +def new_figure_manager(num, *args, FigureClass=Figure, **kwargs): """ Create a new figure manager instance """ @@ -195,7 +195,6 @@ def new_figure_manager(num, *args, **kwargs): # backend_wx, backend_wxagg and backend_tkagg for examples. Not all GUIs # require explicit instantiation of a main-level app (egg backend_gtk, # backend_gtkagg) for pylab. - FigureClass = kwargs.pop('FigureClass', Figure) thisFig = FigureClass(*args, **kwargs) return new_figure_manager_given_figure(num, thisFig) diff --git a/lib/matplotlib/backends/backend_webagg.py b/lib/matplotlib/backends/backend_webagg.py index 4891047a35c1..18a995b97619 100644 --- a/lib/matplotlib/backends/backend_webagg.py +++ b/lib/matplotlib/backends/backend_webagg.py @@ -68,10 +68,9 @@ def get(self): self.write(image_path.read_bytes()) class SingleFigurePage(tornado.web.RequestHandler): - def __init__(self, application, request, **kwargs): - self.url_prefix = kwargs.pop('url_prefix', '') - tornado.web.RequestHandler.__init__(self, application, - request, **kwargs) + def __init__(self, application, request, *, url_prefix='', **kwargs): + self.url_prefix = url_prefix + super().__init__(application, request, **kwargs) def get(self, fignum): fignum = int(fignum) @@ -88,10 +87,9 @@ def get(self, fignum): canvas=manager.canvas) class AllFiguresPage(tornado.web.RequestHandler): - def __init__(self, application, request, **kwargs): - self.url_prefix = kwargs.pop('url_prefix', '') - tornado.web.RequestHandler.__init__(self, application, - request, **kwargs) + def __init__(self, application, request, *, url_prefix='', **kwargs): + self.url_prefix = url_prefix + super().__init__(application, request, **kwargs) def get(self): ws_uri = 'ws://{req.host}{prefix}/'.format(req=self.request, diff --git a/lib/matplotlib/contour.py b/lib/matplotlib/contour.py index 6e473671419e..39b5775ee2f9 100644 --- a/lib/matplotlib/contour.py +++ b/lib/matplotlib/contour.py @@ -12,7 +12,7 @@ import matplotlib.path as mpath import matplotlib.ticker as ticker import matplotlib.cm as cm -import matplotlib.colors as colors +import matplotlib.colors as mcolors import matplotlib.collections as mcoll import matplotlib.font_manager as font_manager import matplotlib.text as text @@ -51,7 +51,10 @@ def get_rotation(self): class ContourLabeler(object): """Mixin to provide labelling capability to ContourSet""" - def clabel(self, *args, **kwargs): + def clabel(self, *args, + fontsize=None, inline=True, inline_spacing=5, fmt='%1.3f', + colors=None, use_clabeltext=False, manual=False, + rightside_up=True): """ Label a contour plot. @@ -153,18 +156,12 @@ def clabel(self, *args, **kwargs): `BlockingContourLabeler` (case of manual label placement). """ - fontsize = kwargs.get('fontsize', None) - inline = kwargs.get('inline', 1) - inline_spacing = kwargs.get('inline_spacing', 5) - self.labelFmt = kwargs.get('fmt', '%1.3f') - _colors = kwargs.get('colors', None) + self.labelFmt = fmt + self._use_clabeltext = use_clabeltext + # Detect if manual selection is desired and remove from argument list. + self.labelManual = manual + self.rightside_up = rightside_up - self._use_clabeltext = kwargs.get('use_clabeltext', False) - - # Detect if manual selection is desired and remove from argument list - self.labelManual = kwargs.get('manual', False) - - self.rightside_up = kwargs.get('rightside_up', True) if len(args) == 0: levels = self.levels indices = list(range(len(self.cvalues))) @@ -188,14 +185,14 @@ def clabel(self, *args, **kwargs): font_size_pts = self.labelFontProps.get_size_in_points() self.labelFontSizeList = [font_size_pts] * len(levels) - if _colors is None: + if colors is None: self.labelMappable = self self.labelCValueList = np.take(self.cvalues, self.labelIndiceList) else: - cmap = colors.ListedColormap(_colors, N=len(self.labelLevelList)) + cmap = mcolors.ListedColormap(colors, N=len(self.labelLevelList)) self.labelCValueList = list(range(len(self.labelLevelList))) self.labelMappable = cm.ScalarMappable(cmap=cmap, - norm=colors.NoNorm()) + norm=mcolors.NoNorm()) self.labelXYs = [] @@ -822,11 +819,11 @@ def __init__(self, ax, *args, **kwargs): self.nchunk = kwargs.pop('nchunk', 0) self.locator = kwargs.pop('locator', None) - if (isinstance(norm, colors.LogNorm) + if (isinstance(norm, mcolors.LogNorm) or isinstance(self.locator, ticker.LogLocator)): self.logscale = True if norm is None: - norm = colors.LogNorm() + norm = mcolors.LogNorm() else: self.logscale = False @@ -867,7 +864,7 @@ def __init__(self, ax, *args, **kwargs): if extend_min: i0 = 1 - cmap = colors.ListedColormap(self.colors[i0:None], N=ncolors) + cmap = mcolors.ListedColormap(self.colors[i0:None], N=ncolors) if use_set_under_over: if extend_min: @@ -1249,7 +1246,7 @@ def _process_colors(self): if self.extend in ('both', 'max'): i1 += 1 self.cvalues = list(range(i0, i1)) - self.set_norm(colors.NoNorm()) + self.set_norm(mcolors.NoNorm()) else: self.cvalues = self.layers self.set_array(self.levels) diff --git a/lib/matplotlib/figure.py b/lib/matplotlib/figure.py index 9e6980b007e6..fd209d0c5ad0 100644 --- a/lib/matplotlib/figure.py +++ b/lib/matplotlib/figure.py @@ -677,7 +677,7 @@ def get_window_extent(self, *args, **kwargs): """ return self.bbox - def suptitle(self, t, **kwargs): + def suptitle(self, t, *, x=.5, y=.98, **kwargs): """ Add a centered title to the figure. @@ -731,9 +731,6 @@ def suptitle(self, t, **kwargs): >>> fig.suptitle('This is the figure title', fontsize=12) """ - x = kwargs.pop('x', 0.5) - y = kwargs.pop('y', 0.98) - if ('horizontalalignment' not in kwargs) and ('ha' not in kwargs): kwargs['horizontalalignment'] = 'center' if ('verticalalignment' not in kwargs) and ('va' not in kwargs): diff --git a/lib/matplotlib/image.py b/lib/matplotlib/image.py index 81357ecb2cc4..eb20bc2b6361 100644 --- a/lib/matplotlib/image.py +++ b/lib/matplotlib/image.py @@ -887,15 +887,14 @@ def get_cursor_data(self, event): class NonUniformImage(AxesImage): - def __init__(self, ax, **kwargs): + def __init__(self, ax, *, interpolation='nearest', **kwargs): """ kwargs are identical to those for AxesImage, except that 'nearest' and 'bilinear' are the only supported 'interpolation' options. """ - interp = kwargs.pop('interpolation', 'nearest') super().__init__(ax, **kwargs) - self.set_interpolation(interp) + self.set_interpolation(interpolation) def _check_unsampled_image(self, renderer): """ diff --git a/lib/matplotlib/legend.py b/lib/matplotlib/legend.py index 39ffbcc737ba..c345a31f1940 100644 --- a/lib/matplotlib/legend.py +++ b/lib/matplotlib/legend.py @@ -1174,7 +1174,7 @@ def _get_legend_handles_labels(axs, legend_handler_map=None): return handles, labels -def _parse_legend_args(axs, *args, **kwargs): +def _parse_legend_args(axs, *args, handles=None, labels=None, **kwargs): """ Get the handles and labels from the calls to either ``figure.legend`` or ``axes.legend``. @@ -1184,17 +1184,11 @@ def _parse_legend_args(axs, *args, **kwargs): log = logging.getLogger(__name__) handlers = kwargs.get('handler_map', {}) or {} - - # Support handles and labels being passed as keywords. - handles = kwargs.pop('handles', None) - labels = kwargs.pop('labels', None) - extra_args = () - if (handles is not None or labels is not None) and len(args): - warnings.warn("You have mixed positional and keyword " - "arguments, some input may be " - "discarded.") + if (handles is not None or labels is not None) and args: + warnings.warn("You have mixed positional and keyword arguments, some " + "input may be discarded.") # if got both handles and labels as kwargs, make same length if handles and labels: diff --git a/lib/matplotlib/projections/__init__.py b/lib/matplotlib/projections/__init__.py index 3da609b8051d..2b63bca083ca 100644 --- a/lib/matplotlib/projections/__init__.py +++ b/lib/matplotlib/projections/__init__.py @@ -1,8 +1,9 @@ +from .. import axes from .geo import AitoffAxes, HammerAxes, LambertAxes, MollweideAxes from .polar import PolarAxes -from matplotlib import axes -class ProjectionRegistry(object): + +class ProjectionRegistry: """ Manages the set of projections available to the system. """ @@ -11,7 +12,7 @@ def __init__(self): def register(self, *projections): """ - Register a new set of projection(s). + Register a new set of projections. """ for projection in projections: name = projection.name @@ -25,12 +26,12 @@ def get_projection_class(self, name): def get_projection_names(self): """ - Get a list of the names of all projections currently - registered. + Get a list of the names of all projections currently registered. """ return sorted(self._all_projection_types) -projection_registry = ProjectionRegistry() + +projection_registry = ProjectionRegistry() projection_registry.register( axes.Axes, PolarAxes, @@ -48,8 +49,7 @@ def get_projection_class(projection=None): """ Get a projection class from its name. - If *projection* is None, a standard rectilinear projection is - returned. + If *projection* is None, a standard rectilinear projection is returned. """ if projection is None: projection = 'rectilinear' @@ -57,10 +57,11 @@ def get_projection_class(projection=None): try: return projection_registry.get_projection_class(projection) except KeyError: - raise ValueError("Unknown projection '%s'" % projection) + raise ValueError("Unknown projection %r" % projection) -def process_projection_requirements(figure, *args, **kwargs): +def process_projection_requirements( + figure, *args, polar=False, projection=None, **kwargs): """ Handle the args/kwargs to add_axes/add_subplot/gca, returning:: @@ -68,9 +69,7 @@ def process_projection_requirements(figure, *args, **kwargs): which can be used for new axes initialization/identification. """ - ispolar = kwargs.pop('polar', False) - projection = kwargs.pop('projection', None) - if ispolar: + if polar: if projection is not None and projection != 'polar': raise ValueError( "polar=True, yet projection=%r. " diff --git a/lib/matplotlib/projections/geo.py b/lib/matplotlib/projections/geo.py index 842c047459a8..f82bed8b2244 100644 --- a/lib/matplotlib/projections/geo.py +++ b/lib/matplotlib/projections/geo.py @@ -518,10 +518,10 @@ def inverted(self): self._resolution) inverted.__doc__ = Transform.inverted.__doc__ - def __init__(self, *args, **kwargs): - self._longitude_cap = np.pi / 2.0 - self._center_longitude = kwargs.pop("center_longitude", 0.0) - self._center_latitude = kwargs.pop("center_latitude", 0.0) + def __init__(self, *args, center_longitude=0, center_latitude=0, **kwargs): + self._longitude_cap = np.pi / 2 + self._center_longitude = center_longitude + self._center_latitude = center_latitude GeoAxes.__init__(self, *args, **kwargs) self.set_aspect('equal', adjustable='box', anchor='C') self.cla() diff --git a/lib/matplotlib/projections/polar.py b/lib/matplotlib/projections/polar.py index fb139ff01cb3..015d4ea382ae 100644 --- a/lib/matplotlib/projections/polar.py +++ b/lib/matplotlib/projections/polar.py @@ -838,16 +838,17 @@ class PolarAxes(Axes): """ name = 'polar' - def __init__(self, *args, **kwargs): + def __init__(self, *args, + theta_offset=0, theta_direction=1, rlabel_position=22.5, + **kwargs): """ Create a new Polar Axes for a polar plot. """ - self._default_theta_offset = kwargs.pop('theta_offset', 0) - self._default_theta_direction = kwargs.pop('theta_direction', 1) - self._default_rlabel_position = np.deg2rad( - kwargs.pop('rlabel_position', 22.5)) + self._default_theta_offset = theta_offset + self._default_theta_direction = theta_direction + self._default_rlabel_position = np.deg2rad(rlabel_position) - Axes.__init__(self, *args, **kwargs) + super().__init__(*args, **kwargs) self.use_sticky_edges = True self.set_aspect('equal', adjustable='box', anchor='C') self.cla() diff --git a/lib/matplotlib/table.py b/lib/matplotlib/table.py index 86a874a2d6cf..abd398357ea8 100644 --- a/lib/matplotlib/table.py +++ b/lib/matplotlib/table.py @@ -146,7 +146,6 @@ def set_text_props(self, **kwargs): class CustomCell(Cell): """ A subclass of Cell where the sides may be visibly toggled. - """ _edges = 'BRTL' @@ -156,9 +155,8 @@ class CustomCell(Cell): 'vertical': 'RL' } - def __init__(self, *args, **kwargs): - visible_edges = kwargs.pop('visible_edges') - Cell.__init__(self, *args, **kwargs) + def __init__(self, *args, visible_edges, **kwargs): + super().__init__(*args, **kwargs) self.visible_edges = visible_edges @property diff --git a/lib/matplotlib/tests/test_figure.py b/lib/matplotlib/tests/test_figure.py index 229ce192cc75..be055ae43f78 100644 --- a/lib/matplotlib/tests/test_figure.py +++ b/lib/matplotlib/tests/test_figure.py @@ -215,7 +215,7 @@ def test_iterability_axes_argument(): # This is a regression test for matplotlib/matplotlib#3196. If one of the # arguments returned by _as_mpl_axes defines __getitem__ but is not - # iterable, this would raise an execption. This is because we check + # iterable, this would raise an exception. This is because we check # whether the arguments are iterable, and if so we try and convert them # to a tuple. However, the ``iterable`` function returns True if # __getitem__ is present, but some classes can define __getitem__ without @@ -223,8 +223,7 @@ def test_iterability_axes_argument(): # case it fails. class MyAxes(Axes): - def __init__(self, *args, **kwargs): - kwargs.pop('myclass', None) + def __init__(self, *args, myclass=None, **kwargs): return Axes.__init__(self, *args, **kwargs) class MyClass(object): diff --git a/lib/mpl_toolkits/axes_grid/axes_grid.py b/lib/mpl_toolkits/axes_grid/axes_grid.py index b9093f0d8c30..49a77a1fb2e9 100644 --- a/lib/mpl_toolkits/axes_grid/axes_grid.py +++ b/lib/mpl_toolkits/axes_grid/axes_grid.py @@ -1,19 +1,13 @@ -from __future__ import (absolute_import, division, print_function, - unicode_literals) - import mpl_toolkits.axes_grid1.axes_grid as axes_grid_orig from .axes_divider import LocatableAxes + class CbarAxes(axes_grid_orig.CbarAxesBase, LocatableAxes): - def __init__(self, *kl, **kwargs): - orientation=kwargs.pop("orientation", None) - if orientation is None: - raise ValueError("orientation must be specified") + def __init__(self, *args, orientation, **kwargs): self.orientation = orientation self._default_label_on = False self.locator = None - - super().__init__(*kl, **kwargs) + super().__init__(*args, **kwargs) def cla(self): super().cla() @@ -23,8 +17,10 @@ def cla(self): class Grid(axes_grid_orig.Grid): _defaultLocatableAxesClass = LocatableAxes + class ImageGrid(axes_grid_orig.ImageGrid): _defaultLocatableAxesClass = LocatableAxes _defaultCbarAxesClass = CbarAxes + AxesGrid = ImageGrid diff --git a/lib/mpl_toolkits/axes_grid1/axes_divider.py b/lib/mpl_toolkits/axes_grid1/axes_divider.py index b238e73cc5ec..62050e5b4b5f 100644 --- a/lib/mpl_toolkits/axes_grid1/axes_divider.py +++ b/lib/mpl_toolkits/axes_grid1/axes_divider.py @@ -521,21 +521,15 @@ def __init__(self, axes, xref=None, yref=None): horizontal=[self._xref], vertical=[self._yref], aspect=None, anchor="C") - def _get_new_axes(self, **kwargs): + def _get_new_axes(self, *, axes_class=None, **kwargs): axes = self._axes - - axes_class = kwargs.pop("axes_class", None) - if axes_class is None: if isinstance(axes, SubplotBase): axes_class = axes._axes_class else: axes_class = type(axes) - - ax = axes_class(axes.get_figure(), - axes.get_position(original=True), **kwargs) - - return ax + return axes_class(axes.get_figure(), axes.get_position(original=True), + **kwargs) def new_horizontal(self, size, pad=None, pack_start=False, **kwargs): """ diff --git a/lib/mpl_toolkits/axes_grid1/axes_grid.py b/lib/mpl_toolkits/axes_grid1/axes_grid.py index c19e9cedd0cc..c31a9471dc49 100644 --- a/lib/mpl_toolkits/axes_grid1/axes_grid.py +++ b/lib/mpl_toolkits/axes_grid1/axes_grid.py @@ -34,8 +34,7 @@ def _tick_only(ax, bottom_on, left_on): class CbarAxesBase(object): - def colorbar(self, mappable, **kwargs): - locator = kwargs.pop("locator", None) + def colorbar(self, mappable, *, locator=None, **kwargs): if locator is None: if "ticks" not in kwargs: @@ -107,15 +106,11 @@ def toggle_label(self, b): class CbarAxes(CbarAxesBase, LocatableAxes): - def __init__(self, *kl, **kwargs): - orientation = kwargs.pop("orientation", None) - if orientation is None: - raise ValueError("orientation must be specified") + def __init__(self, *args, orientation, **kwargs): self.orientation = orientation self._default_label_on = True self.locator = None - - super().__init__(*kl, **kwargs) + super().__init__(*args, **kwargs) def cla(self): super().cla() diff --git a/lib/mpl_toolkits/axes_grid1/axes_rgb.py b/lib/mpl_toolkits/axes_grid1/axes_rgb.py index e62d4f061544..6eb96bb79ee4 100644 --- a/lib/mpl_toolkits/axes_grid1/axes_rgb.py +++ b/lib/mpl_toolkits/axes_grid1/axes_rgb.py @@ -99,7 +99,7 @@ class RGBAxesBase(object): B : _defaultAxesClass The axes object for the blue channel imshow """ - def __init__(self, *kl, **kwargs): + def __init__(self, *args, pad=0, add_all=True, **kwargs): """ Parameters ---------- @@ -116,8 +116,6 @@ def __init__(self, *kl, **kwargs): kwargs : Unpacked into axes_class() init for RGB, R, G, B axes """ - pad = kwargs.pop("pad", 0.0) - add_all = kwargs.pop("add_all", True) try: axes_class = kwargs.pop("axes_class", self._defaultAxesClass) except AttributeError: @@ -128,7 +126,7 @@ def __init__(self, *kl, **kwargs): six.reraise(AttributeError, AttributeError(new_msg), sys.exc_info()[2]) - ax = axes_class(*kl, **kwargs) + ax = axes_class(*args, **kwargs) divider = make_axes_locatable(ax) diff --git a/lib/mpl_toolkits/axes_grid1/parasite_axes.py b/lib/mpl_toolkits/axes_grid1/parasite_axes.py index a543a012c915..c6fe7e57e18d 100644 --- a/lib/mpl_toolkits/axes_grid1/parasite_axes.py +++ b/lib/mpl_toolkits/axes_grid1/parasite_axes.py @@ -425,7 +425,7 @@ def host_subplot_class_factory(axes_class): SubplotHost = subplot_class_factory(HostAxes) -def host_axes(*args, **kwargs): +def host_axes(*args, axes_class=None, figure=None, **kwargs): """ Create axes that can act as a hosts to parasitic axes. @@ -439,17 +439,15 @@ def host_axes(*args, **kwargs): Will be passed on to the underlying ``Axes`` object creation. """ import matplotlib.pyplot as plt - axes_class = kwargs.pop("axes_class", None) host_axes_class = host_axes_class_factory(axes_class) - fig = kwargs.get("figure", None) - if fig is None: - fig = plt.gcf() - ax = host_axes_class(fig, *args, **kwargs) - fig.add_axes(ax) + if figure is None: + figure = plt.gcf() + ax = host_axes_class(figure, *args, **kwargs) + figure.add_axes(ax) plt.draw_if_interactive() return ax -def host_subplot(*args, **kwargs): +def host_subplot(*args, axes_class=None, figure=None, **kwargs): """ Create a subplot that can act as a host to parasitic axes. @@ -463,12 +461,10 @@ def host_subplot(*args, **kwargs): Will be passed on to the underlying ``Axes`` object creation. """ import matplotlib.pyplot as plt - axes_class = kwargs.pop("axes_class", None) host_subplot_class = host_subplot_class_factory(axes_class) - fig = kwargs.get("figure", None) - if fig is None: - fig = plt.gcf() - ax = host_subplot_class(fig, *args, **kwargs) - fig.add_subplot(ax) + if figure is None: + figure = plt.gcf() + ax = host_subplot_class(figure, *args, **kwargs) + figure.add_subplot(ax) plt.draw_if_interactive() return ax diff --git a/lib/mpl_toolkits/axisartist/axes_grid.py b/lib/mpl_toolkits/axisartist/axes_grid.py index b9093f0d8c30..49a77a1fb2e9 100644 --- a/lib/mpl_toolkits/axisartist/axes_grid.py +++ b/lib/mpl_toolkits/axisartist/axes_grid.py @@ -1,19 +1,13 @@ -from __future__ import (absolute_import, division, print_function, - unicode_literals) - import mpl_toolkits.axes_grid1.axes_grid as axes_grid_orig from .axes_divider import LocatableAxes + class CbarAxes(axes_grid_orig.CbarAxesBase, LocatableAxes): - def __init__(self, *kl, **kwargs): - orientation=kwargs.pop("orientation", None) - if orientation is None: - raise ValueError("orientation must be specified") + def __init__(self, *args, orientation, **kwargs): self.orientation = orientation self._default_label_on = False self.locator = None - - super().__init__(*kl, **kwargs) + super().__init__(*args, **kwargs) def cla(self): super().cla() @@ -23,8 +17,10 @@ def cla(self): class Grid(axes_grid_orig.Grid): _defaultLocatableAxesClass = LocatableAxes + class ImageGrid(axes_grid_orig.ImageGrid): _defaultLocatableAxesClass = LocatableAxes _defaultCbarAxesClass = CbarAxes + AxesGrid = ImageGrid diff --git a/lib/mpl_toolkits/axisartist/axis_artist.py b/lib/mpl_toolkits/axisartist/axis_artist.py index 4d95bc5a31ed..a7a0d7889f50 100644 --- a/lib/mpl_toolkits/axisartist/axis_artist.py +++ b/lib/mpl_toolkits/axisartist/axis_artist.py @@ -212,13 +212,13 @@ class Ticks(Line2D, AttributeCopier): set_tick_out(False). """ - def __init__(self, ticksize, tick_out=False, **kwargs): + def __init__(self, ticksize, tick_out=False, *, axis=None, **kwargs): self._ticksize = ticksize self.locs_angles_labels = [] self.set_tick_out(tick_out) - self._axis = kwargs.pop("axis", None) + self._axis = axis if self._axis is not None: if "color" not in kwargs: kwargs["color"] = "auto" @@ -455,11 +455,10 @@ class AxisLabel(LabelBase, AttributeCopier): To change the pad between ticklabels and axis label, use set_pad. """ - def __init__(self, *kl, **kwargs): + def __init__(self, *args, axis_direction="bottom", axis=None, **kwargs): - axis_direction = kwargs.pop("axis_direction", "bottom") - self._axis = kwargs.pop("axis", None) - LabelBase.__init__(self, *kl, **kwargs) + self._axis = axis + LabelBase.__init__(self, *args, **kwargs) AttributeCopier.__init__(self, self._axis, klass=LabelBase) self.set_axis_direction(axis_direction) @@ -600,16 +599,13 @@ class TickLabels(AxisLabel, AttributeCopier): # mtext.Text To change the pad between ticks and ticklabels, use set_pad. """ - def __init__(self, **kwargs): - - axis_direction = kwargs.pop("axis_direction", "bottom") + def __init__(self, *, axis_direction="bottom", **kwargs): AxisLabel.__init__(self, **kwargs) self.set_axis_direction(axis_direction) #self._axis_direction = axis_direction self._axislabel_pad = 0 #self._extra_pad = 0 - # attribute copier def get_ref_artist(self): return self._axis.get_ticklabels()[0] @@ -802,14 +798,14 @@ def get_texts_widths_heights_descents(self, renderer): class GridlinesCollection(LineCollection): - def __init__(self, *kl, **kwargs): + def __init__(self, *args, which="major", axis="both", **kwargs): """ *which* : "major" or "minor" *axis* : "both", "x" or "y" """ - self._which = kwargs.pop("which", "major") - self._axis = kwargs.pop("axis", "both") - super().__init__(*kl, **kwargs) + self._which = which + self._axis = axis + super().__init__(*args, **kwargs) self.set_grid_helper(None) def set_which(self, which): diff --git a/lib/mpl_toolkits/axisartist/axislines.py b/lib/mpl_toolkits/axisartist/axislines.py index c97119399a01..f1a6e0ea36f0 100644 --- a/lib/mpl_toolkits/axisartist/axislines.py +++ b/lib/mpl_toolkits/axisartist/axislines.py @@ -521,19 +521,18 @@ def __init__(self, axes): def __getitem__(self, k): if isinstance(k, tuple): - r = SimpleChainedObjects([dict.__getitem__(self, k1) for k1 in k]) - return r + return SimpleChainedObjects( + [dict.__getitem__(self, k1) for k1 in k]) elif isinstance(k, slice): - if k.start == None and k.stop == None and k.step == None: - r = SimpleChainedObjects(list(six.itervalues(self))) - return r + if k == slice(None): + return SimpleChainedObjects(list(six.itervalues(self))) else: raise ValueError("Unsupported slice") else: return dict.__getitem__(self, k) - def __call__(self, *v, **kwargs): - return maxes.Axes.axis(self.axes, *v, **kwargs) + def __call__(self, *args, **kwargs): + return maxes.Axes.axis(self.axes, *args, **kwargs) def __init__(self, *args, grid_helper=None, **kwargs): self._axisline_on = True @@ -558,9 +557,6 @@ def toggle_axisline(self, b=None): self.xaxis.set_visible(True) self.yaxis.set_visible(True) - def _init_axis(self): - super()._init_axis() - def _init_axis_artists(self, axes=None): if axes is None: axes = self diff --git a/lib/mpl_toolkits/mplot3d/art3d.py b/lib/mpl_toolkits/mplot3d/art3d.py index 5fc62ad89beb..0d0ff2e9aecc 100644 --- a/lib/mpl_toolkits/mplot3d/art3d.py +++ b/lib/mpl_toolkits/mplot3d/art3d.py @@ -364,7 +364,7 @@ class Patch3DCollection(PatchCollection): A collection of 3D patches. """ - def __init__(self, *args, **kwargs): + def __init__(self, *args, zs=0, zdir='z', depthshade=True, **kwargs): """ Create a collection of flat 3D patches with its normal vector pointed in *zdir* direction, and located at *zs* on the *zdir* @@ -380,10 +380,8 @@ def __init__(self, *args, **kwargs): give the appearance of depth (default is *True*). This is typically desired in scatter plots. """ - zs = kwargs.pop('zs', 0) - zdir = kwargs.pop('zdir', 'z') - self._depthshade = kwargs.pop('depthshade', True) - PatchCollection.__init__(self, *args, **kwargs) + self._depthshade = depthshade + super().__init__(*args, **kwargs) self.set_3d_properties(zs, zdir) def set_sort_zpos(self, val): @@ -432,7 +430,7 @@ class Path3DCollection(PathCollection): A collection of 3D paths. """ - def __init__(self, *args, **kwargs): + def __init__(self, *args, zs=0, zdir='z', depthshade=True, **kwargs): """ Create a collection of flat 3D paths with its normal vector pointed in *zdir* direction, and located at *zs* on the *zdir* @@ -448,10 +446,8 @@ def __init__(self, *args, **kwargs): give the appearance of depth (default is *True*). This is typically desired in scatter plots. """ - zs = kwargs.pop('zs', 0) - zdir = kwargs.pop('zdir', 'z') - self._depthshade = kwargs.pop('depthshade', True) - PathCollection.__init__(self, *args, **kwargs) + self._depthshade = depthshade + super().__init__(*args, **kwargs) self.set_3d_properties(zs, zdir) def set_sort_zpos(self, val): @@ -526,7 +522,7 @@ class Poly3DCollection(PolyCollection): A collection of 3D polygons. """ - def __init__(self, verts, *args, **kwargs): + def __init__(self, verts, *args, zsort=True, **kwargs): """ Create a Poly3DCollection. @@ -538,8 +534,7 @@ def __init__(self, verts, *args, **kwargs): Note that this class does a bit of magic with the _facecolors and _edgecolors properties. """ - zsort = kwargs.pop('zsort', True) - PolyCollection.__init__(self, verts, *args, **kwargs) + super().__init__(verts, *args, **kwargs) self.set_zsort(zsort) self._codes3d = None diff --git a/lib/mpl_toolkits/mplot3d/axes3d.py b/lib/mpl_toolkits/mplot3d/axes3d.py index 1bd3cf7c0a25..df62cb6464e7 100644 --- a/lib/mpl_toolkits/mplot3d/axes3d.py +++ b/lib/mpl_toolkits/mplot3d/axes3d.py @@ -51,7 +51,10 @@ class Axes3D(Axes): name = '3d' _shared_z_axes = cbook.Grouper() - def __init__(self, fig, rect=None, *args, **kwargs): + def __init__( + self, fig, rect=None, *args, + azim=-60, elev=30, zscale=None, sharez=None, proj_type='persp', + **kwargs): ''' Build an :class:`Axes3D` instance in :class:`~matplotlib.figure.Figure` *fig* with @@ -79,11 +82,9 @@ def __init__(self, fig, rect=None, *args, **kwargs): rect = [0.0, 0.0, 1.0, 1.0] self._cids = [] - self.initial_azim = kwargs.pop('azim', -60) - self.initial_elev = kwargs.pop('elev', 30) - zscale = kwargs.pop('zscale', None) - sharez = kwargs.pop('sharez', None) - self.set_proj_type(kwargs.pop('proj_type', 'persp')) + self.initial_azim = azim + self.initial_elev = elev + self.set_proj_type(proj_type) self.xy_viewLim = unit_bbox() self.zz_viewLim = unit_bbox() @@ -1329,7 +1330,8 @@ def grid(self, b=True, **kwargs): self._draw_grid = cbook._string_to_bool(b) self.stale = True - def ticklabel_format(self, **kwargs): + def ticklabel_format( + self, *, style='', scilimits=None, useOffset=None, axis='both'): """ Convenience method for manipulating the ScalarFormatter used by default for linear axes in Axed3D objects. @@ -1343,10 +1345,8 @@ def ticklabel_format(self, **kwargs): .. versionadded :: 1.1.0 This function was added, but not tested. Please report any bugs. """ - style = kwargs.pop('style', '').lower() - scilimits = kwargs.pop('scilimits', None) - useOffset = kwargs.pop('useOffset', None) - axis = kwargs.pop('axis', 'both').lower() + style = style.lower() + axis = axis.lower() if scilimits is not None: try: m, n = scilimits @@ -2096,7 +2096,8 @@ def add_contourf_set(self, cset, zdir='z', offset=None): art3d.poly_collection_2d_to_3d(linec, z, zdir=zdir) linec.set_sort_zpos(z) - def contour(self, X, Y, Z, *args, **kwargs): + def contour(self, X, Y, Z, *args, + extend3d=False, stride=5, zdir='z', offset=None, **kwargs): ''' Create a 3D contour plot. @@ -2118,11 +2119,6 @@ def contour(self, X, Y, Z, *args, **kwargs): Returns a :class:`~matplotlib.axes.Axes.contour` ''' - extend3d = kwargs.pop('extend3d', False) - stride = kwargs.pop('stride', 5) - zdir = kwargs.pop('zdir', 'z') - offset = kwargs.pop('offset', None) - had_data = self.has_data() jX, jY, jZ = art3d.rotate_axes(X, Y, Z, zdir) @@ -2134,7 +2130,8 @@ def contour(self, X, Y, Z, *args, **kwargs): contour3D = contour - def tricontour(self, *args, **kwargs): + def tricontour(self, *args, + extend3d=False, stride=5, zdir='z', offset=None, **kwargs): """ Create a 3D contour plot. @@ -2162,11 +2159,6 @@ def tricontour(self, *args, **kwargs): longstanding bug in 3D PolyCollection rendering. """ - extend3d = kwargs.pop('extend3d', False) - stride = kwargs.pop('stride', 5) - zdir = kwargs.pop('zdir', 'z') - offset = kwargs.pop('offset', None) - had_data = self.has_data() tri, args, kwargs = Triangulation.get_from_args_and_kwargs( @@ -2189,7 +2181,7 @@ def tricontour(self, *args, **kwargs): self.auto_scale_xyz(X, Y, Z, had_data) return cset - def contourf(self, X, Y, Z, *args, **kwargs): + def contourf(self, X, Y, Z, *args, zdir='z', offset=None, **kwargs): ''' Create a 3D contourf plot. @@ -2212,9 +2204,6 @@ def contourf(self, X, Y, Z, *args, **kwargs): The *zdir* and *offset* kwargs were added. ''' - zdir = kwargs.pop('zdir', 'z') - offset = kwargs.pop('offset', None) - had_data = self.has_data() jX, jY, jZ = art3d.rotate_axes(X, Y, Z, zdir) @@ -2226,7 +2215,7 @@ def contourf(self, X, Y, Z, *args, **kwargs): contourf3D = contourf - def tricontourf(self, *args, **kwargs): + def tricontourf(self, *args, zdir='z', offset=None, **kwargs): """ Create a 3D contourf plot. @@ -2251,8 +2240,6 @@ def tricontourf(self, *args, **kwargs): EXPERIMENTAL: This method currently produces incorrect output due to a longstanding bug in 3D PolyCollection rendering. """ - zdir = kwargs.pop('zdir', 'z') - offset = kwargs.pop('offset', None) had_data = self.has_data() @@ -2544,7 +2531,9 @@ def set_title(self, label, fontdict=None, loc='center', **kwargs): return ret set_title.__doc__ = maxes.Axes.set_title.__doc__ - def quiver(self, *args, **kwargs): + def quiver(self, *args, + length=1, arrow_length_ratio=.3, pivot='tail', normalize=False, + **kwargs): """ Plot a 3D field of arrows. @@ -2621,16 +2610,6 @@ def calc_arrow(uvw, angle=15): had_data = self.has_data() - # handle kwargs - # shaft length - length = kwargs.pop('length', 1) - # arrow length ratio to the shaft length - arrow_length_ratio = kwargs.pop('arrow_length_ratio', 0.3) - # pivot point - pivot = kwargs.pop('pivot', 'tail') - # normalize - normalize = kwargs.pop('normalize', False) - # handle args argi = 6 if len(args) < argi: @@ -2719,7 +2698,7 @@ def calc_arrow(uvw, angle=15): quiver3D = quiver - def voxels(self, *args, **kwargs): + def voxels(self, *args, facecolors=None, edgecolors=None, **kwargs): """ ax.voxels([x, y, z,] /, filled, **kwargs) @@ -2825,14 +2804,12 @@ def _broadcast_color_arg(color, name): else: raise ValueError("Invalid {} argument".format(name)) - # intercept the facecolors, handling defaults and broacasting - facecolors = kwargs.pop('facecolors', None) + # broadcast and default on facecolors if facecolors is None: facecolors = self._get_patches_for_fill.get_next_color() facecolors = _broadcast_color_arg(facecolors, 'facecolors') # broadcast but no default on edgecolors - edgecolors = kwargs.pop('edgecolors', None) edgecolors = _broadcast_color_arg(edgecolors, 'edgecolors') # always scale to the full array, even if the data is only in the center diff --git a/lib/mpl_toolkits/mplot3d/axis3d.py b/lib/mpl_toolkits/mplot3d/axis3d.py index 4bfe8facbe46..f01d0a13e62d 100644 --- a/lib/mpl_toolkits/mplot3d/axis3d.py +++ b/lib/mpl_toolkits/mplot3d/axis3d.py @@ -66,7 +66,8 @@ class Axis(maxis.XAxis): 'color': (0.925, 0.925, 0.925, 0.5)}, } - def __init__(self, adir, v_intervalx, d_intervalx, axes, *args, **kwargs): + def __init__(self, adir, v_intervalx, d_intervalx, axes, *args, + rotate_label=None, **kwargs): # adir identifies which axes this is self.adir = adir # data and viewing intervals for this direction @@ -110,7 +111,7 @@ def __init__(self, adir, v_intervalx, d_intervalx, axes, *args, **kwargs): }) maxis.XAxis.__init__(self, axes, *args, **kwargs) - self.set_rotate_label(kwargs.get('rotate_label', None)) + self.set_rotate_label(rotate_label) def init3d(self): self.line = mlines.Line2D(