""" Base class for subplots, which are :class:`Axes` instances with additional methods to facilitate generating and manipulating a set of :class:`Axes` within a figure. """
""" *fig* is a :class:`matplotlib.figure.Figure` instance.
*args* is the tuple (*numRows*, *numCols*, *plotNum*), where the array of subplots in the figure has dimensions *numRows*, *numCols*, and where *plotNum* is the number of the subplot being created. *plotNum* starts at 1 in the upper left corner and increases to the right.
If *numRows* <= *numCols* <= *plotNum* < 10, *args* can be the decimal integer *numRows* * 100 + *numCols* * 10 + *plotNum*. """
else: try: s = str(int(args[0])) rows, cols, num = map(int, s) except ValueError: raise ValueError('Single argument to subplot must be ' 'a 3-digit integer') self._subplotspec = GridSpec(rows, cols, figure=self.figure)[num - 1] # num - 1 for converting from MATLAB to python indexing num = [int(n) for n in num] self._subplotspec = GridSpec( rows, cols, figure=self.figure)[(num[0] - 1):num[1]] else: raise ValueError( ("num must be 1 <= num <= {maxn}, not {num}" ).format(maxn=rows*cols, num=num)) rows, cols, figure=self.figure)[int(num) - 1] # num - 1 for converting from MATLAB to python indexing else: raise ValueError('Illegal argument(s) to subplot: %s' % (args,))
# _axes_class is set in the subplot_class_factory # add a layout box to this, for both the full axis, and the poss # of the axis. We need both because the axes may become smaller # due to parasitic axes and hence no longer fill the subplotspec. else: name = self._subplotspec._layoutbox.name + '.ax' name = name + layoutbox.seq_id() self._layoutbox = layoutbox.LayoutBox( parent=self._subplotspec._layoutbox, name=name, artist=self) self._poslayoutbox = layoutbox.LayoutBox( parent=self._layoutbox, name=self._layoutbox.name+'.pos', pos=True, subplot=True, artist=self)
# get the first axes class which does not inherit from a subplotbase axes_class = next( c for c in type(self).__mro__ if issubclass(c, Axes) and not issubclass(c, SubplotBase)) return (_picklable_subplot_class_constructor, (axes_class,), self.__getstate__())
"""get the subplot geometry, e.g., 2,2,3""" rows, cols, num1, num2 = self.get_subplotspec().get_geometry() return rows, cols, num1 + 1 # for compatibility
# COVERAGE NOTE: Never used internally or from examples """change subplot geometry, e.g., from 1,1,1 to 2,2,3""" self._subplotspec = GridSpec(numrows, numcols, figure=self.figure)[num - 1] self.update_params() self.set_position(self.figbox)
"""get the SubplotSpec instance associated with the subplot"""
"""set the SubplotSpec instance associated with the subplot""" self._subplotspec = subplotspec
"""get the GridSpec instance associated with the subplot""" return self._subplotspec.get_gridspec()
"""update the subplot position from fig.subplotpars"""
self.get_subplotspec().get_position(self.figure, return_all=True)
return self.colNum == 0
return self.rowNum == 0
return self.rowNum == self.numRows - 1
return self.colNum == self.numCols - 1
# COVERAGE NOTE: Never used internally. """Only show "outer" labels and tick labels.
x-labels are only kept for subplots on the last row; y-labels only for subplots on the first column. """ lastrow = self.is_last_row() firstcol = self.is_first_col() if not lastrow: for label in self.get_xticklabels(which="both"): label.set_visible(False) self.get_xaxis().get_offset_text().set_visible(False) self.set_xlabel("") if not firstcol: for label in self.get_yticklabels(which="both"): label.set_visible(False) self.get_yaxis().get_offset_text().set_visible(False) self.set_ylabel("")
""" Make a twinx axes of self. This is used for twinx and twiny. """ # The following line is added in v2.2 to avoid breaking Seaborn, # which currently uses this internal API. if kwargs["sharex"] is not self and kwargs["sharey"] is not self: raise ValueError("Twinned Axes may share only one axis.") self.figure, *kl, **kwargs)
*kl, **kwargs)
# make the layout boxes be explicitly the same ax2._layoutbox.constrain_same(self._layoutbox) ax2._poslayoutbox.constrain_same(self._poslayoutbox)
# this here to support cartopy which was using a private part of the # API to register their Axes subclasses.
# In 3.1 this should be changed to a dict subclass that warns on use # In 3.3 to a dict subclass that raises a useful exception on use # In 3.4 should be removed
# The slow timeline is to give cartopy enough time to get several # release out before we break them.
""" This makes a new class that inherits from `.SubplotBase` and the given axes_class (which is assumed to be a subclass of `.axes.Axes`). This is perhaps a little bit roundabout to make a new class on the fly like this, but it means that a new Subplot class does not have to be created for every type of Axes. """ # Avoid creating two different instances of GeoAxesSubplot... # Only a temporary backcompat fix. This should be removed in # 3.4 if cls.__bases__ == (SubplotBase, axes_class)) (SubplotBase, axes_class), {'_axes_class': axes_class})
# This is provided for backward compatibility
""" This stub class exists to return the appropriate subplot class when called with an axes class. This is purely to allow pickling of Axes and Subplots. """ subplot_class = subplot_class_factory(axes_class) return subplot_class.__new__(subplot_class)
|