Hide keyboard shortcuts

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

1import collections.abc 

2import functools 

3import itertools 

4import logging 

5import math 

6from numbers import Number 

7 

8import numpy as np 

9from numpy import ma 

10 

11import matplotlib.category as _ # <-registers a category unit converter 

12import matplotlib.cbook as cbook 

13import matplotlib.collections as mcoll 

14import matplotlib.colors as mcolors 

15import matplotlib.contour as mcontour 

16import matplotlib.dates as _ # <-registers a date unit converter 

17import matplotlib.docstring as docstring 

18import matplotlib.image as mimage 

19import matplotlib.legend as mlegend 

20import matplotlib.lines as mlines 

21import matplotlib.markers as mmarkers 

22import matplotlib.mlab as mlab 

23import matplotlib.patches as mpatches 

24import matplotlib.path as mpath 

25import matplotlib.quiver as mquiver 

26import matplotlib.stackplot as mstack 

27import matplotlib.streamplot as mstream 

28import matplotlib.table as mtable 

29import matplotlib.text as mtext 

30import matplotlib.ticker as mticker 

31import matplotlib.transforms as mtransforms 

32import matplotlib.tri as mtri 

33from matplotlib import _preprocess_data, rcParams 

34from matplotlib.axes._base import _AxesBase, _process_plot_format 

35from matplotlib.axes._secondary_axes import SecondaryAxis 

36from matplotlib.container import BarContainer, ErrorbarContainer, StemContainer 

37 

38try: 

39 from numpy.lib.histograms import ( 

40 histogram_bin_edges as _histogram_bin_edges) 

41except ImportError: 

42 # this function is new in np 1.15 

43 def _histogram_bin_edges(arr, bins, range=None, weights=None): 

44 # this in True for 1D arrays, and False for None and str 

45 if np.ndim(bins) == 1: 

46 return bins 

47 

48 if isinstance(bins, str): 

49 # rather than backporting the internals, just do the full 

50 # computation. If this is too slow for users, they can 

51 # update numpy, or pick a manual number of bins 

52 return np.histogram(arr, bins, range, weights)[1] 

53 else: 

54 if bins is None: 

55 # hard-code numpy's default 

56 bins = 10 

57 if range is None: 

58 range = np.min(arr), np.max(arr) 

59 

60 return np.linspace(*range, bins + 1) 

61 

62 

63_log = logging.getLogger(__name__) 

64 

65 

66def _make_inset_locator(bounds, trans, parent): 

67 """ 

68 Helper function to locate inset axes, used in 

69 `.Axes.inset_axes`. 

70 

71 A locator gets used in `Axes.set_aspect` to override the default 

72 locations... It is a function that takes an axes object and 

73 a renderer and tells `set_aspect` where it is to be placed. 

74 

75 Here *rect* is a rectangle [l, b, w, h] that specifies the 

76 location for the axes in the transform given by *trans* on the 

77 *parent*. 

78 """ 

79 _bounds = mtransforms.Bbox.from_bounds(*bounds) 

80 _trans = trans 

81 _parent = parent 

82 

83 def inset_locator(ax, renderer): 

84 bbox = _bounds 

85 bb = mtransforms.TransformedBbox(bbox, _trans) 

86 tr = _parent.figure.transFigure.inverted() 

87 bb = mtransforms.TransformedBbox(bb, tr) 

88 return bb 

89 

90 return inset_locator 

91 

92 

93# The axes module contains all the wrappers to plotting functions. 

94# All the other methods should go in the _AxesBase class. 

95 

96 

97class Axes(_AxesBase): 

98 """ 

99 The `Axes` contains most of the figure elements: `~.axis.Axis`, 

100 `~.axis.Tick`, `~.lines.Line2D`, `~.text.Text`, `~.patches.Polygon`, etc., 

101 and sets the coordinate system. 

102 

103 The `Axes` instance supports callbacks through a callbacks attribute which 

104 is a `~.cbook.CallbackRegistry` instance. The events you can connect to 

105 are 'xlim_changed' and 'ylim_changed' and the callback will be called with 

106 func(*ax*) where *ax* is the `Axes` instance. 

107 

108 Attributes 

109 ---------- 

110 dataLim : `.Bbox` 

111 The bounding box enclosing all data displayed in the Axes. 

112 viewLim : `.Bbox` 

113 The view limits in data coordinates. 

114 

115 """ 

116 ### Labelling, legend and texts 

117 

118 @cbook.deprecated("3.1") 

119 @property 

120 def aname(self): 

121 return 'Axes' 

122 

123 def get_title(self, loc="center"): 

124 """ 

125 Get an axes title. 

126 

127 Get one of the three available axes titles. The available titles 

128 are positioned above the axes in the center, flush with the left 

129 edge, and flush with the right edge. 

130 

131 Parameters 

132 ---------- 

133 loc : {'center', 'left', 'right'}, str, optional 

134 Which title to get, defaults to 'center'. 

135 

136 Returns 

137 ------- 

138 title : str 

139 The title text string. 

140 

141 """ 

142 titles = {'left': self._left_title, 

143 'center': self.title, 

144 'right': self._right_title} 

145 title = cbook._check_getitem(titles, loc=loc.lower()) 

146 return title.get_text() 

147 

148 def set_title(self, label, fontdict=None, loc=None, pad=None, 

149 **kwargs): 

150 """ 

151 Set a title for the axes. 

152 

153 Set one of the three available axes titles. The available titles 

154 are positioned above the axes in the center, flush with the left 

155 edge, and flush with the right edge. 

156 

157 Parameters 

158 ---------- 

159 label : str 

160 Text to use for the title 

161 

162 fontdict : dict 

163 A dictionary controlling the appearance of the title text, 

164 the default *fontdict* is:: 

165 

166 {'fontsize': rcParams['axes.titlesize'], 

167 'fontweight' : rcParams['axes.titleweight'], 

168 'color' : rcParams['axes.titlecolor'], 

169 'verticalalignment': 'baseline', 

170 'horizontalalignment': loc} 

171 

172 loc : {'center', 'left', 'right'}, str, optional 

173 Which title to set. 

174 If *None*, defaults to :rc:`axes.titlelocation`. 

175 

176 pad : float 

177 The offset of the title from the top of the axes, in points. 

178 If *None*, defaults to :rc:`axes.titlepad`. 

179 

180 Returns 

181 ------- 

182 text : :class:`~matplotlib.text.Text` 

183 The matplotlib text instance representing the title 

184 

185 Other Parameters 

186 ---------------- 

187 **kwargs : `~matplotlib.text.Text` properties 

188 Other keyword arguments are text properties, see 

189 :class:`~matplotlib.text.Text` for a list of valid text 

190 properties. 

191 """ 

192 if loc is None: 

193 loc = rcParams['axes.titlelocation'] 

194 

195 titles = {'left': self._left_title, 

196 'center': self.title, 

197 'right': self._right_title} 

198 title = cbook._check_getitem(titles, loc=loc.lower()) 

199 default = { 

200 'fontsize': rcParams['axes.titlesize'], 

201 'fontweight': rcParams['axes.titleweight'], 

202 'verticalalignment': 'baseline', 

203 'horizontalalignment': loc.lower()} 

204 titlecolor = rcParams['axes.titlecolor'] 

205 if not cbook._str_lower_equal(titlecolor, 'auto'): 

206 default["color"] = titlecolor 

207 if pad is None: 

208 pad = rcParams['axes.titlepad'] 

209 self._set_title_offset_trans(float(pad)) 

210 title.set_text(label) 

211 title.update(default) 

212 if fontdict is not None: 

213 title.update(fontdict) 

214 title.update(kwargs) 

215 return title 

216 

217 def get_xlabel(self): 

218 """ 

219 Get the xlabel text string. 

220 """ 

221 label = self.xaxis.get_label() 

222 return label.get_text() 

223 

224 def set_xlabel(self, xlabel, fontdict=None, labelpad=None, **kwargs): 

225 """ 

226 Set the label for the x-axis. 

227 

228 Parameters 

229 ---------- 

230 xlabel : str 

231 The label text. 

232 

233 labelpad : scalar, optional, default: None 

234 Spacing in points from the axes bounding box including ticks 

235 and tick labels. 

236 

237 Other Parameters 

238 ---------------- 

239 **kwargs : `.Text` properties 

240 `.Text` properties control the appearance of the label. 

241 

242 See also 

243 -------- 

244 text : for information on how override and the optional args work 

245 """ 

246 if labelpad is not None: 

247 self.xaxis.labelpad = labelpad 

248 return self.xaxis.set_label_text(xlabel, fontdict, **kwargs) 

249 

250 def get_ylabel(self): 

251 """ 

252 Get the ylabel text string. 

253 """ 

254 label = self.yaxis.get_label() 

255 return label.get_text() 

256 

257 def set_ylabel(self, ylabel, fontdict=None, labelpad=None, **kwargs): 

258 """ 

259 Set the label for the y-axis. 

260 

261 Parameters 

262 ---------- 

263 ylabel : str 

264 The label text. 

265 

266 labelpad : scalar, optional, default: None 

267 Spacing in points from the axes bounding box including ticks 

268 and tick labels. 

269 

270 Other Parameters 

271 ---------------- 

272 **kwargs : `.Text` properties 

273 `.Text` properties control the appearance of the label. 

274 

275 See also 

276 -------- 

277 text : for information on how override and the optional args work 

278 

279 """ 

280 if labelpad is not None: 

281 self.yaxis.labelpad = labelpad 

282 return self.yaxis.set_label_text(ylabel, fontdict, **kwargs) 

283 

284 def get_legend_handles_labels(self, legend_handler_map=None): 

285 """ 

286 Return handles and labels for legend 

287 

288 ``ax.legend()`` is equivalent to :: 

289 

290 h, l = ax.get_legend_handles_labels() 

291 ax.legend(h, l) 

292 

293 """ 

294 

295 # pass through to legend. 

296 handles, labels = mlegend._get_legend_handles_labels([self], 

297 legend_handler_map) 

298 return handles, labels 

299 

300 @docstring.dedent_interpd 

301 def legend(self, *args, **kwargs): 

302 """ 

303 Place a legend on the axes. 

304 

305 Call signatures:: 

306 

307 legend() 

308 legend(labels) 

309 legend(handles, labels) 

310 

311 The call signatures correspond to three different ways how to use 

312 this method. 

313 

314 **1. Automatic detection of elements to be shown in the legend** 

315 

316 The elements to be added to the legend are automatically determined, 

317 when you do not pass in any extra arguments. 

318 

319 In this case, the labels are taken from the artist. You can specify 

320 them either at artist creation or by calling the 

321 :meth:`~.Artist.set_label` method on the artist:: 

322 

323 line, = ax.plot([1, 2, 3], label='Inline label') 

324 ax.legend() 

325 

326 or:: 

327 

328 line, = ax.plot([1, 2, 3]) 

329 line.set_label('Label via method') 

330 ax.legend() 

331 

332 Specific lines can be excluded from the automatic legend element 

333 selection by defining a label starting with an underscore. 

334 This is default for all artists, so calling `Axes.legend` without 

335 any arguments and without setting the labels manually will result in 

336 no legend being drawn. 

337 

338 

339 **2. Labeling existing plot elements** 

340 

341 To make a legend for lines which already exist on the axes 

342 (via plot for instance), simply call this function with an iterable 

343 of strings, one for each legend item. For example:: 

344 

345 ax.plot([1, 2, 3]) 

346 ax.legend(['A simple line']) 

347 

348 Note: This way of using is discouraged, because the relation between 

349 plot elements and labels is only implicit by their order and can 

350 easily be mixed up. 

351 

352 

353 **3. Explicitly defining the elements in the legend** 

354 

355 For full control of which artists have a legend entry, it is possible 

356 to pass an iterable of legend artists followed by an iterable of 

357 legend labels respectively:: 

358 

359 legend((line1, line2, line3), ('label1', 'label2', 'label3')) 

360 

361 Parameters 

362 ---------- 

363 handles : sequence of `.Artist`, optional 

364 A list of Artists (lines, patches) to be added to the legend. 

365 Use this together with *labels*, if you need full control on what 

366 is shown in the legend and the automatic mechanism described above 

367 is not sufficient. 

368 

369 The length of handles and labels should be the same in this 

370 case. If they are not, they are truncated to the smaller length. 

371 

372 labels : list of str, optional 

373 A list of labels to show next to the artists. 

374 Use this together with *handles*, if you need full control on what 

375 is shown in the legend and the automatic mechanism described above 

376 is not sufficient. 

377 

378 Other Parameters 

379 ---------------- 

380 %(_legend_kw_doc)s 

381 

382 Returns 

383 ------- 

384 legend : `~matplotlib.legend.Legend` 

385 

386 Notes 

387 ----- 

388 Not all kinds of artist are supported by the legend command. See 

389 :doc:`/tutorials/intermediate/legend_guide` for details. 

390 

391 Examples 

392 -------- 

393 .. plot:: gallery/text_labels_and_annotations/legend.py 

394 """ 

395 handles, labels, extra_args, kwargs = mlegend._parse_legend_args( 

396 [self], 

397 *args, 

398 **kwargs) 

399 if len(extra_args): 

400 raise TypeError('legend only accepts two non-keyword arguments') 

401 self.legend_ = mlegend.Legend(self, handles, labels, **kwargs) 

402 self.legend_._remove_method = self._remove_legend 

403 return self.legend_ 

404 

405 def _remove_legend(self, legend): 

406 self.legend_ = None 

407 

408 def inset_axes(self, bounds, *, transform=None, zorder=5, 

409 **kwargs): 

410 """ 

411 Add a child inset axes to this existing axes. 

412 

413 Warnings 

414 -------- 

415 This method is experimental as of 3.0, and the API may change. 

416 

417 Parameters 

418 ---------- 

419 bounds : [x0, y0, width, height] 

420 Lower-left corner of inset axes, and its width and height. 

421 

422 transform : `.Transform` 

423 Defaults to `ax.transAxes`, i.e. the units of *rect* are in 

424 axes-relative coordinates. 

425 

426 zorder : number 

427 Defaults to 5 (same as `.Axes.legend`). Adjust higher or lower 

428 to change whether it is above or below data plotted on the 

429 parent axes. 

430 

431 **kwargs 

432 Other keyword arguments are passed on to the `.Axes` child axes. 

433 

434 Returns 

435 ------- 

436 ax 

437 The created `~.axes.Axes` instance. 

438 

439 Examples 

440 -------- 

441 This example makes two inset axes, the first is in axes-relative 

442 coordinates, and the second in data-coordinates:: 

443 

444 fig, ax = plt.subplots() 

445 ax.plot(range(10)) 

446 axin1 = ax.inset_axes([0.8, 0.1, 0.15, 0.15]) 

447 axin2 = ax.inset_axes( 

448 [5, 7, 2.3, 2.3], transform=ax.transData) 

449 

450 """ 

451 if transform is None: 

452 transform = self.transAxes 

453 label = kwargs.pop('label', 'inset_axes') 

454 

455 # This puts the rectangle into figure-relative coordinates. 

456 inset_locator = _make_inset_locator(bounds, transform, self) 

457 bb = inset_locator(None, None) 

458 

459 inset_ax = Axes(self.figure, bb.bounds, zorder=zorder, 

460 label=label, **kwargs) 

461 

462 # this locator lets the axes move if in data coordinates. 

463 # it gets called in `ax.apply_aspect() (of all places) 

464 inset_ax.set_axes_locator(inset_locator) 

465 

466 self.add_child_axes(inset_ax) 

467 

468 return inset_ax 

469 

470 def indicate_inset(self, bounds, inset_ax=None, *, transform=None, 

471 facecolor='none', edgecolor='0.5', alpha=0.5, 

472 zorder=4.99, **kwargs): 

473 """ 

474 Add an inset indicator to the axes. This is a rectangle on the plot 

475 at the position indicated by *bounds* that optionally has lines that 

476 connect the rectangle to an inset axes (`.Axes.inset_axes`). 

477 

478 Warnings 

479 -------- 

480 This method is experimental as of 3.0, and the API may change. 

481 

482 

483 Parameters 

484 ---------- 

485 bounds : [x0, y0, width, height] 

486 Lower-left corner of rectangle to be marked, and its width 

487 and height. 

488 

489 inset_ax : `.Axes` 

490 An optional inset axes to draw connecting lines to. Two lines are 

491 drawn connecting the indicator box to the inset axes on corners 

492 chosen so as to not overlap with the indicator box. 

493 

494 transform : `.Transform` 

495 Transform for the rectangle co-ordinates. Defaults to 

496 `ax.transAxes`, i.e. the units of *rect* are in axes-relative 

497 coordinates. 

498 

499 facecolor : Matplotlib color 

500 Facecolor of the rectangle (default 'none'). 

501 

502 edgecolor : Matplotlib color 

503 Color of the rectangle and color of the connecting lines. Default 

504 is '0.5'. 

505 

506 alpha : float 

507 Transparency of the rectangle and connector lines. Default is 0.5. 

508 

509 zorder : float 

510 Drawing order of the rectangle and connector lines. Default is 4.99 

511 (just below the default level of inset axes). 

512 

513 **kwargs 

514 Other keyword arguments are passed on to the rectangle patch. 

515 

516 Returns 

517 ------- 

518 rectangle_patch : `.patches.Rectangle` 

519 The indicator frame. 

520 

521 connector_lines : 4-tuple of `.patches.ConnectionPatch` 

522 The four connector lines connecting to (lower_left, upper_left, 

523 lower_right upper_right) corners of *inset_ax*. Two lines are 

524 set with visibility to *False*, but the user can set the 

525 visibility to True if the automatic choice is not deemed correct. 

526 

527 """ 

528 # to make the axes connectors work, we need to apply the aspect to 

529 # the parent axes. 

530 self.apply_aspect() 

531 

532 if transform is None: 

533 transform = self.transData 

534 label = kwargs.pop('label', 'indicate_inset') 

535 

536 x, y, width, height = bounds 

537 rectangle_patch = mpatches.Rectangle( 

538 (x, y), width, height, 

539 facecolor=facecolor, edgecolor=edgecolor, alpha=alpha, 

540 zorder=zorder, label=label, transform=transform, **kwargs) 

541 self.add_patch(rectangle_patch) 

542 

543 connects = [] 

544 

545 if inset_ax is not None: 

546 # connect the inset_axes to the rectangle 

547 for xy_inset_ax in [(0, 0), (0, 1), (1, 0), (1, 1)]: 

548 # inset_ax positions are in axes coordinates 

549 # The 0, 1 values define the four edges if the inset_ax 

550 # lower_left, upper_left, lower_right upper_right. 

551 ex, ey = xy_inset_ax 

552 if self.xaxis.get_inverted(): 

553 ex = 1 - ex 

554 if self.yaxis.get_inverted(): 

555 ey = 1 - ey 

556 xy_data = x + ex * width, y + ey * height 

557 p = mpatches.ConnectionPatch( 

558 xyA=xy_inset_ax, coordsA=inset_ax.transAxes, 

559 xyB=xy_data, coordsB=self.transData, 

560 arrowstyle="-", zorder=zorder, 

561 edgecolor=edgecolor, alpha=alpha) 

562 connects.append(p) 

563 self.add_patch(p) 

564 

565 # decide which two of the lines to keep visible.... 

566 pos = inset_ax.get_position() 

567 bboxins = pos.transformed(self.figure.transFigure) 

568 rectbbox = mtransforms.Bbox.from_bounds( 

569 *bounds 

570 ).transformed(transform) 

571 x0 = rectbbox.x0 < bboxins.x0 

572 x1 = rectbbox.x1 < bboxins.x1 

573 y0 = rectbbox.y0 < bboxins.y0 

574 y1 = rectbbox.y1 < bboxins.y1 

575 connects[0].set_visible(x0 ^ y0) 

576 connects[1].set_visible(x0 == y1) 

577 connects[2].set_visible(x1 == y0) 

578 connects[3].set_visible(x1 ^ y1) 

579 

580 return rectangle_patch, tuple(connects) if connects else None 

581 

582 def indicate_inset_zoom(self, inset_ax, **kwargs): 

583 """ 

584 Add an inset indicator rectangle to the axes based on the axis 

585 limits for an *inset_ax* and draw connectors between *inset_ax* 

586 and the rectangle. 

587 

588 Warnings 

589 -------- 

590 This method is experimental as of 3.0, and the API may change. 

591 

592 Parameters 

593 ---------- 

594 inset_ax : `.Axes` 

595 Inset axes to draw connecting lines to. Two lines are 

596 drawn connecting the indicator box to the inset axes on corners 

597 chosen so as to not overlap with the indicator box. 

598 

599 **kwargs 

600 Other keyword arguments are passed on to `.Axes.indicate_inset` 

601 

602 Returns 

603 ------- 

604 rectangle_patch : `.Patches.Rectangle` 

605 Rectangle artist. 

606 

607 connector_lines : 4-tuple of `.Patches.ConnectionPatch` 

608 Each of four connector lines coming from the rectangle drawn on 

609 this axis, in the order lower left, upper left, lower right, 

610 upper right. 

611 Two are set with visibility to *False*, but the user can 

612 set the visibility to *True* if the automatic choice is not deemed 

613 correct. 

614 """ 

615 

616 xlim = inset_ax.get_xlim() 

617 ylim = inset_ax.get_ylim() 

618 rect = (xlim[0], ylim[0], xlim[1] - xlim[0], ylim[1] - ylim[0]) 

619 return self.indicate_inset(rect, inset_ax, **kwargs) 

620 

621 @docstring.dedent_interpd 

622 def secondary_xaxis(self, location, *, functions=None, **kwargs): 

623 """ 

624 Add a second x-axis to this axes. 

625 

626 For example if we want to have a second scale for the data plotted on 

627 the xaxis. 

628 

629 %(_secax_docstring)s 

630 

631 Examples 

632 -------- 

633 The main axis shows frequency, and the secondary axis shows period. 

634 

635 .. plot:: 

636 

637 fig, ax = plt.subplots() 

638 ax.loglog(range(1, 360, 5), range(1, 360, 5)) 

639 ax.set_xlabel('frequency [Hz]') 

640 

641 def invert(x): 

642 return 1 / x 

643 

644 secax = ax.secondary_xaxis('top', functions=(invert, invert)) 

645 secax.set_xlabel('Period [s]') 

646 plt.show() 

647 """ 

648 if (location in ['top', 'bottom'] or isinstance(location, Number)): 

649 secondary_ax = SecondaryAxis(self, 'x', location, functions, 

650 **kwargs) 

651 self.add_child_axes(secondary_ax) 

652 return secondary_ax 

653 else: 

654 raise ValueError('secondary_xaxis location must be either ' 

655 'a float or "top"/"bottom"') 

656 

657 @docstring.dedent_interpd 

658 def secondary_yaxis(self, location, *, functions=None, **kwargs): 

659 """ 

660 Add a second y-axis to this axes. 

661 

662 For example if we want to have a second scale for the data plotted on 

663 the yaxis. 

664 

665 %(_secax_docstring)s 

666 

667 Examples 

668 -------- 

669 Add a secondary axes that converts from radians to degrees 

670 

671 .. plot:: 

672 

673 fig, ax = plt.subplots() 

674 ax.plot(range(1, 360, 5), range(1, 360, 5)) 

675 ax.set_ylabel('degrees') 

676 secax = ax.secondary_yaxis('right', functions=(np.deg2rad, 

677 np.rad2deg)) 

678 secax.set_ylabel('radians') 

679 """ 

680 if location in ['left', 'right'] or isinstance(location, Number): 

681 secondary_ax = SecondaryAxis(self, 'y', location, 

682 functions, **kwargs) 

683 self.add_child_axes(secondary_ax) 

684 return secondary_ax 

685 else: 

686 raise ValueError('secondary_yaxis location must be either ' 

687 'a float or "left"/"right"') 

688 

689 @cbook._delete_parameter("3.1", "withdash") 

690 def text(self, x, y, s, fontdict=None, withdash=False, **kwargs): 

691 """ 

692 Add text to the axes. 

693 

694 Add the text *s* to the axes at location *x*, *y* in data coordinates. 

695 

696 Parameters 

697 ---------- 

698 x, y : scalars 

699 The position to place the text. By default, this is in data 

700 coordinates. The coordinate system can be changed using the 

701 *transform* parameter. 

702 

703 s : str 

704 The text. 

705 

706 fontdict : dictionary, optional, default: None 

707 A dictionary to override the default text properties. If fontdict 

708 is None, the defaults are determined by your rc parameters. 

709 

710 withdash : boolean, optional, default: False 

711 Creates a `~matplotlib.text.TextWithDash` instance instead of a 

712 `~matplotlib.text.Text` instance. 

713 

714 Returns 

715 ------- 

716 text : `.Text` 

717 The created `.Text` instance. 

718 

719 Other Parameters 

720 ---------------- 

721 **kwargs : `~matplotlib.text.Text` properties. 

722 Other miscellaneous text parameters. 

723 

724 Examples 

725 -------- 

726 Individual keyword arguments can be used to override any given 

727 parameter:: 

728 

729 >>> text(x, y, s, fontsize=12) 

730 

731 The default transform specifies that text is in data coords, 

732 alternatively, you can specify text in axis coords ((0, 0) is 

733 lower-left and (1, 1) is upper-right). The example below places 

734 text in the center of the axes:: 

735 

736 >>> text(0.5, 0.5, 'matplotlib', horizontalalignment='center', 

737 ... verticalalignment='center', transform=ax.transAxes) 

738 

739 You can put a rectangular box around the text instance (e.g., to 

740 set a background color) by using the keyword *bbox*. *bbox* is 

741 a dictionary of `~matplotlib.patches.Rectangle` 

742 properties. For example:: 

743 

744 >>> text(x, y, s, bbox=dict(facecolor='red', alpha=0.5)) 

745 """ 

746 if fontdict is None: 

747 fontdict = {} 

748 

749 effective_kwargs = { 

750 'verticalalignment': 'baseline', 

751 'horizontalalignment': 'left', 

752 'transform': self.transData, 

753 'clip_on': False, 

754 **fontdict, 

755 **kwargs, 

756 } 

757 

758 # At some point if we feel confident that TextWithDash 

759 # is robust as a drop-in replacement for Text and that 

760 # the performance impact of the heavier-weight class 

761 # isn't too significant, it may make sense to eliminate 

762 # the withdash kwarg and simply delegate whether there's 

763 # a dash to TextWithDash and dashlength. 

764 

765 if (withdash 

766 and withdash is not cbook.deprecation._deprecated_parameter): 

767 t = mtext.TextWithDash(x, y, text=s) 

768 else: 

769 t = mtext.Text(x, y, text=s) 

770 t.update(effective_kwargs) 

771 

772 t.set_clip_path(self.patch) 

773 self._add_text(t) 

774 return t 

775 

776 @docstring.dedent_interpd 

777 def annotate(self, s, xy, *args, **kwargs): 

778 a = mtext.Annotation(s, xy, *args, **kwargs) 

779 a.set_transform(mtransforms.IdentityTransform()) 

780 if 'clip_on' in kwargs: 

781 a.set_clip_path(self.patch) 

782 self._add_text(a) 

783 return a 

784 annotate.__doc__ = mtext.Annotation.__init__.__doc__ 

785 #### Lines and spans 

786 

787 @docstring.dedent_interpd 

788 def axhline(self, y=0, xmin=0, xmax=1, **kwargs): 

789 """ 

790 Add a horizontal line across the axis. 

791 

792 Parameters 

793 ---------- 

794 y : scalar, optional, default: 0 

795 y position in data coordinates of the horizontal line. 

796 

797 xmin : scalar, optional, default: 0 

798 Should be between 0 and 1, 0 being the far left of the plot, 1 the 

799 far right of the plot. 

800 

801 xmax : scalar, optional, default: 1 

802 Should be between 0 and 1, 0 being the far left of the plot, 1 the 

803 far right of the plot. 

804 

805 Returns 

806 ------- 

807 line : `~matplotlib.lines.Line2D` 

808 

809 Other Parameters 

810 ---------------- 

811 **kwargs 

812 Valid keyword arguments are `.Line2D` properties, with the 

813 exception of 'transform': 

814 

815 %(_Line2D_docstr)s 

816 

817 See also 

818 -------- 

819 hlines : Add horizontal lines in data coordinates. 

820 axhspan : Add a horizontal span (rectangle) across the axis. 

821 

822 Examples 

823 -------- 

824 * draw a thick red hline at 'y' = 0 that spans the xrange:: 

825 

826 >>> axhline(linewidth=4, color='r') 

827 

828 * draw a default hline at 'y' = 1 that spans the xrange:: 

829 

830 >>> axhline(y=1) 

831 

832 * draw a default hline at 'y' = .5 that spans the middle half of 

833 the xrange:: 

834 

835 >>> axhline(y=.5, xmin=0.25, xmax=0.75) 

836 """ 

837 if "transform" in kwargs: 

838 raise ValueError( 

839 "'transform' is not allowed as a kwarg;" 

840 + "axhline generates its own transform.") 

841 ymin, ymax = self.get_ybound() 

842 

843 # We need to strip away the units for comparison with 

844 # non-unitized bounds 

845 self._process_unit_info(ydata=y, kwargs=kwargs) 

846 yy = self.convert_yunits(y) 

847 scaley = (yy < ymin) or (yy > ymax) 

848 

849 trans = self.get_yaxis_transform(which='grid') 

850 l = mlines.Line2D([xmin, xmax], [y, y], transform=trans, **kwargs) 

851 self.add_line(l) 

852 self._request_autoscale_view(scalex=False, scaley=scaley) 

853 return l 

854 

855 @docstring.dedent_interpd 

856 def axvline(self, x=0, ymin=0, ymax=1, **kwargs): 

857 """ 

858 Add a vertical line across the axes. 

859 

860 Parameters 

861 ---------- 

862 x : scalar, optional, default: 0 

863 x position in data coordinates of the vertical line. 

864 

865 ymin : scalar, optional, default: 0 

866 Should be between 0 and 1, 0 being the bottom of the plot, 1 the 

867 top of the plot. 

868 

869 ymax : scalar, optional, default: 1 

870 Should be between 0 and 1, 0 being the bottom of the plot, 1 the 

871 top of the plot. 

872 

873 Returns 

874 ------- 

875 line : `~matplotlib.lines.Line2D` 

876 

877 Other Parameters 

878 ---------------- 

879 **kwargs 

880 Valid keyword arguments are `.Line2D` properties, with the 

881 exception of 'transform': 

882 

883 %(_Line2D_docstr)s 

884 

885 Examples 

886 -------- 

887 * draw a thick red vline at *x* = 0 that spans the yrange:: 

888 

889 >>> axvline(linewidth=4, color='r') 

890 

891 * draw a default vline at *x* = 1 that spans the yrange:: 

892 

893 >>> axvline(x=1) 

894 

895 * draw a default vline at *x* = .5 that spans the middle half of 

896 the yrange:: 

897 

898 >>> axvline(x=.5, ymin=0.25, ymax=0.75) 

899 

900 See also 

901 -------- 

902 vlines : Add vertical lines in data coordinates. 

903 axvspan : Add a vertical span (rectangle) across the axis. 

904 """ 

905 

906 if "transform" in kwargs: 

907 raise ValueError( 

908 "'transform' is not allowed as a kwarg;" 

909 + "axvline generates its own transform.") 

910 xmin, xmax = self.get_xbound() 

911 

912 # We need to strip away the units for comparison with 

913 # non-unitized bounds 

914 self._process_unit_info(xdata=x, kwargs=kwargs) 

915 xx = self.convert_xunits(x) 

916 scalex = (xx < xmin) or (xx > xmax) 

917 

918 trans = self.get_xaxis_transform(which='grid') 

919 l = mlines.Line2D([x, x], [ymin, ymax], transform=trans, **kwargs) 

920 self.add_line(l) 

921 self._request_autoscale_view(scalex=scalex, scaley=False) 

922 return l 

923 

924 @docstring.dedent_interpd 

925 def axhspan(self, ymin, ymax, xmin=0, xmax=1, **kwargs): 

926 """ 

927 Add a horizontal span (rectangle) across the axis. 

928 

929 Draw a horizontal span (rectangle) from *ymin* to *ymax*. 

930 With the default values of *xmin* = 0 and *xmax* = 1, this 

931 always spans the xrange, regardless of the xlim settings, even 

932 if you change them, e.g., with the :meth:`set_xlim` command. 

933 That is, the horizontal extent is in axes coords: 0=left, 

934 0.5=middle, 1.0=right but the *y* location is in data 

935 coordinates. 

936 

937 Parameters 

938 ---------- 

939 ymin : float 

940 Lower limit of the horizontal span in data units. 

941 ymax : float 

942 Upper limit of the horizontal span in data units. 

943 xmin : float, optional, default: 0 

944 Lower limit of the vertical span in axes (relative 

945 0-1) units. 

946 xmax : float, optional, default: 1 

947 Upper limit of the vertical span in axes (relative 

948 0-1) units. 

949 

950 Returns 

951 ------- 

952 Polygon : `~matplotlib.patches.Polygon` 

953 

954 Other Parameters 

955 ---------------- 

956 **kwargs : `~matplotlib.patches.Polygon` properties. 

957 

958 %(Polygon)s 

959 

960 See Also 

961 -------- 

962 axvspan : Add a vertical span across the axes. 

963 """ 

964 trans = self.get_yaxis_transform(which='grid') 

965 

966 # process the unit information 

967 self._process_unit_info([xmin, xmax], [ymin, ymax], kwargs=kwargs) 

968 

969 # first we need to strip away the units 

970 xmin, xmax = self.convert_xunits([xmin, xmax]) 

971 ymin, ymax = self.convert_yunits([ymin, ymax]) 

972 

973 verts = (xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin) 

974 p = mpatches.Polygon(verts, **kwargs) 

975 p.set_transform(trans) 

976 self.add_patch(p) 

977 self._request_autoscale_view(scalex=False) 

978 return p 

979 

980 def axvspan(self, xmin, xmax, ymin=0, ymax=1, **kwargs): 

981 """ 

982 Add a vertical span (rectangle) across the axes. 

983 

984 Draw a vertical span (rectangle) from *xmin* to *xmax*. With 

985 the default values of *ymin* = 0 and *ymax* = 1. This always 

986 spans the yrange, regardless of the ylim settings, even if you 

987 change them, e.g., with the :meth:`set_ylim` command. That is, 

988 the vertical extent is in axes coords: 0=bottom, 0.5=middle, 

989 1.0=top but the x location is in data coordinates. 

990 

991 Parameters 

992 ---------- 

993 xmin : scalar 

994 Number indicating the first X-axis coordinate of the vertical 

995 span rectangle in data units. 

996 xmax : scalar 

997 Number indicating the second X-axis coordinate of the vertical 

998 span rectangle in data units. 

999 ymin : scalar, optional 

1000 Number indicating the first Y-axis coordinate of the vertical 

1001 span rectangle in relative Y-axis units (0-1). Default to 0. 

1002 ymax : scalar, optional 

1003 Number indicating the second Y-axis coordinate of the vertical 

1004 span rectangle in relative Y-axis units (0-1). Default to 1. 

1005 

1006 Returns 

1007 ------- 

1008 rectangle : `~matplotlib.patches.Polygon` 

1009 Vertical span (rectangle) from (xmin, ymin) to (xmax, ymax). 

1010 

1011 Other Parameters 

1012 ---------------- 

1013 **kwargs 

1014 Optional parameters are properties of the class `.Polygon`. 

1015 

1016 See Also 

1017 -------- 

1018 axhspan : Add a horizontal span across the axes. 

1019 

1020 Examples 

1021 -------- 

1022 Draw a vertical, green, translucent rectangle from x = 1.25 to 

1023 x = 1.55 that spans the yrange of the axes. 

1024 

1025 >>> axvspan(1.25, 1.55, facecolor='g', alpha=0.5) 

1026 

1027 """ 

1028 trans = self.get_xaxis_transform(which='grid') 

1029 

1030 # process the unit information 

1031 self._process_unit_info([xmin, xmax], [ymin, ymax], kwargs=kwargs) 

1032 

1033 # first we need to strip away the units 

1034 xmin, xmax = self.convert_xunits([xmin, xmax]) 

1035 ymin, ymax = self.convert_yunits([ymin, ymax]) 

1036 

1037 verts = [(xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin)] 

1038 p = mpatches.Polygon(verts, **kwargs) 

1039 p.set_transform(trans) 

1040 self.add_patch(p) 

1041 self._request_autoscale_view(scaley=False) 

1042 return p 

1043 

1044 @_preprocess_data(replace_names=["y", "xmin", "xmax", "colors"], 

1045 label_namer="y") 

1046 def hlines(self, y, xmin, xmax, colors='k', linestyles='solid', 

1047 label='', **kwargs): 

1048 """ 

1049 Plot horizontal lines at each *y* from *xmin* to *xmax*. 

1050 

1051 Parameters 

1052 ---------- 

1053 y : scalar or sequence of scalar 

1054 y-indexes where to plot the lines. 

1055 

1056 xmin, xmax : scalar or 1D array-like 

1057 Respective beginning and end of each line. If scalars are 

1058 provided, all lines will have same length. 

1059 

1060 colors : array-like of colors, optional, default: 'k' 

1061 

1062 linestyles : {'solid', 'dashed', 'dashdot', 'dotted'}, optional 

1063 

1064 label : str, optional, default: '' 

1065 

1066 Returns 

1067 ------- 

1068 lines : `~matplotlib.collections.LineCollection` 

1069 

1070 Other Parameters 

1071 ---------------- 

1072 **kwargs : `~matplotlib.collections.LineCollection` properties. 

1073 

1074 See also 

1075 -------- 

1076 vlines : vertical lines 

1077 axhline: horizontal line across the axes 

1078 """ 

1079 

1080 # We do the conversion first since not all unitized data is uniform 

1081 # process the unit information 

1082 self._process_unit_info([xmin, xmax], y, kwargs=kwargs) 

1083 y = self.convert_yunits(y) 

1084 xmin = self.convert_xunits(xmin) 

1085 xmax = self.convert_xunits(xmax) 

1086 

1087 if not np.iterable(y): 

1088 y = [y] 

1089 if not np.iterable(xmin): 

1090 xmin = [xmin] 

1091 if not np.iterable(xmax): 

1092 xmax = [xmax] 

1093 

1094 y, xmin, xmax = cbook.delete_masked_points(y, xmin, xmax) 

1095 

1096 y = np.ravel(y) 

1097 xmin = np.resize(xmin, y.shape) 

1098 xmax = np.resize(xmax, y.shape) 

1099 

1100 verts = [((thisxmin, thisy), (thisxmax, thisy)) 

1101 for thisxmin, thisxmax, thisy in zip(xmin, xmax, y)] 

1102 lines = mcoll.LineCollection(verts, colors=colors, 

1103 linestyles=linestyles, label=label) 

1104 self.add_collection(lines, autolim=False) 

1105 lines.update(kwargs) 

1106 

1107 if len(y) > 0: 

1108 minx = min(xmin.min(), xmax.min()) 

1109 maxx = max(xmin.max(), xmax.max()) 

1110 miny = y.min() 

1111 maxy = y.max() 

1112 

1113 corners = (minx, miny), (maxx, maxy) 

1114 

1115 self.update_datalim(corners) 

1116 self._request_autoscale_view() 

1117 

1118 return lines 

1119 

1120 @_preprocess_data(replace_names=["x", "ymin", "ymax", "colors"], 

1121 label_namer="x") 

1122 def vlines(self, x, ymin, ymax, colors='k', linestyles='solid', 

1123 label='', **kwargs): 

1124 """ 

1125 Plot vertical lines. 

1126 

1127 Plot vertical lines at each *x* from *ymin* to *ymax*. 

1128 

1129 Parameters 

1130 ---------- 

1131 x : scalar or 1D array-like 

1132 x-indexes where to plot the lines. 

1133 

1134 ymin, ymax : scalar or 1D array-like 

1135 Respective beginning and end of each line. If scalars are 

1136 provided, all lines will have same length. 

1137 

1138 colors : array-like of colors, optional, default: 'k' 

1139 

1140 linestyles : {'solid', 'dashed', 'dashdot', 'dotted'}, optional 

1141 

1142 label : str, optional, default: '' 

1143 

1144 Returns 

1145 ------- 

1146 lines : `~matplotlib.collections.LineCollection` 

1147 

1148 Other Parameters 

1149 ---------------- 

1150 **kwargs : `~matplotlib.collections.LineCollection` properties. 

1151 

1152 See also 

1153 -------- 

1154 hlines : horizontal lines 

1155 axvline: vertical line across the axes 

1156 """ 

1157 

1158 self._process_unit_info(xdata=x, ydata=[ymin, ymax], kwargs=kwargs) 

1159 

1160 # We do the conversion first since not all unitized data is uniform 

1161 x = self.convert_xunits(x) 

1162 ymin = self.convert_yunits(ymin) 

1163 ymax = self.convert_yunits(ymax) 

1164 

1165 if not np.iterable(x): 

1166 x = [x] 

1167 if not np.iterable(ymin): 

1168 ymin = [ymin] 

1169 if not np.iterable(ymax): 

1170 ymax = [ymax] 

1171 

1172 x, ymin, ymax = cbook.delete_masked_points(x, ymin, ymax) 

1173 

1174 x = np.ravel(x) 

1175 ymin = np.resize(ymin, x.shape) 

1176 ymax = np.resize(ymax, x.shape) 

1177 

1178 verts = [((thisx, thisymin), (thisx, thisymax)) 

1179 for thisx, thisymin, thisymax in zip(x, ymin, ymax)] 

1180 lines = mcoll.LineCollection(verts, colors=colors, 

1181 linestyles=linestyles, label=label) 

1182 self.add_collection(lines, autolim=False) 

1183 lines.update(kwargs) 

1184 

1185 if len(x) > 0: 

1186 minx = x.min() 

1187 maxx = x.max() 

1188 miny = min(ymin.min(), ymax.min()) 

1189 maxy = max(ymin.max(), ymax.max()) 

1190 

1191 corners = (minx, miny), (maxx, maxy) 

1192 self.update_datalim(corners) 

1193 self._request_autoscale_view() 

1194 

1195 return lines 

1196 

1197 @_preprocess_data(replace_names=["positions", "lineoffsets", 

1198 "linelengths", "linewidths", 

1199 "colors", "linestyles"]) 

1200 @docstring.dedent_interpd 

1201 def eventplot(self, positions, orientation='horizontal', lineoffsets=1, 

1202 linelengths=1, linewidths=None, colors=None, 

1203 linestyles='solid', **kwargs): 

1204 """ 

1205 Plot identical parallel lines at the given positions. 

1206 

1207 *positions* should be a 1D or 2D array-like object, with each row 

1208 corresponding to a row or column of lines. 

1209 

1210 This type of plot is commonly used in neuroscience for representing 

1211 neural events, where it is usually called a spike raster, dot raster, 

1212 or raster plot. 

1213 

1214 However, it is useful in any situation where you wish to show the 

1215 timing or position of multiple sets of discrete events, such as the 

1216 arrival times of people to a business on each day of the month or the 

1217 date of hurricanes each year of the last century. 

1218 

1219 Parameters 

1220 ---------- 

1221 positions : 1D or 2D array-like object 

1222 Each value is an event. If *positions* is a 2D array-like, each 

1223 row corresponds to a row or a column of lines (depending on the 

1224 *orientation* parameter). 

1225 

1226 orientation : {'horizontal', 'vertical'}, optional 

1227 Controls the direction of the event collections: 

1228 

1229 - 'horizontal' : the lines are arranged horizontally in rows, 

1230 and are vertical. 

1231 - 'vertical' : the lines are arranged vertically in columns, 

1232 and are horizontal. 

1233 

1234 lineoffsets : scalar or sequence of scalars, optional, default: 1 

1235 The offset of the center of the lines from the origin, in the 

1236 direction orthogonal to *orientation*. 

1237 

1238 linelengths : scalar or sequence of scalars, optional, default: 1 

1239 The total height of the lines (i.e. the lines stretches from 

1240 ``lineoffset - linelength/2`` to ``lineoffset + linelength/2``). 

1241 

1242 linewidths : scalar, scalar sequence or None, optional, default: None 

1243 The line width(s) of the event lines, in points. If it is None, 

1244 defaults to its rcParams setting. 

1245 

1246 colors : color, sequence of colors or None, optional, default: None 

1247 The color(s) of the event lines. If it is None, defaults to its 

1248 rcParams setting. 

1249 

1250 linestyles : str or tuple or a sequence of such values, optional 

1251 Default is 'solid'. Valid strings are ['solid', 'dashed', 

1252 'dashdot', 'dotted', '-', '--', '-.', ':']. Dash tuples 

1253 should be of the form:: 

1254 

1255 (offset, onoffseq), 

1256 

1257 where *onoffseq* is an even length tuple of on and off ink 

1258 in points. 

1259 

1260 **kwargs : optional 

1261 Other keyword arguments are line collection properties. See 

1262 :class:`~matplotlib.collections.LineCollection` for a list of 

1263 the valid properties. 

1264 

1265 Returns 

1266 ------- 

1267 list : A list of :class:`~.collections.EventCollection` objects. 

1268 Contains the :class:`~.collections.EventCollection` that 

1269 were added. 

1270 

1271 Notes 

1272 ----- 

1273 For *linelengths*, *linewidths*, *colors*, and *linestyles*, if only 

1274 a single value is given, that value is applied to all lines. If an 

1275 array-like is given, it must have the same length as *positions*, and 

1276 each value will be applied to the corresponding row of the array. 

1277 

1278 Examples 

1279 -------- 

1280 .. plot:: gallery/lines_bars_and_markers/eventplot_demo.py 

1281 """ 

1282 self._process_unit_info(xdata=positions, 

1283 ydata=[lineoffsets, linelengths], 

1284 kwargs=kwargs) 

1285 

1286 # We do the conversion first since not all unitized data is uniform 

1287 positions = self.convert_xunits(positions) 

1288 lineoffsets = self.convert_yunits(lineoffsets) 

1289 linelengths = self.convert_yunits(linelengths) 

1290 

1291 if not np.iterable(positions): 

1292 positions = [positions] 

1293 elif any(np.iterable(position) for position in positions): 

1294 positions = [np.asanyarray(position) for position in positions] 

1295 else: 

1296 positions = [np.asanyarray(positions)] 

1297 

1298 if len(positions) == 0: 

1299 return [] 

1300 

1301 # prevent 'singular' keys from **kwargs dict from overriding the effect 

1302 # of 'plural' keyword arguments (e.g. 'color' overriding 'colors') 

1303 colors = cbook.local_over_kwdict(colors, kwargs, 'color') 

1304 linewidths = cbook.local_over_kwdict(linewidths, kwargs, 'linewidth') 

1305 linestyles = cbook.local_over_kwdict(linestyles, kwargs, 'linestyle') 

1306 

1307 if not np.iterable(lineoffsets): 

1308 lineoffsets = [lineoffsets] 

1309 if not np.iterable(linelengths): 

1310 linelengths = [linelengths] 

1311 if not np.iterable(linewidths): 

1312 linewidths = [linewidths] 

1313 if not np.iterable(colors): 

1314 colors = [colors] 

1315 if hasattr(linestyles, 'lower') or not np.iterable(linestyles): 

1316 linestyles = [linestyles] 

1317 

1318 lineoffsets = np.asarray(lineoffsets) 

1319 linelengths = np.asarray(linelengths) 

1320 linewidths = np.asarray(linewidths) 

1321 

1322 if len(lineoffsets) == 0: 

1323 lineoffsets = [None] 

1324 if len(linelengths) == 0: 

1325 linelengths = [None] 

1326 if len(linewidths) == 0: 

1327 lineoffsets = [None] 

1328 if len(linewidths) == 0: 

1329 lineoffsets = [None] 

1330 if len(colors) == 0: 

1331 colors = [None] 

1332 try: 

1333 # Early conversion of the colors into RGBA values to take care 

1334 # of cases like colors='0.5' or colors='C1'. (Issue #8193) 

1335 colors = mcolors.to_rgba_array(colors) 

1336 except ValueError: 

1337 # Will fail if any element of *colors* is None. But as long 

1338 # as len(colors) == 1 or len(positions), the rest of the 

1339 # code should process *colors* properly. 

1340 pass 

1341 

1342 if len(lineoffsets) == 1 and len(positions) != 1: 

1343 lineoffsets = np.tile(lineoffsets, len(positions)) 

1344 lineoffsets[0] = 0 

1345 lineoffsets = np.cumsum(lineoffsets) 

1346 if len(linelengths) == 1: 

1347 linelengths = np.tile(linelengths, len(positions)) 

1348 if len(linewidths) == 1: 

1349 linewidths = np.tile(linewidths, len(positions)) 

1350 if len(colors) == 1: 

1351 colors = list(colors) 

1352 colors = colors * len(positions) 

1353 if len(linestyles) == 1: 

1354 linestyles = [linestyles] * len(positions) 

1355 

1356 if len(lineoffsets) != len(positions): 

1357 raise ValueError('lineoffsets and positions are unequal sized ' 

1358 'sequences') 

1359 if len(linelengths) != len(positions): 

1360 raise ValueError('linelengths and positions are unequal sized ' 

1361 'sequences') 

1362 if len(linewidths) != len(positions): 

1363 raise ValueError('linewidths and positions are unequal sized ' 

1364 'sequences') 

1365 if len(colors) != len(positions): 

1366 raise ValueError('colors and positions are unequal sized ' 

1367 'sequences') 

1368 if len(linestyles) != len(positions): 

1369 raise ValueError('linestyles and positions are unequal sized ' 

1370 'sequences') 

1371 

1372 colls = [] 

1373 for position, lineoffset, linelength, linewidth, color, linestyle in \ 

1374 zip(positions, lineoffsets, linelengths, linewidths, 

1375 colors, linestyles): 

1376 coll = mcoll.EventCollection(position, 

1377 orientation=orientation, 

1378 lineoffset=lineoffset, 

1379 linelength=linelength, 

1380 linewidth=linewidth, 

1381 color=color, 

1382 linestyle=linestyle) 

1383 self.add_collection(coll, autolim=False) 

1384 coll.update(kwargs) 

1385 colls.append(coll) 

1386 

1387 if len(positions) > 0: 

1388 # try to get min/max 

1389 min_max = [(np.min(_p), np.max(_p)) for _p in positions 

1390 if len(_p) > 0] 

1391 # if we have any non-empty positions, try to autoscale 

1392 if len(min_max) > 0: 

1393 mins, maxes = zip(*min_max) 

1394 minpos = np.min(mins) 

1395 maxpos = np.max(maxes) 

1396 

1397 minline = (lineoffsets - linelengths).min() 

1398 maxline = (lineoffsets + linelengths).max() 

1399 

1400 if (orientation is not None and 

1401 orientation.lower() == "vertical"): 

1402 corners = (minline, minpos), (maxline, maxpos) 

1403 else: # "horizontal", None or "none" (see EventCollection) 

1404 corners = (minpos, minline), (maxpos, maxline) 

1405 self.update_datalim(corners) 

1406 self._request_autoscale_view() 

1407 

1408 return colls 

1409 

1410 #### Basic plotting 

1411 

1412 # Uses a custom implementation of data-kwarg handling in 

1413 # _process_plot_var_args. 

1414 @docstring.dedent_interpd 

1415 def plot(self, *args, scalex=True, scaley=True, data=None, **kwargs): 

1416 """ 

1417 Plot y versus x as lines and/or markers. 

1418 

1419 Call signatures:: 

1420 

1421 plot([x], y, [fmt], *, data=None, **kwargs) 

1422 plot([x], y, [fmt], [x2], y2, [fmt2], ..., **kwargs) 

1423 

1424 The coordinates of the points or line nodes are given by *x*, *y*. 

1425 

1426 The optional parameter *fmt* is a convenient way for defining basic 

1427 formatting like color, marker and linestyle. It's a shortcut string 

1428 notation described in the *Notes* section below. 

1429 

1430 >>> plot(x, y) # plot x and y using default line style and color 

1431 >>> plot(x, y, 'bo') # plot x and y using blue circle markers 

1432 >>> plot(y) # plot y using x as index array 0..N-1 

1433 >>> plot(y, 'r+') # ditto, but with red plusses 

1434 

1435 You can use `.Line2D` properties as keyword arguments for more 

1436 control on the appearance. Line properties and *fmt* can be mixed. 

1437 The following two calls yield identical results: 

1438 

1439 >>> plot(x, y, 'go--', linewidth=2, markersize=12) 

1440 >>> plot(x, y, color='green', marker='o', linestyle='dashed', 

1441 ... linewidth=2, markersize=12) 

1442 

1443 When conflicting with *fmt*, keyword arguments take precedence. 

1444 

1445 

1446 **Plotting labelled data** 

1447 

1448 There's a convenient way for plotting objects with labelled data (i.e. 

1449 data that can be accessed by index ``obj['y']``). Instead of giving 

1450 the data in *x* and *y*, you can provide the object in the *data* 

1451 parameter and just give the labels for *x* and *y*:: 

1452 

1453 >>> plot('xlabel', 'ylabel', data=obj) 

1454 

1455 All indexable objects are supported. This could e.g. be a `dict`, a 

1456 `pandas.DataFame` or a structured numpy array. 

1457 

1458 

1459 **Plotting multiple sets of data** 

1460 

1461 There are various ways to plot multiple sets of data. 

1462 

1463 - The most straight forward way is just to call `plot` multiple times. 

1464 Example: 

1465 

1466 >>> plot(x1, y1, 'bo') 

1467 >>> plot(x2, y2, 'go') 

1468 

1469 - Alternatively, if your data is already a 2d array, you can pass it 

1470 directly to *x*, *y*. A separate data set will be drawn for every 

1471 column. 

1472 

1473 Example: an array ``a`` where the first column represents the *x* 

1474 values and the other columns are the *y* columns:: 

1475 

1476 >>> plot(a[0], a[1:]) 

1477 

1478 - The third way is to specify multiple sets of *[x]*, *y*, *[fmt]* 

1479 groups:: 

1480 

1481 >>> plot(x1, y1, 'g^', x2, y2, 'g-') 

1482 

1483 In this case, any additional keyword argument applies to all 

1484 datasets. Also this syntax cannot be combined with the *data* 

1485 parameter. 

1486 

1487 By default, each line is assigned a different style specified by a 

1488 'style cycle'. The *fmt* and line property parameters are only 

1489 necessary if you want explicit deviations from these defaults. 

1490 Alternatively, you can also change the style cycle using 

1491 :rc:`axes.prop_cycle`. 

1492 

1493 

1494 Parameters 

1495 ---------- 

1496 x, y : array-like or scalar 

1497 The horizontal / vertical coordinates of the data points. 

1498 *x* values are optional and default to `range(len(y))`. 

1499 

1500 Commonly, these parameters are 1D arrays. 

1501 

1502 They can also be scalars, or two-dimensional (in that case, the 

1503 columns represent separate data sets). 

1504 

1505 These arguments cannot be passed as keywords. 

1506 

1507 fmt : str, optional 

1508 A format string, e.g. 'ro' for red circles. See the *Notes* 

1509 section for a full description of the format strings. 

1510 

1511 Format strings are just an abbreviation for quickly setting 

1512 basic line properties. All of these and more can also be 

1513 controlled by keyword arguments. 

1514 

1515 This argument cannot be passed as keyword. 

1516 

1517 data : indexable object, optional 

1518 An object with labelled data. If given, provide the label names to 

1519 plot in *x* and *y*. 

1520 

1521 .. note:: 

1522 Technically there's a slight ambiguity in calls where the 

1523 second label is a valid *fmt*. `plot('n', 'o', data=obj)` 

1524 could be `plt(x, y)` or `plt(y, fmt)`. In such cases, 

1525 the former interpretation is chosen, but a warning is issued. 

1526 You may suppress the warning by adding an empty format string 

1527 `plot('n', 'o', '', data=obj)`. 

1528 

1529 Other Parameters 

1530 ---------------- 

1531 scalex, scaley : bool, optional, default: True 

1532 These parameters determined if the view limits are adapted to 

1533 the data limits. The values are passed on to `autoscale_view`. 

1534 

1535 **kwargs : `.Line2D` properties, optional 

1536 *kwargs* are used to specify properties like a line label (for 

1537 auto legends), linewidth, antialiasing, marker face color. 

1538 Example:: 

1539 

1540 >>> plot([1, 2, 3], [1, 2, 3], 'go-', label='line 1', linewidth=2) 

1541 >>> plot([1, 2, 3], [1, 4, 9], 'rs', label='line 2') 

1542 

1543 If you make multiple lines with one plot command, the kwargs 

1544 apply to all those lines. 

1545 

1546 Here is a list of available `.Line2D` properties: 

1547 

1548 %(_Line2D_docstr)s 

1549 

1550 Returns 

1551 ------- 

1552 lines 

1553 A list of `.Line2D` objects representing the plotted data. 

1554 

1555 See Also 

1556 -------- 

1557 scatter : XY scatter plot with markers of varying size and/or color ( 

1558 sometimes also called bubble chart). 

1559 

1560 Notes 

1561 ----- 

1562 **Format Strings** 

1563 

1564 A format string consists of a part for color, marker and line:: 

1565 

1566 fmt = '[marker][line][color]' 

1567 

1568 Each of them is optional. If not provided, the value from the style 

1569 cycle is used. Exception: If ``line`` is given, but no ``marker``, 

1570 the data will be a line without markers. 

1571 

1572 Other combinations such as ``[color][marker][line]`` are also 

1573 supported, but note that their parsing may be ambiguous. 

1574 

1575 **Markers** 

1576 

1577 ============= =============================== 

1578 character description 

1579 ============= =============================== 

1580 ``'.'`` point marker 

1581 ``','`` pixel marker 

1582 ``'o'`` circle marker 

1583 ``'v'`` triangle_down marker 

1584 ``'^'`` triangle_up marker 

1585 ``'<'`` triangle_left marker 

1586 ``'>'`` triangle_right marker 

1587 ``'1'`` tri_down marker 

1588 ``'2'`` tri_up marker 

1589 ``'3'`` tri_left marker 

1590 ``'4'`` tri_right marker 

1591 ``'s'`` square marker 

1592 ``'p'`` pentagon marker 

1593 ``'*'`` star marker 

1594 ``'h'`` hexagon1 marker 

1595 ``'H'`` hexagon2 marker 

1596 ``'+'`` plus marker 

1597 ``'x'`` x marker 

1598 ``'D'`` diamond marker 

1599 ``'d'`` thin_diamond marker 

1600 ``'|'`` vline marker 

1601 ``'_'`` hline marker 

1602 ============= =============================== 

1603 

1604 **Line Styles** 

1605 

1606 ============= =============================== 

1607 character description 

1608 ============= =============================== 

1609 ``'-'`` solid line style 

1610 ``'--'`` dashed line style 

1611 ``'-.'`` dash-dot line style 

1612 ``':'`` dotted line style 

1613 ============= =============================== 

1614 

1615 Example format strings:: 

1616 

1617 'b' # blue markers with default shape 

1618 'or' # red circles 

1619 '-g' # green solid line 

1620 '--' # dashed line with default color 

1621 '^k:' # black triangle_up markers connected by a dotted line 

1622 

1623 **Colors** 

1624 

1625 The supported color abbreviations are the single letter codes 

1626 

1627 ============= =============================== 

1628 character color 

1629 ============= =============================== 

1630 ``'b'`` blue 

1631 ``'g'`` green 

1632 ``'r'`` red 

1633 ``'c'`` cyan 

1634 ``'m'`` magenta 

1635 ``'y'`` yellow 

1636 ``'k'`` black 

1637 ``'w'`` white 

1638 ============= =============================== 

1639 

1640 and the ``'CN'`` colors that index into the default property cycle. 

1641 

1642 If the color is the only part of the format string, you can 

1643 additionally use any `matplotlib.colors` spec, e.g. full names 

1644 (``'green'``) or hex strings (``'#008000'``). 

1645 """ 

1646 kwargs = cbook.normalize_kwargs(kwargs, mlines.Line2D) 

1647 lines = [*self._get_lines(*args, data=data, **kwargs)] 

1648 for line in lines: 

1649 self.add_line(line) 

1650 self._request_autoscale_view(scalex=scalex, scaley=scaley) 

1651 return lines 

1652 

1653 @_preprocess_data(replace_names=["x", "y"], label_namer="y") 

1654 @docstring.dedent_interpd 

1655 def plot_date(self, x, y, fmt='o', tz=None, xdate=True, ydate=False, 

1656 **kwargs): 

1657 """ 

1658 Plot data that contains dates. 

1659 

1660 Similar to `.plot`, this plots *y* vs. *x* as lines or markers. 

1661 However, the axis labels are formatted as dates depending on *xdate* 

1662 and *ydate*. 

1663 

1664 Parameters 

1665 ---------- 

1666 x, y : array-like 

1667 The coordinates of the data points. If *xdate* or *ydate* is 

1668 *True*, the respective values *x* or *y* are interpreted as 

1669 :ref:`Matplotlib dates <date-format>`. 

1670 

1671 fmt : str, optional 

1672 The plot format string. For details, see the corresponding 

1673 parameter in `.plot`. 

1674 

1675 tz : timezone string or `tzinfo` or None 

1676 The time zone to use in labeling dates. If *None*, defaults to 

1677 :rc:`timezone`. 

1678 

1679 xdate : bool, optional, default: True 

1680 If *True*, the *x*-axis will be interpreted as Matplotlib dates. 

1681 

1682 ydate : bool, optional, default: False 

1683 If *True*, the *y*-axis will be interpreted as Matplotlib dates. 

1684 

1685 

1686 Returns 

1687 ------- 

1688 lines 

1689 A list of `.Line2D` objects representing the plotted data. 

1690 

1691 

1692 Other Parameters 

1693 ---------------- 

1694 **kwargs 

1695 Keyword arguments control the `.Line2D` properties: 

1696 

1697 %(_Line2D_docstr)s 

1698 

1699 See Also 

1700 -------- 

1701 matplotlib.dates : Helper functions on dates. 

1702 matplotlib.dates.date2num : Convert dates to num. 

1703 matplotlib.dates.num2date : Convert num to dates. 

1704 matplotlib.dates.drange : Create an equally spaced sequence of dates. 

1705 

1706 Notes 

1707 ----- 

1708 If you are using custom date tickers and formatters, it may be 

1709 necessary to set the formatters/locators after the call to 

1710 `.plot_date`. `.plot_date` will set the default tick locator to 

1711 `.AutoDateLocator` (if the tick locator is not already set to a 

1712 `.DateLocator` instance) and the default tick formatter to 

1713 `.AutoDateFormatter` (if the tick formatter is not already set to a 

1714 `.DateFormatter` instance). 

1715 """ 

1716 if xdate: 

1717 self.xaxis_date(tz) 

1718 if ydate: 

1719 self.yaxis_date(tz) 

1720 

1721 ret = self.plot(x, y, fmt, **kwargs) 

1722 

1723 self._request_autoscale_view() 

1724 

1725 return ret 

1726 

1727 # @_preprocess_data() # let 'plot' do the unpacking.. 

1728 @docstring.dedent_interpd 

1729 def loglog(self, *args, **kwargs): 

1730 """ 

1731 Make a plot with log scaling on both the x and y axis. 

1732 

1733 Call signatures:: 

1734 

1735 loglog([x], y, [fmt], data=None, **kwargs) 

1736 loglog([x], y, [fmt], [x2], y2, [fmt2], ..., **kwargs) 

1737 

1738 This is just a thin wrapper around `.plot` which additionally changes 

1739 both the x-axis and the y-axis to log scaling. All of the concepts and 

1740 parameters of plot can be used here as well. 

1741 

1742 The additional parameters *basex/y*, *subsx/y* and *nonposx/y* control 

1743 the x/y-axis properties. They are just forwarded to `.Axes.set_xscale` 

1744 and `.Axes.set_yscale`. 

1745 

1746 Parameters 

1747 ---------- 

1748 basex, basey : scalar, optional, default 10 

1749 Base of the x/y logarithm. 

1750 

1751 subsx, subsy : sequence, optional 

1752 The location of the minor x/y ticks. If *None*, reasonable 

1753 locations are automatically chosen depending on the number of 

1754 decades in the plot. 

1755 See `.Axes.set_xscale` / `.Axes.set_yscale` for details. 

1756 

1757 nonposx, nonposy : {'mask', 'clip'}, optional, default 'mask' 

1758 Non-positive values in x or y can be masked as invalid, or clipped 

1759 to a very small positive number. 

1760 

1761 Returns 

1762 ------- 

1763 lines 

1764 A list of `.Line2D` objects representing the plotted data. 

1765 

1766 Other Parameters 

1767 ---------------- 

1768 **kwargs 

1769 All parameters supported by `.plot`. 

1770 """ 

1771 dx = {k: kwargs.pop(k) for k in ['basex', 'subsx', 'nonposx'] 

1772 if k in kwargs} 

1773 dy = {k: kwargs.pop(k) for k in ['basey', 'subsy', 'nonposy'] 

1774 if k in kwargs} 

1775 

1776 self.set_xscale('log', **dx) 

1777 self.set_yscale('log', **dy) 

1778 

1779 l = self.plot(*args, **kwargs) 

1780 return l 

1781 

1782 # @_preprocess_data() # let 'plot' do the unpacking.. 

1783 @docstring.dedent_interpd 

1784 def semilogx(self, *args, **kwargs): 

1785 """ 

1786 Make a plot with log scaling on the x axis. 

1787 

1788 Call signatures:: 

1789 

1790 semilogx([x], y, [fmt], data=None, **kwargs) 

1791 semilogx([x], y, [fmt], [x2], y2, [fmt2], ..., **kwargs) 

1792 

1793 This is just a thin wrapper around `.plot` which additionally changes 

1794 the x-axis to log scaling. All of the concepts and parameters of plot 

1795 can be used here as well. 

1796 

1797 The additional parameters *basex*, *subsx* and *nonposx* control the 

1798 x-axis properties. They are just forwarded to `.Axes.set_xscale`. 

1799 

1800 Parameters 

1801 ---------- 

1802 basex : scalar, optional, default 10 

1803 Base of the x logarithm. 

1804 

1805 subsx : array-like, optional 

1806 The location of the minor xticks. If *None*, reasonable locations 

1807 are automatically chosen depending on the number of decades in the 

1808 plot. See `.Axes.set_xscale` for details. 

1809 

1810 nonposx : {'mask', 'clip'}, optional, default 'mask' 

1811 Non-positive values in x can be masked as invalid, or clipped to a 

1812 very small positive number. 

1813 

1814 Returns 

1815 ------- 

1816 lines 

1817 A list of `.Line2D` objects representing the plotted data. 

1818 

1819 Other Parameters 

1820 ---------------- 

1821 **kwargs 

1822 All parameters supported by `.plot`. 

1823 """ 

1824 d = {k: kwargs.pop(k) for k in ['basex', 'subsx', 'nonposx'] 

1825 if k in kwargs} 

1826 

1827 self.set_xscale('log', **d) 

1828 l = self.plot(*args, **kwargs) 

1829 return l 

1830 

1831 # @_preprocess_data() # let 'plot' do the unpacking.. 

1832 @docstring.dedent_interpd 

1833 def semilogy(self, *args, **kwargs): 

1834 """ 

1835 Make a plot with log scaling on the y axis. 

1836 

1837 Call signatures:: 

1838 

1839 semilogy([x], y, [fmt], data=None, **kwargs) 

1840 semilogy([x], y, [fmt], [x2], y2, [fmt2], ..., **kwargs) 

1841 

1842 This is just a thin wrapper around `.plot` which additionally changes 

1843 the y-axis to log scaling. All of the concepts and parameters of plot 

1844 can be used here as well. 

1845 

1846 The additional parameters *basey*, *subsy* and *nonposy* control the 

1847 y-axis properties. They are just forwarded to `.Axes.set_yscale`. 

1848 

1849 Parameters 

1850 ---------- 

1851 basey : scalar, optional, default 10 

1852 Base of the y logarithm. 

1853 

1854 subsy : array-like, optional 

1855 The location of the minor yticks. If *None*, reasonable locations 

1856 are automatically chosen depending on the number of decades in the 

1857 plot. See `.Axes.set_yscale` for details. 

1858 

1859 nonposy : {'mask', 'clip'}, optional, default 'mask' 

1860 Non-positive values in y can be masked as invalid, or clipped to a 

1861 very small positive number. 

1862 

1863 Returns 

1864 ------- 

1865 lines 

1866 A list of `.Line2D` objects representing the plotted data. 

1867 

1868 Other Parameters 

1869 ---------------- 

1870 **kwargs 

1871 All parameters supported by `.plot`. 

1872 """ 

1873 d = {k: kwargs.pop(k) for k in ['basey', 'subsy', 'nonposy'] 

1874 if k in kwargs} 

1875 self.set_yscale('log', **d) 

1876 l = self.plot(*args, **kwargs) 

1877 

1878 return l 

1879 

1880 @_preprocess_data(replace_names=["x"], label_namer="x") 

1881 def acorr(self, x, **kwargs): 

1882 """ 

1883 Plot the autocorrelation of *x*. 

1884 

1885 Parameters 

1886 ---------- 

1887 x : array-like 

1888 

1889 detrend : callable, optional, default: `mlab.detrend_none` 

1890 *x* is detrended by the *detrend* callable. This must be a 

1891 function ``x = detrend(x)`` accepting and returning an 

1892 `numpy.array`. Default is no normalization. 

1893 

1894 normed : bool, optional, default: True 

1895 If ``True``, input vectors are normalised to unit length. 

1896 

1897 usevlines : bool, optional, default: True 

1898 Determines the plot style. 

1899 

1900 If ``True``, vertical lines are plotted from 0 to the acorr value 

1901 using `Axes.vlines`. Additionally, a horizontal line is plotted 

1902 at y=0 using `Axes.axhline`. 

1903 

1904 If ``False``, markers are plotted at the acorr values using 

1905 `Axes.plot`. 

1906 

1907 maxlags : int, optional, default: 10 

1908 Number of lags to show. If ``None``, will return all 

1909 ``2 * len(x) - 1`` lags. 

1910 

1911 Returns 

1912 ------- 

1913 lags : array (length ``2*maxlags+1``) 

1914 The lag vector. 

1915 c : array (length ``2*maxlags+1``) 

1916 The auto correlation vector. 

1917 line : `.LineCollection` or `.Line2D` 

1918 `.Artist` added to the axes of the correlation: 

1919 

1920 - `.LineCollection` if *usevlines* is True. 

1921 - `.Line2D` if *usevlines* is False. 

1922 b : `.Line2D` or None 

1923 Horizontal line at 0 if *usevlines* is True 

1924 None *usevlines* is False. 

1925 

1926 Other Parameters 

1927 ---------------- 

1928 linestyle : `.Line2D` property, optional 

1929 The linestyle for plotting the data points. 

1930 Only used if *usevlines* is ``False``. 

1931 

1932 marker : str, optional, default: 'o' 

1933 The marker for plotting the data points. 

1934 Only used if *usevlines* is ``False``. 

1935 

1936 Notes 

1937 ----- 

1938 The cross correlation is performed with :func:`numpy.correlate` with 

1939 ``mode = "full"``. 

1940 """ 

1941 return self.xcorr(x, x, **kwargs) 

1942 

1943 @_preprocess_data(replace_names=["x", "y"], label_namer="y") 

1944 def xcorr(self, x, y, normed=True, detrend=mlab.detrend_none, 

1945 usevlines=True, maxlags=10, **kwargs): 

1946 r""" 

1947 Plot the cross correlation between *x* and *y*. 

1948 

1949 The correlation with lag k is defined as 

1950 :math:`\sum_n x[n+k] \cdot y^*[n]`, where :math:`y^*` is the complex 

1951 conjugate of :math:`y`. 

1952 

1953 Parameters 

1954 ---------- 

1955 x : array-like of length n 

1956 

1957 y : array-like of length n 

1958 

1959 detrend : callable, optional, default: `mlab.detrend_none` 

1960 *x* and *y* are detrended by the *detrend* callable. This must be a 

1961 function ``x = detrend(x)`` accepting and returning an 

1962 `numpy.array`. Default is no normalization. 

1963 

1964 normed : bool, optional, default: True 

1965 If ``True``, input vectors are normalised to unit length. 

1966 

1967 usevlines : bool, optional, default: True 

1968 Determines the plot style. 

1969 

1970 If ``True``, vertical lines are plotted from 0 to the xcorr value 

1971 using `Axes.vlines`. Additionally, a horizontal line is plotted 

1972 at y=0 using `Axes.axhline`. 

1973 

1974 If ``False``, markers are plotted at the xcorr values using 

1975 `Axes.plot`. 

1976 

1977 maxlags : int, optional, default: 10 

1978 Number of lags to show. If None, will return all ``2 * len(x) - 1`` 

1979 lags. 

1980 

1981 Returns 

1982 ------- 

1983 lags : array (length ``2*maxlags+1``) 

1984 The lag vector. 

1985 c : array (length ``2*maxlags+1``) 

1986 The auto correlation vector. 

1987 line : `.LineCollection` or `.Line2D` 

1988 `.Artist` added to the axes of the correlation: 

1989 

1990 - `.LineCollection` if *usevlines* is True. 

1991 - `.Line2D` if *usevlines* is False. 

1992 b : `.Line2D` or None 

1993 Horizontal line at 0 if *usevlines* is True 

1994 None *usevlines* is False. 

1995 

1996 Other Parameters 

1997 ---------------- 

1998 linestyle : `.Line2D` property, optional 

1999 The linestyle for plotting the data points. 

2000 Only used if *usevlines* is ``False``. 

2001 

2002 marker : str, optional, default: 'o' 

2003 The marker for plotting the data points. 

2004 Only used if *usevlines* is ``False``. 

2005 

2006 Notes 

2007 ----- 

2008 The cross correlation is performed with :func:`numpy.correlate` with 

2009 ``mode = "full"``. 

2010 """ 

2011 Nx = len(x) 

2012 if Nx != len(y): 

2013 raise ValueError('x and y must be equal length') 

2014 

2015 x = detrend(np.asarray(x)) 

2016 y = detrend(np.asarray(y)) 

2017 

2018 correls = np.correlate(x, y, mode="full") 

2019 

2020 if normed: 

2021 correls /= np.sqrt(np.dot(x, x) * np.dot(y, y)) 

2022 

2023 if maxlags is None: 

2024 maxlags = Nx - 1 

2025 

2026 if maxlags >= Nx or maxlags < 1: 

2027 raise ValueError('maxlags must be None or strictly ' 

2028 'positive < %d' % Nx) 

2029 

2030 lags = np.arange(-maxlags, maxlags + 1) 

2031 correls = correls[Nx - 1 - maxlags:Nx + maxlags] 

2032 

2033 if usevlines: 

2034 a = self.vlines(lags, [0], correls, **kwargs) 

2035 # Make label empty so only vertical lines get a legend entry 

2036 kwargs.pop('label', '') 

2037 b = self.axhline(**kwargs) 

2038 else: 

2039 kwargs.setdefault('marker', 'o') 

2040 kwargs.setdefault('linestyle', 'None') 

2041 a, = self.plot(lags, correls, **kwargs) 

2042 b = None 

2043 return lags, correls, a, b 

2044 

2045 #### Specialized plotting 

2046 

2047 # @_preprocess_data() # let 'plot' do the unpacking.. 

2048 def step(self, x, y, *args, where='pre', data=None, **kwargs): 

2049 """ 

2050 Make a step plot. 

2051 

2052 Call signatures:: 

2053 

2054 step(x, y, [fmt], *, data=None, where='pre', **kwargs) 

2055 step(x, y, [fmt], x2, y2, [fmt2], ..., *, where='pre', **kwargs) 

2056 

2057 This is just a thin wrapper around `.plot` which changes some 

2058 formatting options. Most of the concepts and parameters of plot can be 

2059 used here as well. 

2060 

2061 Parameters 

2062 ---------- 

2063 x : array-like 

2064 1-D sequence of x positions. It is assumed, but not checked, that 

2065 it is uniformly increasing. 

2066 

2067 y : array-like 

2068 1-D sequence of y levels. 

2069 

2070 fmt : str, optional 

2071 A format string, e.g. 'g' for a green line. See `.plot` for a more 

2072 detailed description. 

2073 

2074 Note: While full format strings are accepted, it is recommended to 

2075 only specify the color. Line styles are currently ignored (use 

2076 the keyword argument *linestyle* instead). Markers are accepted 

2077 and plotted on the given positions, however, this is a rarely 

2078 needed feature for step plots. 

2079 

2080 data : indexable object, optional 

2081 An object with labelled data. If given, provide the label names to 

2082 plot in *x* and *y*. 

2083 

2084 where : {'pre', 'post', 'mid'}, optional, default 'pre' 

2085 Define where the steps should be placed: 

2086 

2087 - 'pre': The y value is continued constantly to the left from 

2088 every *x* position, i.e. the interval ``(x[i-1], x[i]]`` has the 

2089 value ``y[i]``. 

2090 - 'post': The y value is continued constantly to the right from 

2091 every *x* position, i.e. the interval ``[x[i], x[i+1])`` has the 

2092 value ``y[i]``. 

2093 - 'mid': Steps occur half-way between the *x* positions. 

2094 

2095 Returns 

2096 ------- 

2097 lines 

2098 A list of `.Line2D` objects representing the plotted data. 

2099 

2100 Other Parameters 

2101 ---------------- 

2102 **kwargs 

2103 Additional parameters are the same as those for `.plot`. 

2104 

2105 Notes 

2106 ----- 

2107 .. [notes section required to get data note injection right] 

2108 """ 

2109 cbook._check_in_list(('pre', 'post', 'mid'), where=where) 

2110 kwargs['drawstyle'] = 'steps-' + where 

2111 return self.plot(x, y, *args, data=data, **kwargs) 

2112 

2113 @staticmethod 

2114 def _convert_dx(dx, x0, xconv, convert): 

2115 """ 

2116 Small helper to do logic of width conversion flexibly. 

2117 

2118 *dx* and *x0* have units, but *xconv* has already been converted 

2119 to unitless (and is an ndarray). This allows the *dx* to have units 

2120 that are different from *x0*, but are still accepted by the 

2121 ``__add__`` operator of *x0*. 

2122 """ 

2123 

2124 # x should be an array... 

2125 assert type(xconv) is np.ndarray 

2126 

2127 if xconv.size == 0: 

2128 # xconv has already been converted, but maybe empty... 

2129 return convert(dx) 

2130 

2131 try: 

2132 # attempt to add the width to x0; this works for 

2133 # datetime+timedelta, for instance 

2134 

2135 # only use the first element of x and x0. This saves 

2136 # having to be sure addition works across the whole 

2137 # vector. This is particularly an issue if 

2138 # x0 and dx are lists so x0 + dx just concatenates the lists. 

2139 # We can't just cast x0 and dx to numpy arrays because that 

2140 # removes the units from unit packages like `pint` that 

2141 # wrap numpy arrays. 

2142 try: 

2143 x0 = cbook.safe_first_element(x0) 

2144 except (TypeError, IndexError, KeyError): 

2145 x0 = x0 

2146 

2147 try: 

2148 x = cbook.safe_first_element(xconv) 

2149 except (TypeError, IndexError, KeyError): 

2150 x = xconv 

2151 

2152 delist = False 

2153 if not np.iterable(dx): 

2154 dx = [dx] 

2155 delist = True 

2156 dx = [convert(x0 + ddx) - x for ddx in dx] 

2157 if delist: 

2158 dx = dx[0] 

2159 except (ValueError, TypeError, AttributeError): 

2160 # if the above fails (for any reason) just fallback to what 

2161 # we do by default and convert dx by itself. 

2162 dx = convert(dx) 

2163 return dx 

2164 

2165 @_preprocess_data() 

2166 @docstring.dedent_interpd 

2167 def bar(self, x, height, width=0.8, bottom=None, *, align="center", 

2168 **kwargs): 

2169 r""" 

2170 Make a bar plot. 

2171 

2172 The bars are positioned at *x* with the given *align*\ment. Their 

2173 dimensions are given by *width* and *height*. The vertical baseline 

2174 is *bottom* (default 0). 

2175 

2176 Each of *x*, *height*, *width*, and *bottom* may either be a scalar 

2177 applying to all bars, or it may be a sequence of length N providing a 

2178 separate value for each bar. 

2179 

2180 Parameters 

2181 ---------- 

2182 x : sequence of scalars 

2183 The x coordinates of the bars. See also *align* for the 

2184 alignment of the bars to the coordinates. 

2185 

2186 height : scalar or sequence of scalars 

2187 The height(s) of the bars. 

2188 

2189 width : scalar or array-like, optional 

2190 The width(s) of the bars (default: 0.8). 

2191 

2192 bottom : scalar or array-like, optional 

2193 The y coordinate(s) of the bars bases (default: 0). 

2194 

2195 align : {'center', 'edge'}, optional, default: 'center' 

2196 Alignment of the bars to the *x* coordinates: 

2197 

2198 - 'center': Center the base on the *x* positions. 

2199 - 'edge': Align the left edges of the bars with the *x* positions. 

2200 

2201 To align the bars on the right edge pass a negative *width* and 

2202 ``align='edge'``. 

2203 

2204 Returns 

2205 ------- 

2206 container : `.BarContainer` 

2207 Container with all the bars and optionally errorbars. 

2208 

2209 Other Parameters 

2210 ---------------- 

2211 color : scalar or array-like, optional 

2212 The colors of the bar faces. 

2213 

2214 edgecolor : scalar or array-like, optional 

2215 The colors of the bar edges. 

2216 

2217 linewidth : scalar or array-like, optional 

2218 Width of the bar edge(s). If 0, don't draw edges. 

2219 

2220 tick_label : str or array-like, optional 

2221 The tick labels of the bars. 

2222 Default: None (Use default numeric labels.) 

2223 

2224 xerr, yerr : scalar or array-like of shape(N,) or shape(2, N), optional 

2225 If not *None*, add horizontal / vertical errorbars to the bar tips. 

2226 The values are +/- sizes relative to the data: 

2227 

2228 - scalar: symmetric +/- values for all bars 

2229 - shape(N,): symmetric +/- values for each bar 

2230 - shape(2, N): Separate - and + values for each bar. First row 

2231 contains the lower errors, the second row contains the upper 

2232 errors. 

2233 - *None*: No errorbar. (Default) 

2234 

2235 See :doc:`/gallery/statistics/errorbar_features` 

2236 for an example on the usage of ``xerr`` and ``yerr``. 

2237 

2238 ecolor : scalar or array-like, optional, default: 'black' 

2239 The line color of the errorbars. 

2240 

2241 capsize : scalar, optional 

2242 The length of the error bar caps in points. 

2243 Default: None, which will take the value from 

2244 :rc:`errorbar.capsize`. 

2245 

2246 error_kw : dict, optional 

2247 Dictionary of kwargs to be passed to the `~.Axes.errorbar` 

2248 method. Values of *ecolor* or *capsize* defined here take 

2249 precedence over the independent kwargs. 

2250 

2251 log : bool, optional, default: False 

2252 If *True*, set the y-axis to be log scale. 

2253 

2254 orientation : {'vertical', 'horizontal'}, optional 

2255 *This is for internal use only.* Please use `barh` for 

2256 horizontal bar plots. Default: 'vertical'. 

2257 

2258 See also 

2259 -------- 

2260 barh: Plot a horizontal bar plot. 

2261 

2262 Notes 

2263 ----- 

2264 The optional arguments *color*, *edgecolor*, *linewidth*, 

2265 *xerr*, and *yerr* can be either scalars or sequences of 

2266 length equal to the number of bars. This enables you to use 

2267 bar as the basis for stacked bar charts, or candlestick plots. 

2268 Detail: *xerr* and *yerr* are passed directly to 

2269 :meth:`errorbar`, so they can also have shape 2xN for 

2270 independent specification of lower and upper errors. 

2271 

2272 Other optional kwargs: 

2273 

2274 %(Rectangle)s 

2275 """ 

2276 kwargs = cbook.normalize_kwargs(kwargs, mpatches.Patch) 

2277 color = kwargs.pop('color', None) 

2278 if color is None: 

2279 color = self._get_patches_for_fill.get_next_color() 

2280 edgecolor = kwargs.pop('edgecolor', None) 

2281 linewidth = kwargs.pop('linewidth', None) 

2282 

2283 # Because xerr and yerr will be passed to errorbar, most dimension 

2284 # checking and processing will be left to the errorbar method. 

2285 xerr = kwargs.pop('xerr', None) 

2286 yerr = kwargs.pop('yerr', None) 

2287 error_kw = kwargs.pop('error_kw', {}) 

2288 ezorder = error_kw.pop('zorder', None) 

2289 if ezorder is None: 

2290 ezorder = kwargs.get('zorder', None) 

2291 if ezorder is not None: 

2292 # If using the bar zorder, increment slightly to make sure 

2293 # errorbars are drawn on top of bars 

2294 ezorder += 0.01 

2295 error_kw.setdefault('zorder', ezorder) 

2296 ecolor = kwargs.pop('ecolor', 'k') 

2297 capsize = kwargs.pop('capsize', rcParams["errorbar.capsize"]) 

2298 error_kw.setdefault('ecolor', ecolor) 

2299 error_kw.setdefault('capsize', capsize) 

2300 

2301 orientation = kwargs.pop('orientation', 'vertical') 

2302 cbook._check_in_list(['vertical', 'horizontal'], 

2303 orientation=orientation) 

2304 log = kwargs.pop('log', False) 

2305 label = kwargs.pop('label', '') 

2306 tick_labels = kwargs.pop('tick_label', None) 

2307 

2308 y = bottom # Matches barh call signature. 

2309 if orientation == 'vertical': 

2310 if y is None: 

2311 y = 0 

2312 elif orientation == 'horizontal': 

2313 if x is None: 

2314 x = 0 

2315 

2316 if orientation == 'vertical': 

2317 self._process_unit_info(xdata=x, ydata=height, kwargs=kwargs) 

2318 if log: 

2319 self.set_yscale('log', nonposy='clip') 

2320 elif orientation == 'horizontal': 

2321 self._process_unit_info(xdata=width, ydata=y, kwargs=kwargs) 

2322 if log: 

2323 self.set_xscale('log', nonposx='clip') 

2324 

2325 # lets do some conversions now since some types cannot be 

2326 # subtracted uniformly 

2327 if self.xaxis is not None: 

2328 x0 = x 

2329 x = np.asarray(self.convert_xunits(x)) 

2330 width = self._convert_dx(width, x0, x, self.convert_xunits) 

2331 if xerr is not None: 

2332 xerr = self._convert_dx(xerr, x0, x, self.convert_xunits) 

2333 if self.yaxis is not None: 

2334 y0 = y 

2335 y = np.asarray(self.convert_yunits(y)) 

2336 height = self._convert_dx(height, y0, y, self.convert_yunits) 

2337 if yerr is not None: 

2338 yerr = self._convert_dx(yerr, y0, y, self.convert_yunits) 

2339 

2340 x, height, width, y, linewidth = np.broadcast_arrays( 

2341 # Make args iterable too. 

2342 np.atleast_1d(x), height, width, y, linewidth) 

2343 

2344 # Now that units have been converted, set the tick locations. 

2345 if orientation == 'vertical': 

2346 tick_label_axis = self.xaxis 

2347 tick_label_position = x 

2348 elif orientation == 'horizontal': 

2349 tick_label_axis = self.yaxis 

2350 tick_label_position = y 

2351 

2352 linewidth = itertools.cycle(np.atleast_1d(linewidth)) 

2353 color = itertools.chain(itertools.cycle(mcolors.to_rgba_array(color)), 

2354 # Fallback if color == "none". 

2355 itertools.repeat('none')) 

2356 if edgecolor is None: 

2357 edgecolor = itertools.repeat(None) 

2358 else: 

2359 edgecolor = itertools.chain( 

2360 itertools.cycle(mcolors.to_rgba_array(edgecolor)), 

2361 # Fallback if edgecolor == "none". 

2362 itertools.repeat('none')) 

2363 

2364 # We will now resolve the alignment and really have 

2365 # left, bottom, width, height vectors 

2366 cbook._check_in_list(['center', 'edge'], align=align) 

2367 if align == 'center': 

2368 if orientation == 'vertical': 

2369 try: 

2370 left = x - width / 2 

2371 except TypeError as e: 

2372 raise TypeError(f'the dtypes of parameters x ({x.dtype}) ' 

2373 f'and width ({width.dtype}) ' 

2374 f'are incompatible') from e 

2375 bottom = y 

2376 elif orientation == 'horizontal': 

2377 try: 

2378 bottom = y - height / 2 

2379 except TypeError as e: 

2380 raise TypeError(f'the dtypes of parameters y ({y.dtype}) ' 

2381 f'and height ({height.dtype}) ' 

2382 f'are incompatible') from e 

2383 left = x 

2384 elif align == 'edge': 

2385 left = x 

2386 bottom = y 

2387 

2388 patches = [] 

2389 args = zip(left, bottom, width, height, color, edgecolor, linewidth) 

2390 for l, b, w, h, c, e, lw in args: 

2391 r = mpatches.Rectangle( 

2392 xy=(l, b), width=w, height=h, 

2393 facecolor=c, 

2394 edgecolor=e, 

2395 linewidth=lw, 

2396 label='_nolegend_', 

2397 ) 

2398 r.update(kwargs) 

2399 r.get_path()._interpolation_steps = 100 

2400 if orientation == 'vertical': 

2401 r.sticky_edges.y.append(b) 

2402 elif orientation == 'horizontal': 

2403 r.sticky_edges.x.append(l) 

2404 self.add_patch(r) 

2405 patches.append(r) 

2406 

2407 if xerr is not None or yerr is not None: 

2408 if orientation == 'vertical': 

2409 # using list comps rather than arrays to preserve unit info 

2410 ex = [l + 0.5 * w for l, w in zip(left, width)] 

2411 ey = [b + h for b, h in zip(bottom, height)] 

2412 

2413 elif orientation == 'horizontal': 

2414 # using list comps rather than arrays to preserve unit info 

2415 ex = [l + w for l, w in zip(left, width)] 

2416 ey = [b + 0.5 * h for b, h in zip(bottom, height)] 

2417 

2418 error_kw.setdefault("label", '_nolegend_') 

2419 

2420 errorbar = self.errorbar(ex, ey, 

2421 yerr=yerr, xerr=xerr, 

2422 fmt='none', **error_kw) 

2423 else: 

2424 errorbar = None 

2425 

2426 self._request_autoscale_view() 

2427 

2428 bar_container = BarContainer(patches, errorbar, label=label) 

2429 self.add_container(bar_container) 

2430 

2431 if tick_labels is not None: 

2432 tick_labels = np.broadcast_to(tick_labels, len(patches)) 

2433 tick_label_axis.set_ticks(tick_label_position) 

2434 tick_label_axis.set_ticklabels(tick_labels) 

2435 

2436 return bar_container 

2437 

2438 @docstring.dedent_interpd 

2439 def barh(self, y, width, height=0.8, left=None, *, align="center", 

2440 **kwargs): 

2441 r""" 

2442 Make a horizontal bar plot. 

2443 

2444 The bars are positioned at *y* with the given *align*\ment. Their 

2445 dimensions are given by *width* and *height*. The horizontal baseline 

2446 is *left* (default 0). 

2447 

2448 Each of *y*, *width*, *height*, and *left* may either be a scalar 

2449 applying to all bars, or it may be a sequence of length N providing a 

2450 separate value for each bar. 

2451 

2452 Parameters 

2453 ---------- 

2454 y : scalar or array-like 

2455 The y coordinates of the bars. See also *align* for the 

2456 alignment of the bars to the coordinates. 

2457 

2458 width : scalar or array-like 

2459 The width(s) of the bars. 

2460 

2461 height : sequence of scalars, optional, default: 0.8 

2462 The heights of the bars. 

2463 

2464 left : sequence of scalars 

2465 The x coordinates of the left sides of the bars (default: 0). 

2466 

2467 align : {'center', 'edge'}, optional, default: 'center' 

2468 Alignment of the base to the *y* coordinates*: 

2469 

2470 - 'center': Center the bars on the *y* positions. 

2471 - 'edge': Align the bottom edges of the bars with the *y* 

2472 positions. 

2473 

2474 To align the bars on the top edge pass a negative *height* and 

2475 ``align='edge'``. 

2476 

2477 Returns 

2478 ------- 

2479 container : `.BarContainer` 

2480 Container with all the bars and optionally errorbars. 

2481 

2482 Other Parameters 

2483 ---------------- 

2484 color : scalar or array-like, optional 

2485 The colors of the bar faces. 

2486 

2487 edgecolor : scalar or array-like, optional 

2488 The colors of the bar edges. 

2489 

2490 linewidth : scalar or array-like, optional 

2491 Width of the bar edge(s). If 0, don't draw edges. 

2492 

2493 tick_label : str or array-like, optional 

2494 The tick labels of the bars. 

2495 Default: None (Use default numeric labels.) 

2496 

2497 xerr, yerr : scalar or array-like of shape(N,) or shape(2, N), optional 

2498 If not ``None``, add horizontal / vertical errorbars to the 

2499 bar tips. The values are +/- sizes relative to the data: 

2500 

2501 - scalar: symmetric +/- values for all bars 

2502 - shape(N,): symmetric +/- values for each bar 

2503 - shape(2, N): Separate - and + values for each bar. First row 

2504 contains the lower errors, the second row contains the upper 

2505 errors. 

2506 - *None*: No errorbar. (default) 

2507 

2508 See :doc:`/gallery/statistics/errorbar_features` 

2509 for an example on the usage of ``xerr`` and ``yerr``. 

2510 

2511 ecolor : scalar or array-like, optional, default: 'black' 

2512 The line color of the errorbars. 

2513 

2514 capsize : scalar, optional 

2515 The length of the error bar caps in points. 

2516 Default: None, which will take the value from 

2517 :rc:`errorbar.capsize`. 

2518 

2519 error_kw : dict, optional 

2520 Dictionary of kwargs to be passed to the `~.Axes.errorbar` 

2521 method. Values of *ecolor* or *capsize* defined here take 

2522 precedence over the independent kwargs. 

2523 

2524 log : bool, optional, default: False 

2525 If ``True``, set the x-axis to be log scale. 

2526 

2527 See also 

2528 -------- 

2529 bar: Plot a vertical bar plot. 

2530 

2531 Notes 

2532 ----- 

2533 The optional arguments *color*, *edgecolor*, *linewidth*, 

2534 *xerr*, and *yerr* can be either scalars or sequences of 

2535 length equal to the number of bars. This enables you to use 

2536 bar as the basis for stacked bar charts, or candlestick plots. 

2537 Detail: *xerr* and *yerr* are passed directly to 

2538 :meth:`errorbar`, so they can also have shape 2xN for 

2539 independent specification of lower and upper errors. 

2540 

2541 Other optional kwargs: 

2542 

2543 %(Rectangle)s 

2544 """ 

2545 kwargs.setdefault('orientation', 'horizontal') 

2546 patches = self.bar(x=left, height=height, width=width, bottom=y, 

2547 align=align, **kwargs) 

2548 return patches 

2549 

2550 @_preprocess_data() 

2551 @docstring.dedent_interpd 

2552 def broken_barh(self, xranges, yrange, **kwargs): 

2553 """ 

2554 Plot a horizontal sequence of rectangles. 

2555 

2556 A rectangle is drawn for each element of *xranges*. All rectangles 

2557 have the same vertical position and size defined by *yrange*. 

2558 

2559 This is a convenience function for instantiating a 

2560 `.BrokenBarHCollection`, adding it to the axes and autoscaling the 

2561 view. 

2562 

2563 Parameters 

2564 ---------- 

2565 xranges : sequence of tuples (*xmin*, *xwidth*) 

2566 The x-positions and extends of the rectangles. For each tuple 

2567 (*xmin*, *xwidth*) a rectangle is drawn from *xmin* to *xmin* + 

2568 *xwidth*. 

2569 yrange : (*ymin*, *yheight*) 

2570 The y-position and extend for all the rectangles. 

2571 

2572 Other Parameters 

2573 ---------------- 

2574 **kwargs : :class:`.BrokenBarHCollection` properties 

2575 

2576 Each *kwarg* can be either a single argument applying to all 

2577 rectangles, e.g.:: 

2578 

2579 facecolors='black' 

2580 

2581 or a sequence of arguments over which is cycled, e.g.:: 

2582 

2583 facecolors=('black', 'blue') 

2584 

2585 would create interleaving black and blue rectangles. 

2586 

2587 Supported keywords: 

2588 

2589 %(BrokenBarHCollection)s 

2590 

2591 Returns 

2592 ------- 

2593 collection : A :class:`~.collections.BrokenBarHCollection` 

2594 """ 

2595 # process the unit information 

2596 if len(xranges): 

2597 xdata = cbook.safe_first_element(xranges) 

2598 else: 

2599 xdata = None 

2600 if len(yrange): 

2601 ydata = cbook.safe_first_element(yrange) 

2602 else: 

2603 ydata = None 

2604 self._process_unit_info(xdata=xdata, 

2605 ydata=ydata, 

2606 kwargs=kwargs) 

2607 xranges_conv = [] 

2608 for xr in xranges: 

2609 if len(xr) != 2: 

2610 raise ValueError('each range in xrange must be a sequence ' 

2611 'with two elements (i.e. an Nx2 array)') 

2612 # convert the absolute values, not the x and dx... 

2613 x_conv = np.asarray(self.convert_xunits(xr[0])) 

2614 x1 = self._convert_dx(xr[1], xr[0], x_conv, self.convert_xunits) 

2615 xranges_conv.append((x_conv, x1)) 

2616 

2617 yrange_conv = self.convert_yunits(yrange) 

2618 

2619 col = mcoll.BrokenBarHCollection(xranges_conv, yrange_conv, **kwargs) 

2620 self.add_collection(col, autolim=True) 

2621 self._request_autoscale_view() 

2622 

2623 return col 

2624 

2625 @_preprocess_data() 

2626 def stem(self, *args, linefmt=None, markerfmt=None, basefmt=None, bottom=0, 

2627 label=None, use_line_collection=False): 

2628 """ 

2629 Create a stem plot. 

2630 

2631 A stem plot plots vertical lines at each *x* location from the baseline 

2632 to *y*, and places a marker there. 

2633 

2634 Call signature:: 

2635 

2636 stem([x,] y, linefmt=None, markerfmt=None, basefmt=None) 

2637 

2638 The x-positions are optional. The formats may be provided either as 

2639 positional or as keyword-arguments. 

2640 

2641 Parameters 

2642 ---------- 

2643 x : array-like, optional 

2644 The x-positions of the stems. Default: (0, 1, ..., len(y) - 1). 

2645 

2646 y : array-like 

2647 The y-values of the stem heads. 

2648 

2649 linefmt : str, optional 

2650 A string defining the properties of the vertical lines. Usually, 

2651 this will be a color or a color and a linestyle: 

2652 

2653 ========= ============= 

2654 Character Line Style 

2655 ========= ============= 

2656 ``'-'`` solid line 

2657 ``'--'`` dashed line 

2658 ``'-.'`` dash-dot line 

2659 ``':'`` dotted line 

2660 ========= ============= 

2661 

2662 Default: 'C0-', i.e. solid line with the first color of the color 

2663 cycle. 

2664 

2665 Note: While it is technically possible to specify valid formats 

2666 other than color or color and linestyle (e.g. 'rx' or '-.'), this 

2667 is beyond the intention of the method and will most likely not 

2668 result in a reasonable reasonable plot. 

2669 

2670 markerfmt : str, optional 

2671 A string defining the properties of the markers at the stem heads. 

2672 Default: 'C0o', i.e. filled circles with the first color of the 

2673 color cycle. 

2674 

2675 basefmt : str, optional 

2676 A format string defining the properties of the baseline. 

2677 

2678 Default: 'C3-' ('C2-' in classic mode). 

2679 

2680 bottom : float, optional, default: 0 

2681 The y-position of the baseline. 

2682 

2683 label : str, optional, default: None 

2684 The label to use for the stems in legends. 

2685 

2686 use_line_collection : bool, optional, default: False 

2687 If ``True``, store and plot the stem lines as a 

2688 `~.collections.LineCollection` instead of individual lines. This 

2689 significantly increases performance, and will become the default 

2690 option in Matplotlib 3.3. If ``False``, defaults to the old 

2691 behavior of using a list of `.Line2D` objects. 

2692 

2693 

2694 Returns 

2695 ------- 

2696 container : :class:`~matplotlib.container.StemContainer` 

2697 The container may be treated like a tuple 

2698 (*markerline*, *stemlines*, *baseline*) 

2699 

2700 

2701 Notes 

2702 ----- 

2703 .. seealso:: 

2704 The MATLAB function 

2705 `stem <http://www.mathworks.com/help/techdoc/ref/stem.html>`_ 

2706 which inspired this method. 

2707 

2708 """ 

2709 if not 1 <= len(args) <= 5: 

2710 raise TypeError('stem expected between 1 and 5 positional ' 

2711 'arguments, got {}'.format(args)) 

2712 

2713 if len(args) == 1: 

2714 y, = args 

2715 x = np.arange(len(y)) 

2716 args = () 

2717 else: 

2718 x, y, *args = args 

2719 

2720 self._process_unit_info(xdata=x, ydata=y) 

2721 x = self.convert_xunits(x) 

2722 y = self.convert_yunits(y) 

2723 

2724 # defaults for formats 

2725 if linefmt is None: 

2726 try: 

2727 # fallback to positional argument 

2728 linefmt = args[0] 

2729 except IndexError: 

2730 linecolor = 'C0' 

2731 linemarker = 'None' 

2732 linestyle = '-' 

2733 else: 

2734 linestyle, linemarker, linecolor = \ 

2735 _process_plot_format(linefmt) 

2736 else: 

2737 linestyle, linemarker, linecolor = _process_plot_format(linefmt) 

2738 

2739 if markerfmt is None: 

2740 try: 

2741 # fallback to positional argument 

2742 markerfmt = args[1] 

2743 except IndexError: 

2744 markercolor = 'C0' 

2745 markermarker = 'o' 

2746 markerstyle = 'None' 

2747 else: 

2748 markerstyle, markermarker, markercolor = \ 

2749 _process_plot_format(markerfmt) 

2750 else: 

2751 markerstyle, markermarker, markercolor = \ 

2752 _process_plot_format(markerfmt) 

2753 

2754 if basefmt is None: 

2755 try: 

2756 # fallback to positional argument 

2757 basefmt = args[2] 

2758 except IndexError: 

2759 if rcParams['_internal.classic_mode']: 

2760 basecolor = 'C2' 

2761 else: 

2762 basecolor = 'C3' 

2763 basemarker = 'None' 

2764 basestyle = '-' 

2765 else: 

2766 basestyle, basemarker, basecolor = \ 

2767 _process_plot_format(basefmt) 

2768 else: 

2769 basestyle, basemarker, basecolor = _process_plot_format(basefmt) 

2770 

2771 # New behaviour in 3.1 is to use a LineCollection for the stemlines 

2772 if use_line_collection: 

2773 stemlines = [((xi, bottom), (xi, yi)) for xi, yi in zip(x, y)] 

2774 if linestyle is None: 

2775 linestyle = rcParams['lines.linestyle'] 

2776 stemlines = mcoll.LineCollection(stemlines, linestyles=linestyle, 

2777 colors=linecolor, 

2778 label='_nolegend_') 

2779 self.add_collection(stemlines) 

2780 # Old behaviour is to plot each of the lines individually 

2781 else: 

2782 cbook._warn_external( 

2783 'In Matplotlib 3.3 individual lines on a stem plot will be ' 

2784 'added as a LineCollection instead of individual lines. ' 

2785 'This significantly improves the performance of a stem plot. ' 

2786 'To remove this warning and switch to the new behaviour, ' 

2787 'set the "use_line_collection" keyword argument to True.') 

2788 stemlines = [] 

2789 for xi, yi in zip(x, y): 

2790 l, = self.plot([xi, xi], [bottom, yi], 

2791 color=linecolor, linestyle=linestyle, 

2792 marker=linemarker, label="_nolegend_") 

2793 stemlines.append(l) 

2794 

2795 markerline, = self.plot(x, y, color=markercolor, linestyle=markerstyle, 

2796 marker=markermarker, label="_nolegend_") 

2797 

2798 baseline, = self.plot([np.min(x), np.max(x)], [bottom, bottom], 

2799 color=basecolor, linestyle=basestyle, 

2800 marker=basemarker, label="_nolegend_") 

2801 

2802 stem_container = StemContainer((markerline, stemlines, baseline), 

2803 label=label) 

2804 self.add_container(stem_container) 

2805 return stem_container 

2806 

2807 @_preprocess_data(replace_names=["x", "explode", "labels", "colors"]) 

2808 def pie(self, x, explode=None, labels=None, colors=None, 

2809 autopct=None, pctdistance=0.6, shadow=False, labeldistance=1.1, 

2810 startangle=None, radius=None, counterclock=True, 

2811 wedgeprops=None, textprops=None, center=(0, 0), 

2812 frame=False, rotatelabels=False): 

2813 """ 

2814 Plot a pie chart. 

2815 

2816 Make a pie chart of array *x*. The fractional area of each wedge is 

2817 given by ``x/sum(x)``. If ``sum(x) < 1``, then the values of *x* give 

2818 the fractional area directly and the array will not be normalized. The 

2819 resulting pie will have an empty wedge of size ``1 - sum(x)``. 

2820 

2821 The wedges are plotted counterclockwise, by default starting from the 

2822 x-axis. 

2823 

2824 Parameters 

2825 ---------- 

2826 x : array-like 

2827 The wedge sizes. 

2828 

2829 explode : array-like, optional, default: None 

2830 If not *None*, is a ``len(x)`` array which specifies the fraction 

2831 of the radius with which to offset each wedge. 

2832 

2833 labels : list, optional, default: None 

2834 A sequence of strings providing the labels for each wedge 

2835 

2836 colors : array-like, optional, default: None 

2837 A sequence of matplotlib color args through which the pie chart 

2838 will cycle. If *None*, will use the colors in the currently 

2839 active cycle. 

2840 

2841 autopct : None (default), str, or function, optional 

2842 If not *None*, is a string or function used to label the wedges 

2843 with their numeric value. The label will be placed inside the 

2844 wedge. If it is a format string, the label will be ``fmt%pct``. 

2845 If it is a function, it will be called. 

2846 

2847 pctdistance : float, optional, default: 0.6 

2848 The ratio between the center of each pie slice and the start of 

2849 the text generated by *autopct*. Ignored if *autopct* is *None*. 

2850 

2851 shadow : bool, optional, default: False 

2852 Draw a shadow beneath the pie. 

2853 

2854 labeldistance : float or None, optional, default: 1.1 

2855 The radial distance at which the pie labels are drawn. 

2856 If set to ``None``, label are not drawn, but are stored for use in 

2857 ``legend()`` 

2858 

2859 startangle : float, optional, default: None 

2860 If not *None*, rotates the start of the pie chart by *angle* 

2861 degrees counterclockwise from the x-axis. 

2862 

2863 radius : float, optional, default: None 

2864 The radius of the pie, if *radius* is *None* it will be set to 1. 

2865 

2866 counterclock : bool, optional, default: True 

2867 Specify fractions direction, clockwise or counterclockwise. 

2868 

2869 wedgeprops : dict, optional, default: None 

2870 Dict of arguments passed to the wedge objects making the pie. 

2871 For example, you can pass in ``wedgeprops = {'linewidth': 3}`` 

2872 to set the width of the wedge border lines equal to 3. 

2873 For more details, look at the doc/arguments of the wedge object. 

2874 By default ``clip_on=False``. 

2875 

2876 textprops : dict, optional, default: None 

2877 Dict of arguments to pass to the text objects. 

2878 

2879 center : list of float, optional, default: (0, 0) 

2880 Center position of the chart. Takes value (0, 0) or is a sequence 

2881 of 2 scalars. 

2882 

2883 frame : bool, optional, default: False 

2884 Plot axes frame with the chart if true. 

2885 

2886 rotatelabels : bool, optional, default: False 

2887 Rotate each label to the angle of the corresponding slice if true. 

2888 

2889 Returns 

2890 ------- 

2891 patches : list 

2892 A sequence of :class:`matplotlib.patches.Wedge` instances 

2893 

2894 texts : list 

2895 A list of the label :class:`matplotlib.text.Text` instances. 

2896 

2897 autotexts : list 

2898 A list of :class:`~matplotlib.text.Text` instances for the numeric 

2899 labels. This will only be returned if the parameter *autopct* is 

2900 not *None*. 

2901 

2902 Notes 

2903 ----- 

2904 The pie chart will probably look best if the figure and axes are 

2905 square, or the Axes aspect is equal. 

2906 This method sets the aspect ratio of the axis to "equal". 

2907 The axes aspect ratio can be controlled with `Axes.set_aspect`. 

2908 """ 

2909 self.set_aspect('equal') 

2910 # The use of float32 is "historical", but can't be changed without 

2911 # regenerating the test baselines. 

2912 x = np.asarray(x, np.float32) 

2913 if x.ndim != 1 and x.squeeze().ndim <= 1: 

2914 cbook.warn_deprecated( 

2915 "3.1", message="Non-1D inputs to pie() are currently " 

2916 "squeeze()d, but this behavior is deprecated since %(since)s " 

2917 "and will be removed %(removal)s; pass a 1D array instead.") 

2918 x = np.atleast_1d(x.squeeze()) 

2919 

2920 sx = x.sum() 

2921 if sx > 1: 

2922 x = x / sx 

2923 

2924 if labels is None: 

2925 labels = [''] * len(x) 

2926 if explode is None: 

2927 explode = [0] * len(x) 

2928 if len(x) != len(labels): 

2929 raise ValueError("'label' must be of length 'x'") 

2930 if len(x) != len(explode): 

2931 raise ValueError("'explode' must be of length 'x'") 

2932 if colors is None: 

2933 get_next_color = self._get_patches_for_fill.get_next_color 

2934 else: 

2935 color_cycle = itertools.cycle(colors) 

2936 

2937 def get_next_color(): 

2938 return next(color_cycle) 

2939 

2940 if radius is None: 

2941 radius = 1 

2942 

2943 # Starting theta1 is the start fraction of the circle 

2944 if startangle is None: 

2945 theta1 = 0 

2946 else: 

2947 theta1 = startangle / 360.0 

2948 

2949 # set default values in wedge_prop 

2950 if wedgeprops is None: 

2951 wedgeprops = {} 

2952 wedgeprops.setdefault('clip_on', False) 

2953 

2954 if textprops is None: 

2955 textprops = {} 

2956 textprops.setdefault('clip_on', False) 

2957 

2958 texts = [] 

2959 slices = [] 

2960 autotexts = [] 

2961 

2962 for frac, label, expl in zip(x, labels, explode): 

2963 x, y = center 

2964 theta2 = (theta1 + frac) if counterclock else (theta1 - frac) 

2965 thetam = 2 * np.pi * 0.5 * (theta1 + theta2) 

2966 x += expl * math.cos(thetam) 

2967 y += expl * math.sin(thetam) 

2968 

2969 w = mpatches.Wedge((x, y), radius, 360. * min(theta1, theta2), 

2970 360. * max(theta1, theta2), 

2971 facecolor=get_next_color(), 

2972 **wedgeprops) 

2973 slices.append(w) 

2974 self.add_patch(w) 

2975 w.set_label(label) 

2976 

2977 if shadow: 

2978 # make sure to add a shadow after the call to 

2979 # add_patch so the figure and transform props will be 

2980 # set 

2981 shad = mpatches.Shadow(w, -0.02, -0.02) 

2982 shad.set_zorder(0.9 * w.get_zorder()) 

2983 shad.set_label('_nolegend_') 

2984 self.add_patch(shad) 

2985 

2986 if labeldistance is not None: 

2987 xt = x + labeldistance * radius * math.cos(thetam) 

2988 yt = y + labeldistance * radius * math.sin(thetam) 

2989 label_alignment_h = 'left' if xt > 0 else 'right' 

2990 label_alignment_v = 'center' 

2991 label_rotation = 'horizontal' 

2992 if rotatelabels: 

2993 label_alignment_v = 'bottom' if yt > 0 else 'top' 

2994 label_rotation = (np.rad2deg(thetam) 

2995 + (0 if xt > 0 else 180)) 

2996 props = dict(horizontalalignment=label_alignment_h, 

2997 verticalalignment=label_alignment_v, 

2998 rotation=label_rotation, 

2999 size=rcParams['xtick.labelsize']) 

3000 props.update(textprops) 

3001 

3002 t = self.text(xt, yt, label, **props) 

3003 

3004 texts.append(t) 

3005 

3006 if autopct is not None: 

3007 xt = x + pctdistance * radius * math.cos(thetam) 

3008 yt = y + pctdistance * radius * math.sin(thetam) 

3009 if isinstance(autopct, str): 

3010 s = autopct % (100. * frac) 

3011 elif callable(autopct): 

3012 s = autopct(100. * frac) 

3013 else: 

3014 raise TypeError( 

3015 'autopct must be callable or a format string') 

3016 

3017 props = dict(horizontalalignment='center', 

3018 verticalalignment='center') 

3019 props.update(textprops) 

3020 t = self.text(xt, yt, s, **props) 

3021 

3022 autotexts.append(t) 

3023 

3024 theta1 = theta2 

3025 

3026 if not frame: 

3027 self.set_frame_on(False) 

3028 

3029 self.set_xlim((-1.25 + center[0], 

3030 1.25 + center[0])) 

3031 self.set_ylim((-1.25 + center[1], 

3032 1.25 + center[1])) 

3033 self.set_xticks([]) 

3034 self.set_yticks([]) 

3035 

3036 if autopct is None: 

3037 return slices, texts 

3038 else: 

3039 return slices, texts, autotexts 

3040 

3041 @_preprocess_data(replace_names=["x", "y", "xerr", "yerr"], 

3042 label_namer="y") 

3043 @docstring.dedent_interpd 

3044 def errorbar(self, x, y, yerr=None, xerr=None, 

3045 fmt='', ecolor=None, elinewidth=None, capsize=None, 

3046 barsabove=False, lolims=False, uplims=False, 

3047 xlolims=False, xuplims=False, errorevery=1, capthick=None, 

3048 **kwargs): 

3049 """ 

3050 Plot y versus x as lines and/or markers with attached errorbars. 

3051 

3052 *x*, *y* define the data locations, *xerr*, *yerr* define the errorbar 

3053 sizes. By default, this draws the data markers/lines as well the 

3054 errorbars. Use fmt='none' to draw errorbars without any data markers. 

3055 

3056 Parameters 

3057 ---------- 

3058 x, y : scalar or array-like 

3059 The data positions. 

3060 

3061 xerr, yerr : scalar or array-like, shape(N,) or shape(2, N), optional 

3062 The errorbar sizes: 

3063 

3064 - scalar: Symmetric +/- values for all data points. 

3065 - shape(N,): Symmetric +/-values for each data point. 

3066 - shape(2, N): Separate - and + values for each bar. First row 

3067 contains the lower errors, the second row contains the upper 

3068 errors. 

3069 - *None*: No errorbar. 

3070 

3071 Note that all error arrays should have *positive* values. 

3072 

3073 See :doc:`/gallery/statistics/errorbar_features` 

3074 for an example on the usage of ``xerr`` and ``yerr``. 

3075 

3076 fmt : str, optional, default: '' 

3077 The format for the data points / data lines. See `.plot` for 

3078 details. 

3079 

3080 Use 'none' (case insensitive) to plot errorbars without any data 

3081 markers. 

3082 

3083 ecolor : color, optional, default: None 

3084 The color of the errorbar lines. If None, use the color of the 

3085 line connecting the markers. 

3086 

3087 elinewidth : scalar, optional, default: None 

3088 The linewidth of the errorbar lines. If None, the linewidth of 

3089 the current style is used. 

3090 

3091 capsize : scalar, optional, default: None 

3092 The length of the error bar caps in points. If None, it will take 

3093 the value from :rc:`errorbar.capsize`. 

3094 

3095 capthick : scalar, optional, default: None 

3096 An alias to the keyword argument *markeredgewidth* (a.k.a. *mew*). 

3097 This setting is a more sensible name for the property that 

3098 controls the thickness of the error bar cap in points. For 

3099 backwards compatibility, if *mew* or *markeredgewidth* are given, 

3100 then they will over-ride *capthick*. This may change in future 

3101 releases. 

3102 

3103 barsabove : bool, optional, default: False 

3104 If True, will plot the errorbars above the plot 

3105 symbols. Default is below. 

3106 

3107 lolims, uplims, xlolims, xuplims : bool, optional, default: False 

3108 These arguments can be used to indicate that a value gives only 

3109 upper/lower limits. In that case a caret symbol is used to 

3110 indicate this. *lims*-arguments may be of the same type as *xerr* 

3111 and *yerr*. To use limits with inverted axes, :meth:`set_xlim` 

3112 or :meth:`set_ylim` must be called before :meth:`errorbar`. 

3113 

3114 errorevery : int or (int, int), optional, default: 1 

3115 draws error bars on a subset of the data. *errorevery* =N draws 

3116 error bars on the points (x[::N], y[::N]). 

3117 *errorevery* =(start, N) draws error bars on the points 

3118 (x[start::N], y[start::N]). e.g. errorevery=(6, 3) 

3119 adds error bars to the data at (x[6], x[9], x[12], x[15], ...). 

3120 Used to avoid overlapping error bars when two series share x-axis 

3121 values. 

3122 

3123 Returns 

3124 ------- 

3125 container : :class:`~.container.ErrorbarContainer` 

3126 The container contains: 

3127 

3128 - plotline: `.Line2D` instance of x, y plot markers and/or line. 

3129 - caplines: A tuple of `.Line2D` instances of the error bar caps. 

3130 - barlinecols: A tuple of 

3131 :class:`~matplotlib.collections.LineCollection` with the 

3132 horizontal and vertical error ranges. 

3133 

3134 Other Parameters 

3135 ---------------- 

3136 **kwargs 

3137 All other keyword arguments are passed on to the plot 

3138 command for the markers. For example, this code makes big red 

3139 squares with thick green edges:: 

3140 

3141 x, y, yerr = rand(3, 10) 

3142 errorbar(x, y, yerr, marker='s', mfc='red', 

3143 mec='green', ms=20, mew=4) 

3144 

3145 where *mfc*, *mec*, *ms* and *mew* are aliases for the longer 

3146 property names, *markerfacecolor*, *markeredgecolor*, *markersize* 

3147 and *markeredgewidth*. 

3148 

3149 Valid kwargs for the marker properties are `.Lines2D` properties: 

3150 

3151 %(_Line2D_docstr)s 

3152 """ 

3153 kwargs = cbook.normalize_kwargs(kwargs, mlines.Line2D) 

3154 # anything that comes in as 'None', drop so the default thing 

3155 # happens down stream 

3156 kwargs = {k: v for k, v in kwargs.items() if v is not None} 

3157 kwargs.setdefault('zorder', 2) 

3158 

3159 try: 

3160 offset, errorevery = errorevery 

3161 except TypeError: 

3162 offset = 0 

3163 

3164 if errorevery < 1 or int(errorevery) != errorevery: 

3165 raise ValueError( 

3166 'errorevery must be positive integer or tuple of integers') 

3167 if int(offset) != offset: 

3168 raise ValueError("errorevery's starting index must be an integer") 

3169 

3170 self._process_unit_info(xdata=x, ydata=y, kwargs=kwargs) 

3171 

3172 plot_line = (fmt.lower() != 'none') 

3173 label = kwargs.pop("label", None) 

3174 

3175 if fmt == '': 

3176 fmt_style_kwargs = {} 

3177 else: 

3178 fmt_style_kwargs = {k: v for k, v in 

3179 zip(('linestyle', 'marker', 'color'), 

3180 _process_plot_format(fmt)) 

3181 if v is not None} 

3182 if fmt == 'none': 

3183 # Remove alpha=0 color that _process_plot_format returns 

3184 fmt_style_kwargs.pop('color') 

3185 

3186 if ('color' in kwargs or 'color' in fmt_style_kwargs or 

3187 ecolor is not None): 

3188 base_style = {} 

3189 if 'color' in kwargs: 

3190 base_style['color'] = kwargs.pop('color') 

3191 else: 

3192 base_style = next(self._get_lines.prop_cycler) 

3193 

3194 base_style['label'] = '_nolegend_' 

3195 base_style.update(fmt_style_kwargs) 

3196 if 'color' not in base_style: 

3197 base_style['color'] = 'C0' 

3198 if ecolor is None: 

3199 ecolor = base_style['color'] 

3200 # make sure all the args are iterable; use lists not arrays to 

3201 # preserve units 

3202 if not np.iterable(x): 

3203 x = [x] 

3204 

3205 if not np.iterable(y): 

3206 y = [y] 

3207 

3208 if xerr is not None: 

3209 if not np.iterable(xerr): 

3210 xerr = [xerr] * len(x) 

3211 

3212 if yerr is not None: 

3213 if not np.iterable(yerr): 

3214 yerr = [yerr] * len(y) 

3215 

3216 # make the style dict for the 'normal' plot line 

3217 plot_line_style = { 

3218 **base_style, 

3219 **kwargs, 

3220 'zorder': (kwargs['zorder'] - .1 if barsabove else 

3221 kwargs['zorder'] + .1), 

3222 } 

3223 

3224 # make the style dict for the line collections (the bars) 

3225 eb_lines_style = dict(base_style) 

3226 eb_lines_style.pop('marker', None) 

3227 eb_lines_style.pop('linestyle', None) 

3228 eb_lines_style['color'] = ecolor 

3229 

3230 if elinewidth: 

3231 eb_lines_style['linewidth'] = elinewidth 

3232 elif 'linewidth' in kwargs: 

3233 eb_lines_style['linewidth'] = kwargs['linewidth'] 

3234 

3235 for key in ('transform', 'alpha', 'zorder', 'rasterized'): 

3236 if key in kwargs: 

3237 eb_lines_style[key] = kwargs[key] 

3238 

3239 # set up cap style dictionary 

3240 eb_cap_style = dict(base_style) 

3241 # eject any marker information from format string 

3242 eb_cap_style.pop('marker', None) 

3243 eb_lines_style.pop('markerfacecolor', None) 

3244 eb_lines_style.pop('markeredgewidth', None) 

3245 eb_lines_style.pop('markeredgecolor', None) 

3246 eb_cap_style.pop('ls', None) 

3247 eb_cap_style['linestyle'] = 'none' 

3248 if capsize is None: 

3249 capsize = rcParams["errorbar.capsize"] 

3250 if capsize > 0: 

3251 eb_cap_style['markersize'] = 2. * capsize 

3252 if capthick is not None: 

3253 eb_cap_style['markeredgewidth'] = capthick 

3254 

3255 # For backwards-compat, allow explicit setting of 

3256 # 'markeredgewidth' to over-ride capthick. 

3257 for key in ('markeredgewidth', 'transform', 'alpha', 

3258 'zorder', 'rasterized'): 

3259 if key in kwargs: 

3260 eb_cap_style[key] = kwargs[key] 

3261 eb_cap_style['color'] = ecolor 

3262 

3263 data_line = None 

3264 if plot_line: 

3265 data_line = mlines.Line2D(x, y, **plot_line_style) 

3266 self.add_line(data_line) 

3267 

3268 barcols = [] 

3269 caplines = [] 

3270 

3271 # arrays fine here, they are booleans and hence not units 

3272 lolims = np.broadcast_to(lolims, len(x)).astype(bool) 

3273 uplims = np.broadcast_to(uplims, len(x)).astype(bool) 

3274 xlolims = np.broadcast_to(xlolims, len(x)).astype(bool) 

3275 xuplims = np.broadcast_to(xuplims, len(x)).astype(bool) 

3276 

3277 everymask = np.zeros(len(x), bool) 

3278 everymask[offset::errorevery] = True 

3279 

3280 def xywhere(xs, ys, mask): 

3281 """ 

3282 return xs[mask], ys[mask] where mask is True but xs and 

3283 ys are not arrays 

3284 """ 

3285 assert len(xs) == len(ys) 

3286 assert len(xs) == len(mask) 

3287 xs = [thisx for thisx, b in zip(xs, mask) if b] 

3288 ys = [thisy for thisy, b in zip(ys, mask) if b] 

3289 return xs, ys 

3290 

3291 def extract_err(err, data): 

3292 """ 

3293 Private function to parse *err* and subtract/add it to *data*. 

3294 

3295 Both *err* and *data* are already iterables at this point. 

3296 """ 

3297 try: # Asymmetric error: pair of 1D iterables. 

3298 a, b = err 

3299 iter(a) 

3300 iter(b) 

3301 except (TypeError, ValueError): 

3302 a = b = err # Symmetric error: 1D iterable. 

3303 # This could just be `np.ndim(a) > 1 and np.ndim(b) > 1`, except 

3304 # for the (undocumented, but tested) support for (n, 1) arrays. 

3305 a_sh = np.shape(a) 

3306 b_sh = np.shape(b) 

3307 if (len(a_sh) > 2 or (len(a_sh) == 2 and a_sh[1] != 1) 

3308 or len(b_sh) > 2 or (len(b_sh) == 2 and b_sh[1] != 1)): 

3309 raise ValueError( 

3310 "err must be a scalar or a 1D or (2, n) array-like") 

3311 if len(a_sh) == 2 or len(b_sh) == 2: 

3312 cbook.warn_deprecated( 

3313 "3.1", message="Support for passing a (n, 1)-shaped error " 

3314 "array to errorbar() is deprecated since Matplotlib " 

3315 "%(since)s and will be removed %(removal)s; pass a 1D " 

3316 "array instead.") 

3317 # Using list comprehensions rather than arrays to preserve units. 

3318 for e in [a, b]: 

3319 if len(data) != len(e): 

3320 raise ValueError( 

3321 f"The lengths of the data ({len(data)}) and the " 

3322 f"error {len(e)} do not match") 

3323 low = [v - e for v, e in zip(data, a)] 

3324 high = [v + e for v, e in zip(data, b)] 

3325 return low, high 

3326 

3327 if xerr is not None: 

3328 left, right = extract_err(xerr, x) 

3329 # select points without upper/lower limits in x and 

3330 # draw normal errorbars for these points 

3331 noxlims = ~(xlolims | xuplims) 

3332 if noxlims.any() or len(noxlims) == 0: 

3333 yo, _ = xywhere(y, right, noxlims & everymask) 

3334 lo, ro = xywhere(left, right, noxlims & everymask) 

3335 barcols.append(self.hlines(yo, lo, ro, **eb_lines_style)) 

3336 if capsize > 0: 

3337 caplines.append(mlines.Line2D(lo, yo, marker='|', 

3338 **eb_cap_style)) 

3339 caplines.append(mlines.Line2D(ro, yo, marker='|', 

3340 **eb_cap_style)) 

3341 

3342 if xlolims.any(): 

3343 yo, _ = xywhere(y, right, xlolims & everymask) 

3344 lo, ro = xywhere(x, right, xlolims & everymask) 

3345 barcols.append(self.hlines(yo, lo, ro, **eb_lines_style)) 

3346 rightup, yup = xywhere(right, y, xlolims & everymask) 

3347 if self.xaxis_inverted(): 

3348 marker = mlines.CARETLEFTBASE 

3349 else: 

3350 marker = mlines.CARETRIGHTBASE 

3351 caplines.append( 

3352 mlines.Line2D(rightup, yup, ls='None', marker=marker, 

3353 **eb_cap_style)) 

3354 if capsize > 0: 

3355 xlo, ylo = xywhere(x, y, xlolims & everymask) 

3356 caplines.append(mlines.Line2D(xlo, ylo, marker='|', 

3357 **eb_cap_style)) 

3358 

3359 if xuplims.any(): 

3360 yo, _ = xywhere(y, right, xuplims & everymask) 

3361 lo, ro = xywhere(left, x, xuplims & everymask) 

3362 barcols.append(self.hlines(yo, lo, ro, **eb_lines_style)) 

3363 leftlo, ylo = xywhere(left, y, xuplims & everymask) 

3364 if self.xaxis_inverted(): 

3365 marker = mlines.CARETRIGHTBASE 

3366 else: 

3367 marker = mlines.CARETLEFTBASE 

3368 caplines.append( 

3369 mlines.Line2D(leftlo, ylo, ls='None', marker=marker, 

3370 **eb_cap_style)) 

3371 if capsize > 0: 

3372 xup, yup = xywhere(x, y, xuplims & everymask) 

3373 caplines.append(mlines.Line2D(xup, yup, marker='|', 

3374 **eb_cap_style)) 

3375 

3376 if yerr is not None: 

3377 lower, upper = extract_err(yerr, y) 

3378 # select points without upper/lower limits in y and 

3379 # draw normal errorbars for these points 

3380 noylims = ~(lolims | uplims) 

3381 if noylims.any() or len(noylims) == 0: 

3382 xo, _ = xywhere(x, lower, noylims & everymask) 

3383 lo, uo = xywhere(lower, upper, noylims & everymask) 

3384 barcols.append(self.vlines(xo, lo, uo, **eb_lines_style)) 

3385 if capsize > 0: 

3386 caplines.append(mlines.Line2D(xo, lo, marker='_', 

3387 **eb_cap_style)) 

3388 caplines.append(mlines.Line2D(xo, uo, marker='_', 

3389 **eb_cap_style)) 

3390 

3391 if lolims.any(): 

3392 xo, _ = xywhere(x, lower, lolims & everymask) 

3393 lo, uo = xywhere(y, upper, lolims & everymask) 

3394 barcols.append(self.vlines(xo, lo, uo, **eb_lines_style)) 

3395 xup, upperup = xywhere(x, upper, lolims & everymask) 

3396 if self.yaxis_inverted(): 

3397 marker = mlines.CARETDOWNBASE 

3398 else: 

3399 marker = mlines.CARETUPBASE 

3400 caplines.append( 

3401 mlines.Line2D(xup, upperup, ls='None', marker=marker, 

3402 **eb_cap_style)) 

3403 if capsize > 0: 

3404 xlo, ylo = xywhere(x, y, lolims & everymask) 

3405 caplines.append(mlines.Line2D(xlo, ylo, marker='_', 

3406 **eb_cap_style)) 

3407 

3408 if uplims.any(): 

3409 xo, _ = xywhere(x, lower, uplims & everymask) 

3410 lo, uo = xywhere(lower, y, uplims & everymask) 

3411 barcols.append(self.vlines(xo, lo, uo, **eb_lines_style)) 

3412 xlo, lowerlo = xywhere(x, lower, uplims & everymask) 

3413 if self.yaxis_inverted(): 

3414 marker = mlines.CARETUPBASE 

3415 else: 

3416 marker = mlines.CARETDOWNBASE 

3417 caplines.append( 

3418 mlines.Line2D(xlo, lowerlo, ls='None', marker=marker, 

3419 **eb_cap_style)) 

3420 if capsize > 0: 

3421 xup, yup = xywhere(x, y, uplims & everymask) 

3422 caplines.append(mlines.Line2D(xup, yup, marker='_', 

3423 **eb_cap_style)) 

3424 for l in caplines: 

3425 self.add_line(l) 

3426 

3427 self._request_autoscale_view() 

3428 errorbar_container = ErrorbarContainer((data_line, tuple(caplines), 

3429 tuple(barcols)), 

3430 has_xerr=(xerr is not None), 

3431 has_yerr=(yerr is not None), 

3432 label=label) 

3433 self.containers.append(errorbar_container) 

3434 

3435 return errorbar_container # (l0, caplines, barcols) 

3436 

3437 @cbook._rename_parameter("3.1", "manage_xticks", "manage_ticks") 

3438 @_preprocess_data() 

3439 def boxplot(self, x, notch=None, sym=None, vert=None, whis=None, 

3440 positions=None, widths=None, patch_artist=None, 

3441 bootstrap=None, usermedians=None, conf_intervals=None, 

3442 meanline=None, showmeans=None, showcaps=None, 

3443 showbox=None, showfliers=None, boxprops=None, 

3444 labels=None, flierprops=None, medianprops=None, 

3445 meanprops=None, capprops=None, whiskerprops=None, 

3446 manage_ticks=True, autorange=False, zorder=None): 

3447 """ 

3448 Make a box and whisker plot. 

3449 

3450 Make a box and whisker plot for each column of ``x`` or each 

3451 vector in sequence ``x``. The box extends from the lower to 

3452 upper quartile values of the data, with a line at the median. 

3453 The whiskers extend from the box to show the range of the 

3454 data. Flier points are those past the end of the whiskers. 

3455 

3456 Parameters 

3457 ---------- 

3458 x : Array or a sequence of vectors. 

3459 The input data. 

3460 

3461 notch : bool, optional (False) 

3462 If `True`, will produce a notched box plot. Otherwise, a 

3463 rectangular boxplot is produced. The notches represent the 

3464 confidence interval (CI) around the median. See the entry 

3465 for the ``bootstrap`` parameter for information regarding 

3466 how the locations of the notches are computed. 

3467 

3468 .. note:: 

3469 

3470 In cases where the values of the CI are less than the 

3471 lower quartile or greater than the upper quartile, the 

3472 notches will extend beyond the box, giving it a 

3473 distinctive "flipped" appearance. This is expected 

3474 behavior and consistent with other statistical 

3475 visualization packages. 

3476 

3477 sym : str, optional 

3478 The default symbol for flier points. Enter an empty string 

3479 ('') if you don't want to show fliers. If `None`, then the 

3480 fliers default to 'b+' If you want more control use the 

3481 flierprops kwarg. 

3482 

3483 vert : bool, optional (True) 

3484 If `True` (default), makes the boxes vertical. If `False`, 

3485 everything is drawn horizontally. 

3486 

3487 whis : float or (float, float) (default = 1.5) 

3488 The position of the whiskers. 

3489 

3490 If a float, the lower whisker is at the lowest datum above 

3491 ``Q1 - whis*(Q3-Q1)``, and the upper whisker at the highest datum 

3492 below ``Q3 + whis*(Q3-Q1)``, where Q1 and Q3 are the first and 

3493 third quartiles. The default value of ``whis = 1.5`` corresponds 

3494 to Tukey's original definition of boxplots. 

3495 

3496 If a pair of floats, they indicate the percentiles at which to 

3497 draw the whiskers (e.g., (5, 95)). In particular, setting this to 

3498 (0, 100) results in whiskers covering the whole range of the data. 

3499 "range" is a deprecated synonym for (0, 100). 

3500 

3501 In the edge case where ``Q1 == Q3``, *whis* is automatically set 

3502 to (0, 100) (cover the whole range of the data) if *autorange* is 

3503 True. 

3504 

3505 Beyond the whiskers, data are considered outliers and are plotted 

3506 as individual points. 

3507 

3508 bootstrap : int, optional 

3509 Specifies whether to bootstrap the confidence intervals 

3510 around the median for notched boxplots. If ``bootstrap`` is 

3511 None, no bootstrapping is performed, and notches are 

3512 calculated using a Gaussian-based asymptotic approximation 

3513 (see McGill, R., Tukey, J.W., and Larsen, W.A., 1978, and 

3514 Kendall and Stuart, 1967). Otherwise, bootstrap specifies 

3515 the number of times to bootstrap the median to determine its 

3516 95% confidence intervals. Values between 1000 and 10000 are 

3517 recommended. 

3518 

3519 usermedians : array-like, optional 

3520 An array or sequence whose first dimension (or length) is 

3521 compatible with ``x``. This overrides the medians computed 

3522 by matplotlib for each element of ``usermedians`` that is not 

3523 `None`. When an element of ``usermedians`` is None, the median 

3524 will be computed by matplotlib as normal. 

3525 

3526 conf_intervals : array-like, optional 

3527 Array or sequence whose first dimension (or length) is 

3528 compatible with ``x`` and whose second dimension is 2. When 

3529 the an element of ``conf_intervals`` is not None, the 

3530 notch locations computed by matplotlib are overridden 

3531 (provided ``notch`` is `True`). When an element of 

3532 ``conf_intervals`` is `None`, the notches are computed by the 

3533 method specified by the other kwargs (e.g., ``bootstrap``). 

3534 

3535 positions : array-like, optional 

3536 Sets the positions of the boxes. The ticks and limits are 

3537 automatically set to match the positions. Defaults to 

3538 `range(1, N+1)` where N is the number of boxes to be drawn. 

3539 

3540 widths : scalar or array-like 

3541 Sets the width of each box either with a scalar or a 

3542 sequence. The default is 0.5, or ``0.15*(distance between 

3543 extreme positions)``, if that is smaller. 

3544 

3545 patch_artist : bool, optional (False) 

3546 If `False` produces boxes with the Line2D artist. Otherwise, 

3547 boxes and drawn with Patch artists. 

3548 

3549 labels : sequence, optional 

3550 Labels for each dataset. Length must be compatible with 

3551 dimensions of ``x``. 

3552 

3553 manage_ticks : bool, optional (True) 

3554 If True, the tick locations and labels will be adjusted to match 

3555 the boxplot positions. 

3556 

3557 autorange : bool, optional (False) 

3558 When `True` and the data are distributed such that the 25th and 

3559 75th percentiles are equal, ``whis`` is set to (0, 100) such 

3560 that the whisker ends are at the minimum and maximum of the data. 

3561 

3562 meanline : bool, optional (False) 

3563 If `True` (and ``showmeans`` is `True`), will try to render 

3564 the mean as a line spanning the full width of the box 

3565 according to ``meanprops`` (see below). Not recommended if 

3566 ``shownotches`` is also True. Otherwise, means will be shown 

3567 as points. 

3568 

3569 zorder : scalar, optional (None) 

3570 Sets the zorder of the boxplot. 

3571 

3572 Other Parameters 

3573 ---------------- 

3574 showcaps : bool, optional (True) 

3575 Show the caps on the ends of whiskers. 

3576 showbox : bool, optional (True) 

3577 Show the central box. 

3578 showfliers : bool, optional (True) 

3579 Show the outliers beyond the caps. 

3580 showmeans : bool, optional (False) 

3581 Show the arithmetic means. 

3582 capprops : dict, optional (None) 

3583 Specifies the style of the caps. 

3584 boxprops : dict, optional (None) 

3585 Specifies the style of the box. 

3586 whiskerprops : dict, optional (None) 

3587 Specifies the style of the whiskers. 

3588 flierprops : dict, optional (None) 

3589 Specifies the style of the fliers. 

3590 medianprops : dict, optional (None) 

3591 Specifies the style of the median. 

3592 meanprops : dict, optional (None) 

3593 Specifies the style of the mean. 

3594 

3595 Returns 

3596 ------- 

3597 result : dict 

3598 A dictionary mapping each component of the boxplot to a list 

3599 of the `.Line2D` instances created. That dictionary has the 

3600 following keys (assuming vertical boxplots): 

3601 

3602 - ``boxes``: the main body of the boxplot showing the 

3603 quartiles and the median's confidence intervals if 

3604 enabled. 

3605 

3606 - ``medians``: horizontal lines at the median of each box. 

3607 

3608 - ``whiskers``: the vertical lines extending to the most 

3609 extreme, non-outlier data points. 

3610 

3611 - ``caps``: the horizontal lines at the ends of the 

3612 whiskers. 

3613 

3614 - ``fliers``: points representing data that extend beyond 

3615 the whiskers (fliers). 

3616 

3617 - ``means``: points or lines representing the means. 

3618 

3619 """ 

3620 

3621 # Missing arguments default to rcParams. 

3622 if whis is None: 

3623 whis = rcParams['boxplot.whiskers'] 

3624 if bootstrap is None: 

3625 bootstrap = rcParams['boxplot.bootstrap'] 

3626 

3627 bxpstats = cbook.boxplot_stats(x, whis=whis, bootstrap=bootstrap, 

3628 labels=labels, autorange=autorange) 

3629 if notch is None: 

3630 notch = rcParams['boxplot.notch'] 

3631 if vert is None: 

3632 vert = rcParams['boxplot.vertical'] 

3633 if patch_artist is None: 

3634 patch_artist = rcParams['boxplot.patchartist'] 

3635 if meanline is None: 

3636 meanline = rcParams['boxplot.meanline'] 

3637 if showmeans is None: 

3638 showmeans = rcParams['boxplot.showmeans'] 

3639 if showcaps is None: 

3640 showcaps = rcParams['boxplot.showcaps'] 

3641 if showbox is None: 

3642 showbox = rcParams['boxplot.showbox'] 

3643 if showfliers is None: 

3644 showfliers = rcParams['boxplot.showfliers'] 

3645 

3646 if boxprops is None: 

3647 boxprops = {} 

3648 if whiskerprops is None: 

3649 whiskerprops = {} 

3650 if capprops is None: 

3651 capprops = {} 

3652 if medianprops is None: 

3653 medianprops = {} 

3654 if meanprops is None: 

3655 meanprops = {} 

3656 if flierprops is None: 

3657 flierprops = {} 

3658 

3659 if patch_artist: 

3660 boxprops['linestyle'] = 'solid' # Not consistent with bxp. 

3661 if 'color' in boxprops: 

3662 boxprops['edgecolor'] = boxprops.pop('color') 

3663 

3664 # if non-default sym value, put it into the flier dictionary 

3665 # the logic for providing the default symbol ('b+') now lives 

3666 # in bxp in the initial value of final_flierprops 

3667 # handle all of the *sym* related logic here so we only have to pass 

3668 # on the flierprops dict. 

3669 if sym is not None: 

3670 # no-flier case, which should really be done with 

3671 # 'showfliers=False' but none-the-less deal with it to keep back 

3672 # compatibility 

3673 if sym == '': 

3674 # blow away existing dict and make one for invisible markers 

3675 flierprops = dict(linestyle='none', marker='', color='none') 

3676 # turn the fliers off just to be safe 

3677 showfliers = False 

3678 # now process the symbol string 

3679 else: 

3680 # process the symbol string 

3681 # discarded linestyle 

3682 _, marker, color = _process_plot_format(sym) 

3683 # if we have a marker, use it 

3684 if marker is not None: 

3685 flierprops['marker'] = marker 

3686 # if we have a color, use it 

3687 if color is not None: 

3688 # assume that if color is passed in the user want 

3689 # filled symbol, if the users want more control use 

3690 # flierprops 

3691 flierprops['color'] = color 

3692 flierprops['markerfacecolor'] = color 

3693 flierprops['markeredgecolor'] = color 

3694 

3695 # replace medians if necessary: 

3696 if usermedians is not None: 

3697 if (len(np.ravel(usermedians)) != len(bxpstats) or 

3698 np.shape(usermedians)[0] != len(bxpstats)): 

3699 raise ValueError('usermedians length not compatible with x') 

3700 else: 

3701 # reassign medians as necessary 

3702 for stats, med in zip(bxpstats, usermedians): 

3703 if med is not None: 

3704 stats['med'] = med 

3705 

3706 if conf_intervals is not None: 

3707 if np.shape(conf_intervals)[0] != len(bxpstats): 

3708 err_mess = 'conf_intervals length not compatible with x' 

3709 raise ValueError(err_mess) 

3710 else: 

3711 for stats, ci in zip(bxpstats, conf_intervals): 

3712 if ci is not None: 

3713 if len(ci) != 2: 

3714 raise ValueError('each confidence interval must ' 

3715 'have two values') 

3716 else: 

3717 if ci[0] is not None: 

3718 stats['cilo'] = ci[0] 

3719 if ci[1] is not None: 

3720 stats['cihi'] = ci[1] 

3721 

3722 artists = self.bxp(bxpstats, positions=positions, widths=widths, 

3723 vert=vert, patch_artist=patch_artist, 

3724 shownotches=notch, showmeans=showmeans, 

3725 showcaps=showcaps, showbox=showbox, 

3726 boxprops=boxprops, flierprops=flierprops, 

3727 medianprops=medianprops, meanprops=meanprops, 

3728 meanline=meanline, showfliers=showfliers, 

3729 capprops=capprops, whiskerprops=whiskerprops, 

3730 manage_ticks=manage_ticks, zorder=zorder) 

3731 return artists 

3732 

3733 @cbook._rename_parameter("3.1", "manage_xticks", "manage_ticks") 

3734 def bxp(self, bxpstats, positions=None, widths=None, vert=True, 

3735 patch_artist=False, shownotches=False, showmeans=False, 

3736 showcaps=True, showbox=True, showfliers=True, 

3737 boxprops=None, whiskerprops=None, flierprops=None, 

3738 medianprops=None, capprops=None, meanprops=None, 

3739 meanline=False, manage_ticks=True, zorder=None): 

3740 """ 

3741 Drawing function for box and whisker plots. 

3742 

3743 Make a box and whisker plot for each column of *x* or each 

3744 vector in sequence *x*. The box extends from the lower to 

3745 upper quartile values of the data, with a line at the median. 

3746 The whiskers extend from the box to show the range of the 

3747 data. Flier points are those past the end of the whiskers. 

3748 

3749 Parameters 

3750 ---------- 

3751 bxpstats : list of dicts 

3752 A list of dictionaries containing stats for each boxplot. 

3753 Required keys are: 

3754 

3755 - ``med``: The median (scalar float). 

3756 

3757 - ``q1``: The first quartile (25th percentile) (scalar 

3758 float). 

3759 

3760 - ``q3``: The third quartile (75th percentile) (scalar 

3761 float). 

3762 

3763 - ``whislo``: Lower bound of the lower whisker (scalar 

3764 float). 

3765 

3766 - ``whishi``: Upper bound of the upper whisker (scalar 

3767 float). 

3768 

3769 Optional keys are: 

3770 

3771 - ``mean``: The mean (scalar float). Needed if 

3772 ``showmeans=True``. 

3773 

3774 - ``fliers``: Data beyond the whiskers (sequence of floats). 

3775 Needed if ``showfliers=True``. 

3776 

3777 - ``cilo`` & ``cihi``: Lower and upper confidence intervals 

3778 about the median. Needed if ``shownotches=True``. 

3779 

3780 - ``label``: Name of the dataset (string). If available, 

3781 this will be used a tick label for the boxplot 

3782 

3783 positions : array-like, default = [1, 2, ..., n] 

3784 Sets the positions of the boxes. The ticks and limits 

3785 are automatically set to match the positions. 

3786 

3787 widths : array-like, default = None 

3788 Either a scalar or a vector and sets the width of each 

3789 box. The default is ``0.15*(distance between extreme 

3790 positions)``, clipped to no less than 0.15 and no more than 

3791 0.5. 

3792 

3793 vert : bool, default = True 

3794 If `True` (default), makes the boxes vertical. If `False`, 

3795 makes horizontal boxes. 

3796 

3797 patch_artist : bool, default = False 

3798 If `False` produces boxes with the `.Line2D` artist. 

3799 If `True` produces boxes with the `~matplotlib.patches.Patch` artist. 

3800 

3801 shownotches : bool, default = False 

3802 If `False` (default), produces a rectangular box plot. 

3803 If `True`, will produce a notched box plot 

3804 

3805 showmeans : bool, default = False 

3806 If `True`, will toggle on the rendering of the means 

3807 

3808 showcaps : bool, default = True 

3809 If `True`, will toggle on the rendering of the caps 

3810 

3811 showbox : bool, default = True 

3812 If `True`, will toggle on the rendering of the box 

3813 

3814 showfliers : bool, default = True 

3815 If `True`, will toggle on the rendering of the fliers 

3816 

3817 boxprops : dict or None (default) 

3818 If provided, will set the plotting style of the boxes 

3819 

3820 whiskerprops : dict or None (default) 

3821 If provided, will set the plotting style of the whiskers 

3822 

3823 capprops : dict or None (default) 

3824 If provided, will set the plotting style of the caps 

3825 

3826 flierprops : dict or None (default) 

3827 If provided will set the plotting style of the fliers 

3828 

3829 medianprops : dict or None (default) 

3830 If provided, will set the plotting style of the medians 

3831 

3832 meanprops : dict or None (default) 

3833 If provided, will set the plotting style of the means 

3834 

3835 meanline : bool, default = False 

3836 If `True` (and *showmeans* is `True`), will try to render the mean 

3837 as a line spanning the full width of the box according to 

3838 *meanprops*. Not recommended if *shownotches* is also True. 

3839 Otherwise, means will be shown as points. 

3840 

3841 manage_ticks : bool, default = True 

3842 If True, the tick locations and labels will be adjusted to match the 

3843 boxplot positions. 

3844 

3845 zorder : scalar, default = None 

3846 The zorder of the resulting boxplot. 

3847 

3848 Returns 

3849 ------- 

3850 result : dict 

3851 A dictionary mapping each component of the boxplot to a list 

3852 of the `.Line2D` instances created. That dictionary has the 

3853 following keys (assuming vertical boxplots): 

3854 

3855 - ``boxes``: the main body of the boxplot showing the 

3856 quartiles and the median's confidence intervals if 

3857 enabled. 

3858 

3859 - ``medians``: horizontal lines at the median of each box. 

3860 

3861 - ``whiskers``: the vertical lines extending to the most 

3862 extreme, non-outlier data points. 

3863 

3864 - ``caps``: the horizontal lines at the ends of the 

3865 whiskers. 

3866 

3867 - ``fliers``: points representing data that extend beyond 

3868 the whiskers (fliers). 

3869 

3870 - ``means``: points or lines representing the means. 

3871 

3872 Examples 

3873 -------- 

3874 .. plot:: gallery/statistics/bxp.py 

3875 

3876 """ 

3877 # lists of artists to be output 

3878 whiskers = [] 

3879 caps = [] 

3880 boxes = [] 

3881 medians = [] 

3882 means = [] 

3883 fliers = [] 

3884 

3885 # empty list of xticklabels 

3886 datalabels = [] 

3887 

3888 # Use default zorder if none specified 

3889 if zorder is None: 

3890 zorder = mlines.Line2D.zorder 

3891 

3892 zdelta = 0.1 

3893 

3894 def line_props_with_rcdefaults(subkey, explicit, zdelta=0): 

3895 d = {k.split('.')[-1]: v for k, v in rcParams.items() 

3896 if k.startswith(f'boxplot.{subkey}')} 

3897 d['zorder'] = zorder + zdelta 

3898 if explicit is not None: 

3899 d.update( 

3900 cbook.normalize_kwargs(explicit, mlines.Line2D._alias_map)) 

3901 return d 

3902 

3903 # box properties 

3904 if patch_artist: 

3905 final_boxprops = dict( 

3906 linestyle=rcParams['boxplot.boxprops.linestyle'], 

3907 linewidth=rcParams['boxplot.boxprops.linewidth'], 

3908 edgecolor=rcParams['boxplot.boxprops.color'], 

3909 facecolor=('white' if rcParams['_internal.classic_mode'] else 

3910 rcParams['patch.facecolor']), 

3911 zorder=zorder, 

3912 ) 

3913 if boxprops is not None: 

3914 final_boxprops.update( 

3915 cbook.normalize_kwargs( 

3916 boxprops, mpatches.PathPatch._alias_map)) 

3917 else: 

3918 final_boxprops = line_props_with_rcdefaults('boxprops', boxprops) 

3919 final_whiskerprops = line_props_with_rcdefaults( 

3920 'whiskerprops', whiskerprops) 

3921 final_capprops = line_props_with_rcdefaults( 

3922 'capprops', capprops) 

3923 final_flierprops = line_props_with_rcdefaults( 

3924 'flierprops', flierprops) 

3925 final_medianprops = line_props_with_rcdefaults( 

3926 'medianprops', medianprops, zdelta) 

3927 final_meanprops = line_props_with_rcdefaults( 

3928 'meanprops', meanprops, zdelta) 

3929 removed_prop = 'marker' if meanline else 'linestyle' 

3930 # Only remove the property if it's not set explicitly as a parameter. 

3931 if meanprops is None or removed_prop not in meanprops: 

3932 final_meanprops[removed_prop] = '' 

3933 

3934 def to_vc(xs, ys): 

3935 # convert arguments to verts and codes, append (0, 0) (ignored). 

3936 verts = np.append(np.column_stack([xs, ys]), [(0, 0)], 0) 

3937 codes = ([mpath.Path.MOVETO] 

3938 + [mpath.Path.LINETO] * (len(verts) - 2) 

3939 + [mpath.Path.CLOSEPOLY]) 

3940 return verts, codes 

3941 

3942 def patch_list(xs, ys, **kwargs): 

3943 verts, codes = to_vc(xs, ys) 

3944 path = mpath.Path(verts, codes) 

3945 patch = mpatches.PathPatch(path, **kwargs) 

3946 self.add_artist(patch) 

3947 return [patch] 

3948 

3949 # vertical or horizontal plot? 

3950 if vert: 

3951 def doplot(*args, **kwargs): 

3952 return self.plot(*args, **kwargs) 

3953 

3954 def dopatch(xs, ys, **kwargs): 

3955 return patch_list(xs, ys, **kwargs) 

3956 

3957 else: 

3958 def doplot(*args, **kwargs): 

3959 shuffled = [] 

3960 for i in range(0, len(args), 2): 

3961 shuffled.extend([args[i + 1], args[i]]) 

3962 return self.plot(*shuffled, **kwargs) 

3963 

3964 def dopatch(xs, ys, **kwargs): 

3965 xs, ys = ys, xs # flip X, Y 

3966 return patch_list(xs, ys, **kwargs) 

3967 

3968 # input validation 

3969 N = len(bxpstats) 

3970 datashape_message = ("List of boxplot statistics and `{0}` " 

3971 "values must have same the length") 

3972 # check position 

3973 if positions is None: 

3974 positions = list(range(1, N + 1)) 

3975 elif len(positions) != N: 

3976 raise ValueError(datashape_message.format("positions")) 

3977 

3978 positions = np.array(positions) 

3979 if len(positions) > 0 and not isinstance(positions[0], Number): 

3980 raise TypeError("positions should be an iterable of numbers") 

3981 

3982 # width 

3983 if widths is None: 

3984 widths = [np.clip(0.15 * np.ptp(positions), 0.15, 0.5)] * N 

3985 elif np.isscalar(widths): 

3986 widths = [widths] * N 

3987 elif len(widths) != N: 

3988 raise ValueError(datashape_message.format("widths")) 

3989 

3990 for pos, width, stats in zip(positions, widths, bxpstats): 

3991 # try to find a new label 

3992 datalabels.append(stats.get('label', pos)) 

3993 

3994 # whisker coords 

3995 whisker_x = np.ones(2) * pos 

3996 whiskerlo_y = np.array([stats['q1'], stats['whislo']]) 

3997 whiskerhi_y = np.array([stats['q3'], stats['whishi']]) 

3998 

3999 # cap coords 

4000 cap_left = pos - width * 0.25 

4001 cap_right = pos + width * 0.25 

4002 cap_x = np.array([cap_left, cap_right]) 

4003 cap_lo = np.ones(2) * stats['whislo'] 

4004 cap_hi = np.ones(2) * stats['whishi'] 

4005 

4006 # box and median coords 

4007 box_left = pos - width * 0.5 

4008 box_right = pos + width * 0.5 

4009 med_y = [stats['med'], stats['med']] 

4010 

4011 # notched boxes 

4012 if shownotches: 

4013 box_x = [box_left, box_right, box_right, cap_right, box_right, 

4014 box_right, box_left, box_left, cap_left, box_left, 

4015 box_left] 

4016 box_y = [stats['q1'], stats['q1'], stats['cilo'], 

4017 stats['med'], stats['cihi'], stats['q3'], 

4018 stats['q3'], stats['cihi'], stats['med'], 

4019 stats['cilo'], stats['q1']] 

4020 med_x = cap_x 

4021 

4022 # plain boxes 

4023 else: 

4024 box_x = [box_left, box_right, box_right, box_left, box_left] 

4025 box_y = [stats['q1'], stats['q1'], stats['q3'], stats['q3'], 

4026 stats['q1']] 

4027 med_x = [box_left, box_right] 

4028 

4029 # maybe draw the box: 

4030 if showbox: 

4031 if patch_artist: 

4032 boxes.extend(dopatch(box_x, box_y, **final_boxprops)) 

4033 else: 

4034 boxes.extend(doplot(box_x, box_y, **final_boxprops)) 

4035 

4036 # draw the whiskers 

4037 whiskers.extend(doplot( 

4038 whisker_x, whiskerlo_y, **final_whiskerprops 

4039 )) 

4040 whiskers.extend(doplot( 

4041 whisker_x, whiskerhi_y, **final_whiskerprops 

4042 )) 

4043 

4044 # maybe draw the caps: 

4045 if showcaps: 

4046 caps.extend(doplot(cap_x, cap_lo, **final_capprops)) 

4047 caps.extend(doplot(cap_x, cap_hi, **final_capprops)) 

4048 

4049 # draw the medians 

4050 medians.extend(doplot(med_x, med_y, **final_medianprops)) 

4051 

4052 # maybe draw the means 

4053 if showmeans: 

4054 if meanline: 

4055 means.extend(doplot( 

4056 [box_left, box_right], [stats['mean'], stats['mean']], 

4057 **final_meanprops 

4058 )) 

4059 else: 

4060 means.extend(doplot( 

4061 [pos], [stats['mean']], **final_meanprops 

4062 )) 

4063 

4064 # maybe draw the fliers 

4065 if showfliers: 

4066 # fliers coords 

4067 flier_x = np.full(len(stats['fliers']), pos, dtype=np.float64) 

4068 flier_y = stats['fliers'] 

4069 

4070 fliers.extend(doplot( 

4071 flier_x, flier_y, **final_flierprops 

4072 )) 

4073 

4074 if manage_ticks: 

4075 axis_name = "x" if vert else "y" 

4076 interval = getattr(self.dataLim, f"interval{axis_name}") 

4077 axis = getattr(self, f"{axis_name}axis") 

4078 positions = axis.convert_units(positions) 

4079 # The 0.5 additional padding ensures reasonable-looking boxes 

4080 # even when drawing a single box. We set the sticky edge to 

4081 # prevent margins expansion, in order to match old behavior (back 

4082 # when separate calls to boxplot() would completely reset the axis 

4083 # limits regardless of what was drawn before). The sticky edges 

4084 # are attached to the median lines, as they are always present. 

4085 interval[:] = (min(interval[0], min(positions) - .5), 

4086 max(interval[1], max(positions) + .5)) 

4087 for median, position in zip(medians, positions): 

4088 getattr(median.sticky_edges, axis_name).extend( 

4089 [position - .5, position + .5]) 

4090 # Modified from Axis.set_ticks and Axis.set_ticklabels. 

4091 locator = axis.get_major_locator() 

4092 if not isinstance(axis.get_major_locator(), 

4093 mticker.FixedLocator): 

4094 locator = mticker.FixedLocator([]) 

4095 axis.set_major_locator(locator) 

4096 locator.locs = np.array([*locator.locs, *positions]) 

4097 formatter = axis.get_major_formatter() 

4098 if not isinstance(axis.get_major_formatter(), 

4099 mticker.FixedFormatter): 

4100 formatter = mticker.FixedFormatter([]) 

4101 axis.set_major_formatter(formatter) 

4102 formatter.seq = [*formatter.seq, *datalabels] 

4103 

4104 self._request_autoscale_view( 

4105 scalex=self._autoscaleXon, scaley=self._autoscaleYon) 

4106 

4107 return dict(whiskers=whiskers, caps=caps, boxes=boxes, 

4108 medians=medians, fliers=fliers, means=means) 

4109 

4110 @staticmethod 

4111 def _parse_scatter_color_args(c, edgecolors, kwargs, xsize, 

4112 get_next_color_func): 

4113 """ 

4114 Helper function to process color related arguments of `.Axes.scatter`. 

4115 

4116 Argument precedence for facecolors: 

4117 

4118 - c (if not None) 

4119 - kwargs['facecolors'] 

4120 - kwargs['facecolor'] 

4121 - kwargs['color'] (==kwcolor) 

4122 - 'b' if in classic mode else the result of ``get_next_color_func()`` 

4123 

4124 Argument precedence for edgecolors: 

4125 

4126 - edgecolors (is an explicit kw argument in scatter()) 

4127 - kwargs['edgecolor'] 

4128 - kwargs['color'] (==kwcolor) 

4129 - 'face' if not in classic mode else None 

4130 

4131 Parameters 

4132 ---------- 

4133 c : color or sequence or sequence of color or None 

4134 See argument description of `.Axes.scatter`. 

4135 edgecolors : color or sequence of color or {'face', 'none'} or None 

4136 See argument description of `.Axes.scatter`. 

4137 kwargs : dict 

4138 Additional kwargs. If these keys exist, we pop and process them: 

4139 'facecolors', 'facecolor', 'edgecolor', 'color' 

4140 Note: The dict is modified by this function. 

4141 xsize : int 

4142 The size of the x and y arrays passed to `.Axes.scatter`. 

4143 get_next_color_func : callable 

4144 A callable that returns a color. This color is used as facecolor 

4145 if no other color is provided. 

4146 

4147 Note, that this is a function rather than a fixed color value to 

4148 support conditional evaluation of the next color. As of the 

4149 current implementation obtaining the next color from the 

4150 property cycle advances the cycle. This must only happen if we 

4151 actually use the color, which will only be decided within this 

4152 method. 

4153 

4154 Returns 

4155 ------- 

4156 c 

4157 The input *c* if it was not *None*, else a color derived from the 

4158 other inputs or defaults. 

4159 colors : array(N, 4) or None 

4160 The facecolors as RGBA values, or *None* if a colormap is used. 

4161 edgecolors 

4162 The edgecolor. 

4163 

4164 """ 

4165 facecolors = kwargs.pop('facecolors', None) 

4166 facecolors = kwargs.pop('facecolor', facecolors) 

4167 edgecolors = kwargs.pop('edgecolor', edgecolors) 

4168 

4169 kwcolor = kwargs.pop('color', None) 

4170 

4171 if kwcolor is not None and c is not None: 

4172 raise ValueError("Supply a 'c' argument or a 'color'" 

4173 " kwarg but not both; they differ but" 

4174 " their functionalities overlap.") 

4175 

4176 if kwcolor is not None: 

4177 try: 

4178 mcolors.to_rgba_array(kwcolor) 

4179 except ValueError: 

4180 raise ValueError( 

4181 "'color' kwarg must be an color or sequence of color " 

4182 "specs. For a sequence of values to be color-mapped, use " 

4183 "the 'c' argument instead.") 

4184 if edgecolors is None: 

4185 edgecolors = kwcolor 

4186 if facecolors is None: 

4187 facecolors = kwcolor 

4188 

4189 if edgecolors is None and not rcParams['_internal.classic_mode']: 

4190 edgecolors = rcParams['scatter.edgecolors'] 

4191 

4192 c_was_none = c is None 

4193 if c is None: 

4194 c = (facecolors if facecolors is not None 

4195 else "b" if rcParams['_internal.classic_mode'] 

4196 else get_next_color_func()) 

4197 c_is_string_or_strings = ( 

4198 isinstance(c, str) 

4199 or (isinstance(c, collections.abc.Iterable) and len(c) > 0 

4200 and isinstance(cbook.safe_first_element(c), str))) 

4201 

4202 def invalid_shape_exception(csize, xsize): 

4203 return ValueError( 

4204 f"'c' argument has {csize} elements, which is inconsistent " 

4205 f"with 'x' and 'y' with size {xsize}.") 

4206 

4207 c_is_mapped = False # Unless proven otherwise below. 

4208 valid_shape = True # Unless proven otherwise below. 

4209 if not c_was_none and kwcolor is None and not c_is_string_or_strings: 

4210 try: # First, does 'c' look suitable for value-mapping? 

4211 c = np.asanyarray(c, dtype=float) 

4212 except ValueError: 

4213 pass # Failed to convert to float array; must be color specs. 

4214 else: 

4215 # handle the documented special case of a 2D array with 1 

4216 # row which as RGB(A) to broadcast. 

4217 if c.shape == (1, 4) or c.shape == (1, 3): 

4218 c_is_mapped = False 

4219 if c.size != xsize: 

4220 valid_shape = False 

4221 # If c can be either mapped values or a RGB(A) color, prefer 

4222 # the former if shapes match, the latter otherwise. 

4223 elif c.size == xsize: 

4224 c = c.ravel() 

4225 c_is_mapped = True 

4226 else: # Wrong size; it must not be intended for mapping. 

4227 if c.shape in ((3,), (4,)): 

4228 _log.warning( 

4229 "*c* argument looks like a single numeric RGB or " 

4230 "RGBA sequence, which should be avoided as value-" 

4231 "mapping will have precedence in case its length " 

4232 "matches with *x* & *y*. Please use the *color* " 

4233 "keyword-argument or provide a 2-D array " 

4234 "with a single row if you intend to specify " 

4235 "the same RGB or RGBA value for all points.") 

4236 valid_shape = False 

4237 if not c_is_mapped: 

4238 try: # Is 'c' acceptable as PathCollection facecolors? 

4239 colors = mcolors.to_rgba_array(c) 

4240 except ValueError: 

4241 if not valid_shape: 

4242 raise invalid_shape_exception(c.size, xsize) 

4243 # Both the mapping *and* the RGBA conversion failed: pretty 

4244 # severe failure => one may appreciate a verbose feedback. 

4245 raise ValueError( 

4246 f"'c' argument must be a color, a sequence of colors, or " 

4247 f"a sequence of numbers, not {c}") 

4248 else: 

4249 if len(colors) not in (0, 1, xsize): 

4250 # NB: remember that a single color is also acceptable. 

4251 # Besides *colors* will be an empty array if c == 'none'. 

4252 raise invalid_shape_exception(len(colors), xsize) 

4253 else: 

4254 colors = None # use cmap, norm after collection is created 

4255 return c, colors, edgecolors 

4256 

4257 @_preprocess_data(replace_names=["x", "y", "s", "linewidths", 

4258 "edgecolors", "c", "facecolor", 

4259 "facecolors", "color"], 

4260 label_namer="y") 

4261 @cbook._delete_parameter("3.2", "verts") 

4262 def scatter(self, x, y, s=None, c=None, marker=None, cmap=None, norm=None, 

4263 vmin=None, vmax=None, alpha=None, linewidths=None, 

4264 verts=None, edgecolors=None, *, plotnonfinite=False, 

4265 **kwargs): 

4266 """ 

4267 A scatter plot of *y* vs. *x* with varying marker size and/or color. 

4268 

4269 Parameters 

4270 ---------- 

4271 x, y : scalar or array-like, shape (n, ) 

4272 The data positions. 

4273 

4274 s : scalar or array-like, shape (n, ), optional 

4275 The marker size in points**2. 

4276 Default is ``rcParams['lines.markersize'] ** 2``. 

4277 

4278 c : array-like or list of colors or color, optional 

4279 The marker colors. Possible values: 

4280 

4281 - A scalar or sequence of n numbers to be mapped to colors using 

4282 *cmap* and *norm*. 

4283 - A 2-D array in which the rows are RGB or RGBA. 

4284 - A sequence of colors of length n. 

4285 - A single color format string. 

4286 

4287 Note that *c* should not be a single numeric RGB or RGBA sequence 

4288 because that is indistinguishable from an array of values to be 

4289 colormapped. If you want to specify the same RGB or RGBA value for 

4290 all points, use a 2-D array with a single row. Otherwise, value- 

4291 matching will have precedence in case of a size matching with *x* 

4292 and *y*. 

4293 

4294 If you wish to specify a single color for all points 

4295 prefer the *color* keyword argument. 

4296 

4297 Defaults to `None`. In that case the marker color is determined 

4298 by the value of *color*, *facecolor* or *facecolors*. In case 

4299 those are not specified or `None`, the marker color is determined 

4300 by the next color of the ``Axes``' current "shape and fill" color 

4301 cycle. This cycle defaults to :rc:`axes.prop_cycle`. 

4302 

4303 marker : `~matplotlib.markers.MarkerStyle`, optional 

4304 The marker style. *marker* can be either an instance of the class 

4305 or the text shorthand for a particular marker. 

4306 Defaults to ``None``, in which case it takes the value of 

4307 :rc:`scatter.marker` = 'o'. 

4308 See `~matplotlib.markers` for more information about marker styles. 

4309 

4310 cmap : `~matplotlib.colors.Colormap`, optional, default: None 

4311 A `.Colormap` instance or registered colormap name. *cmap* is only 

4312 used if *c* is an array of floats. If ``None``, defaults to rc 

4313 ``image.cmap``. 

4314 

4315 norm : `~matplotlib.colors.Normalize`, optional, default: None 

4316 A `.Normalize` instance is used to scale luminance data to 0, 1. 

4317 *norm* is only used if *c* is an array of floats. If *None*, use 

4318 the default `.colors.Normalize`. 

4319 

4320 vmin, vmax : scalar, optional, default: None 

4321 *vmin* and *vmax* are used in conjunction with *norm* to normalize 

4322 luminance data. If None, the respective min and max of the color 

4323 array is used. *vmin* and *vmax* are ignored if you pass a *norm* 

4324 instance. 

4325 

4326 alpha : scalar, optional, default: None 

4327 The alpha blending value, between 0 (transparent) and 1 (opaque). 

4328 

4329 linewidths : scalar or array-like, optional, default: None 

4330 The linewidth of the marker edges. Note: The default *edgecolors* 

4331 is 'face'. You may want to change this as well. 

4332 If *None*, defaults to :rc:`lines.linewidth`. 

4333 

4334 edgecolors : {'face', 'none', *None*} or color or sequence of color, \ 

4335optional. 

4336 The edge color of the marker. Possible values: 

4337 

4338 - 'face': The edge color will always be the same as the face color. 

4339 - 'none': No patch boundary will be drawn. 

4340 - A Matplotlib color or sequence of color. 

4341 

4342 Defaults to ``None``, in which case it takes the value of 

4343 :rc:`scatter.edgecolors` = 'face'. 

4344 

4345 For non-filled markers, the *edgecolors* kwarg is ignored and 

4346 forced to 'face' internally. 

4347 

4348 plotnonfinite : boolean, optional, default: False 

4349 Set to plot points with nonfinite *c*, in conjunction with 

4350 `~matplotlib.colors.Colormap.set_bad`. 

4351 

4352 Returns 

4353 ------- 

4354 paths : `~matplotlib.collections.PathCollection` 

4355 

4356 Other Parameters 

4357 ---------------- 

4358 **kwargs : `~matplotlib.collections.Collection` properties 

4359 

4360 See Also 

4361 -------- 

4362 plot : To plot scatter plots when markers are identical in size and 

4363 color. 

4364 

4365 Notes 

4366 ----- 

4367 * The `.plot` function will be faster for scatterplots where markers 

4368 don't vary in size or color. 

4369 

4370 * Any or all of *x*, *y*, *s*, and *c* may be masked arrays, in which 

4371 case all masks will be combined and only unmasked points will be 

4372 plotted. 

4373 

4374 * Fundamentally, scatter works with 1-D arrays; *x*, *y*, *s*, and *c* 

4375 may be input as N-D arrays, but within scatter they will be 

4376 flattened. The exception is *c*, which will be flattened only if its 

4377 size matches the size of *x* and *y*. 

4378 

4379 """ 

4380 # Process **kwargs to handle aliases, conflicts with explicit kwargs: 

4381 

4382 self._process_unit_info(xdata=x, ydata=y, kwargs=kwargs) 

4383 x = self.convert_xunits(x) 

4384 y = self.convert_yunits(y) 

4385 

4386 # np.ma.ravel yields an ndarray, not a masked array, 

4387 # unless its argument is a masked array. 

4388 x = np.ma.ravel(x) 

4389 y = np.ma.ravel(y) 

4390 if x.size != y.size: 

4391 raise ValueError("x and y must be the same size") 

4392 

4393 if s is None: 

4394 s = (20 if rcParams['_internal.classic_mode'] else 

4395 rcParams['lines.markersize'] ** 2.0) 

4396 s = np.ma.ravel(s) 

4397 if len(s) not in (1, x.size): 

4398 raise ValueError("s must be a scalar, or the same size as x and y") 

4399 

4400 c, colors, edgecolors = \ 

4401 self._parse_scatter_color_args( 

4402 c, edgecolors, kwargs, x.size, 

4403 get_next_color_func=self._get_patches_for_fill.get_next_color) 

4404 

4405 if plotnonfinite and colors is None: 

4406 c = np.ma.masked_invalid(c) 

4407 x, y, s, edgecolors, linewidths = \ 

4408 cbook._combine_masks(x, y, s, edgecolors, linewidths) 

4409 else: 

4410 x, y, s, c, colors, edgecolors, linewidths = \ 

4411 cbook._combine_masks( 

4412 x, y, s, c, colors, edgecolors, linewidths) 

4413 

4414 scales = s # Renamed for readability below. 

4415 

4416 # load default marker from rcParams 

4417 if marker is None: 

4418 marker = rcParams['scatter.marker'] 

4419 

4420 if isinstance(marker, mmarkers.MarkerStyle): 

4421 marker_obj = marker 

4422 else: 

4423 marker_obj = mmarkers.MarkerStyle(marker) 

4424 

4425 path = marker_obj.get_path().transformed( 

4426 marker_obj.get_transform()) 

4427 if not marker_obj.is_filled(): 

4428 edgecolors = 'face' 

4429 linewidths = rcParams['lines.linewidth'] 

4430 

4431 offsets = np.ma.column_stack([x, y]) 

4432 

4433 collection = mcoll.PathCollection( 

4434 (path,), scales, 

4435 facecolors=colors, 

4436 edgecolors=edgecolors, 

4437 linewidths=linewidths, 

4438 offsets=offsets, 

4439 transOffset=kwargs.pop('transform', self.transData), 

4440 alpha=alpha 

4441 ) 

4442 collection.set_transform(mtransforms.IdentityTransform()) 

4443 collection.update(kwargs) 

4444 

4445 if colors is None: 

4446 collection.set_array(c) 

4447 collection.set_cmap(cmap) 

4448 collection.set_norm(norm) 

4449 

4450 if vmin is not None or vmax is not None: 

4451 collection.set_clim(vmin, vmax) 

4452 else: 

4453 collection.autoscale_None() 

4454 

4455 # Classic mode only: 

4456 # ensure there are margins to allow for the 

4457 # finite size of the symbols. In v2.x, margins 

4458 # are present by default, so we disable this 

4459 # scatter-specific override. 

4460 if rcParams['_internal.classic_mode']: 

4461 if self._xmargin < 0.05 and x.size > 0: 

4462 self.set_xmargin(0.05) 

4463 if self._ymargin < 0.05 and x.size > 0: 

4464 self.set_ymargin(0.05) 

4465 

4466 self.add_collection(collection) 

4467 self._request_autoscale_view() 

4468 

4469 return collection 

4470 

4471 @_preprocess_data(replace_names=["x", "y"], label_namer="y") 

4472 @docstring.dedent_interpd 

4473 def hexbin(self, x, y, C=None, gridsize=100, bins=None, 

4474 xscale='linear', yscale='linear', extent=None, 

4475 cmap=None, norm=None, vmin=None, vmax=None, 

4476 alpha=None, linewidths=None, edgecolors='face', 

4477 reduce_C_function=np.mean, mincnt=None, marginals=False, 

4478 **kwargs): 

4479 """ 

4480 Make a 2D hexagonal binning plot of points *x*, *y*. 

4481 

4482 If *C* is *None*, the value of the hexagon is determined by the number 

4483 of points in the hexagon. Otherwise, *C* specifies values at the 

4484 coordinate (x[i], y[i]). For each hexagon, these values are reduced 

4485 using *reduce_C_function*. 

4486 

4487 Parameters 

4488 ---------- 

4489 x, y : array-like 

4490 The data positions. *x* and *y* must be of the same length. 

4491 

4492 C : array-like, optional 

4493 If given, these values are accumulated in the bins. Otherwise, 

4494 every point has a value of 1. Must be of the same length as *x* 

4495 and *y*. 

4496 

4497 gridsize : int or (int, int), default: 100 

4498 If a single int, the number of hexagons in the *x*-direction. 

4499 The number of hexagons in the *y*-direction is chosen such that 

4500 the hexagons are approximately regular. 

4501 

4502 Alternatively, if a tuple (*nx*, *ny*), the number of hexagons 

4503 in the *x*-direction and the *y*-direction. 

4504 

4505 bins : 'log' or int or sequence, default: *None* 

4506 Discretization of the hexagon values. 

4507 

4508 - If *None*, no binning is applied; the color of each hexagon 

4509 directly corresponds to its count value. 

4510 - If 'log', use a logarithmic scale for the color map. 

4511 Internally, :math:`log_{10}(i+1)` is used to determine the 

4512 hexagon color. This is equivalent to ``norm=LogNorm()``. 

4513 - If an integer, divide the counts in the specified number 

4514 of bins, and color the hexagons accordingly. 

4515 - If a sequence of values, the values of the lower bound of 

4516 the bins to be used. 

4517 

4518 xscale : {'linear', 'log'}, default: 'linear' 

4519 Use a linear or log10 scale on the horizontal axis. 

4520 

4521 yscale : {'linear', 'log'}, default: 'linear' 

4522 Use a linear or log10 scale on the vertical axis. 

4523 

4524 mincnt : int > 0, default: *None* 

4525 If not *None*, only display cells with more than *mincnt* 

4526 number of points in the cell. 

4527 

4528 marginals : bool, default: *False* 

4529 If marginals is *True*, plot the marginal density as 

4530 colormapped rectangles along the bottom of the x-axis and 

4531 left of the y-axis. 

4532 

4533 extent : float, default: *None* 

4534 The limits of the bins. The default assigns the limits 

4535 based on *gridsize*, *x*, *y*, *xscale* and *yscale*. 

4536 

4537 If *xscale* or *yscale* is set to 'log', the limits are 

4538 expected to be the exponent for a power of 10. E.g. for 

4539 x-limits of 1 and 50 in 'linear' scale and y-limits 

4540 of 10 and 1000 in 'log' scale, enter (1, 50, 1, 3). 

4541 

4542 Order of scalars is (left, right, bottom, top). 

4543 

4544 Other Parameters 

4545 ---------------- 

4546 cmap : str or `~matplotlib.colors.Colormap`, optional 

4547 The Colormap instance or registered colormap name used to map 

4548 the bin values to colors. Defaults to :rc:`image.cmap`. 

4549 

4550 norm : `~matplotlib.colors.Normalize`, optional 

4551 The Normalize instance scales the bin values to the canonical 

4552 colormap range [0, 1] for mapping to colors. By default, the data 

4553 range is mapped to the colorbar range using linear scaling. 

4554 

4555 vmin, vmax : float, optional, default: None 

4556 The colorbar range. If *None*, suitable min/max values are 

4557 automatically chosen by the `~.Normalize` instance (defaults to 

4558 the respective min/max values of the bins in case of the default 

4559 linear scaling). This is ignored if *norm* is given. 

4560 

4561 alpha : float between 0 and 1, optional 

4562 The alpha blending value, between 0 (transparent) and 1 (opaque). 

4563 

4564 linewidths : float, default: *None* 

4565 If *None*, defaults to 1.0. 

4566 

4567 edgecolors : {'face', 'none', *None*} or color, default: 'face' 

4568 The color of the hexagon edges. Possible values are: 

4569 

4570 - 'face': Draw the edges in the same color as the fill color. 

4571 - 'none': No edges are drawn. This can sometimes lead to unsightly 

4572 unpainted pixels between the hexagons. 

4573 - *None*: Draw outlines in the default color. 

4574 - An explicit matplotlib color. 

4575 

4576 reduce_C_function : callable, default is `numpy.mean` 

4577 The function to aggregate *C* within the bins. It is ignored if 

4578 *C* is not given. This must have the signature:: 

4579 

4580 def reduce_C_function(C: array) -> float 

4581 

4582 Commonly used functions are: 

4583 

4584 - `numpy.mean`: average of the points 

4585 - `numpy.sum`: integral of the point values 

4586 - `numpy.max`: value taken from the largest point 

4587 

4588 **kwargs : `~matplotlib.collections.PolyCollection` properties 

4589 All other keyword arguments are passed on to `.PolyCollection`: 

4590 

4591 %(PolyCollection)s 

4592 

4593 Returns 

4594 ------- 

4595 polycollection : `~matplotlib.collections.PolyCollection` 

4596 A `.PolyCollection` defining the hexagonal bins. 

4597 

4598 - `.PolyCollection.get_offset` contains a Mx2 array containing 

4599 the x, y positions of the M hexagon centers. 

4600 - `.PolyCollection.get_array` contains the values of the M 

4601 hexagons. 

4602 

4603 If *marginals* is *True*, horizontal 

4604 bar and vertical bar (both PolyCollections) will be attached 

4605 to the return collection as attributes *hbar* and *vbar*. 

4606 

4607 """ 

4608 self._process_unit_info(xdata=x, ydata=y, kwargs=kwargs) 

4609 

4610 x, y, C = cbook.delete_masked_points(x, y, C) 

4611 

4612 # Set the size of the hexagon grid 

4613 if np.iterable(gridsize): 

4614 nx, ny = gridsize 

4615 else: 

4616 nx = gridsize 

4617 ny = int(nx / math.sqrt(3)) 

4618 # Count the number of data in each hexagon 

4619 x = np.array(x, float) 

4620 y = np.array(y, float) 

4621 if xscale == 'log': 

4622 if np.any(x <= 0.0): 

4623 raise ValueError("x contains non-positive values, so can not" 

4624 " be log-scaled") 

4625 x = np.log10(x) 

4626 if yscale == 'log': 

4627 if np.any(y <= 0.0): 

4628 raise ValueError("y contains non-positive values, so can not" 

4629 " be log-scaled") 

4630 y = np.log10(y) 

4631 if extent is not None: 

4632 xmin, xmax, ymin, ymax = extent 

4633 else: 

4634 xmin, xmax = (np.min(x), np.max(x)) if len(x) else (0, 1) 

4635 ymin, ymax = (np.min(y), np.max(y)) if len(y) else (0, 1) 

4636 

4637 # to avoid issues with singular data, expand the min/max pairs 

4638 xmin, xmax = mtransforms.nonsingular(xmin, xmax, expander=0.1) 

4639 ymin, ymax = mtransforms.nonsingular(ymin, ymax, expander=0.1) 

4640 

4641 # In the x-direction, the hexagons exactly cover the region from 

4642 # xmin to xmax. Need some padding to avoid roundoff errors. 

4643 padding = 1.e-9 * (xmax - xmin) 

4644 xmin -= padding 

4645 xmax += padding 

4646 sx = (xmax - xmin) / nx 

4647 sy = (ymax - ymin) / ny 

4648 

4649 if marginals: 

4650 xorig = x.copy() 

4651 yorig = y.copy() 

4652 

4653 x = (x - xmin) / sx 

4654 y = (y - ymin) / sy 

4655 ix1 = np.round(x).astype(int) 

4656 iy1 = np.round(y).astype(int) 

4657 ix2 = np.floor(x).astype(int) 

4658 iy2 = np.floor(y).astype(int) 

4659 

4660 nx1 = nx + 1 

4661 ny1 = ny + 1 

4662 nx2 = nx 

4663 ny2 = ny 

4664 n = nx1 * ny1 + nx2 * ny2 

4665 

4666 d1 = (x - ix1) ** 2 + 3.0 * (y - iy1) ** 2 

4667 d2 = (x - ix2 - 0.5) ** 2 + 3.0 * (y - iy2 - 0.5) ** 2 

4668 bdist = (d1 < d2) 

4669 if C is None: 

4670 lattice1 = np.zeros((nx1, ny1)) 

4671 lattice2 = np.zeros((nx2, ny2)) 

4672 c1 = (0 <= ix1) & (ix1 < nx1) & (0 <= iy1) & (iy1 < ny1) & bdist 

4673 c2 = (0 <= ix2) & (ix2 < nx2) & (0 <= iy2) & (iy2 < ny2) & ~bdist 

4674 np.add.at(lattice1, (ix1[c1], iy1[c1]), 1) 

4675 np.add.at(lattice2, (ix2[c2], iy2[c2]), 1) 

4676 if mincnt is not None: 

4677 lattice1[lattice1 < mincnt] = np.nan 

4678 lattice2[lattice2 < mincnt] = np.nan 

4679 accum = np.concatenate([lattice1.ravel(), lattice2.ravel()]) 

4680 good_idxs = ~np.isnan(accum) 

4681 

4682 else: 

4683 if mincnt is None: 

4684 mincnt = 0 

4685 

4686 # create accumulation arrays 

4687 lattice1 = np.empty((nx1, ny1), dtype=object) 

4688 for i in range(nx1): 

4689 for j in range(ny1): 

4690 lattice1[i, j] = [] 

4691 lattice2 = np.empty((nx2, ny2), dtype=object) 

4692 for i in range(nx2): 

4693 for j in range(ny2): 

4694 lattice2[i, j] = [] 

4695 

4696 for i in range(len(x)): 

4697 if bdist[i]: 

4698 if 0 <= ix1[i] < nx1 and 0 <= iy1[i] < ny1: 

4699 lattice1[ix1[i], iy1[i]].append(C[i]) 

4700 else: 

4701 if 0 <= ix2[i] < nx2 and 0 <= iy2[i] < ny2: 

4702 lattice2[ix2[i], iy2[i]].append(C[i]) 

4703 

4704 for i in range(nx1): 

4705 for j in range(ny1): 

4706 vals = lattice1[i, j] 

4707 if len(vals) > mincnt: 

4708 lattice1[i, j] = reduce_C_function(vals) 

4709 else: 

4710 lattice1[i, j] = np.nan 

4711 for i in range(nx2): 

4712 for j in range(ny2): 

4713 vals = lattice2[i, j] 

4714 if len(vals) > mincnt: 

4715 lattice2[i, j] = reduce_C_function(vals) 

4716 else: 

4717 lattice2[i, j] = np.nan 

4718 

4719 accum = np.hstack((lattice1.astype(float).ravel(), 

4720 lattice2.astype(float).ravel())) 

4721 good_idxs = ~np.isnan(accum) 

4722 

4723 offsets = np.zeros((n, 2), float) 

4724 offsets[:nx1 * ny1, 0] = np.repeat(np.arange(nx1), ny1) 

4725 offsets[:nx1 * ny1, 1] = np.tile(np.arange(ny1), nx1) 

4726 offsets[nx1 * ny1:, 0] = np.repeat(np.arange(nx2) + 0.5, ny2) 

4727 offsets[nx1 * ny1:, 1] = np.tile(np.arange(ny2), nx2) + 0.5 

4728 offsets[:, 0] *= sx 

4729 offsets[:, 1] *= sy 

4730 offsets[:, 0] += xmin 

4731 offsets[:, 1] += ymin 

4732 # remove accumulation bins with no data 

4733 offsets = offsets[good_idxs, :] 

4734 accum = accum[good_idxs] 

4735 

4736 polygon = [sx, sy / 3] * np.array( 

4737 [[.5, -.5], [.5, .5], [0., 1.], [-.5, .5], [-.5, -.5], [0., -1.]]) 

4738 

4739 if linewidths is None: 

4740 linewidths = [1.0] 

4741 

4742 if xscale == 'log' or yscale == 'log': 

4743 polygons = np.expand_dims(polygon, 0) + np.expand_dims(offsets, 1) 

4744 if xscale == 'log': 

4745 polygons[:, :, 0] = 10.0 ** polygons[:, :, 0] 

4746 xmin = 10.0 ** xmin 

4747 xmax = 10.0 ** xmax 

4748 self.set_xscale(xscale) 

4749 if yscale == 'log': 

4750 polygons[:, :, 1] = 10.0 ** polygons[:, :, 1] 

4751 ymin = 10.0 ** ymin 

4752 ymax = 10.0 ** ymax 

4753 self.set_yscale(yscale) 

4754 collection = mcoll.PolyCollection( 

4755 polygons, 

4756 edgecolors=edgecolors, 

4757 linewidths=linewidths, 

4758 ) 

4759 else: 

4760 collection = mcoll.PolyCollection( 

4761 [polygon], 

4762 edgecolors=edgecolors, 

4763 linewidths=linewidths, 

4764 offsets=offsets, 

4765 transOffset=mtransforms.IdentityTransform(), 

4766 offset_position="data" 

4767 ) 

4768 

4769 # Set normalizer if bins is 'log' 

4770 if bins == 'log': 

4771 if norm is not None: 

4772 cbook._warn_external("Only one of 'bins' and 'norm' " 

4773 "arguments can be supplied, ignoring " 

4774 "bins={}".format(bins)) 

4775 else: 

4776 norm = mcolors.LogNorm() 

4777 bins = None 

4778 

4779 if isinstance(norm, mcolors.LogNorm): 

4780 if (accum == 0).any(): 

4781 # make sure we have no zeros 

4782 accum += 1 

4783 

4784 # autoscale the norm with curren accum values if it hasn't 

4785 # been set 

4786 if norm is not None: 

4787 if norm.vmin is None and norm.vmax is None: 

4788 norm.autoscale(accum) 

4789 

4790 if bins is not None: 

4791 if not np.iterable(bins): 

4792 minimum, maximum = min(accum), max(accum) 

4793 bins -= 1 # one less edge than bins 

4794 bins = minimum + (maximum - minimum) * np.arange(bins) / bins 

4795 bins = np.sort(bins) 

4796 accum = bins.searchsorted(accum) 

4797 

4798 collection.set_array(accum) 

4799 collection.set_cmap(cmap) 

4800 collection.set_norm(norm) 

4801 collection.set_alpha(alpha) 

4802 collection.update(kwargs) 

4803 

4804 if vmin is not None or vmax is not None: 

4805 collection.set_clim(vmin, vmax) 

4806 else: 

4807 collection.autoscale_None() 

4808 

4809 corners = ((xmin, ymin), (xmax, ymax)) 

4810 self.update_datalim(corners) 

4811 self._request_autoscale_view(tight=True) 

4812 

4813 # add the collection last 

4814 self.add_collection(collection, autolim=False) 

4815 if not marginals: 

4816 return collection 

4817 

4818 if C is None: 

4819 C = np.ones(len(x)) 

4820 

4821 def coarse_bin(x, y, coarse): 

4822 ind = coarse.searchsorted(x).clip(0, len(coarse) - 1) 

4823 mus = np.zeros(len(coarse)) 

4824 for i in range(len(coarse)): 

4825 yi = y[ind == i] 

4826 if len(yi) > 0: 

4827 mu = reduce_C_function(yi) 

4828 else: 

4829 mu = np.nan 

4830 mus[i] = mu 

4831 return mus 

4832 

4833 coarse = np.linspace(xmin, xmax, gridsize) 

4834 

4835 xcoarse = coarse_bin(xorig, C, coarse) 

4836 valid = ~np.isnan(xcoarse) 

4837 verts, values = [], [] 

4838 for i, val in enumerate(xcoarse): 

4839 thismin = coarse[i] 

4840 if i < len(coarse) - 1: 

4841 thismax = coarse[i + 1] 

4842 else: 

4843 thismax = thismin + np.diff(coarse)[-1] 

4844 

4845 if not valid[i]: 

4846 continue 

4847 

4848 verts.append([(thismin, 0), 

4849 (thismin, 0.05), 

4850 (thismax, 0.05), 

4851 (thismax, 0)]) 

4852 values.append(val) 

4853 

4854 values = np.array(values) 

4855 trans = self.get_xaxis_transform(which='grid') 

4856 

4857 hbar = mcoll.PolyCollection(verts, transform=trans, edgecolors='face') 

4858 

4859 hbar.set_array(values) 

4860 hbar.set_cmap(cmap) 

4861 hbar.set_norm(norm) 

4862 hbar.set_alpha(alpha) 

4863 hbar.update(kwargs) 

4864 self.add_collection(hbar, autolim=False) 

4865 

4866 coarse = np.linspace(ymin, ymax, gridsize) 

4867 ycoarse = coarse_bin(yorig, C, coarse) 

4868 valid = ~np.isnan(ycoarse) 

4869 verts, values = [], [] 

4870 for i, val in enumerate(ycoarse): 

4871 thismin = coarse[i] 

4872 if i < len(coarse) - 1: 

4873 thismax = coarse[i + 1] 

4874 else: 

4875 thismax = thismin + np.diff(coarse)[-1] 

4876 if not valid[i]: 

4877 continue 

4878 verts.append([(0, thismin), (0.0, thismax), 

4879 (0.05, thismax), (0.05, thismin)]) 

4880 values.append(val) 

4881 

4882 values = np.array(values) 

4883 

4884 trans = self.get_yaxis_transform(which='grid') 

4885 

4886 vbar = mcoll.PolyCollection(verts, transform=trans, edgecolors='face') 

4887 vbar.set_array(values) 

4888 vbar.set_cmap(cmap) 

4889 vbar.set_norm(norm) 

4890 vbar.set_alpha(alpha) 

4891 vbar.update(kwargs) 

4892 self.add_collection(vbar, autolim=False) 

4893 

4894 collection.hbar = hbar 

4895 collection.vbar = vbar 

4896 

4897 def on_changed(collection): 

4898 hbar.set_cmap(collection.get_cmap()) 

4899 hbar.set_clim(collection.get_clim()) 

4900 vbar.set_cmap(collection.get_cmap()) 

4901 vbar.set_clim(collection.get_clim()) 

4902 

4903 collection.callbacksSM.connect('changed', on_changed) 

4904 

4905 return collection 

4906 

4907 @docstring.dedent_interpd 

4908 def arrow(self, x, y, dx, dy, **kwargs): 

4909 """ 

4910 Add an arrow to the axes. 

4911 

4912 This draws an arrow from ``(x, y)`` to ``(x+dx, y+dy)``. 

4913 

4914 Parameters 

4915 ---------- 

4916 x, y : float 

4917 The x and y coordinates of the arrow base. 

4918 dx, dy : float 

4919 The length of the arrow along x and y direction. 

4920 

4921 Returns 

4922 ------- 

4923 arrow : `.FancyArrow` 

4924 The created `.FancyArrow` object. 

4925 

4926 Other Parameters 

4927 ---------------- 

4928 **kwargs 

4929 Optional kwargs (inherited from `.FancyArrow` patch) control the 

4930 arrow construction and properties: 

4931 

4932 %(FancyArrow)s 

4933 

4934 Notes 

4935 ----- 

4936 The resulting arrow is affected by the axes aspect ratio and limits. 

4937 This may produce an arrow whose head is not square with its stem. To 

4938 create an arrow whose head is square with its stem, 

4939 use :meth:`annotate` for example: 

4940 

4941 >>> ax.annotate("", xy=(0.5, 0.5), xytext=(0, 0), 

4942 ... arrowprops=dict(arrowstyle="->")) 

4943 

4944 """ 

4945 # Strip away units for the underlying patch since units 

4946 # do not make sense to most patch-like code 

4947 x = self.convert_xunits(x) 

4948 y = self.convert_yunits(y) 

4949 dx = self.convert_xunits(dx) 

4950 dy = self.convert_yunits(dy) 

4951 

4952 a = mpatches.FancyArrow(x, y, dx, dy, **kwargs) 

4953 self.add_artist(a) 

4954 return a 

4955 

4956 @docstring.copy(mquiver.QuiverKey.__init__) 

4957 def quiverkey(self, Q, X, Y, U, label, **kw): 

4958 qk = mquiver.QuiverKey(Q, X, Y, U, label, **kw) 

4959 self.add_artist(qk) 

4960 return qk 

4961 

4962 # Handle units for x and y, if they've been passed 

4963 def _quiver_units(self, args, kw): 

4964 if len(args) > 3: 

4965 x, y = args[0:2] 

4966 self._process_unit_info(xdata=x, ydata=y, kwargs=kw) 

4967 x = self.convert_xunits(x) 

4968 y = self.convert_yunits(y) 

4969 return (x, y) + args[2:] 

4970 return args 

4971 

4972 # args can by a combination if X, Y, U, V, C and all should be replaced 

4973 @_preprocess_data() 

4974 def quiver(self, *args, **kw): 

4975 # Make sure units are handled for x and y values 

4976 args = self._quiver_units(args, kw) 

4977 

4978 q = mquiver.Quiver(self, *args, **kw) 

4979 

4980 self.add_collection(q, autolim=True) 

4981 self._request_autoscale_view() 

4982 return q 

4983 quiver.__doc__ = mquiver.Quiver.quiver_doc 

4984 

4985 # args can be some combination of X, Y, U, V, C and all should be replaced 

4986 @_preprocess_data() 

4987 @docstring.dedent_interpd 

4988 def barbs(self, *args, **kw): 

4989 """ 

4990 %(barbs_doc)s 

4991 """ 

4992 # Make sure units are handled for x and y values 

4993 args = self._quiver_units(args, kw) 

4994 

4995 b = mquiver.Barbs(self, *args, **kw) 

4996 self.add_collection(b, autolim=True) 

4997 self._request_autoscale_view() 

4998 return b 

4999 

5000 # Uses a custom implementation of data-kwarg handling in 

5001 # _process_plot_var_args. 

5002 def fill(self, *args, data=None, **kwargs): 

5003 """ 

5004 Plot filled polygons. 

5005 

5006 Parameters 

5007 ---------- 

5008 *args : sequence of x, y, [color] 

5009 Each polygon is defined by the lists of *x* and *y* positions of 

5010 its nodes, optionally followed by a *color* specifier. See 

5011 :mod:`matplotlib.colors` for supported color specifiers. The 

5012 standard color cycle is used for polygons without a color 

5013 specifier. 

5014 

5015 You can plot multiple polygons by providing multiple *x*, *y*, 

5016 *[color]* groups. 

5017 

5018 For example, each of the following is legal:: 

5019 

5020 ax.fill(x, y) # a polygon with default color 

5021 ax.fill(x, y, "b") # a blue polygon 

5022 ax.fill(x, y, x2, y2) # two polygons 

5023 ax.fill(x, y, "b", x2, y2, "r") # a blue and a red polygon 

5024 

5025 data : indexable object, optional 

5026 An object with labelled data. If given, provide the label names to 

5027 plot in *x* and *y*, e.g.:: 

5028 

5029 ax.fill("time", "signal", 

5030 data={"time": [0, 1, 2], "signal": [0, 1, 0]}) 

5031 

5032 Returns 

5033 ------- 

5034 a list of :class:`~matplotlib.patches.Polygon` 

5035 

5036 Other Parameters 

5037 ---------------- 

5038 **kwargs : :class:`~matplotlib.patches.Polygon` properties 

5039 

5040 Notes 

5041 ----- 

5042 Use :meth:`fill_between` if you would like to fill the region between 

5043 two curves. 

5044 """ 

5045 # For compatibility(!), get aliases from Line2D rather than Patch. 

5046 kwargs = cbook.normalize_kwargs(kwargs, mlines.Line2D) 

5047 # _get_patches_for_fill returns a generator, convert it to a list. 

5048 patches = [*self._get_patches_for_fill(*args, data=data, **kwargs)] 

5049 for poly in patches: 

5050 self.add_patch(poly) 

5051 self._request_autoscale_view() 

5052 return patches 

5053 

5054 @_preprocess_data(replace_names=["x", "y1", "y2", "where"]) 

5055 @docstring.dedent_interpd 

5056 def fill_between(self, x, y1, y2=0, where=None, interpolate=False, 

5057 step=None, **kwargs): 

5058 """ 

5059 Fill the area between two horizontal curves. 

5060 

5061 The curves are defined by the points (*x*, *y1*) and (*x*, *y2*). This 

5062 creates one or multiple polygons describing the filled area. 

5063 

5064 You may exclude some horizontal sections from filling using *where*. 

5065 

5066 By default, the edges connect the given points directly. Use *step* if 

5067 the filling should be a step function, i.e. constant in between *x*. 

5068 

5069 

5070 Parameters 

5071 ---------- 

5072 x : array (length N) 

5073 The x coordinates of the nodes defining the curves. 

5074 

5075 y1 : array (length N) or scalar 

5076 The y coordinates of the nodes defining the first curve. 

5077 

5078 y2 : array (length N) or scalar, optional, default: 0 

5079 The y coordinates of the nodes defining the second curve. 

5080 

5081 where : array of bool (length N), optional, default: None 

5082 Define *where* to exclude some horizontal regions from being 

5083 filled. The filled regions are defined by the coordinates 

5084 ``x[where]``. More precisely, fill between ``x[i]`` and ``x[i+1]`` 

5085 if ``where[i] and where[i+1]``. Note that this definition implies 

5086 that an isolated *True* value between two *False* values in 

5087 *where* will not result in filling. Both sides of the *True* 

5088 position remain unfilled due to the adjacent *False* values. 

5089 

5090 interpolate : bool, optional 

5091 This option is only relevant if *where* is used and the two curves 

5092 are crossing each other. 

5093 

5094 Semantically, *where* is often used for *y1* > *y2* or similar. 

5095 By default, the nodes of the polygon defining the filled region 

5096 will only be placed at the positions in the *x* array. Such a 

5097 polygon cannot describe the above semantics close to the 

5098 intersection. The x-sections containing the intersection are 

5099 simply clipped. 

5100 

5101 Setting *interpolate* to *True* will calculate the actual 

5102 intersection point and extend the filled region up to this point. 

5103 

5104 step : {'pre', 'post', 'mid'}, optional 

5105 Define *step* if the filling should be a step function, 

5106 i.e. constant in between *x*. The value determines where the 

5107 step will occur: 

5108 

5109 - 'pre': The y value is continued constantly to the left from 

5110 every *x* position, i.e. the interval ``(x[i-1], x[i]]`` has the 

5111 value ``y[i]``. 

5112 - 'post': The y value is continued constantly to the right from 

5113 every *x* position, i.e. the interval ``[x[i], x[i+1])`` has the 

5114 value ``y[i]``. 

5115 - 'mid': Steps occur half-way between the *x* positions. 

5116 

5117 Other Parameters 

5118 ---------------- 

5119 **kwargs 

5120 All other keyword arguments are passed on to `.PolyCollection`. 

5121 They control the `.Polygon` properties: 

5122 

5123 %(PolyCollection)s 

5124 

5125 Returns 

5126 ------- 

5127 `.PolyCollection` 

5128 A `.PolyCollection` containing the plotted polygons. 

5129 

5130 See Also 

5131 -------- 

5132 fill_betweenx : Fill between two sets of x-values. 

5133 

5134 Notes 

5135 ----- 

5136 .. [notes section required to get data note injection right] 

5137 

5138 """ 

5139 if not rcParams['_internal.classic_mode']: 

5140 kwargs = cbook.normalize_kwargs(kwargs, mcoll.Collection) 

5141 if not any(c in kwargs for c in ('color', 'facecolor')): 

5142 kwargs['facecolor'] = \ 

5143 self._get_patches_for_fill.get_next_color() 

5144 

5145 # Handle united data, such as dates 

5146 self._process_unit_info(xdata=x, ydata=y1, kwargs=kwargs) 

5147 self._process_unit_info(ydata=y2) 

5148 

5149 # Convert the arrays so we can work with them 

5150 x = ma.masked_invalid(self.convert_xunits(x)) 

5151 y1 = ma.masked_invalid(self.convert_yunits(y1)) 

5152 y2 = ma.masked_invalid(self.convert_yunits(y2)) 

5153 

5154 for name, array in [('x', x), ('y1', y1), ('y2', y2)]: 

5155 if array.ndim > 1: 

5156 raise ValueError('Input passed into argument "%r"' % name + 

5157 'is not 1-dimensional.') 

5158 

5159 if where is None: 

5160 where = True 

5161 else: 

5162 where = np.asarray(where, dtype=bool) 

5163 if where.size != x.size: 

5164 cbook.warn_deprecated( 

5165 "3.2", 

5166 message="The parameter where must have the same size as x " 

5167 "in fill_between(). This will become an error in " 

5168 "future versions of Matplotlib.") 

5169 where = where & ~functools.reduce(np.logical_or, 

5170 map(np.ma.getmask, [x, y1, y2])) 

5171 

5172 x, y1, y2 = np.broadcast_arrays(np.atleast_1d(x), y1, y2) 

5173 

5174 polys = [] 

5175 for ind0, ind1 in cbook.contiguous_regions(where): 

5176 xslice = x[ind0:ind1] 

5177 y1slice = y1[ind0:ind1] 

5178 y2slice = y2[ind0:ind1] 

5179 if step is not None: 

5180 step_func = cbook.STEP_LOOKUP_MAP["steps-" + step] 

5181 xslice, y1slice, y2slice = step_func(xslice, y1slice, y2slice) 

5182 

5183 if not len(xslice): 

5184 continue 

5185 

5186 N = len(xslice) 

5187 X = np.zeros((2 * N + 2, 2), float) 

5188 

5189 if interpolate: 

5190 def get_interp_point(ind): 

5191 im1 = max(ind - 1, 0) 

5192 x_values = x[im1:ind + 1] 

5193 diff_values = y1[im1:ind + 1] - y2[im1:ind + 1] 

5194 y1_values = y1[im1:ind + 1] 

5195 

5196 if len(diff_values) == 2: 

5197 if np.ma.is_masked(diff_values[1]): 

5198 return x[im1], y1[im1] 

5199 elif np.ma.is_masked(diff_values[0]): 

5200 return x[ind], y1[ind] 

5201 

5202 diff_order = diff_values.argsort() 

5203 diff_root_x = np.interp( 

5204 0, diff_values[diff_order], x_values[diff_order]) 

5205 x_order = x_values.argsort() 

5206 diff_root_y = np.interp(diff_root_x, x_values[x_order], 

5207 y1_values[x_order]) 

5208 return diff_root_x, diff_root_y 

5209 

5210 start = get_interp_point(ind0) 

5211 end = get_interp_point(ind1) 

5212 else: 

5213 # the purpose of the next two lines is for when y2 is a 

5214 # scalar like 0 and we want the fill to go all the way 

5215 # down to 0 even if none of the y1 sample points do 

5216 start = xslice[0], y2slice[0] 

5217 end = xslice[-1], y2slice[-1] 

5218 

5219 X[0] = start 

5220 X[N + 1] = end 

5221 

5222 X[1:N + 1, 0] = xslice 

5223 X[1:N + 1, 1] = y1slice 

5224 X[N + 2:, 0] = xslice[::-1] 

5225 X[N + 2:, 1] = y2slice[::-1] 

5226 

5227 polys.append(X) 

5228 

5229 collection = mcoll.PolyCollection(polys, **kwargs) 

5230 

5231 # now update the datalim and autoscale 

5232 XY1 = np.array([x[where], y1[where]]).T 

5233 XY2 = np.array([x[where], y2[where]]).T 

5234 self.dataLim.update_from_data_xy(XY1, self.ignore_existing_data_limits, 

5235 updatex=True, updatey=True) 

5236 self.ignore_existing_data_limits = False 

5237 self.dataLim.update_from_data_xy(XY2, self.ignore_existing_data_limits, 

5238 updatex=False, updatey=True) 

5239 self.add_collection(collection, autolim=False) 

5240 self._request_autoscale_view() 

5241 return collection 

5242 

5243 @_preprocess_data(replace_names=["y", "x1", "x2", "where"]) 

5244 @docstring.dedent_interpd 

5245 def fill_betweenx(self, y, x1, x2=0, where=None, 

5246 step=None, interpolate=False, **kwargs): 

5247 """ 

5248 Fill the area between two vertical curves. 

5249 

5250 The curves are defined by the points (*x1*, *y*) and (*x2*, *y*). This 

5251 creates one or multiple polygons describing the filled area. 

5252 

5253 You may exclude some vertical sections from filling using *where*. 

5254 

5255 By default, the edges connect the given points directly. Use *step* if 

5256 the filling should be a step function, i.e. constant in between *y*. 

5257 

5258 

5259 Parameters 

5260 ---------- 

5261 y : array (length N) 

5262 The y coordinates of the nodes defining the curves. 

5263 

5264 x1 : array (length N) or scalar 

5265 The x coordinates of the nodes defining the first curve. 

5266 

5267 x2 : array (length N) or scalar, optional, default: 0 

5268 The x coordinates of the nodes defining the second curve. 

5269 

5270 where : array of bool (length N), optional, default: None 

5271 Define *where* to exclude some vertical regions from being 

5272 filled. The filled regions are defined by the coordinates 

5273 ``y[where]``. More precisely, fill between ``y[i]`` and ``y[i+1]`` 

5274 if ``where[i] and where[i+1]``. Note that this definition implies 

5275 that an isolated *True* value between two *False* values in 

5276 *where* will not result in filling. Both sides of the *True* 

5277 position remain unfilled due to the adjacent *False* values. 

5278 

5279 interpolate : bool, optional 

5280 This option is only relevant if *where* is used and the two curves 

5281 are crossing each other. 

5282 

5283 Semantically, *where* is often used for *x1* > *x2* or similar. 

5284 By default, the nodes of the polygon defining the filled region 

5285 will only be placed at the positions in the *y* array. Such a 

5286 polygon cannot describe the above semantics close to the 

5287 intersection. The y-sections containing the intersection are 

5288 simply clipped. 

5289 

5290 Setting *interpolate* to *True* will calculate the actual 

5291 intersection point and extend the filled region up to this point. 

5292 

5293 step : {'pre', 'post', 'mid'}, optional 

5294 Define *step* if the filling should be a step function, 

5295 i.e. constant in between *y*. The value determines where the 

5296 step will occur: 

5297 

5298 - 'pre': The y value is continued constantly to the left from 

5299 every *x* position, i.e. the interval ``(x[i-1], x[i]]`` has the 

5300 value ``y[i]``. 

5301 - 'post': The y value is continued constantly to the right from 

5302 every *x* position, i.e. the interval ``[x[i], x[i+1])`` has the 

5303 value ``y[i]``. 

5304 - 'mid': Steps occur half-way between the *x* positions. 

5305 

5306 Other Parameters 

5307 ---------------- 

5308 **kwargs 

5309 All other keyword arguments are passed on to `.PolyCollection`. 

5310 They control the `.Polygon` properties: 

5311 

5312 %(PolyCollection)s 

5313 

5314 Returns 

5315 ------- 

5316 `.PolyCollection` 

5317 A `.PolyCollection` containing the plotted polygons. 

5318 

5319 See Also 

5320 -------- 

5321 fill_between : Fill between two sets of y-values. 

5322 

5323 Notes 

5324 ----- 

5325 .. [notes section required to get data note injection right] 

5326 

5327 """ 

5328 if not rcParams['_internal.classic_mode']: 

5329 kwargs = cbook.normalize_kwargs(kwargs, mcoll.Collection) 

5330 if not any(c in kwargs for c in ('color', 'facecolor')): 

5331 kwargs['facecolor'] = \ 

5332 self._get_patches_for_fill.get_next_color() 

5333 

5334 # Handle united data, such as dates 

5335 self._process_unit_info(ydata=y, xdata=x1, kwargs=kwargs) 

5336 self._process_unit_info(xdata=x2) 

5337 

5338 # Convert the arrays so we can work with them 

5339 y = ma.masked_invalid(self.convert_yunits(y)) 

5340 x1 = ma.masked_invalid(self.convert_xunits(x1)) 

5341 x2 = ma.masked_invalid(self.convert_xunits(x2)) 

5342 

5343 for name, array in [('y', y), ('x1', x1), ('x2', x2)]: 

5344 if array.ndim > 1: 

5345 raise ValueError('Input passed into argument "%r"' % name + 

5346 'is not 1-dimensional.') 

5347 

5348 if where is None: 

5349 where = True 

5350 else: 

5351 where = np.asarray(where, dtype=bool) 

5352 if where.size != y.size: 

5353 cbook.warn_deprecated( 

5354 "3.2", 

5355 message="The parameter where must have the same size as y " 

5356 "in fill_between(). This will become an error in " 

5357 "future versions of Matplotlib.") 

5358 where = where & ~functools.reduce(np.logical_or, 

5359 map(np.ma.getmask, [y, x1, x2])) 

5360 

5361 y, x1, x2 = np.broadcast_arrays(np.atleast_1d(y), x1, x2) 

5362 

5363 polys = [] 

5364 for ind0, ind1 in cbook.contiguous_regions(where): 

5365 yslice = y[ind0:ind1] 

5366 x1slice = x1[ind0:ind1] 

5367 x2slice = x2[ind0:ind1] 

5368 if step is not None: 

5369 step_func = cbook.STEP_LOOKUP_MAP["steps-" + step] 

5370 yslice, x1slice, x2slice = step_func(yslice, x1slice, x2slice) 

5371 

5372 if not len(yslice): 

5373 continue 

5374 

5375 N = len(yslice) 

5376 Y = np.zeros((2 * N + 2, 2), float) 

5377 if interpolate: 

5378 def get_interp_point(ind): 

5379 im1 = max(ind - 1, 0) 

5380 y_values = y[im1:ind + 1] 

5381 diff_values = x1[im1:ind + 1] - x2[im1:ind + 1] 

5382 x1_values = x1[im1:ind + 1] 

5383 

5384 if len(diff_values) == 2: 

5385 if np.ma.is_masked(diff_values[1]): 

5386 return x1[im1], y[im1] 

5387 elif np.ma.is_masked(diff_values[0]): 

5388 return x1[ind], y[ind] 

5389 

5390 diff_order = diff_values.argsort() 

5391 diff_root_y = np.interp( 

5392 0, diff_values[diff_order], y_values[diff_order]) 

5393 y_order = y_values.argsort() 

5394 diff_root_x = np.interp(diff_root_y, y_values[y_order], 

5395 x1_values[y_order]) 

5396 return diff_root_x, diff_root_y 

5397 

5398 start = get_interp_point(ind0) 

5399 end = get_interp_point(ind1) 

5400 else: 

5401 # the purpose of the next two lines is for when x2 is a 

5402 # scalar like 0 and we want the fill to go all the way 

5403 # down to 0 even if none of the x1 sample points do 

5404 start = x2slice[0], yslice[0] 

5405 end = x2slice[-1], yslice[-1] 

5406 

5407 Y[0] = start 

5408 Y[N + 1] = end 

5409 

5410 Y[1:N + 1, 0] = x1slice 

5411 Y[1:N + 1, 1] = yslice 

5412 Y[N + 2:, 0] = x2slice[::-1] 

5413 Y[N + 2:, 1] = yslice[::-1] 

5414 

5415 polys.append(Y) 

5416 

5417 collection = mcoll.PolyCollection(polys, **kwargs) 

5418 

5419 # now update the datalim and autoscale 

5420 X1Y = np.array([x1[where], y[where]]).T 

5421 X2Y = np.array([x2[where], y[where]]).T 

5422 self.dataLim.update_from_data_xy(X1Y, self.ignore_existing_data_limits, 

5423 updatex=True, updatey=True) 

5424 self.ignore_existing_data_limits = False 

5425 self.dataLim.update_from_data_xy(X2Y, self.ignore_existing_data_limits, 

5426 updatex=True, updatey=False) 

5427 self.add_collection(collection, autolim=False) 

5428 self._request_autoscale_view() 

5429 return collection 

5430 

5431 #### plotting z(x, y): imshow, pcolor and relatives, contour 

5432 @_preprocess_data() 

5433 @cbook._delete_parameter("3.1", "shape") 

5434 @cbook._delete_parameter("3.1", "imlim") 

5435 def imshow(self, X, cmap=None, norm=None, aspect=None, 

5436 interpolation=None, alpha=None, vmin=None, vmax=None, 

5437 origin=None, extent=None, shape=None, filternorm=1, 

5438 filterrad=4.0, imlim=None, resample=None, url=None, **kwargs): 

5439 """ 

5440 Display data as an image; i.e. on a 2D regular raster. 

5441 

5442 The input may either be actual RGB(A) data, or 2D scalar data, which 

5443 will be rendered as a pseudocolor image. Note: For actually displaying 

5444 a grayscale image set up the color mapping using the parameters 

5445 ``cmap='gray', vmin=0, vmax=255``. 

5446 

5447 Parameters 

5448 ---------- 

5449 X : array-like or PIL image 

5450 The image data. Supported array shapes are: 

5451 

5452 - (M, N): an image with scalar data. The values are mapped to 

5453 colors using normalization and a colormap. See parameters *norm*, 

5454 *cmap*, *vmin*, *vmax*. 

5455 - (M, N, 3): an image with RGB values (0-1 float or 0-255 int). 

5456 - (M, N, 4): an image with RGBA values (0-1 float or 0-255 int), 

5457 i.e. including transparency. 

5458 

5459 The first two dimensions (M, N) define the rows and columns of 

5460 the image. 

5461 

5462 Out-of-range RGB(A) values are clipped. 

5463 

5464 cmap : str or `~matplotlib.colors.Colormap`, optional 

5465 The Colormap instance or registered colormap name used to map 

5466 scalar data to colors. This parameter is ignored for RGB(A) data. 

5467 Defaults to :rc:`image.cmap`. 

5468 

5469 norm : `~matplotlib.colors.Normalize`, optional 

5470 The `Normalize` instance used to scale scalar data to the [0, 1] 

5471 range before mapping to colors using *cmap*. By default, a linear 

5472 scaling mapping the lowest value to 0 and the highest to 1 is used. 

5473 This parameter is ignored for RGB(A) data. 

5474 

5475 aspect : {'equal', 'auto'} or float, optional 

5476 Controls the aspect ratio of the axes. The aspect is of particular 

5477 relevance for images since it may distort the image, i.e. pixel 

5478 will not be square. 

5479 

5480 This parameter is a shortcut for explicitly calling 

5481 `.Axes.set_aspect`. See there for further details. 

5482 

5483 - 'equal': Ensures an aspect ratio of 1. Pixels will be square 

5484 (unless pixel sizes are explicitly made non-square in data 

5485 coordinates using *extent*). 

5486 - 'auto': The axes is kept fixed and the aspect is adjusted so 

5487 that the data fit in the axes. In general, this will result in 

5488 non-square pixels. 

5489 

5490 If not given, use :rc:`image.aspect`. 

5491 

5492 interpolation : str, optional 

5493 The interpolation method used. If *None*, :rc:`image.interpolation` 

5494 is used. 

5495 

5496 Supported values are 'none', 'antialiased', 'nearest', 'bilinear', 

5497 'bicubic', 'spline16', 'spline36', 'hanning', 'hamming', 'hermite', 

5498 'kaiser', 'quadric', 'catrom', 'gaussian', 'bessel', 'mitchell', 

5499 'sinc', 'lanczos'. 

5500 

5501 If *interpolation* is 'none', then no interpolation is performed 

5502 on the Agg, ps, pdf and svg backends. Other backends will fall back 

5503 to 'nearest'. Note that most SVG renders perform interpolation at 

5504 rendering and that the default interpolation method they implement 

5505 may differ. 

5506 

5507 If *interpolation* is the default 'antialiased', then 'nearest' 

5508 interpolation is used if the image is upsampled by more than a 

5509 factor of three (i.e. the number of display pixels is at least 

5510 three times the size of the data array). If the upsampling rate is 

5511 smaller than 3, or the image is downsampled, then 'hanning' 

5512 interpolation is used to act as an anti-aliasing filter, unless the 

5513 image happens to be upsampled by exactly a factor of two or one. 

5514 

5515 See 

5516 :doc:`/gallery/images_contours_and_fields/interpolation_methods` 

5517 for an overview of the supported interpolation methods, and 

5518 :doc:`/gallery/images_contours_and_fields/image_antialiasing` for 

5519 a discussion of image antialiasing. 

5520 

5521 Some interpolation methods require an additional radius parameter, 

5522 which can be set by *filterrad*. Additionally, the antigrain image 

5523 resize filter is controlled by the parameter *filternorm*. 

5524 

5525 alpha : scalar or array-like, optional 

5526 The alpha blending value, between 0 (transparent) and 1 (opaque). 

5527 If *alpha* is an array, the alpha blending values are applied pixel 

5528 by pixel, and *alpha* must have the same shape as *X*. 

5529 

5530 vmin, vmax : scalar, optional 

5531 When using scalar data and no explicit *norm*, *vmin* and *vmax* 

5532 define the data range that the colormap covers. By default, 

5533 the colormap covers the complete value range of the supplied 

5534 data. *vmin*, *vmax* are ignored if the *norm* parameter is used. 

5535 

5536 origin : {'upper', 'lower'}, optional 

5537 Place the [0, 0] index of the array in the upper left or lower left 

5538 corner of the axes. The convention 'upper' is typically used for 

5539 matrices and images. 

5540 If not given, :rc:`image.origin` is used, defaulting to 'upper'. 

5541 

5542 Note that the vertical axes points upward for 'lower' 

5543 but downward for 'upper'. 

5544 

5545 See the :doc:`/tutorials/intermediate/imshow_extent` tutorial for 

5546 examples and a more detailed description. 

5547 

5548 extent : scalars (left, right, bottom, top), optional 

5549 The bounding box in data coordinates that the image will fill. 

5550 The image is stretched individually along x and y to fill the box. 

5551 

5552 The default extent is determined by the following conditions. 

5553 Pixels have unit size in data coordinates. Their centers are on 

5554 integer coordinates, and their center coordinates range from 0 to 

5555 columns-1 horizontally and from 0 to rows-1 vertically. 

5556 

5557 Note that the direction of the vertical axis and thus the default 

5558 values for top and bottom depend on *origin*: 

5559 

5560 - For ``origin == 'upper'`` the default is 

5561 ``(-0.5, numcols-0.5, numrows-0.5, -0.5)``. 

5562 - For ``origin == 'lower'`` the default is 

5563 ``(-0.5, numcols-0.5, -0.5, numrows-0.5)``. 

5564 

5565 See the :doc:`/tutorials/intermediate/imshow_extent` tutorial for 

5566 examples and a more detailed description. 

5567 

5568 filternorm : bool, optional, default: True 

5569 A parameter for the antigrain image resize filter (see the 

5570 antigrain documentation). If *filternorm* is set, the filter 

5571 normalizes integer values and corrects the rounding errors. It 

5572 doesn't do anything with the source floating point values, it 

5573 corrects only integers according to the rule of 1.0 which means 

5574 that any sum of pixel weights must be equal to 1.0. So, the 

5575 filter function must produce a graph of the proper shape. 

5576 

5577 filterrad : float > 0, optional, default: 4.0 

5578 The filter radius for filters that have a radius parameter, i.e. 

5579 when interpolation is one of: 'sinc', 'lanczos' or 'blackman'. 

5580 

5581 resample : bool, optional 

5582 When *True*, use a full resampling method. When *False*, only 

5583 resample when the output image is larger than the input image. 

5584 

5585 url : str, optional 

5586 Set the url of the created `.AxesImage`. See `.Artist.set_url`. 

5587 

5588 Returns 

5589 ------- 

5590 image : `~matplotlib.image.AxesImage` 

5591 

5592 Other Parameters 

5593 ---------------- 

5594 **kwargs : `~matplotlib.artist.Artist` properties 

5595 These parameters are passed on to the constructor of the 

5596 `.AxesImage` artist. 

5597 

5598 See also 

5599 -------- 

5600 matshow : Plot a matrix or an array as an image. 

5601 

5602 Notes 

5603 ----- 

5604 Unless *extent* is used, pixel centers will be located at integer 

5605 coordinates. In other words: the origin will coincide with the center 

5606 of pixel (0, 0). 

5607 

5608 There are two common representations for RGB images with an alpha 

5609 channel: 

5610 

5611 - Straight (unassociated) alpha: R, G, and B channels represent the 

5612 color of the pixel, disregarding its opacity. 

5613 - Premultiplied (associated) alpha: R, G, and B channels represent 

5614 the color of the pixel, adjusted for its opacity by multiplication. 

5615 

5616 `~matplotlib.pyplot.imshow` expects RGB images adopting the straight 

5617 (unassociated) alpha representation. 

5618 """ 

5619 if aspect is None: 

5620 aspect = rcParams['image.aspect'] 

5621 self.set_aspect(aspect) 

5622 im = mimage.AxesImage(self, cmap, norm, interpolation, origin, extent, 

5623 filternorm=filternorm, filterrad=filterrad, 

5624 resample=resample, **kwargs) 

5625 

5626 im.set_data(X) 

5627 im.set_alpha(alpha) 

5628 if im.get_clip_path() is None: 

5629 # image does not already have clipping set, clip to axes patch 

5630 im.set_clip_path(self.patch) 

5631 if vmin is not None or vmax is not None: 

5632 im.set_clim(vmin, vmax) 

5633 else: 

5634 im.autoscale_None() 

5635 im.set_url(url) 

5636 

5637 # update ax.dataLim, and, if autoscaling, set viewLim 

5638 # to tightly fit the image, regardless of dataLim. 

5639 im.set_extent(im.get_extent()) 

5640 

5641 self.add_image(im) 

5642 return im 

5643 

5644 @staticmethod 

5645 def _pcolorargs(funcname, *args, allmatch=False): 

5646 # If allmatch is True, then the incoming X, Y, C must have matching 

5647 # dimensions, taking into account that X and Y can be 1-D rather than 

5648 # 2-D. This perfect match is required for Gouraud shading. For flat 

5649 # shading, X and Y specify boundaries, so we need one more boundary 

5650 # than color in each direction. For convenience, and consistent with 

5651 # Matlab, we discard the last row and/or column of C if necessary to 

5652 # meet this condition. This is done if allmatch is False. 

5653 

5654 if len(args) == 1: 

5655 C = np.asanyarray(args[0]) 

5656 nrows, ncols = C.shape 

5657 if allmatch: 

5658 X, Y = np.meshgrid(np.arange(ncols), np.arange(nrows)) 

5659 else: 

5660 X, Y = np.meshgrid(np.arange(ncols + 1), np.arange(nrows + 1)) 

5661 C = cbook.safe_masked_invalid(C) 

5662 return X, Y, C 

5663 

5664 if len(args) == 3: 

5665 # Check x and y for bad data... 

5666 C = np.asanyarray(args[2]) 

5667 X, Y = [cbook.safe_masked_invalid(a) for a in args[:2]] 

5668 if funcname == 'pcolormesh': 

5669 if np.ma.is_masked(X) or np.ma.is_masked(Y): 

5670 raise ValueError( 

5671 'x and y arguments to pcolormesh cannot have ' 

5672 'non-finite values or be of type ' 

5673 'numpy.ma.core.MaskedArray with masked values') 

5674 # safe_masked_invalid() returns an ndarray for dtypes other 

5675 # than floating point. 

5676 if isinstance(X, np.ma.core.MaskedArray): 

5677 X = X.data # strip mask as downstream doesn't like it... 

5678 if isinstance(Y, np.ma.core.MaskedArray): 

5679 Y = Y.data 

5680 nrows, ncols = C.shape 

5681 else: 

5682 raise TypeError( 

5683 'Illegal arguments to %s; see help(%s)' % (funcname, funcname)) 

5684 

5685 Nx = X.shape[-1] 

5686 Ny = Y.shape[0] 

5687 if X.ndim != 2 or X.shape[0] == 1: 

5688 x = X.reshape(1, Nx) 

5689 X = x.repeat(Ny, axis=0) 

5690 if Y.ndim != 2 or Y.shape[1] == 1: 

5691 y = Y.reshape(Ny, 1) 

5692 Y = y.repeat(Nx, axis=1) 

5693 if X.shape != Y.shape: 

5694 raise TypeError( 

5695 'Incompatible X, Y inputs to %s; see help(%s)' % ( 

5696 funcname, funcname)) 

5697 if allmatch: 

5698 if (Nx, Ny) != (ncols, nrows): 

5699 raise TypeError('Dimensions of C %s are incompatible with' 

5700 ' X (%d) and/or Y (%d); see help(%s)' % ( 

5701 C.shape, Nx, Ny, funcname)) 

5702 else: 

5703 if not (ncols in (Nx, Nx - 1) and nrows in (Ny, Ny - 1)): 

5704 raise TypeError('Dimensions of C %s are incompatible with' 

5705 ' X (%d) and/or Y (%d); see help(%s)' % ( 

5706 C.shape, Nx, Ny, funcname)) 

5707 C = C[:Ny - 1, :Nx - 1] 

5708 C = cbook.safe_masked_invalid(C) 

5709 return X, Y, C 

5710 

5711 @_preprocess_data() 

5712 @docstring.dedent_interpd 

5713 def pcolor(self, *args, alpha=None, norm=None, cmap=None, vmin=None, 

5714 vmax=None, **kwargs): 

5715 r""" 

5716 Create a pseudocolor plot with a non-regular rectangular grid. 

5717 

5718 Call signature:: 

5719 

5720 pcolor([X, Y,] C, **kwargs) 

5721 

5722 *X* and *Y* can be used to specify the corners of the quadrilaterals. 

5723 

5724 .. hint:: 

5725 

5726 ``pcolor()`` can be very slow for large arrays. In most 

5727 cases you should use the similar but much faster 

5728 `~.Axes.pcolormesh` instead. See there for a discussion of the 

5729 differences. 

5730 

5731 Parameters 

5732 ---------- 

5733 C : array-like 

5734 A scalar 2-D array. The values will be color-mapped. 

5735 

5736 X, Y : array-like, optional 

5737 The coordinates of the quadrilateral corners. The quadrilateral 

5738 for ``C[i, j]`` has corners at:: 

5739 

5740 (X[i+1, j], Y[i+1, j]) (X[i+1, j+1], Y[i+1, j+1]) 

5741 +---------+ 

5742 | C[i, j] | 

5743 +---------+ 

5744 (X[i, j], Y[i, j]) (X[i, j+1], Y[i, j+1]) 

5745 

5746 Note that the column index corresponds to the 

5747 x-coordinate, and the row index corresponds to y. For 

5748 details, see the :ref:`Notes <axes-pcolor-grid-orientation>` 

5749 section below. 

5750 

5751 The dimensions of *X* and *Y* should be one greater than those of 

5752 *C*. Alternatively, *X*, *Y* and *C* may have equal dimensions, in 

5753 which case the last row and column of *C* will be ignored. 

5754 

5755 If *X* and/or *Y* are 1-D arrays or column vectors they will be 

5756 expanded as needed into the appropriate 2-D arrays, making a 

5757 rectangular grid. 

5758 

5759 cmap : str or `~matplotlib.colors.Colormap`, optional 

5760 A Colormap instance or registered colormap name. The colormap 

5761 maps the *C* values to colors. Defaults to :rc:`image.cmap`. 

5762 

5763 norm : `~matplotlib.colors.Normalize`, optional 

5764 The Normalize instance scales the data values to the canonical 

5765 colormap range [0, 1] for mapping to colors. By default, the data 

5766 range is mapped to the colorbar range using linear scaling. 

5767 

5768 vmin, vmax : scalar, optional, default: None 

5769 The colorbar range. If *None*, suitable min/max values are 

5770 automatically chosen by the `~.Normalize` instance (defaults to 

5771 the respective min/max values of *C* in case of the default linear 

5772 scaling). 

5773 

5774 edgecolors : {'none', None, 'face', color, color sequence}, optional 

5775 The color of the edges. Defaults to 'none'. Possible values: 

5776 

5777 - 'none' or '': No edge. 

5778 - *None*: :rc:`patch.edgecolor` will be used. Note that currently 

5779 :rc:`patch.force_edgecolor` has to be True for this to work. 

5780 - 'face': Use the adjacent face color. 

5781 - A color or sequence of colors will set the edge color. 

5782 

5783 The singular form *edgecolor* works as an alias. 

5784 

5785 alpha : scalar, optional, default: None 

5786 The alpha blending value of the face color, between 0 (transparent) 

5787 and 1 (opaque). Note: The edgecolor is currently not affected by 

5788 this. 

5789 

5790 snap : bool, optional, default: False 

5791 Whether to snap the mesh to pixel boundaries. 

5792 

5793 Returns 

5794 ------- 

5795 collection : `matplotlib.collections.Collection` 

5796 

5797 Other Parameters 

5798 ---------------- 

5799 antialiaseds : bool, optional, default: False 

5800 The default *antialiaseds* is False if the default 

5801 *edgecolors*\ ="none" is used. This eliminates artificial lines 

5802 at patch boundaries, and works regardless of the value of alpha. 

5803 If *edgecolors* is not "none", then the default *antialiaseds* 

5804 is taken from :rc:`patch.antialiased`. 

5805 Stroking the edges may be preferred if *alpha* is 1, but will 

5806 cause artifacts otherwise. 

5807 

5808 **kwargs 

5809 Additionally, the following arguments are allowed. They are passed 

5810 along to the `~matplotlib.collections.PolyCollection` constructor: 

5811 

5812 %(PolyCollection)s 

5813 

5814 See Also 

5815 -------- 

5816 pcolormesh : for an explanation of the differences between 

5817 pcolor and pcolormesh. 

5818 imshow : If *X* and *Y* are each equidistant, `~.Axes.imshow` can be a 

5819 faster alternative. 

5820 

5821 Notes 

5822 ----- 

5823 **Masked arrays** 

5824 

5825 *X*, *Y* and *C* may be masked arrays. If either ``C[i, j]``, or one 

5826 of the vertices surrounding ``C[i, j]`` (*X* or *Y* at 

5827 ``[i, j], [i+1, j], [i, j+1], [i+1, j+1]``) is masked, nothing is 

5828 plotted. 

5829 

5830 .. _axes-pcolor-grid-orientation: 

5831 

5832 **Grid orientation** 

5833 

5834 The grid orientation follows the standard matrix convention: An array 

5835 *C* with shape (nrows, ncolumns) is plotted with the column number as 

5836 *X* and the row number as *Y*. 

5837 

5838 **Handling of pcolor() end-cases** 

5839 

5840 ``pcolor()`` displays all columns of *C* if *X* and *Y* are not 

5841 specified, or if *X* and *Y* have one more column than *C*. 

5842 If *X* and *Y* have the same number of columns as *C* then the last 

5843 column of *C* is dropped. Similarly for the rows. 

5844 

5845 Note: This behavior is different from MATLAB's ``pcolor()``, which 

5846 always discards the last row and column of *C*. 

5847 """ 

5848 X, Y, C = self._pcolorargs('pcolor', *args, allmatch=False) 

5849 Ny, Nx = X.shape 

5850 

5851 # unit conversion allows e.g. datetime objects as axis values 

5852 self._process_unit_info(xdata=X, ydata=Y, kwargs=kwargs) 

5853 X = self.convert_xunits(X) 

5854 Y = self.convert_yunits(Y) 

5855 

5856 # convert to MA, if necessary. 

5857 C = ma.asarray(C) 

5858 X = ma.asarray(X) 

5859 Y = ma.asarray(Y) 

5860 

5861 mask = ma.getmaskarray(X) + ma.getmaskarray(Y) 

5862 xymask = (mask[0:-1, 0:-1] + mask[1:, 1:] + 

5863 mask[0:-1, 1:] + mask[1:, 0:-1]) 

5864 # don't plot if C or any of the surrounding vertices are masked. 

5865 mask = ma.getmaskarray(C) + xymask 

5866 

5867 unmask = ~mask 

5868 X1 = ma.filled(X[:-1, :-1])[unmask] 

5869 Y1 = ma.filled(Y[:-1, :-1])[unmask] 

5870 X2 = ma.filled(X[1:, :-1])[unmask] 

5871 Y2 = ma.filled(Y[1:, :-1])[unmask] 

5872 X3 = ma.filled(X[1:, 1:])[unmask] 

5873 Y3 = ma.filled(Y[1:, 1:])[unmask] 

5874 X4 = ma.filled(X[:-1, 1:])[unmask] 

5875 Y4 = ma.filled(Y[:-1, 1:])[unmask] 

5876 npoly = len(X1) 

5877 

5878 xy = np.stack([X1, Y1, X2, Y2, X3, Y3, X4, Y4, X1, Y1], axis=-1) 

5879 verts = xy.reshape((npoly, 5, 2)) 

5880 

5881 C = ma.filled(C[:Ny - 1, :Nx - 1])[unmask] 

5882 

5883 linewidths = (0.25,) 

5884 if 'linewidth' in kwargs: 

5885 kwargs['linewidths'] = kwargs.pop('linewidth') 

5886 kwargs.setdefault('linewidths', linewidths) 

5887 

5888 if 'edgecolor' in kwargs: 

5889 kwargs['edgecolors'] = kwargs.pop('edgecolor') 

5890 ec = kwargs.setdefault('edgecolors', 'none') 

5891 

5892 # aa setting will default via collections to patch.antialiased 

5893 # unless the boundary is not stroked, in which case the 

5894 # default will be False; with unstroked boundaries, aa 

5895 # makes artifacts that are often disturbing. 

5896 if 'antialiased' in kwargs: 

5897 kwargs['antialiaseds'] = kwargs.pop('antialiased') 

5898 if 'antialiaseds' not in kwargs and cbook._str_lower_equal(ec, "none"): 

5899 kwargs['antialiaseds'] = False 

5900 

5901 kwargs.setdefault('snap', False) 

5902 

5903 collection = mcoll.PolyCollection(verts, **kwargs) 

5904 

5905 collection.set_alpha(alpha) 

5906 collection.set_array(C) 

5907 collection.set_cmap(cmap) 

5908 collection.set_norm(norm) 

5909 collection.set_clim(vmin, vmax) 

5910 collection.autoscale_None() 

5911 self.grid(False) 

5912 

5913 x = X.compressed() 

5914 y = Y.compressed() 

5915 

5916 # Transform from native to data coordinates? 

5917 t = collection._transform 

5918 if (not isinstance(t, mtransforms.Transform) and 

5919 hasattr(t, '_as_mpl_transform')): 

5920 t = t._as_mpl_transform(self.axes) 

5921 

5922 if t and any(t.contains_branch_seperately(self.transData)): 

5923 trans_to_data = t - self.transData 

5924 pts = np.vstack([x, y]).T.astype(float) 

5925 transformed_pts = trans_to_data.transform(pts) 

5926 x = transformed_pts[..., 0] 

5927 y = transformed_pts[..., 1] 

5928 

5929 self.add_collection(collection, autolim=False) 

5930 

5931 minx = np.min(x) 

5932 maxx = np.max(x) 

5933 miny = np.min(y) 

5934 maxy = np.max(y) 

5935 collection.sticky_edges.x[:] = [minx, maxx] 

5936 collection.sticky_edges.y[:] = [miny, maxy] 

5937 corners = (minx, miny), (maxx, maxy) 

5938 self.update_datalim(corners) 

5939 self._request_autoscale_view() 

5940 return collection 

5941 

5942 @_preprocess_data() 

5943 @docstring.dedent_interpd 

5944 def pcolormesh(self, *args, alpha=None, norm=None, cmap=None, vmin=None, 

5945 vmax=None, shading='flat', antialiased=False, **kwargs): 

5946 """ 

5947 Create a pseudocolor plot with a non-regular rectangular grid. 

5948 

5949 Call signature:: 

5950 

5951 pcolor([X, Y,] C, **kwargs) 

5952 

5953 *X* and *Y* can be used to specify the corners of the quadrilaterals. 

5954 

5955 .. note:: 

5956 

5957 `~Axes.pcolormesh` is similar to `~Axes.pcolor`. It's much faster 

5958 and preferred in most cases. For a detailed discussion on the 

5959 differences see :ref:`Differences between pcolor() and pcolormesh() 

5960 <differences-pcolor-pcolormesh>`. 

5961 

5962 Parameters 

5963 ---------- 

5964 C : array-like 

5965 A scalar 2-D array. The values will be color-mapped. 

5966 

5967 X, Y : array-like, optional 

5968 The coordinates of the quadrilateral corners. The quadrilateral 

5969 for ``C[i, j]`` has corners at:: 

5970 

5971 (X[i+1, j], Y[i+1, j]) (X[i+1, j+1], Y[i+1, j+1]) 

5972 +---------+ 

5973 | C[i, j] | 

5974 +---------+ 

5975 (X[i, j], Y[i, j]) (X[i, j+1], Y[i, j+1]) 

5976 

5977 Note that the column index corresponds to the 

5978 x-coordinate, and the row index corresponds to y. For 

5979 details, see the :ref:`Notes <axes-pcolormesh-grid-orientation>` 

5980 section below. 

5981 

5982 The dimensions of *X* and *Y* should be one greater than those of 

5983 *C*. Alternatively, *X*, *Y* and *C* may have equal dimensions, in 

5984 which case the last row and column of *C* will be ignored. 

5985 

5986 If *X* and/or *Y* are 1-D arrays or column vectors they will be 

5987 expanded as needed into the appropriate 2-D arrays, making a 

5988 rectangular grid. 

5989 

5990 cmap : str or `~matplotlib.colors.Colormap`, optional 

5991 A Colormap instance or registered colormap name. The colormap 

5992 maps the *C* values to colors. Defaults to :rc:`image.cmap`. 

5993 

5994 norm : `~matplotlib.colors.Normalize`, optional 

5995 The Normalize instance scales the data values to the canonical 

5996 colormap range [0, 1] for mapping to colors. By default, the data 

5997 range is mapped to the colorbar range using linear scaling. 

5998 

5999 vmin, vmax : scalar, optional, default: None 

6000 The colorbar range. If *None*, suitable min/max values are 

6001 automatically chosen by the `~.Normalize` instance (defaults to 

6002 the respective min/max values of *C* in case of the default linear 

6003 scaling). 

6004 

6005 edgecolors : {'none', None, 'face', color, color sequence}, optional 

6006 The color of the edges. Defaults to 'none'. Possible values: 

6007 

6008 - 'none' or '': No edge. 

6009 - *None*: :rc:`patch.edgecolor` will be used. Note that currently 

6010 :rc:`patch.force_edgecolor` has to be True for this to work. 

6011 - 'face': Use the adjacent face color. 

6012 - A color or sequence of colors will set the edge color. 

6013 

6014 The singular form *edgecolor* works as an alias. 

6015 

6016 alpha : scalar, optional, default: None 

6017 The alpha blending value, between 0 (transparent) and 1 (opaque). 

6018 

6019 shading : {'flat', 'gouraud'}, optional 

6020 The fill style, Possible values: 

6021 

6022 - 'flat': A solid color is used for each quad. The color of the 

6023 quad (i, j), (i+1, j), (i, j+1), (i+1, j+1) is given by 

6024 ``C[i, j]``. 

6025 - 'gouraud': Each quad will be Gouraud shaded: The color of the 

6026 corners (i', j') are given by ``C[i',j']``. The color values of 

6027 the area in between is interpolated from the corner values. 

6028 When Gouraud shading is used, *edgecolors* is ignored. 

6029 

6030 snap : bool, optional, default: False 

6031 Whether to snap the mesh to pixel boundaries. 

6032 

6033 Returns 

6034 ------- 

6035 mesh : `matplotlib.collections.QuadMesh` 

6036 

6037 Other Parameters 

6038 ---------------- 

6039 **kwargs 

6040 Additionally, the following arguments are allowed. They are passed 

6041 along to the `~matplotlib.collections.QuadMesh` constructor: 

6042 

6043 %(QuadMesh)s 

6044 

6045 See Also 

6046 -------- 

6047 pcolor : An alternative implementation with slightly different 

6048 features. For a detailed discussion on the differences see 

6049 :ref:`Differences between pcolor() and pcolormesh() 

6050 <differences-pcolor-pcolormesh>`. 

6051 imshow : If *X* and *Y* are each equidistant, `~.Axes.imshow` can be a 

6052 faster alternative. 

6053 

6054 Notes 

6055 ----- 

6056 **Masked arrays** 

6057 

6058 *C* may be a masked array. If ``C[i, j]`` is masked, the corresponding 

6059 quadrilateral will be transparent. Masking of *X* and *Y* is not 

6060 supported. Use `~.Axes.pcolor` if you need this functionality. 

6061 

6062 .. _axes-pcolormesh-grid-orientation: 

6063 

6064 **Grid orientation** 

6065 

6066 The grid orientation follows the standard matrix convention: An array 

6067 *C* with shape (nrows, ncolumns) is plotted with the column number as 

6068 *X* and the row number as *Y*. 

6069 

6070 .. _differences-pcolor-pcolormesh: 

6071 

6072 **Differences between pcolor() and pcolormesh()** 

6073 

6074 Both methods are used to create a pseudocolor plot of a 2-D array 

6075 using quadrilaterals. 

6076 

6077 The main difference lies in the created object and internal data 

6078 handling: 

6079 While `~.Axes.pcolor` returns a `.PolyCollection`, `~.Axes.pcolormesh` 

6080 returns a `.QuadMesh`. The latter is more specialized for the given 

6081 purpose and thus is faster. It should almost always be preferred. 

6082 

6083 There is also a slight difference in the handling of masked arrays. 

6084 Both `~.Axes.pcolor` and `~.Axes.pcolormesh` support masked arrays 

6085 for *C*. However, only `~.Axes.pcolor` supports masked arrays for *X* 

6086 and *Y*. The reason lies in the internal handling of the masked values. 

6087 `~.Axes.pcolor` leaves out the respective polygons from the 

6088 PolyCollection. `~.Axes.pcolormesh` sets the facecolor of the masked 

6089 elements to transparent. You can see the difference when using 

6090 edgecolors. While all edges are drawn irrespective of masking in a 

6091 QuadMesh, the edge between two adjacent masked quadrilaterals in 

6092 `~.Axes.pcolor` is not drawn as the corresponding polygons do not 

6093 exist in the PolyCollection. 

6094 

6095 Another difference is the support of Gouraud shading in 

6096 `~.Axes.pcolormesh`, which is not available with `~.Axes.pcolor`. 

6097 

6098 """ 

6099 shading = shading.lower() 

6100 kwargs.setdefault('edgecolors', 'None') 

6101 

6102 allmatch = (shading == 'gouraud') 

6103 

6104 X, Y, C = self._pcolorargs('pcolormesh', *args, allmatch=allmatch) 

6105 Ny, Nx = X.shape 

6106 X = X.ravel() 

6107 Y = Y.ravel() 

6108 # unit conversion allows e.g. datetime objects as axis values 

6109 self._process_unit_info(xdata=X, ydata=Y, kwargs=kwargs) 

6110 X = self.convert_xunits(X) 

6111 Y = self.convert_yunits(Y) 

6112 

6113 # convert to one dimensional arrays 

6114 C = C.ravel() 

6115 coords = np.column_stack((X, Y)).astype(float, copy=False) 

6116 collection = mcoll.QuadMesh(Nx - 1, Ny - 1, coords, 

6117 antialiased=antialiased, shading=shading, 

6118 **kwargs) 

6119 collection.set_alpha(alpha) 

6120 collection.set_array(C) 

6121 collection.set_cmap(cmap) 

6122 collection.set_norm(norm) 

6123 collection.set_clim(vmin, vmax) 

6124 collection.autoscale_None() 

6125 

6126 self.grid(False) 

6127 

6128 # Transform from native to data coordinates? 

6129 t = collection._transform 

6130 if (not isinstance(t, mtransforms.Transform) and 

6131 hasattr(t, '_as_mpl_transform')): 

6132 t = t._as_mpl_transform(self.axes) 

6133 

6134 if t and any(t.contains_branch_seperately(self.transData)): 

6135 trans_to_data = t - self.transData 

6136 coords = trans_to_data.transform(coords) 

6137 

6138 self.add_collection(collection, autolim=False) 

6139 

6140 minx, miny = np.min(coords, axis=0) 

6141 maxx, maxy = np.max(coords, axis=0) 

6142 collection.sticky_edges.x[:] = [minx, maxx] 

6143 collection.sticky_edges.y[:] = [miny, maxy] 

6144 corners = (minx, miny), (maxx, maxy) 

6145 self.update_datalim(corners) 

6146 self._request_autoscale_view() 

6147 return collection 

6148 

6149 @_preprocess_data() 

6150 @docstring.dedent_interpd 

6151 def pcolorfast(self, *args, alpha=None, norm=None, cmap=None, vmin=None, 

6152 vmax=None, **kwargs): 

6153 """ 

6154 Create a pseudocolor plot with a non-regular rectangular grid. 

6155 

6156 Call signature:: 

6157 

6158 ax.pcolorfast([X, Y], C, /, **kwargs) 

6159 

6160 This method is similar to ~.Axes.pcolor` and `~.Axes.pcolormesh`. 

6161 It's designed to provide the fastest pcolor-type plotting with the 

6162 Agg backend. To achieve this, it uses different algorithms internally 

6163 depending on the complexity of the input grid (regular rectangular, 

6164 non-regular rectangular or arbitrary quadrilateral). 

6165 

6166 .. warning:: 

6167 

6168 This method is experimental. Compared to `~.Axes.pcolor` or 

6169 `~.Axes.pcolormesh` it has some limitations: 

6170 

6171 - It supports only flat shading (no outlines) 

6172 - It lacks support for log scaling of the axes. 

6173 - It does not have a have a pyplot wrapper. 

6174 

6175 Parameters 

6176 ---------- 

6177 C : array-like(M, N) 

6178 The image data. Supported array shapes are: 

6179 

6180 - (M, N): an image with scalar data. The data is visualized 

6181 using a colormap. 

6182 - (M, N, 3): an image with RGB values (0-1 float or 0-255 int). 

6183 - (M, N, 4): an image with RGBA values (0-1 float or 0-255 int), 

6184 i.e. including transparency. 

6185 

6186 The first two dimensions (M, N) define the rows and columns of 

6187 the image. 

6188 

6189 This parameter can only be passed positionally. 

6190 

6191 X, Y : tuple or array-like, default: ``(0, N)``, ``(0, M)`` 

6192 *X* and *Y* are used to specify the coordinates of the 

6193 quadrilaterals. There are different ways to do this: 

6194 

6195 - Use tuples ``X=(xmin, xmax)`` and ``Y=(ymin, ymax)`` to define 

6196 a *uniform rectangular grid*. 

6197 

6198 The tuples define the outer edges of the grid. All individual 

6199 quadrilaterals will be of the same size. This is the fastest 

6200 version. 

6201 

6202 - Use 1D arrays *X*, *Y* to specify a *non-uniform rectangular 

6203 grid*. 

6204 

6205 In this case *X* and *Y* have to be monotonic 1D arrays of length 

6206 *N+1* and *M+1*, specifying the x and y boundaries of the cells. 

6207 

6208 The speed is intermediate. Note: The grid is checked, and if 

6209 found to be uniform the fast version is used. 

6210 

6211 - Use 2D arrays *X*, *Y* if you need an *arbitrary quadrilateral 

6212 grid* (i.e. if the quadrilaterals are not rectangular). 

6213 

6214 In this case *X* and *Y* are 2D arrays with shape (M + 1, N + 1), 

6215 specifying the x and y coordinates of the corners of the colored 

6216 quadrilaterals. 

6217 

6218 This is the most general, but the slowest to render. It may 

6219 produce faster and more compact output using ps, pdf, and 

6220 svg backends, however. 

6221 

6222 These arguments can only be passed positionally. 

6223 

6224 cmap : str or `~matplotlib.colors.Colormap`, optional 

6225 A Colormap instance or registered colormap name. The colormap 

6226 maps the *C* values to colors. Defaults to :rc:`image.cmap`. 

6227 

6228 norm : `~matplotlib.colors.Normalize`, optional 

6229 The Normalize instance scales the data values to the canonical 

6230 colormap range [0, 1] for mapping to colors. By default, the data 

6231 range is mapped to the colorbar range using linear scaling. 

6232 

6233 vmin, vmax : scalar, optional, default: None 

6234 The colorbar range. If *None*, suitable min/max values are 

6235 automatically chosen by the `~.Normalize` instance (defaults to 

6236 the respective min/max values of *C* in case of the default linear 

6237 scaling). 

6238 

6239 alpha : scalar, optional, default: None 

6240 The alpha blending value, between 0 (transparent) and 1 (opaque). 

6241 

6242 snap : bool, optional, default: False 

6243 Whether to snap the mesh to pixel boundaries. 

6244 

6245 Returns 

6246 ------- 

6247 image : `.AxesImage` or `.PcolorImage` or `.QuadMesh` 

6248 The return type depends on the type of grid: 

6249 

6250 - `.AxesImage` for a regular rectangular grid. 

6251 - `.PcolorImage` for a non-regular rectangular grid. 

6252 - `.QuadMesh` for a non-rectangular grid. 

6253 

6254 Notes 

6255 ----- 

6256 .. [notes section required to get data note injection right] 

6257 """ 

6258 

6259 C = args[-1] 

6260 nr, nc = np.shape(C)[:2] 

6261 if len(args) == 1: 

6262 style = "image" 

6263 x = [0, nc] 

6264 y = [0, nr] 

6265 elif len(args) == 3: 

6266 x, y = args[:2] 

6267 x = np.asarray(x) 

6268 y = np.asarray(y) 

6269 if x.ndim == 1 and y.ndim == 1: 

6270 if x.size == 2 and y.size == 2: 

6271 style = "image" 

6272 else: 

6273 dx = np.diff(x) 

6274 dy = np.diff(y) 

6275 if (np.ptp(dx) < 0.01 * np.abs(dx.mean()) and 

6276 np.ptp(dy) < 0.01 * np.abs(dy.mean())): 

6277 style = "image" 

6278 else: 

6279 style = "pcolorimage" 

6280 elif x.ndim == 2 and y.ndim == 2: 

6281 style = "quadmesh" 

6282 else: 

6283 raise TypeError("arguments do not match valid signatures") 

6284 else: 

6285 raise TypeError("need 1 argument or 3 arguments") 

6286 

6287 if style == "quadmesh": 

6288 # data point in each cell is value at lower left corner 

6289 coords = np.stack([x, y], axis=-1) 

6290 if np.ndim(C) == 2: 

6291 qm_kwargs = {"array": np.ma.ravel(C)} 

6292 elif np.ndim(C) == 3: 

6293 qm_kwargs = {"color": np.ma.reshape(C, (-1, C.shape[-1]))} 

6294 else: 

6295 raise ValueError("C must be 2D or 3D") 

6296 collection = mcoll.QuadMesh( 

6297 nc, nr, coords, **qm_kwargs, 

6298 alpha=alpha, cmap=cmap, norm=norm, 

6299 antialiased=False, edgecolors="none") 

6300 self.add_collection(collection, autolim=False) 

6301 xl, xr, yb, yt = x.min(), x.max(), y.min(), y.max() 

6302 ret = collection 

6303 

6304 else: # It's one of the two image styles. 

6305 extent = xl, xr, yb, yt = x[0], x[-1], y[0], y[-1] 

6306 if style == "image": 

6307 im = mimage.AxesImage( 

6308 self, cmap, norm, 

6309 data=C, alpha=alpha, extent=extent, 

6310 interpolation='nearest', origin='lower', 

6311 **kwargs) 

6312 elif style == "pcolorimage": 

6313 im = mimage.PcolorImage( 

6314 self, x, y, C, 

6315 cmap=cmap, norm=norm, alpha=alpha, extent=extent, 

6316 **kwargs) 

6317 self.add_image(im) 

6318 ret = im 

6319 

6320 if vmin is not None or vmax is not None: 

6321 ret.set_clim(vmin, vmax) 

6322 elif np.ndim(C) == 2: # C.ndim == 3 is RGB(A) so doesn't need scaling. 

6323 ret.autoscale_None() 

6324 if ret.get_clip_path() is None: 

6325 # image does not already have clipping set, clip to axes patch 

6326 ret.set_clip_path(self.patch) 

6327 

6328 ret.sticky_edges.x[:] = [xl, xr] 

6329 ret.sticky_edges.y[:] = [yb, yt] 

6330 self.update_datalim(np.array([[xl, yb], [xr, yt]])) 

6331 self._request_autoscale_view(tight=True) 

6332 return ret 

6333 

6334 @_preprocess_data() 

6335 def contour(self, *args, **kwargs): 

6336 kwargs['filled'] = False 

6337 contours = mcontour.QuadContourSet(self, *args, **kwargs) 

6338 self._request_autoscale_view() 

6339 return contours 

6340 contour.__doc__ = mcontour.QuadContourSet._contour_doc 

6341 

6342 @_preprocess_data() 

6343 def contourf(self, *args, **kwargs): 

6344 kwargs['filled'] = True 

6345 contours = mcontour.QuadContourSet(self, *args, **kwargs) 

6346 self._request_autoscale_view() 

6347 return contours 

6348 contourf.__doc__ = mcontour.QuadContourSet._contour_doc 

6349 

6350 def clabel(self, CS, *args, **kwargs): 

6351 return CS.clabel(*args, **kwargs) 

6352 clabel.__doc__ = mcontour.ContourSet.clabel.__doc__ 

6353 

6354 #### Data analysis 

6355 

6356 @_preprocess_data(replace_names=["x", 'weights'], label_namer="x") 

6357 def hist(self, x, bins=None, range=None, density=False, weights=None, 

6358 cumulative=False, bottom=None, histtype='bar', align='mid', 

6359 orientation='vertical', rwidth=None, log=False, 

6360 color=None, label=None, stacked=False, **kwargs): 

6361 """ 

6362 Plot a histogram. 

6363 

6364 Compute and draw the histogram of *x*. The return value is a tuple 

6365 (*n*, *bins*, *patches*) or ([*n0*, *n1*, ...], *bins*, [*patches0*, 

6366 *patches1*,...]) if the input contains multiple data. See the 

6367 documentation of the *weights* parameter to draw a histogram of 

6368 already-binned data. 

6369 

6370 Multiple data can be provided via *x* as a list of datasets 

6371 of potentially different length ([*x0*, *x1*, ...]), or as 

6372 a 2-D ndarray in which each column is a dataset. Note that 

6373 the ndarray form is transposed relative to the list form. 

6374 

6375 Masked arrays are not supported. 

6376 

6377 The *bins*, *range*, *weights*, and *density* parameters behave as in 

6378 `numpy.histogram`. 

6379 

6380 Parameters 

6381 ---------- 

6382 x : (n,) array or sequence of (n,) arrays 

6383 Input values, this takes either a single array or a sequence of 

6384 arrays which are not required to be of the same length. 

6385 

6386 bins : int or sequence or str, optional 

6387 If *bins* is an integer, it defines the number of equal-width bins 

6388 in the range. 

6389 

6390 If *bins* is a sequence, it defines the bin edges, including the 

6391 left edge of the first bin and the right edge of the last bin; 

6392 in this case, bins may be unequally spaced. All but the last 

6393 (righthand-most) bin is half-open. In other words, if *bins* is:: 

6394 

6395 [1, 2, 3, 4] 

6396 

6397 then the first bin is ``[1, 2)`` (including 1, but excluding 2) and 

6398 the second ``[2, 3)``. The last bin, however, is ``[3, 4]``, which 

6399 *includes* 4. 

6400 

6401 If *bins* is a string, it is one of the binning strategies 

6402 supported by `numpy.histogram_bin_edges`: 'auto', 'fd', 'doane', 

6403 'scott', 'stone', 'rice', 'sturges', or 'sqrt'. 

6404 

6405 The default is :rc:`hist.bins`. 

6406 

6407 range : tuple or None, optional 

6408 The lower and upper range of the bins. Lower and upper outliers 

6409 are ignored. If not provided, *range* is ``(x.min(), x.max())``. 

6410 Range has no effect if *bins* is a sequence. 

6411 

6412 If *bins* is a sequence or *range* is specified, autoscaling 

6413 is based on the specified bin range instead of the 

6414 range of x. 

6415 

6416 Default is ``None`` 

6417 

6418 density : bool, optional 

6419 If ``True``, the first element of the return tuple will 

6420 be the counts normalized to form a probability density, i.e., 

6421 the area (or integral) under the histogram will sum to 1. 

6422 This is achieved by dividing the count by the number of 

6423 observations times the bin width and not dividing by the total 

6424 number of observations. If *stacked* is also ``True``, the sum of 

6425 the histograms is normalized to 1. 

6426 

6427 Default is ``False``. 

6428 

6429 weights : (n, ) array-like or None, optional 

6430 An array of weights, of the same shape as *x*. Each value in *x* 

6431 only contributes its associated weight towards the bin count 

6432 (instead of 1). If *normed* or *density* is ``True``, 

6433 the weights are normalized, so that the integral of the density 

6434 over the range remains 1. 

6435 

6436 Default is ``None``. 

6437 

6438 This parameter can be used to draw a histogram of data that has 

6439 already been binned, e.g. using `np.histogram` (by treating each 

6440 bin as a single point with a weight equal to its count) :: 

6441 

6442 counts, bins = np.histogram(data) 

6443 plt.hist(bins[:-1], bins, weights=counts) 

6444 

6445 (or you may alternatively use `~.bar()`). 

6446 

6447 cumulative : bool or -1, optional 

6448 If ``True``, then a histogram is computed where each bin gives the 

6449 counts in that bin plus all bins for smaller values. The last bin 

6450 gives the total number of datapoints. 

6451 

6452 If *density* is also ``True`` then the histogram is normalized such 

6453 that the last bin equals 1. 

6454 

6455 If *cumulative* is a number less than 0 (e.g., -1), the direction 

6456 of accumulation is reversed. In this case, if *density* is also 

6457 ``True``, then the histogram is normalized such that the first bin 

6458 equals 1. 

6459 

6460 bottom : array-like, scalar, or None, default: None 

6461 Location of the bottom of each bin, ie. bins are drawn from 

6462 ``bottom`` to ``bottom + hist(x, bins)`` If a scalar, the bottom 

6463 of each bin is shifted by the same amount. If an array, each bin 

6464 is shifted independently and the length of bottom must match the 

6465 number of bins. If None, defaults to 0. 

6466 

6467 histtype : {'bar', 'barstacked', 'step', 'stepfilled'}, optional 

6468 The type of histogram to draw. 

6469 

6470 - 'bar' is a traditional bar-type histogram. If multiple data 

6471 are given the bars are arranged side by side. 

6472 - 'barstacked' is a bar-type histogram where multiple 

6473 data are stacked on top of each other. 

6474 - 'step' generates a lineplot that is by default unfilled. 

6475 - 'stepfilled' generates a lineplot that is by default filled. 

6476 

6477 Default is 'bar' 

6478 

6479 align : {'left', 'mid', 'right'}, optional 

6480 Controls how the histogram is plotted. 

6481 

6482 - 'left': bars are centered on the left bin edges. 

6483 - 'mid': bars are centered between the bin edges. 

6484 - 'right': bars are centered on the right bin edges. 

6485 

6486 Default is 'mid' 

6487 

6488 orientation : {'horizontal', 'vertical'}, optional 

6489 If 'horizontal', `~matplotlib.pyplot.barh` will be used for 

6490 bar-type histograms and the *bottom* kwarg will be the left edges. 

6491 

6492 rwidth : scalar or None, optional 

6493 The relative width of the bars as a fraction of the bin width. If 

6494 ``None``, automatically compute the width. 

6495 

6496 Ignored if *histtype* is 'step' or 'stepfilled'. 

6497 

6498 Default is ``None`` 

6499 

6500 log : bool, optional 

6501 If ``True``, the histogram axis will be set to a log scale. If 

6502 *log* is ``True`` and *x* is a 1D array, empty bins will be 

6503 filtered out and only the non-empty ``(n, bins, patches)`` 

6504 will be returned. 

6505 

6506 Default is ``False`` 

6507 

6508 color : color or array-like of colors or None, optional 

6509 Color or sequence of colors, one per dataset. Default (``None``) 

6510 uses the standard line color sequence. 

6511 

6512 Default is ``None`` 

6513 

6514 label : str or None, optional 

6515 String, or sequence of strings to match multiple datasets. Bar 

6516 charts yield multiple patches per dataset, but only the first gets 

6517 the label, so that the legend command will work as expected. 

6518 

6519 default is ``None`` 

6520 

6521 stacked : bool, optional 

6522 If ``True``, multiple data are stacked on top of each other If 

6523 ``False`` multiple data are arranged side by side if histtype is 

6524 'bar' or on top of each other if histtype is 'step' 

6525 

6526 Default is ``False`` 

6527 

6528 Returns 

6529 ------- 

6530 n : array or list of arrays 

6531 The values of the histogram bins. See *density* and *weights* for a 

6532 description of the possible semantics. If input *x* is an array, 

6533 then this is an array of length *nbins*. If input is a sequence of 

6534 arrays ``[data1, data2, ...]``, then this is a list of arrays with 

6535 the values of the histograms for each of the arrays in the same 

6536 order. The dtype of the array *n* (or of its element arrays) will 

6537 always be float even if no weighting or normalization is used. 

6538 

6539 bins : array 

6540 The edges of the bins. Length nbins + 1 (nbins left edges and right 

6541 edge of last bin). Always a single array even when multiple data 

6542 sets are passed in. 

6543 

6544 patches : list or list of lists 

6545 Silent list of individual patches used to create the histogram 

6546 or list of such list if multiple input datasets. 

6547 

6548 Other Parameters 

6549 ---------------- 

6550 **kwargs : `~matplotlib.patches.Patch` properties 

6551 

6552 See also 

6553 -------- 

6554 hist2d : 2D histograms 

6555 

6556 """ 

6557 # Avoid shadowing the builtin. 

6558 bin_range = range 

6559 from builtins import range 

6560 

6561 if np.isscalar(x): 

6562 x = [x] 

6563 

6564 if bins is None: 

6565 bins = rcParams['hist.bins'] 

6566 

6567 # Validate string inputs here to avoid cluttering subsequent code. 

6568 cbook._check_in_list(['bar', 'barstacked', 'step', 'stepfilled'], 

6569 histtype=histtype) 

6570 cbook._check_in_list(['left', 'mid', 'right'], align=align) 

6571 cbook._check_in_list(['horizontal', 'vertical'], 

6572 orientation=orientation) 

6573 

6574 if histtype == 'barstacked' and not stacked: 

6575 stacked = True 

6576 

6577 # basic input validation 

6578 input_empty = np.size(x) == 0 

6579 # Massage 'x' for processing. 

6580 x = cbook._reshape_2D(x, 'x') 

6581 nx = len(x) # number of datasets 

6582 

6583 # Process unit information 

6584 # Unit conversion is done individually on each dataset 

6585 self._process_unit_info(xdata=x[0], kwargs=kwargs) 

6586 x = [self.convert_xunits(xi) for xi in x] 

6587 

6588 if bin_range is not None: 

6589 bin_range = self.convert_xunits(bin_range) 

6590 

6591 if not cbook.is_scalar_or_string(bins): 

6592 bins = self.convert_xunits(bins) 

6593 

6594 # We need to do to 'weights' what was done to 'x' 

6595 if weights is not None: 

6596 w = cbook._reshape_2D(weights, 'weights') 

6597 else: 

6598 w = [None] * nx 

6599 

6600 if len(w) != nx: 

6601 raise ValueError('weights should have the same shape as x') 

6602 

6603 for xi, wi in zip(x, w): 

6604 if wi is not None and len(wi) != len(xi): 

6605 raise ValueError( 

6606 'weights should have the same shape as x') 

6607 

6608 if color is None: 

6609 color = [self._get_lines.get_next_color() for i in range(nx)] 

6610 else: 

6611 color = mcolors.to_rgba_array(color) 

6612 if len(color) != nx: 

6613 error_message = ( 

6614 "color kwarg must have one color per data set. %d data " 

6615 "sets and %d colors were provided" % (nx, len(color))) 

6616 raise ValueError(error_message) 

6617 

6618 hist_kwargs = dict() 

6619 

6620 # if the bin_range is not given, compute without nan numpy 

6621 # does not do this for us when guessing the range (but will 

6622 # happily ignore nans when computing the histogram). 

6623 if bin_range is None: 

6624 xmin = np.inf 

6625 xmax = -np.inf 

6626 for xi in x: 

6627 if len(xi): 

6628 # python's min/max ignore nan, 

6629 # np.minnan returns nan for all nan input 

6630 xmin = min(xmin, np.nanmin(xi)) 

6631 xmax = max(xmax, np.nanmax(xi)) 

6632 # make sure we have seen at least one non-nan and finite 

6633 # value before we reset the bin range 

6634 if not np.isnan([xmin, xmax]).any() and not (xmin > xmax): 

6635 bin_range = (xmin, xmax) 

6636 

6637 # If bins are not specified either explicitly or via range, 

6638 # we need to figure out the range required for all datasets, 

6639 # and supply that to np.histogram. 

6640 if not input_empty and len(x) > 1: 

6641 if weights is not None: 

6642 _w = np.concatenate(w) 

6643 else: 

6644 _w = None 

6645 

6646 bins = _histogram_bin_edges(np.concatenate(x), bins, bin_range, _w) 

6647 else: 

6648 hist_kwargs['range'] = bin_range 

6649 

6650 density = bool(density) 

6651 if density and not stacked: 

6652 hist_kwargs['density'] = density 

6653 

6654 # List to store all the top coordinates of the histograms 

6655 tops = [] # Will have shape (n_datasets, n_bins). 

6656 # Loop through datasets 

6657 for i in range(nx): 

6658 # this will automatically overwrite bins, 

6659 # so that each histogram uses the same bins 

6660 m, bins = np.histogram(x[i], bins, weights=w[i], **hist_kwargs) 

6661 tops.append(m) 

6662 tops = np.array(tops, float) # causes problems later if it's an int 

6663 if stacked: 

6664 tops = tops.cumsum(axis=0) 

6665 # If a stacked density plot, normalize so the area of all the 

6666 # stacked histograms together is 1 

6667 if density: 

6668 tops = (tops / np.diff(bins)) / tops[-1].sum() 

6669 if cumulative: 

6670 slc = slice(None) 

6671 if isinstance(cumulative, Number) and cumulative < 0: 

6672 slc = slice(None, None, -1) 

6673 if density: 

6674 tops = (tops * np.diff(bins))[:, slc].cumsum(axis=1)[:, slc] 

6675 else: 

6676 tops = tops[:, slc].cumsum(axis=1)[:, slc] 

6677 

6678 patches = [] 

6679 

6680 # Save autoscale state for later restoration; turn autoscaling 

6681 # off so we can do it all a single time at the end, instead 

6682 # of having it done by bar or fill and then having to be redone. 

6683 _saved_autoscalex = self.get_autoscalex_on() 

6684 _saved_autoscaley = self.get_autoscaley_on() 

6685 self.set_autoscalex_on(False) 

6686 self.set_autoscaley_on(False) 

6687 

6688 if histtype.startswith('bar'): 

6689 

6690 totwidth = np.diff(bins) 

6691 

6692 if rwidth is not None: 

6693 dr = np.clip(rwidth, 0, 1) 

6694 elif (len(tops) > 1 and 

6695 ((not stacked) or rcParams['_internal.classic_mode'])): 

6696 dr = 0.8 

6697 else: 

6698 dr = 1.0 

6699 

6700 if histtype == 'bar' and not stacked: 

6701 width = dr * totwidth / nx 

6702 dw = width 

6703 boffset = -0.5 * dr * totwidth * (1 - 1 / nx) 

6704 elif histtype == 'barstacked' or stacked: 

6705 width = dr * totwidth 

6706 boffset, dw = 0.0, 0.0 

6707 

6708 if align == 'mid': 

6709 boffset += 0.5 * totwidth 

6710 elif align == 'right': 

6711 boffset += totwidth 

6712 

6713 if orientation == 'horizontal': 

6714 _barfunc = self.barh 

6715 bottom_kwarg = 'left' 

6716 else: # orientation == 'vertical' 

6717 _barfunc = self.bar 

6718 bottom_kwarg = 'bottom' 

6719 

6720 for m, c in zip(tops, color): 

6721 if bottom is None: 

6722 bottom = np.zeros(len(m)) 

6723 if stacked: 

6724 height = m - bottom 

6725 else: 

6726 height = m 

6727 patch = _barfunc(bins[:-1]+boffset, height, width, 

6728 align='center', log=log, 

6729 color=c, **{bottom_kwarg: bottom}) 

6730 patches.append(patch) 

6731 if stacked: 

6732 bottom[:] = m 

6733 boffset += dw 

6734 

6735 elif histtype.startswith('step'): 

6736 # these define the perimeter of the polygon 

6737 x = np.zeros(4 * len(bins) - 3) 

6738 y = np.zeros(4 * len(bins) - 3) 

6739 

6740 x[0:2*len(bins)-1:2], x[1:2*len(bins)-1:2] = bins, bins[:-1] 

6741 x[2*len(bins)-1:] = x[1:2*len(bins)-1][::-1] 

6742 

6743 if bottom is None: 

6744 bottom = np.zeros(len(bins) - 1) 

6745 

6746 y[1:2*len(bins)-1:2], y[2:2*len(bins):2] = bottom, bottom 

6747 y[2*len(bins)-1:] = y[1:2*len(bins)-1][::-1] 

6748 

6749 if log: 

6750 if orientation == 'horizontal': 

6751 self.set_xscale('log', nonposx='clip') 

6752 else: # orientation == 'vertical' 

6753 self.set_yscale('log', nonposy='clip') 

6754 

6755 if align == 'left': 

6756 x -= 0.5*(bins[1]-bins[0]) 

6757 elif align == 'right': 

6758 x += 0.5*(bins[1]-bins[0]) 

6759 

6760 # If fill kwarg is set, it will be passed to the patch collection, 

6761 # overriding this 

6762 fill = (histtype == 'stepfilled') 

6763 

6764 xvals, yvals = [], [] 

6765 for m in tops: 

6766 if stacked: 

6767 # starting point for drawing polygon 

6768 y[0] = y[1] 

6769 # top of the previous polygon becomes the bottom 

6770 y[2*len(bins)-1:] = y[1:2*len(bins)-1][::-1] 

6771 # set the top of this polygon 

6772 y[1:2*len(bins)-1:2], y[2:2*len(bins):2] = (m + bottom, 

6773 m + bottom) 

6774 if orientation == 'horizontal': 

6775 xvals.append(y.copy()) 

6776 yvals.append(x.copy()) 

6777 else: 

6778 xvals.append(x.copy()) 

6779 yvals.append(y.copy()) 

6780 

6781 # stepfill is closed, step is not 

6782 split = -1 if fill else 2 * len(bins) 

6783 # add patches in reverse order so that when stacking, 

6784 # items lower in the stack are plotted on top of 

6785 # items higher in the stack 

6786 for x, y, c in reversed(list(zip(xvals, yvals, color))): 

6787 patches.append(self.fill( 

6788 x[:split], y[:split], 

6789 closed=True if fill else None, 

6790 facecolor=c, 

6791 edgecolor=None if fill else c, 

6792 fill=fill if fill else None)) 

6793 for patch_list in patches: 

6794 for patch in patch_list: 

6795 if orientation == 'vertical': 

6796 patch.sticky_edges.y.append(0) 

6797 elif orientation == 'horizontal': 

6798 patch.sticky_edges.x.append(0) 

6799 

6800 # we return patches, so put it back in the expected order 

6801 patches.reverse() 

6802 

6803 self.set_autoscalex_on(_saved_autoscalex) 

6804 self.set_autoscaley_on(_saved_autoscaley) 

6805 self._request_autoscale_view() 

6806 

6807 if label is None: 

6808 labels = [None] 

6809 elif isinstance(label, str): 

6810 labels = [label] 

6811 elif not np.iterable(label): 

6812 labels = [str(label)] 

6813 else: 

6814 labels = [str(lab) for lab in label] 

6815 

6816 for patch, lbl in itertools.zip_longest(patches, labels): 

6817 if patch: 

6818 p = patch[0] 

6819 p.update(kwargs) 

6820 if lbl is not None: 

6821 p.set_label(lbl) 

6822 

6823 for p in patch[1:]: 

6824 p.update(kwargs) 

6825 p.set_label('_nolegend_') 

6826 

6827 if nx == 1: 

6828 return tops[0], bins, cbook.silent_list('Patch', patches[0]) 

6829 else: 

6830 return tops, bins, cbook.silent_list('Lists of Patches', patches) 

6831 

6832 @_preprocess_data(replace_names=["x", "y", "weights"]) 

6833 @cbook._rename_parameter("3.1", "normed", "density") 

6834 def hist2d(self, x, y, bins=10, range=None, density=False, weights=None, 

6835 cmin=None, cmax=None, **kwargs): 

6836 """ 

6837 Make a 2D histogram plot. 

6838 

6839 Parameters 

6840 ---------- 

6841 x, y : array-like, shape (n, ) 

6842 Input values 

6843 

6844 bins : None or int or [int, int] or array-like or [array, array] 

6845 

6846 The bin specification: 

6847 

6848 - If int, the number of bins for the two dimensions 

6849 (nx=ny=bins). 

6850 - If ``[int, int]``, the number of bins in each dimension 

6851 (nx, ny = bins). 

6852 - If array-like, the bin edges for the two dimensions 

6853 (x_edges=y_edges=bins). 

6854 - If ``[array, array]``, the bin edges in each dimension 

6855 (x_edges, y_edges = bins). 

6856 

6857 The default value is 10. 

6858 

6859 range : array-like shape(2, 2), optional, default: None 

6860 The leftmost and rightmost edges of the bins along each dimension 

6861 (if not specified explicitly in the bins parameters): ``[[xmin, 

6862 xmax], [ymin, ymax]]``. All values outside of this range will be 

6863 considered outliers and not tallied in the histogram. 

6864 

6865 density : bool, optional, default: False 

6866 Normalize histogram. *normed* is a deprecated synonym for this 

6867 parameter. 

6868 

6869 weights : array-like, shape (n, ), optional, default: None 

6870 An array of values w_i weighing each sample (x_i, y_i). 

6871 

6872 cmin : scalar, optional, default: None 

6873 All bins that has count less than cmin will not be displayed (set 

6874 to NaN before passing to imshow) and these count values in the 

6875 return value count histogram will also be set to nan upon return. 

6876 

6877 cmax : scalar, optional, default: None 

6878 All bins that has count more than cmax will not be displayed (set 

6879 to NaN before passing to imshow) and these count values in the 

6880 return value count histogram will also be set to nan upon return. 

6881 

6882 Returns 

6883 ------- 

6884 h : 2D array 

6885 The bi-dimensional histogram of samples x and y. Values in x are 

6886 histogrammed along the first dimension and values in y are 

6887 histogrammed along the second dimension. 

6888 xedges : 1D array 

6889 The bin edges along the x axis. 

6890 yedges : 1D array 

6891 The bin edges along the y axis. 

6892 image : `~.matplotlib.collections.QuadMesh` 

6893 

6894 Other Parameters 

6895 ---------------- 

6896 cmap : Colormap or str, optional 

6897 A `.colors.Colormap` instance. If not set, use rc settings. 

6898 

6899 norm : Normalize, optional 

6900 A `.colors.Normalize` instance is used to 

6901 scale luminance data to ``[0, 1]``. If not set, defaults to 

6902 `.colors.Normalize()`. 

6903 

6904 vmin/vmax : None or scalar, optional 

6905 Arguments passed to the `~.colors.Normalize` instance. 

6906 

6907 alpha : ``0 <= scalar <= 1`` or ``None``, optional 

6908 The alpha blending value. 

6909 

6910 See also 

6911 -------- 

6912 hist : 1D histogram plotting 

6913 

6914 Notes 

6915 ----- 

6916 - Currently ``hist2d`` calculates its own axis limits, and any limits 

6917 previously set are ignored. 

6918 - Rendering the histogram with a logarithmic color scale is 

6919 accomplished by passing a `.colors.LogNorm` instance to the *norm* 

6920 keyword argument. Likewise, power-law normalization (similar 

6921 in effect to gamma correction) can be accomplished with 

6922 `.colors.PowerNorm`. 

6923 """ 

6924 

6925 h, xedges, yedges = np.histogram2d(x, y, bins=bins, range=range, 

6926 normed=density, weights=weights) 

6927 

6928 if cmin is not None: 

6929 h[h < cmin] = None 

6930 if cmax is not None: 

6931 h[h > cmax] = None 

6932 

6933 pc = self.pcolormesh(xedges, yedges, h.T, **kwargs) 

6934 self.set_xlim(xedges[0], xedges[-1]) 

6935 self.set_ylim(yedges[0], yedges[-1]) 

6936 

6937 return h, xedges, yedges, pc 

6938 

6939 @_preprocess_data(replace_names=["x"]) 

6940 @docstring.dedent_interpd 

6941 def psd(self, x, NFFT=None, Fs=None, Fc=None, detrend=None, 

6942 window=None, noverlap=None, pad_to=None, 

6943 sides=None, scale_by_freq=None, return_line=None, **kwargs): 

6944 r""" 

6945 Plot the power spectral density. 

6946 

6947 The power spectral density :math:`P_{xx}` by Welch's average 

6948 periodogram method. The vector *x* is divided into *NFFT* length 

6949 segments. Each segment is detrended by function *detrend* and 

6950 windowed by function *window*. *noverlap* gives the length of 

6951 the overlap between segments. The :math:`|\mathrm{fft}(i)|^2` 

6952 of each segment :math:`i` are averaged to compute :math:`P_{xx}`, 

6953 with a scaling to correct for power loss due to windowing. 

6954 

6955 If len(*x*) < *NFFT*, it will be zero padded to *NFFT*. 

6956 

6957 Parameters 

6958 ---------- 

6959 x : 1-D array or sequence 

6960 Array or sequence containing the data 

6961 

6962 %(Spectral)s 

6963 

6964 %(PSD)s 

6965 

6966 noverlap : int 

6967 The number of points of overlap between segments. 

6968 The default value is 0 (no overlap). 

6969 

6970 Fc : int 

6971 The center frequency of *x* (defaults to 0), which offsets 

6972 the x extents of the plot to reflect the frequency range used 

6973 when a signal is acquired and then filtered and downsampled to 

6974 baseband. 

6975 

6976 return_line : bool 

6977 Whether to include the line object plotted in the returned values. 

6978 Default is False. 

6979 

6980 Returns 

6981 ------- 

6982 Pxx : 1-D array 

6983 The values for the power spectrum `P_{xx}` before scaling 

6984 (real valued). 

6985 

6986 freqs : 1-D array 

6987 The frequencies corresponding to the elements in *Pxx*. 

6988 

6989 line : `~matplotlib.lines.Line2D` 

6990 The line created by this function. 

6991 Only returned if *return_line* is True. 

6992 

6993 Other Parameters 

6994 ---------------- 

6995 **kwargs 

6996 Keyword arguments control the `.Line2D` properties: 

6997 

6998 %(_Line2D_docstr)s 

6999 

7000 See Also 

7001 -------- 

7002 :func:`specgram` 

7003 :func:`specgram` differs in the default overlap; in not returning 

7004 the mean of the segment periodograms; in returning the times of the 

7005 segments; and in plotting a colormap instead of a line. 

7006 

7007 :func:`magnitude_spectrum` 

7008 :func:`magnitude_spectrum` plots the magnitude spectrum. 

7009 

7010 :func:`csd` 

7011 :func:`csd` plots the spectral density between two signals. 

7012 

7013 Notes 

7014 ----- 

7015 For plotting, the power is plotted as 

7016 :math:`10\log_{10}(P_{xx})` for decibels, though *Pxx* itself 

7017 is returned. 

7018 

7019 References 

7020 ---------- 

7021 Bendat & Piersol -- Random Data: Analysis and Measurement Procedures, 

7022 John Wiley & Sons (1986) 

7023 """ 

7024 if Fc is None: 

7025 Fc = 0 

7026 

7027 pxx, freqs = mlab.psd(x=x, NFFT=NFFT, Fs=Fs, detrend=detrend, 

7028 window=window, noverlap=noverlap, pad_to=pad_to, 

7029 sides=sides, scale_by_freq=scale_by_freq) 

7030 freqs += Fc 

7031 

7032 if scale_by_freq in (None, True): 

7033 psd_units = 'dB/Hz' 

7034 else: 

7035 psd_units = 'dB' 

7036 

7037 line = self.plot(freqs, 10 * np.log10(pxx), **kwargs) 

7038 self.set_xlabel('Frequency') 

7039 self.set_ylabel('Power Spectral Density (%s)' % psd_units) 

7040 self.grid(True) 

7041 vmin, vmax = self.viewLim.intervaly 

7042 intv = vmax - vmin 

7043 logi = int(np.log10(intv)) 

7044 if logi == 0: 

7045 logi = .1 

7046 step = 10 * logi 

7047 ticks = np.arange(math.floor(vmin), math.ceil(vmax) + 1, step) 

7048 self.set_yticks(ticks) 

7049 

7050 if return_line is None or not return_line: 

7051 return pxx, freqs 

7052 else: 

7053 return pxx, freqs, line 

7054 

7055 @_preprocess_data(replace_names=["x", "y"], label_namer="y") 

7056 @docstring.dedent_interpd 

7057 def csd(self, x, y, NFFT=None, Fs=None, Fc=None, detrend=None, 

7058 window=None, noverlap=None, pad_to=None, 

7059 sides=None, scale_by_freq=None, return_line=None, **kwargs): 

7060 r""" 

7061 Plot the cross-spectral density. 

7062 

7063 The cross spectral density :math:`P_{xy}` by Welch's average 

7064 periodogram method. The vectors *x* and *y* are divided into 

7065 *NFFT* length segments. Each segment is detrended by function 

7066 *detrend* and windowed by function *window*. *noverlap* gives 

7067 the length of the overlap between segments. The product of 

7068 the direct FFTs of *x* and *y* are averaged over each segment 

7069 to compute :math:`P_{xy}`, with a scaling to correct for power 

7070 loss due to windowing. 

7071 

7072 If len(*x*) < *NFFT* or len(*y*) < *NFFT*, they will be zero 

7073 padded to *NFFT*. 

7074 

7075 Parameters 

7076 ---------- 

7077 x, y : 1-D arrays or sequences 

7078 Arrays or sequences containing the data. 

7079 

7080 %(Spectral)s 

7081 

7082 %(PSD)s 

7083 

7084 noverlap : int 

7085 The number of points of overlap between segments. 

7086 The default value is 0 (no overlap). 

7087 

7088 Fc : int 

7089 The center frequency of *x* (defaults to 0), which offsets 

7090 the x extents of the plot to reflect the frequency range used 

7091 when a signal is acquired and then filtered and downsampled to 

7092 baseband. 

7093 

7094 return_line : bool 

7095 Whether to include the line object plotted in the returned values. 

7096 Default is False. 

7097 

7098 Returns 

7099 ------- 

7100 Pxy : 1-D array 

7101 The values for the cross spectrum `P_{xy}` before scaling 

7102 (complex valued). 

7103 

7104 freqs : 1-D array 

7105 The frequencies corresponding to the elements in *Pxy*. 

7106 

7107 line : `~matplotlib.lines.Line2D` 

7108 The line created by this function. 

7109 Only returned if *return_line* is True. 

7110 

7111 Other Parameters 

7112 ---------------- 

7113 **kwargs 

7114 Keyword arguments control the `.Line2D` properties: 

7115 

7116 %(_Line2D_docstr)s 

7117 

7118 See Also 

7119 -------- 

7120 :func:`psd` 

7121 :func:`psd` is the equivalent to setting y=x. 

7122 

7123 Notes 

7124 ----- 

7125 For plotting, the power is plotted as 

7126 :math:`10 \log_{10}(P_{xy})` for decibels, though `P_{xy}` itself 

7127 is returned. 

7128 

7129 References 

7130 ---------- 

7131 Bendat & Piersol -- Random Data: Analysis and Measurement Procedures, 

7132 John Wiley & Sons (1986) 

7133 """ 

7134 if Fc is None: 

7135 Fc = 0 

7136 

7137 pxy, freqs = mlab.csd(x=x, y=y, NFFT=NFFT, Fs=Fs, detrend=detrend, 

7138 window=window, noverlap=noverlap, pad_to=pad_to, 

7139 sides=sides, scale_by_freq=scale_by_freq) 

7140 # pxy is complex 

7141 freqs += Fc 

7142 

7143 line = self.plot(freqs, 10 * np.log10(np.abs(pxy)), **kwargs) 

7144 self.set_xlabel('Frequency') 

7145 self.set_ylabel('Cross Spectrum Magnitude (dB)') 

7146 self.grid(True) 

7147 vmin, vmax = self.viewLim.intervaly 

7148 

7149 intv = vmax - vmin 

7150 step = 10 * int(np.log10(intv)) 

7151 

7152 ticks = np.arange(math.floor(vmin), math.ceil(vmax) + 1, step) 

7153 self.set_yticks(ticks) 

7154 

7155 if return_line is None or not return_line: 

7156 return pxy, freqs 

7157 else: 

7158 return pxy, freqs, line 

7159 

7160 @_preprocess_data(replace_names=["x"]) 

7161 @docstring.dedent_interpd 

7162 def magnitude_spectrum(self, x, Fs=None, Fc=None, window=None, 

7163 pad_to=None, sides=None, scale=None, 

7164 **kwargs): 

7165 """ 

7166 Plot the magnitude spectrum. 

7167 

7168 Compute the magnitude spectrum of *x*. Data is padded to a 

7169 length of *pad_to* and the windowing function *window* is applied to 

7170 the signal. 

7171 

7172 Parameters 

7173 ---------- 

7174 x : 1-D array or sequence 

7175 Array or sequence containing the data. 

7176 

7177 %(Spectral)s 

7178 

7179 %(Single_Spectrum)s 

7180 

7181 scale : {'default', 'linear', 'dB'} 

7182 The scaling of the values in the *spec*. 'linear' is no scaling. 

7183 'dB' returns the values in dB scale, i.e., the dB amplitude 

7184 (20 * log10). 'default' is 'linear'. 

7185 

7186 Fc : int 

7187 The center frequency of *x* (defaults to 0), which offsets 

7188 the x extents of the plot to reflect the frequency range used 

7189 when a signal is acquired and then filtered and downsampled to 

7190 baseband. 

7191 

7192 Returns 

7193 ------- 

7194 spectrum : 1-D array 

7195 The values for the magnitude spectrum before scaling (real valued). 

7196 

7197 freqs : 1-D array 

7198 The frequencies corresponding to the elements in *spectrum*. 

7199 

7200 line : `~matplotlib.lines.Line2D` 

7201 The line created by this function. 

7202 

7203 Other Parameters 

7204 ---------------- 

7205 **kwargs 

7206 Keyword arguments control the `.Line2D` properties: 

7207 

7208 %(_Line2D_docstr)s 

7209 

7210 See Also 

7211 -------- 

7212 :func:`psd` 

7213 :func:`psd` plots the power spectral density.`. 

7214 

7215 :func:`angle_spectrum` 

7216 :func:`angle_spectrum` plots the angles of the corresponding 

7217 frequencies. 

7218 

7219 :func:`phase_spectrum` 

7220 :func:`phase_spectrum` plots the phase (unwrapped angle) of the 

7221 corresponding frequencies. 

7222 

7223 :func:`specgram` 

7224 :func:`specgram` can plot the magnitude spectrum of segments within 

7225 the signal in a colormap. 

7226 

7227 """ 

7228 if Fc is None: 

7229 Fc = 0 

7230 

7231 if scale is None or scale == 'default': 

7232 scale = 'linear' 

7233 

7234 spec, freqs = mlab.magnitude_spectrum(x=x, Fs=Fs, window=window, 

7235 pad_to=pad_to, sides=sides) 

7236 freqs += Fc 

7237 

7238 if scale == 'linear': 

7239 Z = spec 

7240 yunits = 'energy' 

7241 elif scale == 'dB': 

7242 Z = 20. * np.log10(spec) 

7243 yunits = 'dB' 

7244 else: 

7245 raise ValueError('Unknown scale %s', scale) 

7246 

7247 lines = self.plot(freqs, Z, **kwargs) 

7248 self.set_xlabel('Frequency') 

7249 self.set_ylabel('Magnitude (%s)' % yunits) 

7250 

7251 return spec, freqs, lines[0] 

7252 

7253 @_preprocess_data(replace_names=["x"]) 

7254 @docstring.dedent_interpd 

7255 def angle_spectrum(self, x, Fs=None, Fc=None, window=None, 

7256 pad_to=None, sides=None, **kwargs): 

7257 """ 

7258 Plot the angle spectrum. 

7259 

7260 Compute the angle spectrum (wrapped phase spectrum) of *x*. 

7261 Data is padded to a length of *pad_to* and the windowing function 

7262 *window* is applied to the signal. 

7263 

7264 Parameters 

7265 ---------- 

7266 x : 1-D array or sequence 

7267 Array or sequence containing the data. 

7268 

7269 %(Spectral)s 

7270 

7271 %(Single_Spectrum)s 

7272 

7273 Fc : int 

7274 The center frequency of *x* (defaults to 0), which offsets 

7275 the x extents of the plot to reflect the frequency range used 

7276 when a signal is acquired and then filtered and downsampled to 

7277 baseband. 

7278 

7279 Returns 

7280 ------- 

7281 spectrum : 1-D array 

7282 The values for the angle spectrum in radians (real valued). 

7283 

7284 freqs : 1-D array 

7285 The frequencies corresponding to the elements in *spectrum*. 

7286 

7287 line : `~matplotlib.lines.Line2D` 

7288 The line created by this function. 

7289 

7290 Other Parameters 

7291 ---------------- 

7292 **kwargs 

7293 Keyword arguments control the `.Line2D` properties: 

7294 

7295 %(_Line2D_docstr)s 

7296 

7297 See Also 

7298 -------- 

7299 :func:`magnitude_spectrum` 

7300 :func:`angle_spectrum` plots the magnitudes of the corresponding 

7301 frequencies. 

7302 

7303 :func:`phase_spectrum` 

7304 :func:`phase_spectrum` plots the unwrapped version of this 

7305 function. 

7306 

7307 :func:`specgram` 

7308 :func:`specgram` can plot the angle spectrum of segments within the 

7309 signal in a colormap. 

7310 

7311 """ 

7312 if Fc is None: 

7313 Fc = 0 

7314 

7315 spec, freqs = mlab.angle_spectrum(x=x, Fs=Fs, window=window, 

7316 pad_to=pad_to, sides=sides) 

7317 freqs += Fc 

7318 

7319 lines = self.plot(freqs, spec, **kwargs) 

7320 self.set_xlabel('Frequency') 

7321 self.set_ylabel('Angle (radians)') 

7322 

7323 return spec, freqs, lines[0] 

7324 

7325 @_preprocess_data(replace_names=["x"]) 

7326 @docstring.dedent_interpd 

7327 def phase_spectrum(self, x, Fs=None, Fc=None, window=None, 

7328 pad_to=None, sides=None, **kwargs): 

7329 """ 

7330 Plot the phase spectrum. 

7331 

7332 Compute the phase spectrum (unwrapped angle spectrum) of *x*. 

7333 Data is padded to a length of *pad_to* and the windowing function 

7334 *window* is applied to the signal. 

7335 

7336 Parameters 

7337 ---------- 

7338 x : 1-D array or sequence 

7339 Array or sequence containing the data 

7340 

7341 %(Spectral)s 

7342 

7343 %(Single_Spectrum)s 

7344 

7345 Fc : int 

7346 The center frequency of *x* (defaults to 0), which offsets 

7347 the x extents of the plot to reflect the frequency range used 

7348 when a signal is acquired and then filtered and downsampled to 

7349 baseband. 

7350 

7351 Returns 

7352 ------- 

7353 spectrum : 1-D array 

7354 The values for the phase spectrum in radians (real valued). 

7355 

7356 freqs : 1-D array 

7357 The frequencies corresponding to the elements in *spectrum*. 

7358 

7359 line : `~matplotlib.lines.Line2D` 

7360 The line created by this function. 

7361 

7362 Other Parameters 

7363 ---------------- 

7364 **kwargs 

7365 Keyword arguments control the `.Line2D` properties: 

7366 

7367 %(_Line2D_docstr)s 

7368 

7369 See Also 

7370 -------- 

7371 :func:`magnitude_spectrum` 

7372 :func:`magnitude_spectrum` plots the magnitudes of the 

7373 corresponding frequencies. 

7374 

7375 :func:`angle_spectrum` 

7376 :func:`angle_spectrum` plots the wrapped version of this function. 

7377 

7378 :func:`specgram` 

7379 :func:`specgram` can plot the phase spectrum of segments within the 

7380 signal in a colormap. 

7381 

7382 """ 

7383 if Fc is None: 

7384 Fc = 0 

7385 

7386 spec, freqs = mlab.phase_spectrum(x=x, Fs=Fs, window=window, 

7387 pad_to=pad_to, sides=sides) 

7388 freqs += Fc 

7389 

7390 lines = self.plot(freqs, spec, **kwargs) 

7391 self.set_xlabel('Frequency') 

7392 self.set_ylabel('Phase (radians)') 

7393 

7394 return spec, freqs, lines[0] 

7395 

7396 @_preprocess_data(replace_names=["x", "y"]) 

7397 @docstring.dedent_interpd 

7398 def cohere(self, x, y, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none, 

7399 window=mlab.window_hanning, noverlap=0, pad_to=None, 

7400 sides='default', scale_by_freq=None, **kwargs): 

7401 r""" 

7402 Plot the coherence between *x* and *y*. 

7403 

7404 Plot the coherence between *x* and *y*. Coherence is the 

7405 normalized cross spectral density: 

7406 

7407 .. math:: 

7408 

7409 C_{xy} = \frac{|P_{xy}|^2}{P_{xx}P_{yy}} 

7410 

7411 Parameters 

7412 ---------- 

7413 %(Spectral)s 

7414 

7415 %(PSD)s 

7416 

7417 noverlap : int 

7418 The number of points of overlap between blocks. The 

7419 default value is 0 (no overlap). 

7420 

7421 Fc : int 

7422 The center frequency of *x* (defaults to 0), which offsets 

7423 the x extents of the plot to reflect the frequency range used 

7424 when a signal is acquired and then filtered and downsampled to 

7425 baseband. 

7426 

7427 

7428 Returns 

7429 ------- 

7430 Cxy : 1-D array 

7431 The coherence vector. 

7432 

7433 freqs : 1-D array 

7434 The frequencies for the elements in *Cxy*. 

7435 

7436 Other Parameters 

7437 ---------------- 

7438 **kwargs 

7439 Keyword arguments control the `.Line2D` properties: 

7440 

7441 %(_Line2D_docstr)s 

7442 

7443 References 

7444 ---------- 

7445 Bendat & Piersol -- Random Data: Analysis and Measurement Procedures, 

7446 John Wiley & Sons (1986) 

7447 """ 

7448 cxy, freqs = mlab.cohere(x=x, y=y, NFFT=NFFT, Fs=Fs, detrend=detrend, 

7449 window=window, noverlap=noverlap, 

7450 scale_by_freq=scale_by_freq) 

7451 freqs += Fc 

7452 

7453 self.plot(freqs, cxy, **kwargs) 

7454 self.set_xlabel('Frequency') 

7455 self.set_ylabel('Coherence') 

7456 self.grid(True) 

7457 

7458 return cxy, freqs 

7459 

7460 @_preprocess_data(replace_names=["x"]) 

7461 @docstring.dedent_interpd 

7462 def specgram(self, x, NFFT=None, Fs=None, Fc=None, detrend=None, 

7463 window=None, noverlap=None, 

7464 cmap=None, xextent=None, pad_to=None, sides=None, 

7465 scale_by_freq=None, mode=None, scale=None, 

7466 vmin=None, vmax=None, **kwargs): 

7467 """ 

7468 Plot a spectrogram. 

7469 

7470 Compute and plot a spectrogram of data in *x*. Data are split into 

7471 *NFFT* length segments and the spectrum of each section is 

7472 computed. The windowing function *window* is applied to each 

7473 segment, and the amount of overlap of each segment is 

7474 specified with *noverlap*. The spectrogram is plotted as a colormap 

7475 (using imshow). 

7476 

7477 Parameters 

7478 ---------- 

7479 x : 1-D array or sequence 

7480 Array or sequence containing the data. 

7481 

7482 %(Spectral)s 

7483 

7484 %(PSD)s 

7485 

7486 mode : {'default', 'psd', 'magnitude', 'angle', 'phase'} 

7487 What sort of spectrum to use. Default is 'psd', which takes the 

7488 power spectral density. 'magnitude' returns the magnitude 

7489 spectrum. 'angle' returns the phase spectrum without unwrapping. 

7490 'phase' returns the phase spectrum with unwrapping. 

7491 

7492 noverlap : int 

7493 The number of points of overlap between blocks. The 

7494 default value is 128. 

7495 

7496 scale : {'default', 'linear', 'dB'} 

7497 The scaling of the values in the *spec*. 'linear' is no scaling. 

7498 'dB' returns the values in dB scale. When *mode* is 'psd', 

7499 this is dB power (10 * log10). Otherwise this is dB amplitude 

7500 (20 * log10). 'default' is 'dB' if *mode* is 'psd' or 

7501 'magnitude' and 'linear' otherwise. This must be 'linear' 

7502 if *mode* is 'angle' or 'phase'. 

7503 

7504 Fc : int 

7505 The center frequency of *x* (defaults to 0), which offsets 

7506 the x extents of the plot to reflect the frequency range used 

7507 when a signal is acquired and then filtered and downsampled to 

7508 baseband. 

7509 

7510 cmap 

7511 A :class:`matplotlib.colors.Colormap` instance; if *None*, use 

7512 default determined by rc 

7513 

7514 xextent : *None* or (xmin, xmax) 

7515 The image extent along the x-axis. The default sets *xmin* to the 

7516 left border of the first bin (*spectrum* column) and *xmax* to the 

7517 right border of the last bin. Note that for *noverlap>0* the width 

7518 of the bins is smaller than those of the segments. 

7519 

7520 **kwargs 

7521 Additional keyword arguments are passed on to imshow which makes 

7522 the specgram image. 

7523 

7524 Returns 

7525 ------- 

7526 spectrum : 2-D array 

7527 Columns are the periodograms of successive segments. 

7528 

7529 freqs : 1-D array 

7530 The frequencies corresponding to the rows in *spectrum*. 

7531 

7532 t : 1-D array 

7533 The times corresponding to midpoints of segments (i.e., the columns 

7534 in *spectrum*). 

7535 

7536 im : instance of class :class:`~matplotlib.image.AxesImage` 

7537 The image created by imshow containing the spectrogram 

7538 

7539 See Also 

7540 -------- 

7541 :func:`psd` 

7542 :func:`psd` differs in the default overlap; in returning the mean 

7543 of the segment periodograms; in not returning times; and in 

7544 generating a line plot instead of colormap. 

7545 

7546 :func:`magnitude_spectrum` 

7547 A single spectrum, similar to having a single segment when *mode* 

7548 is 'magnitude'. Plots a line instead of a colormap. 

7549 

7550 :func:`angle_spectrum` 

7551 A single spectrum, similar to having a single segment when *mode* 

7552 is 'angle'. Plots a line instead of a colormap. 

7553 

7554 :func:`phase_spectrum` 

7555 A single spectrum, similar to having a single segment when *mode* 

7556 is 'phase'. Plots a line instead of a colormap. 

7557 

7558 Notes 

7559 ----- 

7560 The parameters *detrend* and *scale_by_freq* do only apply when *mode* 

7561 is set to 'psd'. 

7562 """ 

7563 if NFFT is None: 

7564 NFFT = 256 # same default as in mlab.specgram() 

7565 if Fc is None: 

7566 Fc = 0 # same default as in mlab._spectral_helper() 

7567 if noverlap is None: 

7568 noverlap = 128 # same default as in mlab.specgram() 

7569 

7570 if mode == 'complex': 

7571 raise ValueError('Cannot plot a complex specgram') 

7572 

7573 if scale is None or scale == 'default': 

7574 if mode in ['angle', 'phase']: 

7575 scale = 'linear' 

7576 else: 

7577 scale = 'dB' 

7578 elif mode in ['angle', 'phase'] and scale == 'dB': 

7579 raise ValueError('Cannot use dB scale with angle or phase mode') 

7580 

7581 spec, freqs, t = mlab.specgram(x=x, NFFT=NFFT, Fs=Fs, 

7582 detrend=detrend, window=window, 

7583 noverlap=noverlap, pad_to=pad_to, 

7584 sides=sides, 

7585 scale_by_freq=scale_by_freq, 

7586 mode=mode) 

7587 

7588 if scale == 'linear': 

7589 Z = spec 

7590 elif scale == 'dB': 

7591 if mode is None or mode == 'default' or mode == 'psd': 

7592 Z = 10. * np.log10(spec) 

7593 else: 

7594 Z = 20. * np.log10(spec) 

7595 else: 

7596 raise ValueError('Unknown scale %s', scale) 

7597 

7598 Z = np.flipud(Z) 

7599 

7600 if xextent is None: 

7601 # padding is needed for first and last segment: 

7602 pad_xextent = (NFFT-noverlap) / Fs / 2 

7603 xextent = np.min(t) - pad_xextent, np.max(t) + pad_xextent 

7604 xmin, xmax = xextent 

7605 freqs += Fc 

7606 extent = xmin, xmax, freqs[0], freqs[-1] 

7607 im = self.imshow(Z, cmap, extent=extent, vmin=vmin, vmax=vmax, 

7608 **kwargs) 

7609 self.axis('auto') 

7610 

7611 return spec, freqs, t, im 

7612 

7613 @docstring.dedent_interpd 

7614 def spy(self, Z, precision=0, marker=None, markersize=None, 

7615 aspect='equal', origin="upper", **kwargs): 

7616 """ 

7617 Plot the sparsity pattern of a 2D array. 

7618 

7619 This visualizes the non-zero values of the array. 

7620 

7621 Two plotting styles are available: image and marker. Both 

7622 are available for full arrays, but only the marker style 

7623 works for `scipy.sparse.spmatrix` instances. 

7624 

7625 **Image style** 

7626 

7627 If *marker* and *markersize* are *None*, `~.Axes.imshow` is used. Any 

7628 extra remaining keyword arguments are passed to this method. 

7629 

7630 **Marker style** 

7631 

7632 If *Z* is a `scipy.sparse.spmatrix` or *marker* or *markersize* are 

7633 *None*, a `.Line2D` object will be returned with the value of marker 

7634 determining the marker type, and any remaining keyword arguments 

7635 passed to `~.Axes.plot`. 

7636 

7637 Parameters 

7638 ---------- 

7639 Z : array-like (M, N) 

7640 The array to be plotted. 

7641 

7642 precision : float or 'present', optional, default: 0 

7643 If *precision* is 0, any non-zero value will be plotted. Otherwise, 

7644 values of :math:`|Z| > precision` will be plotted. 

7645 

7646 For :class:`scipy.sparse.spmatrix` instances, you can also 

7647 pass 'present'. In this case any value present in the array 

7648 will be plotted, even if it is identically zero. 

7649 

7650 origin : {'upper', 'lower'}, optional 

7651 Place the [0, 0] index of the array in the upper left or lower left 

7652 corner of the axes. The convention 'upper' is typically used for 

7653 matrices and images. 

7654 If not given, :rc:`image.origin` is used, defaulting to 'upper'. 

7655 

7656 

7657 aspect : {'equal', 'auto', None} or float, optional 

7658 Controls the aspect ratio of the axes. The aspect is of particular 

7659 relevance for images since it may distort the image, i.e. pixel 

7660 will not be square. 

7661 

7662 This parameter is a shortcut for explicitly calling 

7663 `.Axes.set_aspect`. See there for further details. 

7664 

7665 - 'equal': Ensures an aspect ratio of 1. Pixels will be square. 

7666 - 'auto': The axes is kept fixed and the aspect is adjusted so 

7667 that the data fit in the axes. In general, this will result in 

7668 non-square pixels. 

7669 - *None*: Use :rc:`image.aspect`. 

7670 

7671 Default: 'equal' 

7672 

7673 Returns 

7674 ------- 

7675 ret : `~matplotlib.image.AxesImage` or `.Line2D` 

7676 The return type depends on the plotting style (see above). 

7677 

7678 Other Parameters 

7679 ---------------- 

7680 **kwargs 

7681 The supported additional parameters depend on the plotting style. 

7682 

7683 For the image style, you can pass the following additional 

7684 parameters of `~.Axes.imshow`: 

7685 

7686 - *cmap* 

7687 - *alpha* 

7688 - *url* 

7689 - any `.Artist` properties (passed on to the `.AxesImage`) 

7690 

7691 For the marker style, you can pass any `.Line2D` property except 

7692 for *linestyle*: 

7693 

7694 %(_Line2D_docstr)s 

7695 """ 

7696 if marker is None and markersize is None and hasattr(Z, 'tocoo'): 

7697 marker = 's' 

7698 if marker is None and markersize is None: 

7699 Z = np.asarray(Z) 

7700 mask = np.abs(Z) > precision 

7701 

7702 if 'cmap' not in kwargs: 

7703 kwargs['cmap'] = mcolors.ListedColormap(['w', 'k'], 

7704 name='binary') 

7705 if 'interpolation' in kwargs: 

7706 raise TypeError( 

7707 "spy() got an unexpected keyword argument 'interpolation'") 

7708 ret = self.imshow(mask, interpolation='nearest', aspect=aspect, 

7709 origin=origin, **kwargs) 

7710 else: 

7711 if hasattr(Z, 'tocoo'): 

7712 c = Z.tocoo() 

7713 if precision == 'present': 

7714 y = c.row 

7715 x = c.col 

7716 else: 

7717 nonzero = np.abs(c.data) > precision 

7718 y = c.row[nonzero] 

7719 x = c.col[nonzero] 

7720 else: 

7721 Z = np.asarray(Z) 

7722 nonzero = np.abs(Z) > precision 

7723 y, x = np.nonzero(nonzero) 

7724 if marker is None: 

7725 marker = 's' 

7726 if markersize is None: 

7727 markersize = 10 

7728 if 'linestyle' in kwargs: 

7729 raise TypeError( 

7730 "spy() got an unexpected keyword argument 'linestyle'") 

7731 marks = mlines.Line2D(x, y, linestyle='None', 

7732 marker=marker, markersize=markersize, **kwargs) 

7733 self.add_line(marks) 

7734 nr, nc = Z.shape 

7735 self.set_xlim(-0.5, nc - 0.5) 

7736 self.set_ylim(nr - 0.5, -0.5) 

7737 self.set_aspect(aspect) 

7738 ret = marks 

7739 self.title.set_y(1.05) 

7740 self.xaxis.tick_top() 

7741 self.xaxis.set_ticks_position('both') 

7742 self.xaxis.set_major_locator(mticker.MaxNLocator(nbins=9, 

7743 steps=[1, 2, 5, 10], 

7744 integer=True)) 

7745 self.yaxis.set_major_locator(mticker.MaxNLocator(nbins=9, 

7746 steps=[1, 2, 5, 10], 

7747 integer=True)) 

7748 return ret 

7749 

7750 def matshow(self, Z, **kwargs): 

7751 """ 

7752 Plot the values of a 2D matrix or array as color-coded image. 

7753 

7754 The matrix will be shown the way it would be printed, with the first 

7755 row at the top. Row and column numbering is zero-based. 

7756 

7757 Parameters 

7758 ---------- 

7759 Z : array-like(M, N) 

7760 The matrix to be displayed. 

7761 

7762 Returns 

7763 ------- 

7764 image : `~matplotlib.image.AxesImage` 

7765 

7766 Other Parameters 

7767 ---------------- 

7768 **kwargs : `~matplotlib.axes.Axes.imshow` arguments 

7769 

7770 See Also 

7771 -------- 

7772 imshow : More general function to plot data on a 2D regular raster. 

7773 

7774 Notes 

7775 ----- 

7776 This is just a convenience function wrapping `.imshow` to set useful 

7777 defaults for displaying a matrix. In particular: 

7778 

7779 - Set ``origin='upper'``. 

7780 - Set ``interpolation='nearest'``. 

7781 - Set ``aspect='equal'``. 

7782 - Ticks are placed to the left and above. 

7783 - Ticks are formatted to show integer indices. 

7784 

7785 """ 

7786 Z = np.asanyarray(Z) 

7787 kw = {'origin': 'upper', 

7788 'interpolation': 'nearest', 

7789 'aspect': 'equal', # (already the imshow default) 

7790 **kwargs} 

7791 im = self.imshow(Z, **kw) 

7792 self.title.set_y(1.05) 

7793 self.xaxis.tick_top() 

7794 self.xaxis.set_ticks_position('both') 

7795 self.xaxis.set_major_locator(mticker.MaxNLocator(nbins=9, 

7796 steps=[1, 2, 5, 10], 

7797 integer=True)) 

7798 self.yaxis.set_major_locator(mticker.MaxNLocator(nbins=9, 

7799 steps=[1, 2, 5, 10], 

7800 integer=True)) 

7801 return im 

7802 

7803 @_preprocess_data(replace_names=["dataset"]) 

7804 def violinplot(self, dataset, positions=None, vert=True, widths=0.5, 

7805 showmeans=False, showextrema=True, showmedians=False, 

7806 quantiles=None, points=100, bw_method=None): 

7807 """ 

7808 Make a violin plot. 

7809 

7810 Make a violin plot for each column of *dataset* or each vector in 

7811 sequence *dataset*. Each filled area extends to represent the 

7812 entire data range, with optional lines at the mean, the median, 

7813 the minimum, the maximum, and user-specified quantiles. 

7814 

7815 Parameters 

7816 ---------- 

7817 dataset : Array or a sequence of vectors. 

7818 The input data. 

7819 

7820 positions : array-like, default = [1, 2, ..., n] 

7821 Sets the positions of the violins. The ticks and limits are 

7822 automatically set to match the positions. 

7823 

7824 vert : bool, default = True. 

7825 If true, creates a vertical violin plot. 

7826 Otherwise, creates a horizontal violin plot. 

7827 

7828 widths : array-like, default = 0.5 

7829 Either a scalar or a vector that sets the maximal width of 

7830 each violin. The default is 0.5, which uses about half of the 

7831 available horizontal space. 

7832 

7833 showmeans : bool, default = False 

7834 If `True`, will toggle rendering of the means. 

7835 

7836 showextrema : bool, default = True 

7837 If `True`, will toggle rendering of the extrema. 

7838 

7839 showmedians : bool, default = False 

7840 If `True`, will toggle rendering of the medians. 

7841 

7842 quantiles : array-like, default = None 

7843 If not None, set a list of floats in interval [0, 1] for each violin, 

7844 which stands for the quantiles that will be rendered for that 

7845 violin. 

7846 

7847 points : scalar, default = 100 

7848 Defines the number of points to evaluate each of the 

7849 gaussian kernel density estimations at. 

7850 

7851 bw_method : str, scalar or callable, optional 

7852 The method used to calculate the estimator bandwidth. This can be 

7853 'scott', 'silverman', a scalar constant or a callable. If a 

7854 scalar, this will be used directly as `kde.factor`. If a 

7855 callable, it should take a `GaussianKDE` instance as its only 

7856 parameter and return a scalar. If None (default), 'scott' is used. 

7857 

7858 Returns 

7859 ------- 

7860 result : dict 

7861 A dictionary mapping each component of the violinplot to a 

7862 list of the corresponding collection instances created. The 

7863 dictionary has the following keys: 

7864 

7865 - ``bodies``: A list of the `~.collections.PolyCollection` 

7866 instances containing the filled area of each violin. 

7867 

7868 - ``cmeans``: A `~.collections.LineCollection` instance that marks 

7869 the mean values of each of the violin's distribution. 

7870 

7871 - ``cmins``: A `~.collections.LineCollection` instance that marks 

7872 the bottom of each violin's distribution. 

7873 

7874 - ``cmaxes``: A `~.collections.LineCollection` instance that marks 

7875 the top of each violin's distribution. 

7876 

7877 - ``cbars``: A `~.collections.LineCollection` instance that marks 

7878 the centers of each violin's distribution. 

7879 

7880 - ``cmedians``: A `~.collections.LineCollection` instance that 

7881 marks the median values of each of the violin's distribution. 

7882 

7883 - ``cquantiles``: A `~.collections.LineCollection` instance created 

7884 to identify the quantile values of each of the violin's 

7885 distribution. 

7886 

7887 """ 

7888 

7889 def _kde_method(X, coords): 

7890 # fallback gracefully if the vector contains only one value 

7891 if np.all(X[0] == X): 

7892 return (X[0] == coords).astype(float) 

7893 kde = mlab.GaussianKDE(X, bw_method) 

7894 return kde.evaluate(coords) 

7895 

7896 vpstats = cbook.violin_stats(dataset, _kde_method, points=points, 

7897 quantiles=quantiles) 

7898 return self.violin(vpstats, positions=positions, vert=vert, 

7899 widths=widths, showmeans=showmeans, 

7900 showextrema=showextrema, showmedians=showmedians) 

7901 

7902 def violin(self, vpstats, positions=None, vert=True, widths=0.5, 

7903 showmeans=False, showextrema=True, showmedians=False): 

7904 """Drawing function for violin plots. 

7905 

7906 Draw a violin plot for each column of *vpstats*. Each filled area 

7907 extends to represent the entire data range, with optional lines at the 

7908 mean, the median, the minimum, the maximum, and the quantiles values. 

7909 

7910 Parameters 

7911 ---------- 

7912 vpstats : list of dicts 

7913 A list of dictionaries containing stats for each violin plot. 

7914 Required keys are: 

7915 

7916 - ``coords``: A list of scalars containing the coordinates that 

7917 the violin's kernel density estimate were evaluated at. 

7918 

7919 - ``vals``: A list of scalars containing the values of the 

7920 kernel density estimate at each of the coordinates given 

7921 in *coords*. 

7922 

7923 - ``mean``: The mean value for this violin's dataset. 

7924 

7925 - ``median``: The median value for this violin's dataset. 

7926 

7927 - ``min``: The minimum value for this violin's dataset. 

7928 

7929 - ``max``: The maximum value for this violin's dataset. 

7930 

7931 Optional keys are: 

7932 

7933 - ``quantiles``: A list of scalars containing the quantile values 

7934 for this violin's dataset. 

7935 

7936 positions : array-like, default = [1, 2, ..., n] 

7937 Sets the positions of the violins. The ticks and limits are 

7938 automatically set to match the positions. 

7939 

7940 vert : bool, default = True. 

7941 If true, plots the violins vertically. 

7942 Otherwise, plots the violins horizontally. 

7943 

7944 widths : array-like, default = 0.5 

7945 Either a scalar or a vector that sets the maximal width of 

7946 each violin. The default is 0.5, which uses about half of the 

7947 available horizontal space. 

7948 

7949 showmeans : bool, default = False 

7950 If true, will toggle rendering of the means. 

7951 

7952 showextrema : bool, default = True 

7953 If true, will toggle rendering of the extrema. 

7954 

7955 showmedians : bool, default = False 

7956 If true, will toggle rendering of the medians. 

7957 

7958 Returns 

7959 ------- 

7960 result : dict 

7961 A dictionary mapping each component of the violinplot to a 

7962 list of the corresponding collection instances created. The 

7963 dictionary has the following keys: 

7964 

7965 - ``bodies``: A list of the `~.collections.PolyCollection` 

7966 instances containing the filled area of each violin. 

7967 

7968 - ``cmeans``: A `~.collections.LineCollection` instance that marks 

7969 the mean values of each of the violin's distribution. 

7970 

7971 - ``cmins``: A `~.collections.LineCollection` instance that marks 

7972 the bottom of each violin's distribution. 

7973 

7974 - ``cmaxes``: A `~.collections.LineCollection` instance that marks 

7975 the top of each violin's distribution. 

7976 

7977 - ``cbars``: A `~.collections.LineCollection` instance that marks 

7978 the centers of each violin's distribution. 

7979 

7980 - ``cmedians``: A `~.collections.LineCollection` instance that 

7981 marks the median values of each of the violin's distribution. 

7982 

7983 - ``cquantiles``: A `~.collections.LineCollection` instance created 

7984 to identify the quantiles values of each of the violin's 

7985 distribution. 

7986 

7987 """ 

7988 

7989 # Statistical quantities to be plotted on the violins 

7990 means = [] 

7991 mins = [] 

7992 maxes = [] 

7993 medians = [] 

7994 quantiles = np.asarray([]) 

7995 

7996 # Collections to be returned 

7997 artists = {} 

7998 

7999 N = len(vpstats) 

8000 datashape_message = ("List of violinplot statistics and `{0}` " 

8001 "values must have the same length") 

8002 

8003 # Validate positions 

8004 if positions is None: 

8005 positions = range(1, N + 1) 

8006 elif len(positions) != N: 

8007 raise ValueError(datashape_message.format("positions")) 

8008 

8009 # Validate widths 

8010 if np.isscalar(widths): 

8011 widths = [widths] * N 

8012 elif len(widths) != N: 

8013 raise ValueError(datashape_message.format("widths")) 

8014 

8015 # Calculate ranges for statistics lines 

8016 pmins = -0.25 * np.array(widths) + positions 

8017 pmaxes = 0.25 * np.array(widths) + positions 

8018 

8019 # Check whether we are rendering vertically or horizontally 

8020 if vert: 

8021 fill = self.fill_betweenx 

8022 perp_lines = self.hlines 

8023 par_lines = self.vlines 

8024 else: 

8025 fill = self.fill_between 

8026 perp_lines = self.vlines 

8027 par_lines = self.hlines 

8028 

8029 if rcParams['_internal.classic_mode']: 

8030 fillcolor = 'y' 

8031 edgecolor = 'r' 

8032 else: 

8033 fillcolor = edgecolor = self._get_lines.get_next_color() 

8034 

8035 # Render violins 

8036 bodies = [] 

8037 for stats, pos, width in zip(vpstats, positions, widths): 

8038 # The 0.5 factor reflects the fact that we plot from v-p to 

8039 # v+p 

8040 vals = np.array(stats['vals']) 

8041 vals = 0.5 * width * vals / vals.max() 

8042 bodies += [fill(stats['coords'], 

8043 -vals + pos, 

8044 vals + pos, 

8045 facecolor=fillcolor, 

8046 alpha=0.3)] 

8047 means.append(stats['mean']) 

8048 mins.append(stats['min']) 

8049 maxes.append(stats['max']) 

8050 medians.append(stats['median']) 

8051 q = stats.get('quantiles') 

8052 if q is not None: 

8053 # If exist key quantiles, assume it's a list of floats 

8054 quantiles = np.concatenate((quantiles, q)) 

8055 artists['bodies'] = bodies 

8056 

8057 # Render means 

8058 if showmeans: 

8059 artists['cmeans'] = perp_lines(means, pmins, pmaxes, 

8060 colors=edgecolor) 

8061 

8062 # Render extrema 

8063 if showextrema: 

8064 artists['cmaxes'] = perp_lines(maxes, pmins, pmaxes, 

8065 colors=edgecolor) 

8066 artists['cmins'] = perp_lines(mins, pmins, pmaxes, 

8067 colors=edgecolor) 

8068 artists['cbars'] = par_lines(positions, mins, maxes, 

8069 colors=edgecolor) 

8070 

8071 # Render medians 

8072 if showmedians: 

8073 artists['cmedians'] = perp_lines(medians, 

8074 pmins, 

8075 pmaxes, 

8076 colors=edgecolor) 

8077 

8078 # Render quantile values 

8079 if quantiles.size > 0: 

8080 # Recalculate ranges for statistics lines for quantiles. 

8081 # ppmins are the left end of quantiles lines 

8082 ppmins = np.asarray([]) 

8083 # pmaxes are the right end of quantiles lines 

8084 ppmaxs = np.asarray([]) 

8085 for stats, cmin, cmax in zip(vpstats, pmins, pmaxes): 

8086 q = stats.get('quantiles') 

8087 if q is not None: 

8088 ppmins = np.concatenate((ppmins, [cmin] * np.size(q))) 

8089 ppmaxs = np.concatenate((ppmaxs, [cmax] * np.size(q))) 

8090 # Start rendering 

8091 artists['cquantiles'] = perp_lines(quantiles, ppmins, ppmaxs, 

8092 colors=edgecolor) 

8093 

8094 return artists 

8095 

8096 # Methods that are entirely implemented in other modules. 

8097 

8098 table = mtable.table 

8099 

8100 # args can by either Y or y1, y2, ... and all should be replaced 

8101 stackplot = _preprocess_data()(mstack.stackplot) 

8102 

8103 streamplot = _preprocess_data( 

8104 replace_names=["x", "y", "u", "v", "start_points"])(mstream.streamplot) 

8105 

8106 tricontour = mtri.tricontour 

8107 tricontourf = mtri.tricontourf 

8108 tripcolor = mtri.tripcolor 

8109 triplot = mtri.triplot