Coverage for matplotlib\axes\_subplots.py: 0%

# Coverage for matplotlib\axes\_subplots.py : 0%

## 117 statements 0 run 117 missing 0 excluded

Hot-keys on this page

r m x p toggle line displays

j k next/prev highlighted chunk

0 (zero) top of page

1 (one) first highlighted chunk

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 | from __future__ import (absolute_import, division, print_function, unicode_literals) import six from six.moves import map from matplotlib.gridspec import GridSpec, SubplotSpec from matplotlib import docstring import matplotlib.artist as martist from matplotlib.axes._axes import Axes import matplotlib._layoutbox as layoutbox import warnings from matplotlib.cbook import mplDeprecation class SubplotBase(object): """ 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. """ def __init__(self, fig, *args, **kwargs): """ *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*. """ self.figure = fig if len(args) == 1: if isinstance(args[0], SubplotSpec): self._subplotspec = args[0] 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 elif len(args) == 3: rows, cols, num = args rows = int(rows) cols = int(cols) if isinstance(num, tuple) and len(num) == 2: num = [int(n) for n in num] self._subplotspec = GridSpec( rows, cols, figure=self.figure)[(num[0] - 1):num[1]] else: if num < 1 or num > rows*cols: raise ValueError( ("num must be 1 <= num <= {maxn}, not {num}" ).format(maxn=rows*cols, num=num)) self._subplotspec = GridSpec( 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,)) self.update_params() # _axes_class is set in the subplot_class_factory self._axes_class.__init__(self, fig, self.figbox, **kwargs) # 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. if self._subplotspec._layoutbox is None: self._layoutbox = None self._poslayoutbox = None 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) def __reduce__(self): # get the first axes class which does not # inherit from a subplotbase def not_subplotbase(c): return issubclass(c, Axes) and not issubclass(c, SubplotBase) axes_class = [c for c in self.__class__.mro() if not_subplotbase(c)][0] r = [_PicklableSubplotClassConstructor(), (axes_class,), self.__getstate__()] return tuple(r) def get_geometry(self): """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 def change_geometry(self, numrows, numcols, num): """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) def get_subplotspec(self): """get the SubplotSpec instance associated with the subplot""" return self._subplotspec def set_subplotspec(self, subplotspec): """set the SubplotSpec instance associated with the subplot""" self._subplotspec = subplotspec def update_params(self): """update the subplot position from fig.subplotpars""" self.figbox, self.rowNum, self.colNum, self.numRows, self.numCols = \ self.get_subplotspec().get_position(self.figure, return_all=True) def is_first_col(self): return self.colNum == 0 def is_first_row(self): return self.rowNum == 0 def is_last_row(self): return self.rowNum == self.numRows - 1 def is_last_col(self): return self.colNum == self.numCols - 1 # COVERAGE NOTE: Never used internally. def label_outer(self): """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("") def _make_twin_axes(self, *kl, **kwargs): """ Make a twinx axes of self. This is used for twinx and twiny. """ from matplotlib.projections import process_projection_requirements if 'sharex' in kwargs and 'sharey' in kwargs: # 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.") kl = (self.get_subplotspec(),) + kl projection_class, kwargs, key = process_projection_requirements( self.figure, *kl, **kwargs) ax2 = subplot_class_factory(projection_class)(self.figure, *kl, **kwargs) self.figure.add_subplot(ax2) self.set_adjustable('datalim') ax2.set_adjustable('datalim') if self._layoutbox is not None and ax2._layoutbox is not None: # make the layout boxes be explicitly the same ax2._layoutbox.constrain_same(self._layoutbox) ax2._poslayoutbox.constrain_same(self._poslayoutbox) self._twinned_axes.join(self, ax2) return ax2 _subplot_classes = {} def subplot_class_factory(axes_class=None): # This makes a new class that inherits from SubplotBase and the # given axes_class (which is assumed to be a subclass of 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. if axes_class is None: axes_class = Axes new_class = _subplot_classes.get(axes_class) if new_class is None: new_class = type(str("%sSubplot") % (axes_class.__name__), (SubplotBase, axes_class), {'_axes_class': axes_class}) _subplot_classes[axes_class] = new_class return new_class # This is provided for backward compatibility Subplot = subplot_class_factory() class _PicklableSubplotClassConstructor(object): """ This stub class exists to return the appropriate subplot class when __call__-ed with an axes class. This is purely to allow Pickling of Axes and Subplots. """ def __call__(self, axes_class): # create a dummy object instance subplot_instance = _PicklableSubplotClassConstructor() subplot_class = subplot_class_factory(axes_class) # update the class to the desired subplot class subplot_instance.__class__ = subplot_class return subplot_instance docstring.interpd.update(Axes=martist.kwdoc(Axes)) docstring.interpd.update(Subplot=martist.kwdoc(Axes)) """ # this is some discarded code I was using to find the minimum positive # data point for some log scaling fixes. I realized there was a # cleaner way to do it, but am keeping this around as an example for # how to get the data out of the axes. Might want to make something # like this a method one day, or better yet make get_verts an Artist # method minx, maxx = self.get_xlim() if minx<=0 or maxx<=0: # find the min pos value in the data xs = [] for line in self.lines: xs.extend(line.get_xdata(orig=False)) for patch in self.patches: xs.extend([x for x,y in patch.get_verts()]) for collection in self.collections: xs.extend([x for x,y in collection.get_verts()]) posx = [x for x in xs if x>0] if len(posx): minx = min(posx) maxx = max(posx) # warning, probably breaks inverted axis self.set_xlim((0.1*minx, maxx)) """