Coverage for /usr/lib/python3/dist-packages/matplotlib/axes/_axes.py: 9%

2244 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2025-06-14 15:25 +0200

1import functools 

2import itertools 

3import logging 

4import math 

5from numbers import Integral, Number 

6 

7import numpy as np 

8from numpy import ma 

9 

10import matplotlib as mpl 

11import matplotlib.category # Register category unit converter as side-effect. 

12import matplotlib.cbook as cbook 

13import matplotlib.collections as mcoll 

14import matplotlib.colors as mcolors 

15import matplotlib.contour as mcontour 

16import matplotlib.dates # noqa # Register date unit converter as side-effect. 

17import matplotlib.image as mimage 

18import matplotlib.legend as mlegend 

19import matplotlib.lines as mlines 

20import matplotlib.markers as mmarkers 

21import matplotlib.mlab as mlab 

22import matplotlib.patches as mpatches 

23import matplotlib.path as mpath 

24import matplotlib.quiver as mquiver 

25import matplotlib.stackplot as mstack 

26import matplotlib.streamplot as mstream 

27import matplotlib.table as mtable 

28import matplotlib.text as mtext 

29import matplotlib.ticker as mticker 

30import matplotlib.transforms as mtransforms 

31import matplotlib.tri as mtri 

32import matplotlib.units as munits 

33from matplotlib import _api, _docstring, _preprocess_data 

34from matplotlib.axes._base import ( 

35 _AxesBase, _TransformedBoundsLocator, _process_plot_format) 

36from matplotlib.axes._secondary_axes import SecondaryAxis 

37from matplotlib.container import BarContainer, ErrorbarContainer, StemContainer 

38 

39_log = logging.getLogger(__name__) 

40 

41 

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

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

44 

45 

46@_docstring.interpd 

47class Axes(_AxesBase): 

48 """ 

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

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

51 and sets the coordinate system. 

52 

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

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

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

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

57 

58 .. note:: 

59 

60 As a user, you do not instantiate Axes directly, but use Axes creation 

61 methods instead; e.g. from `.pyplot` or `.Figure`: 

62 `~.pyplot.subplots`, `~.pyplot.subplot_mosaic` or `.Figure.add_axes`. 

63 

64 Attributes 

65 ---------- 

66 dataLim : `.Bbox` 

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

68 viewLim : `.Bbox` 

69 The view limits in data coordinates. 

70 

71 """ 

72 ### Labelling, legend and texts 

73 

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

75 """ 

76 Get an Axes title. 

77 

78 Get one of the three available Axes titles. The available titles 

79 are positioned above the Axes in the center, flush with the left 

80 edge, and flush with the right edge. 

81 

82 Parameters 

83 ---------- 

84 loc : {'center', 'left', 'right'}, str, default: 'center' 

85 Which title to return. 

86 

87 Returns 

88 ------- 

89 str 

90 The title text string. 

91 

92 """ 

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

94 'center': self.title, 

95 'right': self._right_title} 

96 title = _api.check_getitem(titles, loc=loc.lower()) 

97 return title.get_text() 

98 

99 def set_title(self, label, fontdict=None, loc=None, pad=None, *, y=None, 

100 **kwargs): 

101 """ 

102 Set a title for the Axes. 

103 

104 Set one of the three available Axes titles. The available titles 

105 are positioned above the Axes in the center, flush with the left 

106 edge, and flush with the right edge. 

107 

108 Parameters 

109 ---------- 

110 label : str 

111 Text to use for the title 

112 

113 fontdict : dict 

114 A dictionary controlling the appearance of the title text, 

115 the default *fontdict* is:: 

116 

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

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

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

120 'verticalalignment': 'baseline', 

121 'horizontalalignment': loc} 

122 

123 loc : {'center', 'left', 'right'}, default: :rc:`axes.titlelocation` 

124 Which title to set. 

125 

126 y : float, default: :rc:`axes.titley` 

127 Vertical Axes location for the title (1.0 is the top). If 

128 None (the default) and :rc:`axes.titley` is also None, y is 

129 determined automatically to avoid decorators on the Axes. 

130 

131 pad : float, default: :rc:`axes.titlepad` 

132 The offset of the title from the top of the Axes, in points. 

133 

134 Returns 

135 ------- 

136 `.Text` 

137 The matplotlib text instance representing the title 

138 

139 Other Parameters 

140 ---------------- 

141 **kwargs : `.Text` properties 

142 Other keyword arguments are text properties, see `.Text` for a list 

143 of valid text properties. 

144 """ 

145 if loc is None: 

146 loc = mpl.rcParams['axes.titlelocation'] 

147 

148 if y is None: 

149 y = mpl.rcParams['axes.titley'] 

150 if y is None: 

151 y = 1.0 

152 else: 

153 self._autotitlepos = False 

154 kwargs['y'] = y 

155 

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

157 'center': self.title, 

158 'right': self._right_title} 

159 title = _api.check_getitem(titles, loc=loc.lower()) 

160 default = { 

161 'fontsize': mpl.rcParams['axes.titlesize'], 

162 'fontweight': mpl.rcParams['axes.titleweight'], 

163 'verticalalignment': 'baseline', 

164 'horizontalalignment': loc.lower()} 

165 titlecolor = mpl.rcParams['axes.titlecolor'] 

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

167 default["color"] = titlecolor 

168 if pad is None: 

169 pad = mpl.rcParams['axes.titlepad'] 

170 self._set_title_offset_trans(float(pad)) 

171 title.set_text(label) 

172 title.update(default) 

173 if fontdict is not None: 

174 title.update(fontdict) 

175 title._internal_update(kwargs) 

176 return title 

177 

178 def get_legend_handles_labels(self, legend_handler_map=None): 

179 """ 

180 Return handles and labels for legend 

181 

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

183 

184 h, l = ax.get_legend_handles_labels() 

185 ax.legend(h, l) 

186 """ 

187 # pass through to legend. 

188 handles, labels = mlegend._get_legend_handles_labels( 

189 [self], legend_handler_map) 

190 return handles, labels 

191 

192 @_docstring.dedent_interpd 

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

194 """ 

195 Place a legend on the Axes. 

196 

197 Call signatures:: 

198 

199 legend() 

200 legend(handles, labels) 

201 legend(handles=handles) 

202 legend(labels) 

203 

204 The call signatures correspond to the following different ways to use 

205 this method: 

206 

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

208 

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

210 when you do not pass in any extra arguments. 

211 

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

213 them either at artist creation or by calling the 

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

215 

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

217 ax.legend() 

218 

219 or:: 

220 

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

222 line.set_label('Label via method') 

223 ax.legend() 

224 

225 .. note:: 

226 Specific artists can be excluded from the automatic legend element 

227 selection by using a label starting with an underscore, "_". 

228 A string starting with an underscore is the default label for all 

229 artists, so calling `.Axes.legend` without any arguments and 

230 without setting the labels manually will result in no legend being 

231 drawn. 

232 

233 

234 **2. Explicitly listing the artists and labels in the legend** 

235 

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

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

238 legend labels respectively:: 

239 

240 ax.legend([line1, line2, line3], ['label1', 'label2', 'label3']) 

241 

242 

243 **3. Explicitly listing the artists in the legend** 

244 

245 This is similar to 2, but the labels are taken from the artists' 

246 label properties. Example:: 

247 

248 line1, = ax.plot([1, 2, 3], label='label1') 

249 line2, = ax.plot([1, 2, 3], label='label2') 

250 ax.legend(handles=[line1, line2]) 

251 

252 

253 **4. Labeling existing plot elements** 

254 

255 .. admonition:: Discouraged 

256 

257 This call signature is discouraged, because the relation between 

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

259 easily be mixed up. 

260 

261 To make a legend for all artists on an Axes, call this function with 

262 an iterable of strings, one for each legend item. For example:: 

263 

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

265 ax.plot([5, 6, 7]) 

266 ax.legend(['First line', 'Second line']) 

267 

268 

269 Parameters 

270 ---------- 

271 handles : sequence of `.Artist`, optional 

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

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

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

275 is not sufficient. 

276 

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

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

279 

280 labels : list of str, optional 

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

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

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

284 is not sufficient. 

285 

286 Returns 

287 ------- 

288 `~matplotlib.legend.Legend` 

289 

290 Other Parameters 

291 ---------------- 

292 %(_legend_kw_doc)s 

293 

294 See Also 

295 -------- 

296 .Figure.legend 

297 

298 Notes 

299 ----- 

300 Some artists are not supported by this function. See 

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

302 

303 Examples 

304 -------- 

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

306 """ 

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

308 [self], 

309 *args, 

310 **kwargs) 

311 if len(extra_args): 

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

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

314 self.legend_._remove_method = self._remove_legend 

315 return self.legend_ 

316 

317 def _remove_legend(self, legend): 

318 self.legend_ = None 

319 

320 def inset_axes(self, bounds, *, transform=None, zorder=5, **kwargs): 

321 """ 

322 Add a child inset Axes to this existing Axes. 

323 

324 Warnings 

325 -------- 

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

327 

328 Parameters 

329 ---------- 

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

331 Lower-left corner of inset Axes, and its width and height. 

332 

333 transform : `.Transform` 

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

335 Axes-relative coordinates. 

336 

337 projection : {None, 'aitoff', 'hammer', 'lambert', 'mollweide', \ 

338'polar', 'rectilinear', str}, optional 

339 The projection type of the inset `~.axes.Axes`. *str* is the name 

340 of a custom projection, see `~matplotlib.projections`. The default 

341 None results in a 'rectilinear' projection. 

342 

343 polar : bool, default: False 

344 If True, equivalent to projection='polar'. 

345 

346 axes_class : subclass type of `~.axes.Axes`, optional 

347 The `.axes.Axes` subclass that is instantiated. This parameter 

348 is incompatible with *projection* and *polar*. See 

349 :ref:`axisartist_users-guide-index` for examples. 

350 

351 zorder : number 

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

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

354 parent Axes. 

355 

356 **kwargs 

357 Other keyword arguments are passed on to the inset Axes class. 

358 

359 Returns 

360 ------- 

361 ax 

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

363 

364 Examples 

365 -------- 

366 This example makes two inset Axes, the first is in Axes-relative 

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

368 

369 fig, ax = plt.subplots() 

370 ax.plot(range(10)) 

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

372 axin2 = ax.inset_axes( 

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

374 

375 """ 

376 if transform is None: 

377 transform = self.transAxes 

378 kwargs.setdefault('label', 'inset_axes') 

379 

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

381 inset_locator = _TransformedBoundsLocator(bounds, transform) 

382 bounds = inset_locator(self, None).bounds 

383 projection_class, pkw = self.figure._process_projection_requirements( 

384 bounds, **kwargs) 

385 inset_ax = projection_class(self.figure, bounds, zorder=zorder, **pkw) 

386 

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

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

389 inset_ax.set_axes_locator(inset_locator) 

390 

391 self.add_child_axes(inset_ax) 

392 

393 return inset_ax 

394 

395 @_docstring.dedent_interpd 

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

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

398 zorder=4.99, **kwargs): 

399 """ 

400 Add an inset indicator to the Axes. This is a rectangle on the plot 

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

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

403 

404 Warnings 

405 -------- 

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

407 

408 Parameters 

409 ---------- 

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

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

412 and height. 

413 

414 inset_ax : `.Axes` 

415 An optional inset Axes to draw connecting lines to. Two lines are 

416 drawn connecting the indicator box to the inset Axes on corners 

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

418 

419 transform : `.Transform` 

420 Transform for the rectangle coordinates. Defaults to 

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

422 coordinates. 

423 

424 facecolor : color, default: 'none' 

425 Facecolor of the rectangle. 

426 

427 edgecolor : color, default: '0.5' 

428 Color of the rectangle and color of the connecting lines. 

429 

430 alpha : float, default: 0.5 

431 Transparency of the rectangle and connector lines. 

432 

433 zorder : float, default: 4.99 

434 Drawing order of the rectangle and connector lines. The default, 

435 4.99, is just below the default level of inset Axes. 

436 

437 **kwargs 

438 Other keyword arguments are passed on to the `.Rectangle` patch: 

439 

440 %(Rectangle:kwdoc)s 

441 

442 Returns 

443 ------- 

444 rectangle_patch : `.patches.Rectangle` 

445 The indicator frame. 

446 

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

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

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

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

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

452 

453 """ 

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

455 # the parent axes. 

456 self.apply_aspect() 

457 

458 if transform is None: 

459 transform = self.transData 

460 kwargs.setdefault('label', '_indicate_inset') 

461 

462 x, y, width, height = bounds 

463 rectangle_patch = mpatches.Rectangle( 

464 (x, y), width, height, 

465 facecolor=facecolor, edgecolor=edgecolor, alpha=alpha, 

466 zorder=zorder, transform=transform, **kwargs) 

467 self.add_patch(rectangle_patch) 

468 

469 connects = [] 

470 

471 if inset_ax is not None: 

472 # connect the inset_axes to the rectangle 

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

474 # inset_ax positions are in axes coordinates 

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

476 # lower_left, upper_left, lower_right upper_right. 

477 ex, ey = xy_inset_ax 

478 if self.xaxis.get_inverted(): 

479 ex = 1 - ex 

480 if self.yaxis.get_inverted(): 

481 ey = 1 - ey 

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

483 p = mpatches.ConnectionPatch( 

484 xyA=xy_inset_ax, coordsA=inset_ax.transAxes, 

485 xyB=xy_data, coordsB=self.transData, 

486 arrowstyle="-", zorder=zorder, 

487 edgecolor=edgecolor, alpha=alpha) 

488 connects.append(p) 

489 self.add_patch(p) 

490 

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

492 pos = inset_ax.get_position() 

493 bboxins = pos.transformed(self.figure.transSubfigure) 

494 rectbbox = mtransforms.Bbox.from_bounds( 

495 *bounds 

496 ).transformed(transform) 

497 x0 = rectbbox.x0 < bboxins.x0 

498 x1 = rectbbox.x1 < bboxins.x1 

499 y0 = rectbbox.y0 < bboxins.y0 

500 y1 = rectbbox.y1 < bboxins.y1 

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

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

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

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

505 

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

507 

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

509 """ 

510 Add an inset indicator rectangle to the Axes based on the axis 

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

512 and the rectangle. 

513 

514 Warnings 

515 -------- 

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

517 

518 Parameters 

519 ---------- 

520 inset_ax : `.Axes` 

521 Inset Axes to draw connecting lines to. Two lines are 

522 drawn connecting the indicator box to the inset Axes on corners 

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

524 

525 **kwargs 

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

527 

528 Returns 

529 ------- 

530 rectangle_patch : `.patches.Rectangle` 

531 Rectangle artist. 

532 

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

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

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

536 upper right. 

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

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

539 correct. 

540 """ 

541 

542 xlim = inset_ax.get_xlim() 

543 ylim = inset_ax.get_ylim() 

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

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

546 

547 @_docstring.dedent_interpd 

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

549 """ 

550 Add a second x-axis to this Axes. 

551 

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

553 the xaxis. 

554 

555 %(_secax_docstring)s 

556 

557 Examples 

558 -------- 

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

560 

561 .. plot:: 

562 

563 fig, ax = plt.subplots() 

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

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

566 

567 def invert(x): 

568 # 1/x with special treatment of x == 0 

569 x = np.array(x).astype(float) 

570 near_zero = np.isclose(x, 0) 

571 x[near_zero] = np.inf 

572 x[~near_zero] = 1 / x[~near_zero] 

573 return x 

574 

575 # the inverse of 1/x is itself 

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

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

578 plt.show() 

579 """ 

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

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

582 **kwargs) 

583 self.add_child_axes(secondary_ax) 

584 return secondary_ax 

585 else: 

586 raise ValueError('secondary_xaxis location must be either ' 

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

588 

589 @_docstring.dedent_interpd 

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

591 """ 

592 Add a second y-axis to this Axes. 

593 

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

595 the yaxis. 

596 

597 %(_secax_docstring)s 

598 

599 Examples 

600 -------- 

601 Add a secondary Axes that converts from radians to degrees 

602 

603 .. plot:: 

604 

605 fig, ax = plt.subplots() 

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

607 ax.set_ylabel('degrees') 

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

609 np.rad2deg)) 

610 secax.set_ylabel('radians') 

611 """ 

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

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

614 functions, **kwargs) 

615 self.add_child_axes(secondary_ax) 

616 return secondary_ax 

617 else: 

618 raise ValueError('secondary_yaxis location must be either ' 

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

620 

621 @_docstring.dedent_interpd 

622 def text(self, x, y, s, fontdict=None, **kwargs): 

623 """ 

624 Add text to the Axes. 

625 

626 Add the text *s* to the Axes at location *x*, *y* in data coordinates. 

627 

628 Parameters 

629 ---------- 

630 x, y : float 

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

632 coordinates. The coordinate system can be changed using the 

633 *transform* parameter. 

634 

635 s : str 

636 The text. 

637 

638 fontdict : dict, default: None 

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

640 is None, the defaults are determined by `.rcParams`. 

641 

642 Returns 

643 ------- 

644 `.Text` 

645 The created `.Text` instance. 

646 

647 Other Parameters 

648 ---------------- 

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

650 Other miscellaneous text parameters. 

651 

652 %(Text:kwdoc)s 

653 

654 Examples 

655 -------- 

656 Individual keyword arguments can be used to override any given 

657 parameter:: 

658 

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

660 

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

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

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

664 text in the center of the Axes:: 

665 

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

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

668 

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

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

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

672 properties. For example:: 

673 

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

675 """ 

676 effective_kwargs = { 

677 'verticalalignment': 'baseline', 

678 'horizontalalignment': 'left', 

679 'transform': self.transData, 

680 'clip_on': False, 

681 **(fontdict if fontdict is not None else {}), 

682 **kwargs, 

683 } 

684 t = mtext.Text(x, y, text=s, **effective_kwargs) 

685 t.set_clip_path(self.patch) 

686 self._add_text(t) 

687 return t 

688 

689 @_docstring.dedent_interpd 

690 def annotate(self, text, xy, xytext=None, xycoords='data', textcoords=None, 

691 arrowprops=None, annotation_clip=None, **kwargs): 

692 # Signature must match Annotation. This is verified in 

693 # test_annotate_signature(). 

694 a = mtext.Annotation(text, xy, xytext=xytext, xycoords=xycoords, 

695 textcoords=textcoords, arrowprops=arrowprops, 

696 annotation_clip=annotation_clip, **kwargs) 

697 a.set_transform(mtransforms.IdentityTransform()) 

698 if 'clip_on' in kwargs: 

699 a.set_clip_path(self.patch) 

700 self._add_text(a) 

701 return a 

702 annotate.__doc__ = mtext.Annotation.__init__.__doc__ 

703 #### Lines and spans 

704 

705 @_docstring.dedent_interpd 

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

707 """ 

708 Add a horizontal line across the Axes. 

709 

710 Parameters 

711 ---------- 

712 y : float, default: 0 

713 y position in data coordinates of the horizontal line. 

714 

715 xmin : float, default: 0 

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

717 far right of the plot. 

718 

719 xmax : float, default: 1 

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

721 far right of the plot. 

722 

723 Returns 

724 ------- 

725 `~matplotlib.lines.Line2D` 

726 

727 Other Parameters 

728 ---------------- 

729 **kwargs 

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

731 exception of 'transform': 

732 

733 %(Line2D:kwdoc)s 

734 

735 See Also 

736 -------- 

737 hlines : Add horizontal lines in data coordinates. 

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

739 axline : Add a line with an arbitrary slope. 

740 

741 Examples 

742 -------- 

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

744 

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

746 

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

748 

749 >>> axhline(y=1) 

750 

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

752 the xrange:: 

753 

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

755 """ 

756 self._check_no_units([xmin, xmax], ['xmin', 'xmax']) 

757 if "transform" in kwargs: 

758 raise ValueError("'transform' is not allowed as a keyword " 

759 "argument; axhline generates its own transform.") 

760 ymin, ymax = self.get_ybound() 

761 

762 # Strip away the units for comparison with non-unitized bounds. 

763 yy, = self._process_unit_info([("y", y)], kwargs) 

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

765 

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

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

768 self.add_line(l) 

769 if scaley: 

770 self._request_autoscale_view("y") 

771 return l 

772 

773 @_docstring.dedent_interpd 

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

775 """ 

776 Add a vertical line across the Axes. 

777 

778 Parameters 

779 ---------- 

780 x : float, default: 0 

781 x position in data coordinates of the vertical line. 

782 

783 ymin : float, default: 0 

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

785 top of the plot. 

786 

787 ymax : float, default: 1 

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

789 top of the plot. 

790 

791 Returns 

792 ------- 

793 `~matplotlib.lines.Line2D` 

794 

795 Other Parameters 

796 ---------------- 

797 **kwargs 

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

799 exception of 'transform': 

800 

801 %(Line2D:kwdoc)s 

802 

803 See Also 

804 -------- 

805 vlines : Add vertical lines in data coordinates. 

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

807 axline : Add a line with an arbitrary slope. 

808 

809 Examples 

810 -------- 

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

812 

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

814 

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

816 

817 >>> axvline(x=1) 

818 

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

820 the yrange:: 

821 

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

823 """ 

824 self._check_no_units([ymin, ymax], ['ymin', 'ymax']) 

825 if "transform" in kwargs: 

826 raise ValueError("'transform' is not allowed as a keyword " 

827 "argument; axvline generates its own transform.") 

828 xmin, xmax = self.get_xbound() 

829 

830 # Strip away the units for comparison with non-unitized bounds. 

831 xx, = self._process_unit_info([("x", x)], kwargs) 

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

833 

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

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

836 self.add_line(l) 

837 if scalex: 

838 self._request_autoscale_view("x") 

839 return l 

840 

841 @staticmethod 

842 def _check_no_units(vals, names): 

843 # Helper method to check that vals are not unitized 

844 for val, name in zip(vals, names): 

845 if not munits._is_natively_supported(val): 

846 raise ValueError(f"{name} must be a single scalar value, " 

847 f"but got {val}") 

848 

849 @_docstring.dedent_interpd 

850 def axline(self, xy1, xy2=None, *, slope=None, **kwargs): 

851 """ 

852 Add an infinitely long straight line. 

853 

854 The line can be defined either by two points *xy1* and *xy2*, or 

855 by one point *xy1* and a *slope*. 

856 

857 This draws a straight line "on the screen", regardless of the x and y 

858 scales, and is thus also suitable for drawing exponential decays in 

859 semilog plots, power laws in loglog plots, etc. However, *slope* 

860 should only be used with linear scales; It has no clear meaning for 

861 all other scales, and thus the behavior is undefined. Please specify 

862 the line using the points *xy1*, *xy2* for non-linear scales. 

863 

864 The *transform* keyword argument only applies to the points *xy1*, 

865 *xy2*. The *slope* (if given) is always in data coordinates. This can 

866 be used e.g. with ``ax.transAxes`` for drawing grid lines with a fixed 

867 slope. 

868 

869 Parameters 

870 ---------- 

871 xy1, xy2 : (float, float) 

872 Points for the line to pass through. 

873 Either *xy2* or *slope* has to be given. 

874 slope : float, optional 

875 The slope of the line. Either *xy2* or *slope* has to be given. 

876 

877 Returns 

878 ------- 

879 `.Line2D` 

880 

881 Other Parameters 

882 ---------------- 

883 **kwargs 

884 Valid kwargs are `.Line2D` properties 

885 

886 %(Line2D:kwdoc)s 

887 

888 See Also 

889 -------- 

890 axhline : for horizontal lines 

891 axvline : for vertical lines 

892 

893 Examples 

894 -------- 

895 Draw a thick red line passing through (0, 0) and (1, 1):: 

896 

897 >>> axline((0, 0), (1, 1), linewidth=4, color='r') 

898 """ 

899 if slope is not None and (self.get_xscale() != 'linear' or 

900 self.get_yscale() != 'linear'): 

901 raise TypeError("'slope' cannot be used with non-linear scales") 

902 

903 datalim = [xy1] if xy2 is None else [xy1, xy2] 

904 if "transform" in kwargs: 

905 # if a transform is passed (i.e. line points not in data space), 

906 # data limits should not be adjusted. 

907 datalim = [] 

908 

909 line = mlines._AxLine(xy1, xy2, slope, **kwargs) 

910 # Like add_line, but correctly handling data limits. 

911 self._set_artist_props(line) 

912 if line.get_clip_path() is None: 

913 line.set_clip_path(self.patch) 

914 if not line.get_label(): 

915 line.set_label(f"_child{len(self._children)}") 

916 self._children.append(line) 

917 line._remove_method = self._children.remove 

918 self.update_datalim(datalim) 

919 

920 self._request_autoscale_view() 

921 return line 

922 

923 @_docstring.dedent_interpd 

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

925 """ 

926 Add a horizontal span (rectangle) across the Axes. 

927 

928 The rectangle spans from *ymin* to *ymax* vertically, and, by default, 

929 the whole x-axis horizontally. The x-span can be set using *xmin* 

930 (default: 0) and *xmax* (default: 1) which are in axis units; e.g. 

931 ``xmin = 0.5`` always refers to the middle of the x-axis regardless of 

932 the limits set by `~.Axes.set_xlim`. 

933 

934 Parameters 

935 ---------- 

936 ymin : float 

937 Lower y-coordinate of the span, in data units. 

938 ymax : float 

939 Upper y-coordinate of the span, in data units. 

940 xmin : float, default: 0 

941 Lower x-coordinate of the span, in x-axis (0-1) units. 

942 xmax : float, default: 1 

943 Upper x-coordinate of the span, in x-axis (0-1) units. 

944 

945 Returns 

946 ------- 

947 `~matplotlib.patches.Polygon` 

948 Horizontal span (rectangle) from (xmin, ymin) to (xmax, ymax). 

949 

950 Other Parameters 

951 ---------------- 

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

953 

954 %(Polygon:kwdoc)s 

955 

956 See Also 

957 -------- 

958 axvspan : Add a vertical span across the Axes. 

959 """ 

960 # Strip units away. 

961 self._check_no_units([xmin, xmax], ['xmin', 'xmax']) 

962 (ymin, ymax), = self._process_unit_info([("y", [ymin, ymax])], kwargs) 

963 

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

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

966 p.set_transform(self.get_yaxis_transform(which="grid")) 

967 self.add_patch(p) 

968 self._request_autoscale_view("y") 

969 return p 

970 

971 @_docstring.dedent_interpd 

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

973 """ 

974 Add a vertical span (rectangle) across the Axes. 

975 

976 The rectangle spans from *xmin* to *xmax* horizontally, and, by 

977 default, the whole y-axis vertically. The y-span can be set using 

978 *ymin* (default: 0) and *ymax* (default: 1) which are in axis units; 

979 e.g. ``ymin = 0.5`` always refers to the middle of the y-axis 

980 regardless of the limits set by `~.Axes.set_ylim`. 

981 

982 Parameters 

983 ---------- 

984 xmin : float 

985 Lower x-coordinate of the span, in data units. 

986 xmax : float 

987 Upper x-coordinate of the span, in data units. 

988 ymin : float, default: 0 

989 Lower y-coordinate of the span, in y-axis units (0-1). 

990 ymax : float, default: 1 

991 Upper y-coordinate of the span, in y-axis units (0-1). 

992 

993 Returns 

994 ------- 

995 `~matplotlib.patches.Polygon` 

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

997 

998 Other Parameters 

999 ---------------- 

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

1001 

1002 %(Polygon:kwdoc)s 

1003 

1004 See Also 

1005 -------- 

1006 axhspan : Add a horizontal span across the Axes. 

1007 

1008 Examples 

1009 -------- 

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

1011 x = 1.55 that spans the yrange of the Axes. 

1012 

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

1014 

1015 """ 

1016 # Strip units away. 

1017 self._check_no_units([ymin, ymax], ['ymin', 'ymax']) 

1018 (xmin, xmax), = self._process_unit_info([("x", [xmin, xmax])], kwargs) 

1019 

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

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

1022 p.set_transform(self.get_xaxis_transform(which="grid")) 

1023 p.get_path()._interpolation_steps = 100 

1024 self.add_patch(p) 

1025 self._request_autoscale_view("x") 

1026 return p 

1027 

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

1029 label_namer="y") 

1030 def hlines(self, y, xmin, xmax, colors=None, linestyles='solid', 

1031 label='', **kwargs): 

1032 """ 

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

1034 

1035 Parameters 

1036 ---------- 

1037 y : float or array-like 

1038 y-indexes where to plot the lines. 

1039 

1040 xmin, xmax : float or array-like 

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

1042 provided, all lines will have the same length. 

1043 

1044 colors : list of colors, default: :rc:`lines.color` 

1045 

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

1047 

1048 label : str, default: '' 

1049 

1050 Returns 

1051 ------- 

1052 `~matplotlib.collections.LineCollection` 

1053 

1054 Other Parameters 

1055 ---------------- 

1056 data : indexable object, optional 

1057 DATA_PARAMETER_PLACEHOLDER 

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

1059 

1060 See Also 

1061 -------- 

1062 vlines : vertical lines 

1063 axhline : horizontal line across the Axes 

1064 """ 

1065 

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

1067 xmin, xmax, y = self._process_unit_info( 

1068 [("x", xmin), ("x", xmax), ("y", y)], kwargs) 

1069 

1070 if not np.iterable(y): 

1071 y = [y] 

1072 if not np.iterable(xmin): 

1073 xmin = [xmin] 

1074 if not np.iterable(xmax): 

1075 xmax = [xmax] 

1076 

1077 # Create and combine masked_arrays from input 

1078 y, xmin, xmax = cbook._combine_masks(y, xmin, xmax) 

1079 y = np.ravel(y) 

1080 xmin = np.ravel(xmin) 

1081 xmax = np.ravel(xmax) 

1082 

1083 masked_verts = np.ma.empty((len(y), 2, 2)) 

1084 masked_verts[:, 0, 0] = xmin 

1085 masked_verts[:, 0, 1] = y 

1086 masked_verts[:, 1, 0] = xmax 

1087 masked_verts[:, 1, 1] = y 

1088 

1089 lines = mcoll.LineCollection(masked_verts, colors=colors, 

1090 linestyles=linestyles, label=label) 

1091 self.add_collection(lines, autolim=False) 

1092 lines._internal_update(kwargs) 

1093 

1094 if len(y) > 0: 

1095 # Extreme values of xmin/xmax/y. Using masked_verts here handles 

1096 # the case of y being a masked *object* array (as can be generated 

1097 # e.g. by errorbar()), which would make nanmin/nanmax stumble. 

1098 minx = np.nanmin(masked_verts[..., 0]) 

1099 maxx = np.nanmax(masked_verts[..., 0]) 

1100 miny = np.nanmin(masked_verts[..., 1]) 

1101 maxy = np.nanmax(masked_verts[..., 1]) 

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

1103 self.update_datalim(corners) 

1104 self._request_autoscale_view() 

1105 

1106 return lines 

1107 

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

1109 label_namer="x") 

1110 def vlines(self, x, ymin, ymax, colors=None, linestyles='solid', 

1111 label='', **kwargs): 

1112 """ 

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

1114 

1115 Parameters 

1116 ---------- 

1117 x : float or array-like 

1118 x-indexes where to plot the lines. 

1119 

1120 ymin, ymax : float or array-like 

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

1122 provided, all lines will have the same length. 

1123 

1124 colors : list of colors, default: :rc:`lines.color` 

1125 

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

1127 

1128 label : str, default: '' 

1129 

1130 Returns 

1131 ------- 

1132 `~matplotlib.collections.LineCollection` 

1133 

1134 Other Parameters 

1135 ---------------- 

1136 data : indexable object, optional 

1137 DATA_PARAMETER_PLACEHOLDER 

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

1139 

1140 See Also 

1141 -------- 

1142 hlines : horizontal lines 

1143 axvline : vertical line across the Axes 

1144 """ 

1145 

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

1147 x, ymin, ymax = self._process_unit_info( 

1148 [("x", x), ("y", ymin), ("y", ymax)], kwargs) 

1149 

1150 if not np.iterable(x): 

1151 x = [x] 

1152 if not np.iterable(ymin): 

1153 ymin = [ymin] 

1154 if not np.iterable(ymax): 

1155 ymax = [ymax] 

1156 

1157 # Create and combine masked_arrays from input 

1158 x, ymin, ymax = cbook._combine_masks(x, ymin, ymax) 

1159 x = np.ravel(x) 

1160 ymin = np.ravel(ymin) 

1161 ymax = np.ravel(ymax) 

1162 

1163 masked_verts = np.ma.empty((len(x), 2, 2)) 

1164 masked_verts[:, 0, 0] = x 

1165 masked_verts[:, 0, 1] = ymin 

1166 masked_verts[:, 1, 0] = x 

1167 masked_verts[:, 1, 1] = ymax 

1168 

1169 lines = mcoll.LineCollection(masked_verts, colors=colors, 

1170 linestyles=linestyles, label=label) 

1171 self.add_collection(lines, autolim=False) 

1172 lines._internal_update(kwargs) 

1173 

1174 if len(x) > 0: 

1175 # Extreme values of x/ymin/ymax. Using masked_verts here handles 

1176 # the case of x being a masked *object* array (as can be generated 

1177 # e.g. by errorbar()), which would make nanmin/nanmax stumble. 

1178 minx = np.nanmin(masked_verts[..., 0]) 

1179 maxx = np.nanmax(masked_verts[..., 0]) 

1180 miny = np.nanmin(masked_verts[..., 1]) 

1181 maxy = np.nanmax(masked_verts[..., 1]) 

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

1183 self.update_datalim(corners) 

1184 self._request_autoscale_view() 

1185 

1186 return lines 

1187 

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

1189 "linelengths", "linewidths", 

1190 "colors", "linestyles"]) 

1191 @_docstring.dedent_interpd 

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

1193 linelengths=1, linewidths=None, colors=None, 

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

1195 """ 

1196 Plot identical parallel lines at the given positions. 

1197 

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

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

1200 or raster plot. 

1201 

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

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

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

1205 date of hurricanes each year of the last century. 

1206 

1207 Parameters 

1208 ---------- 

1209 positions : array-like or list of array-like 

1210 A 1D array-like defines the positions of one sequence of events. 

1211 

1212 Multiple groups of events may be passed as a list of array-likes. 

1213 Each group can be styled independently by passing lists of values 

1214 to *lineoffsets*, *linelengths*, *linewidths*, *colors* and 

1215 *linestyles*. 

1216 

1217 Note that *positions* can be a 2D array, but in practice different 

1218 event groups usually have different counts so that one will use a 

1219 list of different-length arrays rather than a 2D array. 

1220 

1221 orientation : {'horizontal', 'vertical'}, default: 'horizontal' 

1222 The direction of the event sequence: 

1223 

1224 - 'horizontal': the events are arranged horizontally. 

1225 The indicator lines are vertical. 

1226 - 'vertical': the events are arranged vertically. 

1227 The indicator lines are horizontal. 

1228 

1229 lineoffsets : float or array-like, default: 1 

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

1231 direction orthogonal to *orientation*. 

1232 

1233 If *positions* is 2D, this can be a sequence with length matching 

1234 the length of *positions*. 

1235 

1236 linelengths : float or array-like, default: 1 

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

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

1239 

1240 If *positions* is 2D, this can be a sequence with length matching 

1241 the length of *positions*. 

1242 

1243 linewidths : float or array-like, default: :rc:`lines.linewidth` 

1244 The line width(s) of the event lines, in points. 

1245 

1246 If *positions* is 2D, this can be a sequence with length matching 

1247 the length of *positions*. 

1248 

1249 colors : color or list of colors, default: :rc:`lines.color` 

1250 The color(s) of the event lines. 

1251 

1252 If *positions* is 2D, this can be a sequence with length matching 

1253 the length of *positions*. 

1254 

1255 linestyles : str or tuple or list of such values, default: 'solid' 

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

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

1258 should be of the form:: 

1259 

1260 (offset, onoffseq), 

1261 

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

1263 in points. 

1264 

1265 If *positions* is 2D, this can be a sequence with length matching 

1266 the length of *positions*. 

1267 

1268 data : indexable object, optional 

1269 DATA_PARAMETER_PLACEHOLDER 

1270 

1271 **kwargs 

1272 Other keyword arguments are line collection properties. See 

1273 `.LineCollection` for a list of the valid properties. 

1274 

1275 Returns 

1276 ------- 

1277 list of `.EventCollection` 

1278 The `.EventCollection` that were added. 

1279 

1280 Notes 

1281 ----- 

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

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

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

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

1286 

1287 Examples 

1288 -------- 

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

1290 """ 

1291 

1292 lineoffsets, linelengths = self._process_unit_info( 

1293 [("y", lineoffsets), ("y", linelengths)], kwargs) 

1294 

1295 # fix positions, noting that it can be a list of lists: 

1296 if not np.iterable(positions): 

1297 positions = [positions] 

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

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

1300 else: 

1301 positions = [np.asanyarray(positions)] 

1302 

1303 if len(positions) == 0: 

1304 return [] 

1305 

1306 poss = [] 

1307 for position in positions: 

1308 poss += self._process_unit_info([("x", position)], kwargs) 

1309 positions = poss 

1310 

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

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

1313 colors = cbook._local_over_kwdict(colors, kwargs, 'color') 

1314 linewidths = cbook._local_over_kwdict(linewidths, kwargs, 'linewidth') 

1315 linestyles = cbook._local_over_kwdict(linestyles, kwargs, 'linestyle') 

1316 

1317 if not np.iterable(lineoffsets): 

1318 lineoffsets = [lineoffsets] 

1319 if not np.iterable(linelengths): 

1320 linelengths = [linelengths] 

1321 if not np.iterable(linewidths): 

1322 linewidths = [linewidths] 

1323 if not np.iterable(colors): 

1324 colors = [colors] 

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

1326 linestyles = [linestyles] 

1327 

1328 lineoffsets = np.asarray(lineoffsets) 

1329 linelengths = np.asarray(linelengths) 

1330 linewidths = np.asarray(linewidths) 

1331 

1332 if len(lineoffsets) == 0: 

1333 lineoffsets = [None] 

1334 if len(linelengths) == 0: 

1335 linelengths = [None] 

1336 if len(linewidths) == 0: 

1337 lineoffsets = [None] 

1338 if len(linewidths) == 0: 

1339 lineoffsets = [None] 

1340 if len(colors) == 0: 

1341 colors = [None] 

1342 try: 

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

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

1345 colors = mcolors.to_rgba_array(colors) 

1346 except ValueError: 

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

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

1349 # code should process *colors* properly. 

1350 pass 

1351 

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

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

1354 lineoffsets[0] = 0 

1355 lineoffsets = np.cumsum(lineoffsets) 

1356 if len(linelengths) == 1: 

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

1358 if len(linewidths) == 1: 

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

1360 if len(colors) == 1: 

1361 colors = list(colors) 

1362 colors = colors * len(positions) 

1363 if len(linestyles) == 1: 

1364 linestyles = [linestyles] * len(positions) 

1365 

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

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

1368 'sequences') 

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

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

1371 'sequences') 

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

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

1374 'sequences') 

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

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

1377 'sequences') 

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

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

1380 'sequences') 

1381 

1382 colls = [] 

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

1384 zip(positions, lineoffsets, linelengths, linewidths, 

1385 colors, linestyles): 

1386 coll = mcoll.EventCollection(position, 

1387 orientation=orientation, 

1388 lineoffset=lineoffset, 

1389 linelength=linelength, 

1390 linewidth=linewidth, 

1391 color=color, 

1392 linestyle=linestyle) 

1393 self.add_collection(coll, autolim=False) 

1394 coll._internal_update(kwargs) 

1395 colls.append(coll) 

1396 

1397 if len(positions) > 0: 

1398 # try to get min/max 

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

1400 if len(_p) > 0] 

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

1402 if len(min_max) > 0: 

1403 mins, maxes = zip(*min_max) 

1404 minpos = np.min(mins) 

1405 maxpos = np.max(maxes) 

1406 

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

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

1409 

1410 if orientation == "vertical": 

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

1412 else: # "horizontal" 

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

1414 self.update_datalim(corners) 

1415 self._request_autoscale_view() 

1416 

1417 return colls 

1418 

1419 #### Basic plotting 

1420 

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

1422 # _process_plot_var_args. 

1423 @_docstring.dedent_interpd 

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

1425 """ 

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

1427 

1428 Call signatures:: 

1429 

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

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

1432 

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

1434 

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

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

1437 notation described in the *Notes* section below. 

1438 

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

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

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

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

1443 

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

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

1446 The following two calls yield identical results: 

1447 

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

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

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

1451 

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

1453 

1454 

1455 **Plotting labelled data** 

1456 

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

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

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

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

1461 

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

1463 

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

1465 `pandas.DataFrame` or a structured numpy array. 

1466 

1467 

1468 **Plotting multiple sets of data** 

1469 

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

1471 

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

1473 Example: 

1474 

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

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

1477 

1478 - If *x* and/or *y* are 2D arrays a separate data set will be drawn 

1479 for every column. If both *x* and *y* are 2D, they must have the 

1480 same shape. If only one of them is 2D with shape (N, m) the other 

1481 must have length N and will be used for every data set m. 

1482 

1483 Example: 

1484 

1485 >>> x = [1, 2, 3] 

1486 >>> y = np.array([[1, 2], [3, 4], [5, 6]]) 

1487 >>> plot(x, y) 

1488 

1489 is equivalent to: 

1490 

1491 >>> for col in range(y.shape[1]): 

1492 ... plot(x, y[:, col]) 

1493 

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

1495 groups:: 

1496 

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

1498 

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

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

1501 parameter. 

1502 

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

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

1505 necessary if you want explicit deviations from these defaults. 

1506 Alternatively, you can also change the style cycle using 

1507 :rc:`axes.prop_cycle`. 

1508 

1509 

1510 Parameters 

1511 ---------- 

1512 x, y : array-like or scalar 

1513 The horizontal / vertical coordinates of the data points. 

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

1515 

1516 Commonly, these parameters are 1D arrays. 

1517 

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

1519 columns represent separate data sets). 

1520 

1521 These arguments cannot be passed as keywords. 

1522 

1523 fmt : str, optional 

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

1525 section for a full description of the format strings. 

1526 

1527 Format strings are just an abbreviation for quickly setting 

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

1529 controlled by keyword arguments. 

1530 

1531 This argument cannot be passed as keyword. 

1532 

1533 data : indexable object, optional 

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

1535 plot in *x* and *y*. 

1536 

1537 .. note:: 

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

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

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

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

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

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

1544 

1545 Returns 

1546 ------- 

1547 list of `.Line2D` 

1548 A list of lines representing the plotted data. 

1549 

1550 Other Parameters 

1551 ---------------- 

1552 scalex, scaley : bool, default: True 

1553 These parameters determine if the view limits are adapted to the 

1554 data limits. The values are passed on to 

1555 `~.axes.Axes.autoscale_view`. 

1556 

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

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

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

1560 Example:: 

1561 

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

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

1564 

1565 If you specify multiple lines with one plot call, the kwargs apply 

1566 to all those lines. In case the label object is iterable, each 

1567 element is used as labels for each set of data. 

1568 

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

1570 

1571 %(Line2D:kwdoc)s 

1572 

1573 See Also 

1574 -------- 

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

1576 sometimes also called bubble chart). 

1577 

1578 Notes 

1579 ----- 

1580 **Format Strings** 

1581 

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

1583 

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

1585 

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

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

1588 the data will be a line without markers. 

1589 

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

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

1592 

1593 **Markers** 

1594 

1595 ============= =============================== 

1596 character description 

1597 ============= =============================== 

1598 ``'.'`` point marker 

1599 ``','`` pixel marker 

1600 ``'o'`` circle marker 

1601 ``'v'`` triangle_down marker 

1602 ``'^'`` triangle_up marker 

1603 ``'<'`` triangle_left marker 

1604 ``'>'`` triangle_right marker 

1605 ``'1'`` tri_down marker 

1606 ``'2'`` tri_up marker 

1607 ``'3'`` tri_left marker 

1608 ``'4'`` tri_right marker 

1609 ``'8'`` octagon marker 

1610 ``'s'`` square marker 

1611 ``'p'`` pentagon marker 

1612 ``'P'`` plus (filled) marker 

1613 ``'*'`` star marker 

1614 ``'h'`` hexagon1 marker 

1615 ``'H'`` hexagon2 marker 

1616 ``'+'`` plus marker 

1617 ``'x'`` x marker 

1618 ``'X'`` x (filled) marker 

1619 ``'D'`` diamond marker 

1620 ``'d'`` thin_diamond marker 

1621 ``'|'`` vline marker 

1622 ``'_'`` hline marker 

1623 ============= =============================== 

1624 

1625 **Line Styles** 

1626 

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

1628 character description 

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

1630 ``'-'`` solid line style 

1631 ``'--'`` dashed line style 

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

1633 ``':'`` dotted line style 

1634 ============= =============================== 

1635 

1636 Example format strings:: 

1637 

1638 'b' # blue markers with default shape 

1639 'or' # red circles 

1640 '-g' # green solid line 

1641 '--' # dashed line with default color 

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

1643 

1644 **Colors** 

1645 

1646 The supported color abbreviations are the single letter codes 

1647 

1648 ============= =============================== 

1649 character color 

1650 ============= =============================== 

1651 ``'b'`` blue 

1652 ``'g'`` green 

1653 ``'r'`` red 

1654 ``'c'`` cyan 

1655 ``'m'`` magenta 

1656 ``'y'`` yellow 

1657 ``'k'`` black 

1658 ``'w'`` white 

1659 ============= =============================== 

1660 

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

1662 

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

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

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

1666 """ 

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

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

1669 for line in lines: 

1670 self.add_line(line) 

1671 if scalex: 

1672 self._request_autoscale_view("x") 

1673 if scaley: 

1674 self._request_autoscale_view("y") 

1675 return lines 

1676 

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

1678 @_docstring.dedent_interpd 

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

1680 **kwargs): 

1681 """ 

1682 [*Discouraged*] Plot coercing the axis to treat floats as dates. 

1683 

1684 .. admonition:: Discouraged 

1685 

1686 This method exists for historic reasons and will be deprecated in 

1687 the future. 

1688 

1689 - ``datetime``-like data should directly be plotted using 

1690 `~.Axes.plot`. 

1691 - If you need to plot plain numeric data as :ref:`date-format` or 

1692 need to set a timezone, call ``ax.xaxis.axis_date`` / 

1693 ``ax.yaxis.axis_date`` before `~.Axes.plot`. See 

1694 `.Axis.axis_date`. 

1695 

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

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

1698 and *ydate*. Note that `.plot` will work with `datetime` and 

1699 `numpy.datetime64` objects without resorting to this method. 

1700 

1701 Parameters 

1702 ---------- 

1703 x, y : array-like 

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

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

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

1707 

1708 fmt : str, optional 

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

1710 parameter in `.plot`. 

1711 

1712 tz : timezone string or `datetime.tzinfo`, default: :rc:`timezone` 

1713 The time zone to use in labeling dates. 

1714 

1715 xdate : bool, default: True 

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

1717 

1718 ydate : bool, default: False 

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

1720 

1721 Returns 

1722 ------- 

1723 list of `.Line2D` 

1724 Objects representing the plotted data. 

1725 

1726 Other Parameters 

1727 ---------------- 

1728 data : indexable object, optional 

1729 DATA_PARAMETER_PLACEHOLDER 

1730 **kwargs 

1731 Keyword arguments control the `.Line2D` properties: 

1732 

1733 %(Line2D:kwdoc)s 

1734 

1735 See Also 

1736 -------- 

1737 matplotlib.dates : Helper functions on dates. 

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

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

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

1741 

1742 Notes 

1743 ----- 

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

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

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

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

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

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

1750 `.DateFormatter` instance). 

1751 """ 

1752 if xdate: 

1753 self.xaxis_date(tz) 

1754 if ydate: 

1755 self.yaxis_date(tz) 

1756 return self.plot(x, y, fmt, **kwargs) 

1757 

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

1759 @_docstring.dedent_interpd 

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

1761 """ 

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

1763 

1764 Call signatures:: 

1765 

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

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

1768 

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

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

1771 parameters of plot can be used here as well. 

1772 

1773 The additional parameters *base*, *subs* and *nonpositive* control the 

1774 x/y-axis properties. They are just forwarded to `.Axes.set_xscale` and 

1775 `.Axes.set_yscale`. To use different properties on the x-axis and the 

1776 y-axis, use e.g. 

1777 ``ax.set_xscale("log", base=10); ax.set_yscale("log", base=2)``. 

1778 

1779 Parameters 

1780 ---------- 

1781 base : float, default: 10 

1782 Base of the logarithm. 

1783 

1784 subs : sequence, optional 

1785 The location of the minor ticks. If *None*, reasonable locations 

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

1787 plot. See `.Axes.set_xscale`/`.Axes.set_yscale` for details. 

1788 

1789 nonpositive : {'mask', 'clip'}, default: 'mask' 

1790 Non-positive values can be masked as invalid, or clipped to a very 

1791 small positive number. 

1792 

1793 **kwargs 

1794 All parameters supported by `.plot`. 

1795 

1796 Returns 

1797 ------- 

1798 list of `.Line2D` 

1799 Objects representing the plotted data. 

1800 """ 

1801 dx = {k: v for k, v in kwargs.items() 

1802 if k in ['base', 'subs', 'nonpositive', 

1803 'basex', 'subsx', 'nonposx']} 

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

1805 dy = {k: v for k, v in kwargs.items() 

1806 if k in ['base', 'subs', 'nonpositive', 

1807 'basey', 'subsy', 'nonposy']} 

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

1809 return self.plot( 

1810 *args, **{k: v for k, v in kwargs.items() if k not in {*dx, *dy}}) 

1811 

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

1813 @_docstring.dedent_interpd 

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

1815 """ 

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

1817 

1818 Call signatures:: 

1819 

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

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

1822 

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

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

1825 can be used here as well. 

1826 

1827 The additional parameters *base*, *subs*, and *nonpositive* control the 

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

1829 

1830 Parameters 

1831 ---------- 

1832 base : float, default: 10 

1833 Base of the x logarithm. 

1834 

1835 subs : array-like, optional 

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

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

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

1839 

1840 nonpositive : {'mask', 'clip'}, default: 'mask' 

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

1842 very small positive number. 

1843 

1844 **kwargs 

1845 All parameters supported by `.plot`. 

1846 

1847 Returns 

1848 ------- 

1849 list of `.Line2D` 

1850 Objects representing the plotted data. 

1851 """ 

1852 d = {k: v for k, v in kwargs.items() 

1853 if k in ['base', 'subs', 'nonpositive', 

1854 'basex', 'subsx', 'nonposx']} 

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

1856 return self.plot( 

1857 *args, **{k: v for k, v in kwargs.items() if k not in d}) 

1858 

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

1860 @_docstring.dedent_interpd 

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

1862 """ 

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

1864 

1865 Call signatures:: 

1866 

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

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

1869 

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

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

1872 can be used here as well. 

1873 

1874 The additional parameters *base*, *subs*, and *nonpositive* control the 

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

1876 

1877 Parameters 

1878 ---------- 

1879 base : float, default: 10 

1880 Base of the y logarithm. 

1881 

1882 subs : array-like, optional 

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

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

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

1886 

1887 nonpositive : {'mask', 'clip'}, default: 'mask' 

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

1889 very small positive number. 

1890 

1891 **kwargs 

1892 All parameters supported by `.plot`. 

1893 

1894 Returns 

1895 ------- 

1896 list of `.Line2D` 

1897 Objects representing the plotted data. 

1898 """ 

1899 d = {k: v for k, v in kwargs.items() 

1900 if k in ['base', 'subs', 'nonpositive', 

1901 'basey', 'subsy', 'nonposy']} 

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

1903 return self.plot( 

1904 *args, **{k: v for k, v in kwargs.items() if k not in d}) 

1905 

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

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

1908 """ 

1909 Plot the autocorrelation of *x*. 

1910 

1911 Parameters 

1912 ---------- 

1913 x : array-like 

1914 

1915 detrend : callable, default: `.mlab.detrend_none` (no detrending) 

1916 A detrending function applied to *x*. It must have the 

1917 signature :: 

1918 

1919 detrend(x: np.ndarray) -> np.ndarray 

1920 

1921 normed : bool, default: True 

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

1923 

1924 usevlines : bool, default: True 

1925 Determines the plot style. 

1926 

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

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

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

1930 

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

1932 `.Axes.plot`. 

1933 

1934 maxlags : int, default: 10 

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

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

1937 

1938 Returns 

1939 ------- 

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

1941 The lag vector. 

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

1943 The auto correlation vector. 

1944 line : `.LineCollection` or `.Line2D` 

1945 `.Artist` added to the Axes of the correlation: 

1946 

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

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

1949 b : `.Line2D` or None 

1950 Horizontal line at 0 if *usevlines* is True 

1951 None *usevlines* is False. 

1952 

1953 Other Parameters 

1954 ---------------- 

1955 linestyle : `.Line2D` property, optional 

1956 The linestyle for plotting the data points. 

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

1958 

1959 marker : str, default: 'o' 

1960 The marker for plotting the data points. 

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

1962 

1963 data : indexable object, optional 

1964 DATA_PARAMETER_PLACEHOLDER 

1965 

1966 **kwargs 

1967 Additional parameters are passed to `.Axes.vlines` and 

1968 `.Axes.axhline` if *usevlines* is ``True``; otherwise they are 

1969 passed to `.Axes.plot`. 

1970 

1971 Notes 

1972 ----- 

1973 The cross correlation is performed with `numpy.correlate` with 

1974 ``mode = "full"``. 

1975 """ 

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

1977 

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

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

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

1981 r""" 

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

1983 

1984 The correlation with lag k is defined as 

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

1986 conjugate of :math:`y`. 

1987 

1988 Parameters 

1989 ---------- 

1990 x, y : array-like of length n 

1991 

1992 detrend : callable, default: `.mlab.detrend_none` (no detrending) 

1993 A detrending function applied to *x* and *y*. It must have the 

1994 signature :: 

1995 

1996 detrend(x: np.ndarray) -> np.ndarray 

1997 

1998 normed : bool, default: True 

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

2000 

2001 usevlines : bool, default: True 

2002 Determines the plot style. 

2003 

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

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

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

2007 

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

2009 `.Axes.plot`. 

2010 

2011 maxlags : int, default: 10 

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

2013 lags. 

2014 

2015 Returns 

2016 ------- 

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

2018 The lag vector. 

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

2020 The auto correlation vector. 

2021 line : `.LineCollection` or `.Line2D` 

2022 `.Artist` added to the Axes of the correlation: 

2023 

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

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

2026 b : `.Line2D` or None 

2027 Horizontal line at 0 if *usevlines* is True 

2028 None *usevlines* is False. 

2029 

2030 Other Parameters 

2031 ---------------- 

2032 linestyle : `.Line2D` property, optional 

2033 The linestyle for plotting the data points. 

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

2035 

2036 marker : str, default: 'o' 

2037 The marker for plotting the data points. 

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

2039 

2040 data : indexable object, optional 

2041 DATA_PARAMETER_PLACEHOLDER 

2042 

2043 **kwargs 

2044 Additional parameters are passed to `.Axes.vlines` and 

2045 `.Axes.axhline` if *usevlines* is ``True``; otherwise they are 

2046 passed to `.Axes.plot`. 

2047 

2048 Notes 

2049 ----- 

2050 The cross correlation is performed with `numpy.correlate` with 

2051 ``mode = "full"``. 

2052 """ 

2053 Nx = len(x) 

2054 if Nx != len(y): 

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

2056 

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

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

2059 

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

2061 

2062 if normed: 

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

2064 

2065 if maxlags is None: 

2066 maxlags = Nx - 1 

2067 

2068 if maxlags >= Nx or maxlags < 1: 

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

2070 'positive < %d' % Nx) 

2071 

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

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

2074 

2075 if usevlines: 

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

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

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

2079 b = self.axhline(**kwargs) 

2080 else: 

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

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

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

2084 b = None 

2085 return lags, correls, a, b 

2086 

2087 #### Specialized plotting 

2088 

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

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

2091 """ 

2092 Make a step plot. 

2093 

2094 Call signatures:: 

2095 

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

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

2098 

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

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

2101 used here as well. 

2102 

2103 .. note:: 

2104 

2105 This method uses a standard plot with a step drawstyle: The *x* 

2106 values are the reference positions and steps extend left/right/both 

2107 directions depending on *where*. 

2108 

2109 For the common case where you know the values and edges of the 

2110 steps, use `~.Axes.stairs` instead. 

2111 

2112 Parameters 

2113 ---------- 

2114 x : array-like 

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

2116 it is uniformly increasing. 

2117 

2118 y : array-like 

2119 1D sequence of y levels. 

2120 

2121 fmt : str, optional 

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

2123 detailed description. 

2124 

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

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

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

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

2129 needed feature for step plots. 

2130 

2131 where : {'pre', 'post', 'mid'}, default: 'pre' 

2132 Define where the steps should be placed: 

2133 

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

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

2136 value ``y[i]``. 

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

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

2139 value ``y[i]``. 

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

2141 

2142 data : indexable object, optional 

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

2144 plot in *x* and *y*. 

2145 

2146 **kwargs 

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

2148 

2149 Returns 

2150 ------- 

2151 list of `.Line2D` 

2152 Objects representing the plotted data. 

2153 """ 

2154 _api.check_in_list(('pre', 'post', 'mid'), where=where) 

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

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

2157 

2158 @staticmethod 

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

2160 """ 

2161 Small helper to do logic of width conversion flexibly. 

2162 

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

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

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

2166 ``__add__`` operator of *x0*. 

2167 """ 

2168 

2169 # x should be an array... 

2170 assert type(xconv) is np.ndarray 

2171 

2172 if xconv.size == 0: 

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

2174 return convert(dx) 

2175 

2176 try: 

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

2178 # datetime+timedelta, for instance 

2179 

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

2181 # having to be sure addition works across the whole 

2182 # vector. This is particularly an issue if 

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

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

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

2186 # wrap numpy arrays. 

2187 try: 

2188 x0 = cbook._safe_first_finite(x0) 

2189 except (TypeError, IndexError, KeyError): 

2190 pass 

2191 except StopIteration: 

2192 # this means we found no finite element, fall back to first 

2193 # element unconditionally 

2194 x0 = cbook.safe_first_element(x0) 

2195 

2196 try: 

2197 x = cbook._safe_first_finite(xconv) 

2198 except (TypeError, IndexError, KeyError): 

2199 x = xconv 

2200 except StopIteration: 

2201 # this means we found no finite element, fall back to first 

2202 # element unconditionally 

2203 x = cbook.safe_first_element(xconv) 

2204 

2205 delist = False 

2206 if not np.iterable(dx): 

2207 dx = [dx] 

2208 delist = True 

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

2210 if delist: 

2211 dx = dx[0] 

2212 except (ValueError, TypeError, AttributeError): 

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

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

2215 dx = convert(dx) 

2216 return dx 

2217 

2218 @_preprocess_data() 

2219 @_docstring.dedent_interpd 

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

2221 **kwargs): 

2222 r""" 

2223 Make a bar plot. 

2224 

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

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

2227 is *bottom* (default 0). 

2228 

2229 Many parameters can take either a single value applying to all bars 

2230 or a sequence of values, one for each bar. 

2231 

2232 Parameters 

2233 ---------- 

2234 x : float or array-like 

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

2236 alignment of the bars to the coordinates. 

2237 

2238 height : float or array-like 

2239 The height(s) of the bars. 

2240 

2241 width : float or array-like, default: 0.8 

2242 The width(s) of the bars. 

2243 

2244 bottom : float or array-like, default: 0 

2245 The y coordinate(s) of the bottom side(s) of the bars. 

2246 

2247 align : {'center', 'edge'}, default: 'center' 

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

2249 

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

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

2252 

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

2254 ``align='edge'``. 

2255 

2256 Returns 

2257 ------- 

2258 `.BarContainer` 

2259 Container with all the bars and optionally errorbars. 

2260 

2261 Other Parameters 

2262 ---------------- 

2263 color : color or list of color, optional 

2264 The colors of the bar faces. 

2265 

2266 edgecolor : color or list of color, optional 

2267 The colors of the bar edges. 

2268 

2269 linewidth : float or array-like, optional 

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

2271 

2272 tick_label : str or list of str, optional 

2273 The tick labels of the bars. 

2274 Default: None (Use default numeric labels.) 

2275 

2276 label : str or list of str, optional 

2277 A single label is attached to the resulting `.BarContainer` as a 

2278 label for the whole dataset. 

2279 If a list is provided, it must be the same length as *x* and 

2280 labels the individual bars. Repeated labels are not de-duplicated 

2281 and will cause repeated label entries, so this is best used when 

2282 bars also differ in style (e.g., by passing a list to *color*.) 

2283 

2284 xerr, yerr : float or array-like of shape(N,) or shape(2, N), optional 

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

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

2287 

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

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

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

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

2292 errors. 

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

2294 

2295 See :doc:`/gallery/statistics/errorbar_features` for an example on 

2296 the usage of *xerr* and *yerr*. 

2297 

2298 ecolor : color or list of color, default: 'black' 

2299 The line color of the errorbars. 

2300 

2301 capsize : float, default: :rc:`errorbar.capsize` 

2302 The length of the error bar caps in points. 

2303 

2304 error_kw : dict, optional 

2305 Dictionary of keyword arguments to be passed to the 

2306 `~.Axes.errorbar` method. Values of *ecolor* or *capsize* defined 

2307 here take precedence over the independent keyword arguments. 

2308 

2309 log : bool, default: False 

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

2311 

2312 data : indexable object, optional 

2313 DATA_PARAMETER_PLACEHOLDER 

2314 

2315 **kwargs : `.Rectangle` properties 

2316 

2317 %(Rectangle:kwdoc)s 

2318 

2319 See Also 

2320 -------- 

2321 barh : Plot a horizontal bar plot. 

2322 

2323 Notes 

2324 ----- 

2325 Stacked bars can be achieved by passing individual *bottom* values per 

2326 bar. See :doc:`/gallery/lines_bars_and_markers/bar_stacked`. 

2327 """ 

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

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

2330 if color is None: 

2331 color = self._get_patches_for_fill.get_next_color() 

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

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

2334 hatch = kwargs.pop('hatch', None) 

2335 

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

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

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

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

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

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

2342 if ezorder is None: 

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

2344 if ezorder is not None: 

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

2346 # errorbars are drawn on top of bars 

2347 ezorder += 0.01 

2348 error_kw.setdefault('zorder', ezorder) 

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

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

2351 error_kw.setdefault('ecolor', ecolor) 

2352 error_kw.setdefault('capsize', capsize) 

2353 

2354 # The keyword argument *orientation* is used by barh() to defer all 

2355 # logic and drawing to bar(). It is considered internal and is 

2356 # intentionally not mentioned in the docstring. 

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

2358 _api.check_in_list(['vertical', 'horizontal'], orientation=orientation) 

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

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

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

2362 

2363 y = bottom # Matches barh call signature. 

2364 if orientation == 'vertical': 

2365 if y is None: 

2366 y = 0 

2367 else: # horizontal 

2368 if x is None: 

2369 x = 0 

2370 

2371 if orientation == 'vertical': 

2372 self._process_unit_info( 

2373 [("x", x), ("y", height)], kwargs, convert=False) 

2374 if log: 

2375 self.set_yscale('log', nonpositive='clip') 

2376 else: # horizontal 

2377 self._process_unit_info( 

2378 [("x", width), ("y", y)], kwargs, convert=False) 

2379 if log: 

2380 self.set_xscale('log', nonpositive='clip') 

2381 

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

2383 # subtracted uniformly 

2384 if self.xaxis is not None: 

2385 x0 = x 

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

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

2388 if xerr is not None: 

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

2390 if self.yaxis is not None: 

2391 y0 = y 

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

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

2394 if yerr is not None: 

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

2396 

2397 x, height, width, y, linewidth, hatch = np.broadcast_arrays( 

2398 # Make args iterable too. 

2399 np.atleast_1d(x), height, width, y, linewidth, hatch) 

2400 

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

2402 if orientation == 'vertical': 

2403 tick_label_axis = self.xaxis 

2404 tick_label_position = x 

2405 else: # horizontal 

2406 tick_label_axis = self.yaxis 

2407 tick_label_position = y 

2408 

2409 if not isinstance(label, str) and np.iterable(label): 

2410 bar_container_label = '_nolegend_' 

2411 patch_labels = label 

2412 else: 

2413 bar_container_label = label 

2414 patch_labels = ['_nolegend_'] * len(x) 

2415 if len(patch_labels) != len(x): 

2416 raise ValueError(f'number of labels ({len(patch_labels)}) ' 

2417 f'does not match number of bars ({len(x)}).') 

2418 

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

2420 hatch = itertools.cycle(np.atleast_1d(hatch)) 

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

2422 # Fallback if color == "none". 

2423 itertools.repeat('none')) 

2424 if edgecolor is None: 

2425 edgecolor = itertools.repeat(None) 

2426 else: 

2427 edgecolor = itertools.chain( 

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

2429 # Fallback if edgecolor == "none". 

2430 itertools.repeat('none')) 

2431 

2432 # We will now resolve the alignment and really have 

2433 # left, bottom, width, height vectors 

2434 _api.check_in_list(['center', 'edge'], align=align) 

2435 if align == 'center': 

2436 if orientation == 'vertical': 

2437 try: 

2438 left = x - width / 2 

2439 except TypeError as e: 

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

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

2442 f'are incompatible') from e 

2443 bottom = y 

2444 else: # horizontal 

2445 try: 

2446 bottom = y - height / 2 

2447 except TypeError as e: 

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

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

2450 f'are incompatible') from e 

2451 left = x 

2452 else: # edge 

2453 left = x 

2454 bottom = y 

2455 

2456 patches = [] 

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

2458 hatch, patch_labels) 

2459 for l, b, w, h, c, e, lw, htch, lbl in args: 

2460 r = mpatches.Rectangle( 

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

2462 facecolor=c, 

2463 edgecolor=e, 

2464 linewidth=lw, 

2465 label=lbl, 

2466 hatch=htch, 

2467 ) 

2468 r._internal_update(kwargs) 

2469 r.get_path()._interpolation_steps = 100 

2470 if orientation == 'vertical': 

2471 r.sticky_edges.y.append(b) 

2472 else: # horizontal 

2473 r.sticky_edges.x.append(l) 

2474 self.add_patch(r) 

2475 patches.append(r) 

2476 

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

2478 if orientation == 'vertical': 

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

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

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

2482 

2483 else: # horizontal 

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

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

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

2487 

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

2489 

2490 errorbar = self.errorbar(ex, ey, 

2491 yerr=yerr, xerr=xerr, 

2492 fmt='none', **error_kw) 

2493 else: 

2494 errorbar = None 

2495 

2496 self._request_autoscale_view() 

2497 

2498 if orientation == 'vertical': 

2499 datavalues = height 

2500 else: # horizontal 

2501 datavalues = width 

2502 

2503 bar_container = BarContainer(patches, errorbar, datavalues=datavalues, 

2504 orientation=orientation, 

2505 label=bar_container_label) 

2506 self.add_container(bar_container) 

2507 

2508 if tick_labels is not None: 

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

2510 tick_label_axis.set_ticks(tick_label_position) 

2511 tick_label_axis.set_ticklabels(tick_labels) 

2512 

2513 return bar_container 

2514 

2515 # @_preprocess_data() # let 'bar' do the unpacking.. 

2516 @_docstring.dedent_interpd 

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

2518 data=None, **kwargs): 

2519 r""" 

2520 Make a horizontal bar plot. 

2521 

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

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

2524 is *left* (default 0). 

2525 

2526 Many parameters can take either a single value applying to all bars 

2527 or a sequence of values, one for each bar. 

2528 

2529 Parameters 

2530 ---------- 

2531 y : float or array-like 

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

2533 alignment of the bars to the coordinates. 

2534 

2535 width : float or array-like 

2536 The width(s) of the bars. 

2537 

2538 height : float or array-like, default: 0.8 

2539 The heights of the bars. 

2540 

2541 left : float or array-like, default: 0 

2542 The x coordinates of the left side(s) of the bars. 

2543 

2544 align : {'center', 'edge'}, default: 'center' 

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

2546 

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

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

2549 positions. 

2550 

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

2552 ``align='edge'``. 

2553 

2554 Returns 

2555 ------- 

2556 `.BarContainer` 

2557 Container with all the bars and optionally errorbars. 

2558 

2559 Other Parameters 

2560 ---------------- 

2561 color : color or list of color, optional 

2562 The colors of the bar faces. 

2563 

2564 edgecolor : color or list of color, optional 

2565 The colors of the bar edges. 

2566 

2567 linewidth : float or array-like, optional 

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

2569 

2570 tick_label : str or list of str, optional 

2571 The tick labels of the bars. 

2572 Default: None (Use default numeric labels.) 

2573 

2574 label : str or list of str, optional 

2575 A single label is attached to the resulting `.BarContainer` as a 

2576 label for the whole dataset. 

2577 If a list is provided, it must be the same length as *y* and 

2578 labels the individual bars. Repeated labels are not de-duplicated 

2579 and will cause repeated label entries, so this is best used when 

2580 bars also differ in style (e.g., by passing a list to *color*.) 

2581 

2582 xerr, yerr : float or array-like of shape(N,) or shape(2, N), optional 

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

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

2585 

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

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

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

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

2590 errors. 

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

2592 

2593 See :doc:`/gallery/statistics/errorbar_features` for an example on 

2594 the usage of *xerr* and *yerr*. 

2595 

2596 ecolor : color or list of color, default: 'black' 

2597 The line color of the errorbars. 

2598 

2599 capsize : float, default: :rc:`errorbar.capsize` 

2600 The length of the error bar caps in points. 

2601 

2602 error_kw : dict, optional 

2603 Dictionary of keyword arguments to be passed to the 

2604 `~.Axes.errorbar` method. Values of *ecolor* or *capsize* defined 

2605 here take precedence over the independent keyword arguments. 

2606 

2607 log : bool, default: False 

2608 If ``True``, set the x-axis to be log scale. 

2609 

2610 data : indexable object, optional 

2611 If given, all parameters also accept a string ``s``, which is 

2612 interpreted as ``data[s]`` (unless this raises an exception). 

2613 

2614 **kwargs : `.Rectangle` properties 

2615 

2616 %(Rectangle:kwdoc)s 

2617 

2618 See Also 

2619 -------- 

2620 bar : Plot a vertical bar plot. 

2621 

2622 Notes 

2623 ----- 

2624 Stacked bars can be achieved by passing individual *left* values per 

2625 bar. See 

2626 :doc:`/gallery/lines_bars_and_markers/horizontal_barchart_distribution`. 

2627 """ 

2628 kwargs.setdefault('orientation', 'horizontal') 

2629 patches = self.bar(x=left, height=height, width=width, bottom=y, 

2630 align=align, data=data, **kwargs) 

2631 return patches 

2632 

2633 def bar_label(self, container, labels=None, *, fmt="%g", label_type="edge", 

2634 padding=0, **kwargs): 

2635 """ 

2636 Label a bar plot. 

2637 

2638 Adds labels to bars in the given `.BarContainer`. 

2639 You may need to adjust the axis limits to fit the labels. 

2640 

2641 Parameters 

2642 ---------- 

2643 container : `.BarContainer` 

2644 Container with all the bars and optionally errorbars, likely 

2645 returned from `.bar` or `.barh`. 

2646 

2647 labels : array-like, optional 

2648 A list of label texts, that should be displayed. If not given, the 

2649 label texts will be the data values formatted with *fmt*. 

2650 

2651 fmt : str, default: '%g' 

2652 A format string for the label. 

2653 

2654 label_type : {'edge', 'center'}, default: 'edge' 

2655 The label type. Possible values: 

2656 

2657 - 'edge': label placed at the end-point of the bar segment, and the 

2658 value displayed will be the position of that end-point. 

2659 - 'center': label placed in the center of the bar segment, and the 

2660 value displayed will be the length of that segment. 

2661 (useful for stacked bars, i.e., 

2662 :doc:`/gallery/lines_bars_and_markers/bar_label_demo`) 

2663 

2664 padding : float, default: 0 

2665 Distance of label from the end of the bar, in points. 

2666 

2667 **kwargs 

2668 Any remaining keyword arguments are passed through to 

2669 `.Axes.annotate`. The alignment parameters ( 

2670 *horizontalalignment* / *ha*, *verticalalignment* / *va*) are 

2671 not supported because the labels are automatically aligned to 

2672 the bars. 

2673 

2674 Returns 

2675 ------- 

2676 list of `.Text` 

2677 A list of `.Text` instances for the labels. 

2678 """ 

2679 for key in ['horizontalalignment', 'ha', 'verticalalignment', 'va']: 

2680 if key in kwargs: 

2681 raise ValueError( 

2682 f"Passing {key!r} to bar_label() is not supported.") 

2683 

2684 a, b = self.yaxis.get_view_interval() 

2685 y_inverted = a > b 

2686 c, d = self.xaxis.get_view_interval() 

2687 x_inverted = c > d 

2688 

2689 # want to know whether to put label on positive or negative direction 

2690 # cannot use np.sign here because it will return 0 if x == 0 

2691 def sign(x): 

2692 return 1 if x >= 0 else -1 

2693 

2694 _api.check_in_list(['edge', 'center'], label_type=label_type) 

2695 

2696 bars = container.patches 

2697 errorbar = container.errorbar 

2698 datavalues = container.datavalues 

2699 orientation = container.orientation 

2700 

2701 if errorbar: 

2702 # check "ErrorbarContainer" for the definition of these elements 

2703 lines = errorbar.lines # attribute of "ErrorbarContainer" (tuple) 

2704 barlinecols = lines[2] # 0: data_line, 1: caplines, 2: barlinecols 

2705 barlinecol = barlinecols[0] # the "LineCollection" of error bars 

2706 errs = barlinecol.get_segments() 

2707 else: 

2708 errs = [] 

2709 

2710 if labels is None: 

2711 labels = [] 

2712 

2713 annotations = [] 

2714 

2715 for bar, err, dat, lbl in itertools.zip_longest( 

2716 bars, errs, datavalues, labels 

2717 ): 

2718 (x0, y0), (x1, y1) = bar.get_bbox().get_points() 

2719 xc, yc = (x0 + x1) / 2, (y0 + y1) / 2 

2720 

2721 if orientation == "vertical": 

2722 extrema = max(y0, y1) if dat >= 0 else min(y0, y1) 

2723 length = abs(y0 - y1) 

2724 else: # horizontal 

2725 extrema = max(x0, x1) if dat >= 0 else min(x0, x1) 

2726 length = abs(x0 - x1) 

2727 

2728 if err is None or np.size(err) == 0: 

2729 endpt = extrema 

2730 elif orientation == "vertical": 

2731 endpt = err[:, 1].max() if dat >= 0 else err[:, 1].min() 

2732 else: # horizontal 

2733 endpt = err[:, 0].max() if dat >= 0 else err[:, 0].min() 

2734 

2735 if label_type == "center": 

2736 value = sign(dat) * length 

2737 else: # edge 

2738 value = extrema 

2739 

2740 if label_type == "center": 

2741 xy = xc, yc 

2742 else: # edge 

2743 if orientation == "vertical": 

2744 xy = xc, endpt 

2745 else: # horizontal 

2746 xy = endpt, yc 

2747 

2748 if orientation == "vertical": 

2749 y_direction = -1 if y_inverted else 1 

2750 xytext = 0, y_direction * sign(dat) * padding 

2751 else: # horizontal 

2752 x_direction = -1 if x_inverted else 1 

2753 xytext = x_direction * sign(dat) * padding, 0 

2754 

2755 if label_type == "center": 

2756 ha, va = "center", "center" 

2757 else: # edge 

2758 if orientation == "vertical": 

2759 ha = 'center' 

2760 if y_inverted: 

2761 va = 'top' if dat > 0 else 'bottom' # also handles NaN 

2762 else: 

2763 va = 'top' if dat < 0 else 'bottom' # also handles NaN 

2764 else: # horizontal 

2765 if x_inverted: 

2766 ha = 'right' if dat > 0 else 'left' # also handles NaN 

2767 else: 

2768 ha = 'right' if dat < 0 else 'left' # also handles NaN 

2769 va = 'center' 

2770 

2771 if np.isnan(dat): 

2772 lbl = '' 

2773 

2774 annotation = self.annotate(fmt % value if lbl is None else lbl, 

2775 xy, xytext, textcoords="offset points", 

2776 ha=ha, va=va, **kwargs) 

2777 annotations.append(annotation) 

2778 

2779 return annotations 

2780 

2781 @_preprocess_data() 

2782 @_docstring.dedent_interpd 

2783 def broken_barh(self, xranges, yrange, **kwargs): 

2784 """ 

2785 Plot a horizontal sequence of rectangles. 

2786 

2787 A rectangle is drawn for each element of *xranges*. All rectangles 

2788 have the same vertical position and size defined by *yrange*. 

2789 

2790 This is a convenience function for instantiating a 

2791 `.BrokenBarHCollection`, adding it to the Axes and autoscaling the 

2792 view. 

2793 

2794 Parameters 

2795 ---------- 

2796 xranges : sequence of tuples (*xmin*, *xwidth*) 

2797 The x-positions and extends of the rectangles. For each tuple 

2798 (*xmin*, *xwidth*) a rectangle is drawn from *xmin* to *xmin* + 

2799 *xwidth*. 

2800 yrange : (*ymin*, *yheight*) 

2801 The y-position and extend for all the rectangles. 

2802 

2803 Returns 

2804 ------- 

2805 `~.collections.BrokenBarHCollection` 

2806 

2807 Other Parameters 

2808 ---------------- 

2809 data : indexable object, optional 

2810 DATA_PARAMETER_PLACEHOLDER 

2811 **kwargs : `.BrokenBarHCollection` properties 

2812 

2813 Each *kwarg* can be either a single argument applying to all 

2814 rectangles, e.g.:: 

2815 

2816 facecolors='black' 

2817 

2818 or a sequence of arguments over which is cycled, e.g.:: 

2819 

2820 facecolors=('black', 'blue') 

2821 

2822 would create interleaving black and blue rectangles. 

2823 

2824 Supported keywords: 

2825 

2826 %(BrokenBarHCollection:kwdoc)s 

2827 """ 

2828 # process the unit information 

2829 if len(xranges): 

2830 xdata = cbook._safe_first_finite(xranges) 

2831 else: 

2832 xdata = None 

2833 if len(yrange): 

2834 ydata = cbook._safe_first_finite(yrange) 

2835 else: 

2836 ydata = None 

2837 self._process_unit_info( 

2838 [("x", xdata), ("y", ydata)], kwargs, convert=False) 

2839 xranges_conv = [] 

2840 for xr in xranges: 

2841 if len(xr) != 2: 

2842 raise ValueError('each range in xrange must be a sequence ' 

2843 'with two elements (i.e. an Nx2 array)') 

2844 # convert the absolute values, not the x and dx... 

2845 x_conv = np.asarray(self.convert_xunits(xr[0])) 

2846 x1 = self._convert_dx(xr[1], xr[0], x_conv, self.convert_xunits) 

2847 xranges_conv.append((x_conv, x1)) 

2848 

2849 yrange_conv = self.convert_yunits(yrange) 

2850 

2851 col = mcoll.BrokenBarHCollection(xranges_conv, yrange_conv, **kwargs) 

2852 self.add_collection(col, autolim=True) 

2853 self._request_autoscale_view() 

2854 

2855 return col 

2856 

2857 @_preprocess_data() 

2858 @_api.delete_parameter("3.6", "use_line_collection") 

2859 def stem(self, *args, linefmt=None, markerfmt=None, basefmt=None, bottom=0, 

2860 label=None, use_line_collection=True, orientation='vertical'): 

2861 """ 

2862 Create a stem plot. 

2863 

2864 A stem plot draws lines perpendicular to a baseline at each location 

2865 *locs* from the baseline to *heads*, and places a marker there. For 

2866 vertical stem plots (the default), the *locs* are *x* positions, and 

2867 the *heads* are *y* values. For horizontal stem plots, the *locs* are 

2868 *y* positions, and the *heads* are *x* values. 

2869 

2870 Call signature:: 

2871 

2872 stem([locs,] heads, linefmt=None, markerfmt=None, basefmt=None) 

2873 

2874 The *locs*-positions are optional. The formats may be provided either 

2875 as positional or as keyword-arguments. 

2876 Passing *markerfmt* and *basefmt* positionally is deprecated since 

2877 Matplotlib 3.5. 

2878 

2879 Parameters 

2880 ---------- 

2881 locs : array-like, default: (0, 1, ..., len(heads) - 1) 

2882 For vertical stem plots, the x-positions of the stems. 

2883 For horizontal stem plots, the y-positions of the stems. 

2884 

2885 heads : array-like 

2886 For vertical stem plots, the y-values of the stem heads. 

2887 For horizontal stem plots, the x-values of the stem heads. 

2888 

2889 linefmt : str, optional 

2890 A string defining the color and/or linestyle of the vertical lines: 

2891 

2892 ========= ============= 

2893 Character Line Style 

2894 ========= ============= 

2895 ``'-'`` solid line 

2896 ``'--'`` dashed line 

2897 ``'-.'`` dash-dot line 

2898 ``':'`` dotted line 

2899 ========= ============= 

2900 

2901 Default: 'C0-', i.e. solid line with the first color of the color 

2902 cycle. 

2903 

2904 Note: Markers specified through this parameter (e.g. 'x') will be 

2905 silently ignored (unless using ``use_line_collection=False``). 

2906 Instead, markers should be specified using *markerfmt*. 

2907 

2908 markerfmt : str, optional 

2909 A string defining the color and/or shape of the markers at the stem 

2910 heads. If the marker is not given, use the marker 'o', i.e. filled 

2911 circles. If the color is not given, use the color from *linefmt*. 

2912 

2913 basefmt : str, default: 'C3-' ('C2-' in classic mode) 

2914 A format string defining the properties of the baseline. 

2915 

2916 orientation : {'vertical', 'horizontal'}, default: 'vertical' 

2917 If 'vertical', will produce a plot with stems oriented vertically, 

2918 If 'horizontal', the stems will be oriented horizontally. 

2919 

2920 bottom : float, default: 0 

2921 The y/x-position of the baseline (depending on orientation). 

2922 

2923 label : str, default: None 

2924 The label to use for the stems in legends. 

2925 

2926 use_line_collection : bool, default: True 

2927 *Deprecated since 3.6* 

2928 

2929 If ``True``, store and plot the stem lines as a 

2930 `~.collections.LineCollection` instead of individual lines, which 

2931 significantly increases performance. If ``False``, defaults to the 

2932 old behavior of using a list of `.Line2D` objects. 

2933 

2934 data : indexable object, optional 

2935 DATA_PARAMETER_PLACEHOLDER 

2936 

2937 Returns 

2938 ------- 

2939 `.StemContainer` 

2940 The container may be treated like a tuple 

2941 (*markerline*, *stemlines*, *baseline*) 

2942 

2943 Notes 

2944 ----- 

2945 .. seealso:: 

2946 The MATLAB function 

2947 `stem <https://www.mathworks.com/help/matlab/ref/stem.html>`_ 

2948 which inspired this method. 

2949 """ 

2950 if not 1 <= len(args) <= 5: 

2951 raise TypeError('stem expected between 1 and 5 positional ' 

2952 'arguments, got {}'.format(args)) 

2953 _api.check_in_list(['horizontal', 'vertical'], orientation=orientation) 

2954 

2955 if len(args) == 1: 

2956 heads, = args 

2957 locs = np.arange(len(heads)) 

2958 args = () 

2959 elif isinstance(args[1], str): 

2960 heads, *args = args 

2961 locs = np.arange(len(heads)) 

2962 else: 

2963 locs, heads, *args = args 

2964 if len(args) > 1: 

2965 _api.warn_deprecated( 

2966 "3.5", 

2967 message="Passing the markerfmt parameter positionally is " 

2968 "deprecated since Matplotlib %(since)s; the " 

2969 "parameter will become keyword-only %(removal)s.") 

2970 

2971 if orientation == 'vertical': 

2972 locs, heads = self._process_unit_info([("x", locs), ("y", heads)]) 

2973 else: # horizontal 

2974 heads, locs = self._process_unit_info([("x", heads), ("y", locs)]) 

2975 

2976 # resolve line format 

2977 if linefmt is None: 

2978 linefmt = args[0] if len(args) > 0 else "C0-" 

2979 linestyle, linemarker, linecolor = _process_plot_format(linefmt) 

2980 

2981 # resolve marker format 

2982 if markerfmt is None: 

2983 # if not given as kwarg, check for positional or fall back to 'o' 

2984 markerfmt = args[1] if len(args) > 1 else "o" 

2985 if markerfmt == '': 

2986 markerfmt = ' ' # = empty line style; '' would resolve rcParams 

2987 markerstyle, markermarker, markercolor = \ 

2988 _process_plot_format(markerfmt) 

2989 if markermarker is None: 

2990 markermarker = 'o' 

2991 if markerstyle is None: 

2992 markerstyle = 'None' 

2993 if markercolor is None: 

2994 markercolor = linecolor 

2995 

2996 # resolve baseline format 

2997 if basefmt is None: 

2998 basefmt = (args[2] if len(args) > 2 else 

2999 "C2-" if mpl.rcParams["_internal.classic_mode"] else 

3000 "C3-") 

3001 basestyle, basemarker, basecolor = _process_plot_format(basefmt) 

3002 

3003 # New behaviour in 3.1 is to use a LineCollection for the stemlines 

3004 if use_line_collection: 

3005 if linestyle is None: 

3006 linestyle = mpl.rcParams['lines.linestyle'] 

3007 xlines = self.vlines if orientation == "vertical" else self.hlines 

3008 stemlines = xlines( 

3009 locs, bottom, heads, 

3010 colors=linecolor, linestyles=linestyle, label="_nolegend_") 

3011 # Old behaviour is to plot each of the lines individually 

3012 else: 

3013 stemlines = [] 

3014 for loc, head in zip(locs, heads): 

3015 if orientation == 'horizontal': 

3016 xs = [bottom, head] 

3017 ys = [loc, loc] 

3018 else: 

3019 xs = [loc, loc] 

3020 ys = [bottom, head] 

3021 l, = self.plot(xs, ys, 

3022 color=linecolor, linestyle=linestyle, 

3023 marker=linemarker, label="_nolegend_") 

3024 stemlines.append(l) 

3025 

3026 if orientation == 'horizontal': 

3027 marker_x = heads 

3028 marker_y = locs 

3029 baseline_x = [bottom, bottom] 

3030 baseline_y = [np.min(locs), np.max(locs)] 

3031 else: 

3032 marker_x = locs 

3033 marker_y = heads 

3034 baseline_x = [np.min(locs), np.max(locs)] 

3035 baseline_y = [bottom, bottom] 

3036 

3037 markerline, = self.plot(marker_x, marker_y, 

3038 color=markercolor, linestyle=markerstyle, 

3039 marker=markermarker, label="_nolegend_") 

3040 

3041 baseline, = self.plot(baseline_x, baseline_y, 

3042 color=basecolor, linestyle=basestyle, 

3043 marker=basemarker, label="_nolegend_") 

3044 

3045 stem_container = StemContainer((markerline, stemlines, baseline), 

3046 label=label) 

3047 self.add_container(stem_container) 

3048 return stem_container 

3049 

3050 @_preprocess_data(replace_names=["x", "explode", "labels", "colors"]) 

3051 def pie(self, x, explode=None, labels=None, colors=None, 

3052 autopct=None, pctdistance=0.6, shadow=False, labeldistance=1.1, 

3053 startangle=0, radius=1, counterclock=True, 

3054 wedgeprops=None, textprops=None, center=(0, 0), 

3055 frame=False, rotatelabels=False, *, normalize=True): 

3056 """ 

3057 Plot a pie chart. 

3058 

3059 Make a pie chart of array *x*. The fractional area of each wedge is 

3060 given by ``x/sum(x)``. 

3061 

3062 The wedges are plotted counterclockwise, by default starting from the 

3063 x-axis. 

3064 

3065 Parameters 

3066 ---------- 

3067 x : 1D array-like 

3068 The wedge sizes. 

3069 

3070 explode : array-like, default: None 

3071 If not *None*, is a ``len(x)`` array which specifies the fraction 

3072 of the radius with which to offset each wedge. 

3073 

3074 labels : list, default: None 

3075 A sequence of strings providing the labels for each wedge 

3076 

3077 colors : array-like, default: None 

3078 A sequence of colors through which the pie chart will cycle. If 

3079 *None*, will use the colors in the currently active cycle. 

3080 

3081 autopct : None or str or callable, default: None 

3082 If not *None*, is a string or function used to label the wedges 

3083 with their numeric value. The label will be placed inside the 

3084 wedge. If it is a format string, the label will be ``fmt % pct``. 

3085 If it is a function, it will be called. 

3086 

3087 pctdistance : float, default: 0.6 

3088 The ratio between the center of each pie slice and the start of 

3089 the text generated by *autopct*. Ignored if *autopct* is *None*. 

3090 

3091 shadow : bool, default: False 

3092 Draw a shadow beneath the pie. 

3093 

3094 normalize : bool, default: True 

3095 When *True*, always make a full pie by normalizing x so that 

3096 ``sum(x) == 1``. *False* makes a partial pie if ``sum(x) <= 1`` 

3097 and raises a `ValueError` for ``sum(x) > 1``. 

3098 

3099 labeldistance : float or None, default: 1.1 

3100 The radial distance at which the pie labels are drawn. 

3101 If set to ``None``, label are not drawn, but are stored for use in 

3102 ``legend()`` 

3103 

3104 startangle : float, default: 0 degrees 

3105 The angle by which the start of the pie is rotated, 

3106 counterclockwise from the x-axis. 

3107 

3108 radius : float, default: 1 

3109 The radius of the pie. 

3110 

3111 counterclock : bool, default: True 

3112 Specify fractions direction, clockwise or counterclockwise. 

3113 

3114 wedgeprops : dict, default: None 

3115 Dict of arguments passed to the wedge objects making the pie. 

3116 For example, you can pass in ``wedgeprops = {'linewidth': 3}`` 

3117 to set the width of the wedge border lines equal to 3. 

3118 For more details, look at the doc/arguments of the wedge object. 

3119 By default ``clip_on=False``. 

3120 

3121 textprops : dict, default: None 

3122 Dict of arguments to pass to the text objects. 

3123 

3124 center : (float, float), default: (0, 0) 

3125 The coordinates of the center of the chart. 

3126 

3127 frame : bool, default: False 

3128 Plot Axes frame with the chart if true. 

3129 

3130 rotatelabels : bool, default: False 

3131 Rotate each label to the angle of the corresponding slice if true. 

3132 

3133 data : indexable object, optional 

3134 DATA_PARAMETER_PLACEHOLDER 

3135 

3136 Returns 

3137 ------- 

3138 patches : list 

3139 A sequence of `matplotlib.patches.Wedge` instances 

3140 

3141 texts : list 

3142 A list of the label `.Text` instances. 

3143 

3144 autotexts : list 

3145 A list of `.Text` instances for the numeric labels. This will only 

3146 be returned if the parameter *autopct* is not *None*. 

3147 

3148 Notes 

3149 ----- 

3150 The pie chart will probably look best if the figure and Axes are 

3151 square, or the Axes aspect is equal. 

3152 This method sets the aspect ratio of the axis to "equal". 

3153 The Axes aspect ratio can be controlled with `.Axes.set_aspect`. 

3154 """ 

3155 self.set_aspect('equal') 

3156 # The use of float32 is "historical", but can't be changed without 

3157 # regenerating the test baselines. 

3158 x = np.asarray(x, np.float32) 

3159 if x.ndim > 1: 

3160 raise ValueError("x must be 1D") 

3161 

3162 if np.any(x < 0): 

3163 raise ValueError("Wedge sizes 'x' must be non negative values") 

3164 

3165 sx = x.sum() 

3166 

3167 if normalize: 

3168 x = x / sx 

3169 elif sx > 1: 

3170 raise ValueError('Cannot plot an unnormalized pie with sum(x) > 1') 

3171 if labels is None: 

3172 labels = [''] * len(x) 

3173 if explode is None: 

3174 explode = [0] * len(x) 

3175 if len(x) != len(labels): 

3176 raise ValueError("'label' must be of length 'x'") 

3177 if len(x) != len(explode): 

3178 raise ValueError("'explode' must be of length 'x'") 

3179 if colors is None: 

3180 get_next_color = self._get_patches_for_fill.get_next_color 

3181 else: 

3182 color_cycle = itertools.cycle(colors) 

3183 

3184 def get_next_color(): 

3185 return next(color_cycle) 

3186 

3187 _api.check_isinstance(Number, radius=radius, startangle=startangle) 

3188 if radius <= 0: 

3189 raise ValueError(f'radius must be a positive number, not {radius}') 

3190 

3191 # Starting theta1 is the start fraction of the circle 

3192 theta1 = startangle / 360 

3193 

3194 if wedgeprops is None: 

3195 wedgeprops = {} 

3196 if textprops is None: 

3197 textprops = {} 

3198 

3199 texts = [] 

3200 slices = [] 

3201 autotexts = [] 

3202 

3203 for frac, label, expl in zip(x, labels, explode): 

3204 x, y = center 

3205 theta2 = (theta1 + frac) if counterclock else (theta1 - frac) 

3206 thetam = 2 * np.pi * 0.5 * (theta1 + theta2) 

3207 x += expl * math.cos(thetam) 

3208 y += expl * math.sin(thetam) 

3209 

3210 w = mpatches.Wedge((x, y), radius, 360. * min(theta1, theta2), 

3211 360. * max(theta1, theta2), 

3212 facecolor=get_next_color(), 

3213 clip_on=False, 

3214 label=label) 

3215 w.set(**wedgeprops) 

3216 slices.append(w) 

3217 self.add_patch(w) 

3218 

3219 if shadow: 

3220 # Make sure to add a shadow after the call to add_patch so the 

3221 # figure and transform props will be set. 

3222 shad = mpatches.Shadow(w, -0.02, -0.02, label='_nolegend_') 

3223 self.add_patch(shad) 

3224 

3225 if labeldistance is not None: 

3226 xt = x + labeldistance * radius * math.cos(thetam) 

3227 yt = y + labeldistance * radius * math.sin(thetam) 

3228 label_alignment_h = 'left' if xt > 0 else 'right' 

3229 label_alignment_v = 'center' 

3230 label_rotation = 'horizontal' 

3231 if rotatelabels: 

3232 label_alignment_v = 'bottom' if yt > 0 else 'top' 

3233 label_rotation = (np.rad2deg(thetam) 

3234 + (0 if xt > 0 else 180)) 

3235 t = self.text(xt, yt, label, 

3236 clip_on=False, 

3237 horizontalalignment=label_alignment_h, 

3238 verticalalignment=label_alignment_v, 

3239 rotation=label_rotation, 

3240 size=mpl.rcParams['xtick.labelsize']) 

3241 t.set(**textprops) 

3242 texts.append(t) 

3243 

3244 if autopct is not None: 

3245 xt = x + pctdistance * radius * math.cos(thetam) 

3246 yt = y + pctdistance * radius * math.sin(thetam) 

3247 if isinstance(autopct, str): 

3248 s = autopct % (100. * frac) 

3249 elif callable(autopct): 

3250 s = autopct(100. * frac) 

3251 else: 

3252 raise TypeError( 

3253 'autopct must be callable or a format string') 

3254 t = self.text(xt, yt, s, 

3255 clip_on=False, 

3256 horizontalalignment='center', 

3257 verticalalignment='center') 

3258 t.set(**textprops) 

3259 autotexts.append(t) 

3260 

3261 theta1 = theta2 

3262 

3263 if frame: 

3264 self._request_autoscale_view() 

3265 else: 

3266 self.set(frame_on=False, xticks=[], yticks=[], 

3267 xlim=(-1.25 + center[0], 1.25 + center[0]), 

3268 ylim=(-1.25 + center[1], 1.25 + center[1])) 

3269 

3270 if autopct is None: 

3271 return slices, texts 

3272 else: 

3273 return slices, texts, autotexts 

3274 

3275 @staticmethod 

3276 def _errorevery_to_mask(x, errorevery): 

3277 """ 

3278 Normalize `errorbar`'s *errorevery* to be a boolean mask for data *x*. 

3279 

3280 This function is split out to be usable both by 2D and 3D errorbars. 

3281 """ 

3282 if isinstance(errorevery, Integral): 

3283 errorevery = (0, errorevery) 

3284 if isinstance(errorevery, tuple): 

3285 if (len(errorevery) == 2 and 

3286 isinstance(errorevery[0], Integral) and 

3287 isinstance(errorevery[1], Integral)): 

3288 errorevery = slice(errorevery[0], None, errorevery[1]) 

3289 else: 

3290 raise ValueError( 

3291 f'{errorevery=!r} is a not a tuple of two integers') 

3292 elif isinstance(errorevery, slice): 

3293 pass 

3294 elif not isinstance(errorevery, str) and np.iterable(errorevery): 

3295 try: 

3296 x[errorevery] # fancy indexing 

3297 except (ValueError, IndexError) as err: 

3298 raise ValueError( 

3299 f"{errorevery=!r} is iterable but not a valid NumPy fancy " 

3300 "index to match 'xerr'/'yerr'") from err 

3301 else: 

3302 raise ValueError(f"{errorevery=!r} is not a recognized value") 

3303 everymask = np.zeros(len(x), bool) 

3304 everymask[errorevery] = True 

3305 return everymask 

3306 

3307 @_preprocess_data(replace_names=["x", "y", "xerr", "yerr"], 

3308 label_namer="y") 

3309 @_docstring.dedent_interpd 

3310 def errorbar(self, x, y, yerr=None, xerr=None, 

3311 fmt='', ecolor=None, elinewidth=None, capsize=None, 

3312 barsabove=False, lolims=False, uplims=False, 

3313 xlolims=False, xuplims=False, errorevery=1, capthick=None, 

3314 **kwargs): 

3315 """ 

3316 Plot y versus x as lines and/or markers with attached errorbars. 

3317 

3318 *x*, *y* define the data locations, *xerr*, *yerr* define the errorbar 

3319 sizes. By default, this draws the data markers/lines as well the 

3320 errorbars. Use fmt='none' to draw errorbars without any data markers. 

3321 

3322 Parameters 

3323 ---------- 

3324 x, y : float or array-like 

3325 The data positions. 

3326 

3327 xerr, yerr : float or array-like, shape(N,) or shape(2, N), optional 

3328 The errorbar sizes: 

3329 

3330 - scalar: Symmetric +/- values for all data points. 

3331 - shape(N,): Symmetric +/-values for each data point. 

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

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

3334 errors. 

3335 - *None*: No errorbar. 

3336 

3337 All values must be >= 0. 

3338 

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

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

3341 

3342 fmt : str, default: '' 

3343 The format for the data points / data lines. See `.plot` for 

3344 details. 

3345 

3346 Use 'none' (case insensitive) to plot errorbars without any data 

3347 markers. 

3348 

3349 ecolor : color, default: None 

3350 The color of the errorbar lines. If None, use the color of the 

3351 line connecting the markers. 

3352 

3353 elinewidth : float, default: None 

3354 The linewidth of the errorbar lines. If None, the linewidth of 

3355 the current style is used. 

3356 

3357 capsize : float, default: :rc:`errorbar.capsize` 

3358 The length of the error bar caps in points. 

3359 

3360 capthick : float, default: None 

3361 An alias to the keyword argument *markeredgewidth* (a.k.a. *mew*). 

3362 This setting is a more sensible name for the property that 

3363 controls the thickness of the error bar cap in points. For 

3364 backwards compatibility, if *mew* or *markeredgewidth* are given, 

3365 then they will over-ride *capthick*. This may change in future 

3366 releases. 

3367 

3368 barsabove : bool, default: False 

3369 If True, will plot the errorbars above the plot 

3370 symbols. Default is below. 

3371 

3372 lolims, uplims, xlolims, xuplims : bool, default: False 

3373 These arguments can be used to indicate that a value gives only 

3374 upper/lower limits. In that case a caret symbol is used to 

3375 indicate this. *lims*-arguments may be scalars, or array-likes of 

3376 the same length as *xerr* and *yerr*. To use limits with inverted 

3377 axes, `~.Axes.set_xlim` or `~.Axes.set_ylim` must be called before 

3378 :meth:`errorbar`. Note the tricky parameter names: setting e.g. 

3379 *lolims* to True means that the y-value is a *lower* limit of the 

3380 True value, so, only an *upward*-pointing arrow will be drawn! 

3381 

3382 errorevery : int or (int, int), default: 1 

3383 draws error bars on a subset of the data. *errorevery* =N draws 

3384 error bars on the points (x[::N], y[::N]). 

3385 *errorevery* =(start, N) draws error bars on the points 

3386 (x[start::N], y[start::N]). e.g. errorevery=(6, 3) 

3387 adds error bars to the data at (x[6], x[9], x[12], x[15], ...). 

3388 Used to avoid overlapping error bars when two series share x-axis 

3389 values. 

3390 

3391 Returns 

3392 ------- 

3393 `.ErrorbarContainer` 

3394 The container contains: 

3395 

3396 - plotline: `.Line2D` instance of x, y plot markers and/or line. 

3397 - caplines: A tuple of `.Line2D` instances of the error bar caps. 

3398 - barlinecols: A tuple of `.LineCollection` with the horizontal and 

3399 vertical error ranges. 

3400 

3401 Other Parameters 

3402 ---------------- 

3403 data : indexable object, optional 

3404 DATA_PARAMETER_PLACEHOLDER 

3405 

3406 **kwargs 

3407 All other keyword arguments are passed on to the `~.Axes.plot` call 

3408 drawing the markers. For example, this code makes big red squares 

3409 with thick green edges:: 

3410 

3411 x, y, yerr = rand(3, 10) 

3412 errorbar(x, y, yerr, marker='s', mfc='red', 

3413 mec='green', ms=20, mew=4) 

3414 

3415 where *mfc*, *mec*, *ms* and *mew* are aliases for the longer 

3416 property names, *markerfacecolor*, *markeredgecolor*, *markersize* 

3417 and *markeredgewidth*. 

3418 

3419 Valid kwargs for the marker properties are: 

3420 

3421 - *dashes* 

3422 - *dash_capstyle* 

3423 - *dash_joinstyle* 

3424 - *drawstyle* 

3425 - *fillstyle* 

3426 - *linestyle* 

3427 - *marker* 

3428 - *markeredgecolor* 

3429 - *markeredgewidth* 

3430 - *markerfacecolor* 

3431 - *markerfacecoloralt* 

3432 - *markersize* 

3433 - *markevery* 

3434 - *solid_capstyle* 

3435 - *solid_joinstyle* 

3436 

3437 Refer to the corresponding `.Line2D` property for more details: 

3438 

3439 %(Line2D:kwdoc)s 

3440 """ 

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

3442 # Drop anything that comes in as None to use the default instead. 

3443 kwargs = {k: v for k, v in kwargs.items() if v is not None} 

3444 kwargs.setdefault('zorder', 2) 

3445 

3446 # Casting to object arrays preserves units. 

3447 if not isinstance(x, np.ndarray): 

3448 x = np.asarray(x, dtype=object) 

3449 if not isinstance(y, np.ndarray): 

3450 y = np.asarray(y, dtype=object) 

3451 

3452 def _upcast_err(err): 

3453 """ 

3454 Safely handle tuple of containers that carry units. 

3455 

3456 This function covers the case where the input to the xerr/yerr is a 

3457 length 2 tuple of equal length ndarray-subclasses that carry the 

3458 unit information in the container. 

3459 

3460 If we have a tuple of nested numpy array (subclasses), we defer 

3461 coercing the units to be consistent to the underlying unit 

3462 library (and implicitly the broadcasting). 

3463 

3464 Otherwise, fallback to casting to an object array. 

3465 """ 

3466 

3467 if ( 

3468 # make sure it is not a scalar 

3469 np.iterable(err) and 

3470 # and it is not empty 

3471 len(err) > 0 and 

3472 # and the first element is an array sub-class use 

3473 # safe_first_element because getitem is index-first not 

3474 # location first on pandas objects so err[0] almost always 

3475 # fails. 

3476 isinstance(cbook._safe_first_finite(err), np.ndarray) 

3477 ): 

3478 # Get the type of the first element 

3479 atype = type(cbook._safe_first_finite(err)) 

3480 # Promote the outer container to match the inner container 

3481 if atype is np.ndarray: 

3482 # Converts using np.asarray, because data cannot 

3483 # be directly passed to init of np.ndarray 

3484 return np.asarray(err, dtype=object) 

3485 # If atype is not np.ndarray, directly pass data to init. 

3486 # This works for types such as unyts and astropy units 

3487 return atype(err) 

3488 # Otherwise wrap it in an object array 

3489 return np.asarray(err, dtype=object) 

3490 

3491 if xerr is not None and not isinstance(xerr, np.ndarray): 

3492 xerr = _upcast_err(xerr) 

3493 if yerr is not None and not isinstance(yerr, np.ndarray): 

3494 yerr = _upcast_err(yerr) 

3495 x, y = np.atleast_1d(x, y) # Make sure all the args are iterable. 

3496 if len(x) != len(y): 

3497 raise ValueError("'x' and 'y' must have the same size") 

3498 

3499 everymask = self._errorevery_to_mask(x, errorevery) 

3500 

3501 label = kwargs.pop("label", None) 

3502 kwargs['label'] = '_nolegend_' 

3503 

3504 # Create the main line and determine overall kwargs for child artists. 

3505 # We avoid calling self.plot() directly, or self._get_lines(), because 

3506 # that would call self._process_unit_info again, and do other indirect 

3507 # data processing. 

3508 (data_line, base_style), = self._get_lines._plot_args( 

3509 (x, y) if fmt == '' else (x, y, fmt), kwargs, return_kwargs=True) 

3510 

3511 # Do this after creating `data_line` to avoid modifying `base_style`. 

3512 if barsabove: 

3513 data_line.set_zorder(kwargs['zorder'] - .1) 

3514 else: 

3515 data_line.set_zorder(kwargs['zorder'] + .1) 

3516 

3517 # Add line to plot, or throw it away and use it to determine kwargs. 

3518 if fmt.lower() != 'none': 

3519 self.add_line(data_line) 

3520 else: 

3521 data_line = None 

3522 # Remove alpha=0 color that _get_lines._plot_args returns for 

3523 # 'none' format, and replace it with user-specified color, if 

3524 # supplied. 

3525 base_style.pop('color') 

3526 if 'color' in kwargs: 

3527 base_style['color'] = kwargs.pop('color') 

3528 

3529 if 'color' not in base_style: 

3530 base_style['color'] = 'C0' 

3531 if ecolor is None: 

3532 ecolor = base_style['color'] 

3533 

3534 # Eject any line-specific information from format string, as it's not 

3535 # needed for bars or caps. 

3536 for key in ['marker', 'markersize', 'markerfacecolor', 

3537 'markerfacecoloralt', 

3538 'markeredgewidth', 'markeredgecolor', 'markevery', 

3539 'linestyle', 'fillstyle', 'drawstyle', 'dash_capstyle', 

3540 'dash_joinstyle', 'solid_capstyle', 'solid_joinstyle', 

3541 'dashes']: 

3542 base_style.pop(key, None) 

3543 

3544 # Make the style dict for the line collections (the bars). 

3545 eb_lines_style = {**base_style, 'color': ecolor} 

3546 

3547 if elinewidth is not None: 

3548 eb_lines_style['linewidth'] = elinewidth 

3549 elif 'linewidth' in kwargs: 

3550 eb_lines_style['linewidth'] = kwargs['linewidth'] 

3551 

3552 for key in ('transform', 'alpha', 'zorder', 'rasterized'): 

3553 if key in kwargs: 

3554 eb_lines_style[key] = kwargs[key] 

3555 

3556 # Make the style dict for caps (the "hats"). 

3557 eb_cap_style = {**base_style, 'linestyle': 'none'} 

3558 if capsize is None: 

3559 capsize = mpl.rcParams["errorbar.capsize"] 

3560 if capsize > 0: 

3561 eb_cap_style['markersize'] = 2. * capsize 

3562 if capthick is not None: 

3563 eb_cap_style['markeredgewidth'] = capthick 

3564 

3565 # For backwards-compat, allow explicit setting of 

3566 # 'markeredgewidth' to over-ride capthick. 

3567 for key in ('markeredgewidth', 'transform', 'alpha', 

3568 'zorder', 'rasterized'): 

3569 if key in kwargs: 

3570 eb_cap_style[key] = kwargs[key] 

3571 eb_cap_style['color'] = ecolor 

3572 

3573 barcols = [] 

3574 caplines = [] 

3575 

3576 # Vectorized fancy-indexer. 

3577 def apply_mask(arrays, mask): return [array[mask] for array in arrays] 

3578 

3579 # dep: dependent dataset, indep: independent dataset 

3580 for (dep_axis, dep, err, lolims, uplims, indep, lines_func, 

3581 marker, lomarker, himarker) in [ 

3582 ("x", x, xerr, xlolims, xuplims, y, self.hlines, 

3583 "|", mlines.CARETRIGHTBASE, mlines.CARETLEFTBASE), 

3584 ("y", y, yerr, lolims, uplims, x, self.vlines, 

3585 "_", mlines.CARETUPBASE, mlines.CARETDOWNBASE), 

3586 ]: 

3587 if err is None: 

3588 continue 

3589 lolims = np.broadcast_to(lolims, len(dep)).astype(bool) 

3590 uplims = np.broadcast_to(uplims, len(dep)).astype(bool) 

3591 try: 

3592 np.broadcast_to(err, (2, len(dep))) 

3593 except ValueError: 

3594 raise ValueError( 

3595 f"'{dep_axis}err' (shape: {np.shape(err)}) must be a " 

3596 f"scalar or a 1D or (2, n) array-like whose shape matches " 

3597 f"'{dep_axis}' (shape: {np.shape(dep)})") from None 

3598 res = np.zeros(err.shape, dtype=bool) # Default in case of nan 

3599 if np.any(np.less(err, -err, out=res, where=(err == err))): 

3600 # like err<0, but also works for timedelta and nan. 

3601 raise ValueError( 

3602 f"'{dep_axis}err' must not contain negative values") 

3603 # This is like 

3604 # elow, ehigh = np.broadcast_to(...) 

3605 # return dep - elow * ~lolims, dep + ehigh * ~uplims 

3606 # except that broadcast_to would strip units. 

3607 low, high = dep + np.row_stack([-(1 - lolims), 1 - uplims]) * err 

3608 

3609 barcols.append(lines_func( 

3610 *apply_mask([indep, low, high], everymask), **eb_lines_style)) 

3611 # Normal errorbars for points without upper/lower limits. 

3612 nolims = ~(lolims | uplims) 

3613 if nolims.any() and capsize > 0: 

3614 indep_masked, lo_masked, hi_masked = apply_mask( 

3615 [indep, low, high], nolims & everymask) 

3616 for lh_masked in [lo_masked, hi_masked]: 

3617 # Since this has to work for x and y as dependent data, we 

3618 # first set both x and y to the independent variable and 

3619 # overwrite the respective dependent data in a second step. 

3620 line = mlines.Line2D(indep_masked, indep_masked, 

3621 marker=marker, **eb_cap_style) 

3622 line.set(**{f"{dep_axis}data": lh_masked}) 

3623 caplines.append(line) 

3624 for idx, (lims, hl) in enumerate([(lolims, high), (uplims, low)]): 

3625 if not lims.any(): 

3626 continue 

3627 hlmarker = ( 

3628 himarker 

3629 if getattr(self, f"{dep_axis}axis").get_inverted() ^ idx 

3630 else lomarker) 

3631 x_masked, y_masked, hl_masked = apply_mask( 

3632 [x, y, hl], lims & everymask) 

3633 # As above, we set the dependent data in a second step. 

3634 line = mlines.Line2D(x_masked, y_masked, 

3635 marker=hlmarker, **eb_cap_style) 

3636 line.set(**{f"{dep_axis}data": hl_masked}) 

3637 caplines.append(line) 

3638 if capsize > 0: 

3639 caplines.append(mlines.Line2D( 

3640 x_masked, y_masked, marker=marker, **eb_cap_style)) 

3641 

3642 for l in caplines: 

3643 self.add_line(l) 

3644 

3645 self._request_autoscale_view() 

3646 errorbar_container = ErrorbarContainer( 

3647 (data_line, tuple(caplines), tuple(barcols)), 

3648 has_xerr=(xerr is not None), has_yerr=(yerr is not None), 

3649 label=label) 

3650 self.containers.append(errorbar_container) 

3651 

3652 return errorbar_container # (l0, caplines, barcols) 

3653 

3654 @_preprocess_data() 

3655 def boxplot(self, x, notch=None, sym=None, vert=None, whis=None, 

3656 positions=None, widths=None, patch_artist=None, 

3657 bootstrap=None, usermedians=None, conf_intervals=None, 

3658 meanline=None, showmeans=None, showcaps=None, 

3659 showbox=None, showfliers=None, boxprops=None, 

3660 labels=None, flierprops=None, medianprops=None, 

3661 meanprops=None, capprops=None, whiskerprops=None, 

3662 manage_ticks=True, autorange=False, zorder=None, 

3663 capwidths=None): 

3664 """ 

3665 Draw a box and whisker plot. 

3666 

3667 The box extends from the first quartile (Q1) to the third 

3668 quartile (Q3) of the data, with a line at the median. The 

3669 whiskers extend from the box by 1.5x the inter-quartile range 

3670 (IQR). Flier points are those past the end of the whiskers. 

3671 See https://en.wikipedia.org/wiki/Box_plot for reference. 

3672 

3673 .. code-block:: none 

3674 

3675 Q1-1.5IQR Q1 median Q3 Q3+1.5IQR 

3676 |-----:-----| 

3677 o |--------| : |--------| o o 

3678 |-----:-----| 

3679 flier <-----------> fliers 

3680 IQR 

3681 

3682 

3683 Parameters 

3684 ---------- 

3685 x : Array or a sequence of vectors. 

3686 The input data. If a 2D array, a boxplot is drawn for each column 

3687 in *x*. If a sequence of 1D arrays, a boxplot is drawn for each 

3688 array in *x*. 

3689 

3690 notch : bool, default: False 

3691 Whether to draw a notched boxplot (`True`), or a rectangular 

3692 boxplot (`False`). The notches represent the confidence interval 

3693 (CI) around the median. The documentation for *bootstrap* 

3694 describes how the locations of the notches are computed by 

3695 default, but their locations may also be overridden by setting the 

3696 *conf_intervals* parameter. 

3697 

3698 .. note:: 

3699 

3700 In cases where the values of the CI are less than the 

3701 lower quartile or greater than the upper quartile, the 

3702 notches will extend beyond the box, giving it a 

3703 distinctive "flipped" appearance. This is expected 

3704 behavior and consistent with other statistical 

3705 visualization packages. 

3706 

3707 sym : str, optional 

3708 The default symbol for flier points. An empty string ('') hides 

3709 the fliers. If `None`, then the fliers default to 'b+'. More 

3710 control is provided by the *flierprops* parameter. 

3711 

3712 vert : bool, default: True 

3713 If `True`, draws vertical boxes. 

3714 If `False`, draw horizontal boxes. 

3715 

3716 whis : float or (float, float), default: 1.5 

3717 The position of the whiskers. 

3718 

3719 If a float, the lower whisker is at the lowest datum above 

3720 ``Q1 - whis*(Q3-Q1)``, and the upper whisker at the highest datum 

3721 below ``Q3 + whis*(Q3-Q1)``, where Q1 and Q3 are the first and 

3722 third quartiles. The default value of ``whis = 1.5`` corresponds 

3723 to Tukey's original definition of boxplots. 

3724 

3725 If a pair of floats, they indicate the percentiles at which to 

3726 draw the whiskers (e.g., (5, 95)). In particular, setting this to 

3727 (0, 100) results in whiskers covering the whole range of the data. 

3728 

3729 In the edge case where ``Q1 == Q3``, *whis* is automatically set 

3730 to (0, 100) (cover the whole range of the data) if *autorange* is 

3731 True. 

3732 

3733 Beyond the whiskers, data are considered outliers and are plotted 

3734 as individual points. 

3735 

3736 bootstrap : int, optional 

3737 Specifies whether to bootstrap the confidence intervals 

3738 around the median for notched boxplots. If *bootstrap* is 

3739 None, no bootstrapping is performed, and notches are 

3740 calculated using a Gaussian-based asymptotic approximation 

3741 (see McGill, R., Tukey, J.W., and Larsen, W.A., 1978, and 

3742 Kendall and Stuart, 1967). Otherwise, bootstrap specifies 

3743 the number of times to bootstrap the median to determine its 

3744 95% confidence intervals. Values between 1000 and 10000 are 

3745 recommended. 

3746 

3747 usermedians : 1D array-like, optional 

3748 A 1D array-like of length ``len(x)``. Each entry that is not 

3749 `None` forces the value of the median for the corresponding 

3750 dataset. For entries that are `None`, the medians are computed 

3751 by Matplotlib as normal. 

3752 

3753 conf_intervals : array-like, optional 

3754 A 2D array-like of shape ``(len(x), 2)``. Each entry that is not 

3755 None forces the location of the corresponding notch (which is 

3756 only drawn if *notch* is `True`). For entries that are `None`, 

3757 the notches are computed by the method specified by the other 

3758 parameters (e.g., *bootstrap*). 

3759 

3760 positions : array-like, optional 

3761 The positions of the boxes. The ticks and limits are 

3762 automatically set to match the positions. Defaults to 

3763 ``range(1, N+1)`` where N is the number of boxes to be drawn. 

3764 

3765 widths : float or array-like 

3766 The widths of the boxes. The default is 0.5, or ``0.15*(distance 

3767 between extreme positions)``, if that is smaller. 

3768 

3769 patch_artist : bool, default: False 

3770 If `False` produces boxes with the Line2D artist. Otherwise, 

3771 boxes are drawn with Patch artists. 

3772 

3773 labels : sequence, optional 

3774 Labels for each dataset (one per dataset). 

3775 

3776 manage_ticks : bool, default: True 

3777 If True, the tick locations and labels will be adjusted to match 

3778 the boxplot positions. 

3779 

3780 autorange : bool, default: False 

3781 When `True` and the data are distributed such that the 25th and 

3782 75th percentiles are equal, *whis* is set to (0, 100) such 

3783 that the whisker ends are at the minimum and maximum of the data. 

3784 

3785 meanline : bool, default: False 

3786 If `True` (and *showmeans* is `True`), will try to render the 

3787 mean as a line spanning the full width of the box according to 

3788 *meanprops* (see below). Not recommended if *shownotches* is also 

3789 True. Otherwise, means will be shown as points. 

3790 

3791 zorder : float, default: ``Line2D.zorder = 2`` 

3792 The zorder of the boxplot. 

3793 

3794 Returns 

3795 ------- 

3796 dict 

3797 A dictionary mapping each component of the boxplot to a list 

3798 of the `.Line2D` instances created. That dictionary has the 

3799 following keys (assuming vertical boxplots): 

3800 

3801 - ``boxes``: the main body of the boxplot showing the 

3802 quartiles and the median's confidence intervals if 

3803 enabled. 

3804 

3805 - ``medians``: horizontal lines at the median of each box. 

3806 

3807 - ``whiskers``: the vertical lines extending to the most 

3808 extreme, non-outlier data points. 

3809 

3810 - ``caps``: the horizontal lines at the ends of the 

3811 whiskers. 

3812 

3813 - ``fliers``: points representing data that extend beyond 

3814 the whiskers (fliers). 

3815 

3816 - ``means``: points or lines representing the means. 

3817 

3818 Other Parameters 

3819 ---------------- 

3820 showcaps : bool, default: True 

3821 Show the caps on the ends of whiskers. 

3822 showbox : bool, default: True 

3823 Show the central box. 

3824 showfliers : bool, default: True 

3825 Show the outliers beyond the caps. 

3826 showmeans : bool, default: False 

3827 Show the arithmetic means. 

3828 capprops : dict, default: None 

3829 The style of the caps. 

3830 capwidths : float or array, default: None 

3831 The widths of the caps. 

3832 boxprops : dict, default: None 

3833 The style of the box. 

3834 whiskerprops : dict, default: None 

3835 The style of the whiskers. 

3836 flierprops : dict, default: None 

3837 The style of the fliers. 

3838 medianprops : dict, default: None 

3839 The style of the median. 

3840 meanprops : dict, default: None 

3841 The style of the mean. 

3842 data : indexable object, optional 

3843 DATA_PARAMETER_PLACEHOLDER 

3844 

3845 See Also 

3846 -------- 

3847 violinplot : Draw an estimate of the probability density function. 

3848 """ 

3849 

3850 # Missing arguments default to rcParams. 

3851 if whis is None: 

3852 whis = mpl.rcParams['boxplot.whiskers'] 

3853 if bootstrap is None: 

3854 bootstrap = mpl.rcParams['boxplot.bootstrap'] 

3855 

3856 bxpstats = cbook.boxplot_stats(x, whis=whis, bootstrap=bootstrap, 

3857 labels=labels, autorange=autorange) 

3858 if notch is None: 

3859 notch = mpl.rcParams['boxplot.notch'] 

3860 if vert is None: 

3861 vert = mpl.rcParams['boxplot.vertical'] 

3862 if patch_artist is None: 

3863 patch_artist = mpl.rcParams['boxplot.patchartist'] 

3864 if meanline is None: 

3865 meanline = mpl.rcParams['boxplot.meanline'] 

3866 if showmeans is None: 

3867 showmeans = mpl.rcParams['boxplot.showmeans'] 

3868 if showcaps is None: 

3869 showcaps = mpl.rcParams['boxplot.showcaps'] 

3870 if showbox is None: 

3871 showbox = mpl.rcParams['boxplot.showbox'] 

3872 if showfliers is None: 

3873 showfliers = mpl.rcParams['boxplot.showfliers'] 

3874 

3875 if boxprops is None: 

3876 boxprops = {} 

3877 if whiskerprops is None: 

3878 whiskerprops = {} 

3879 if capprops is None: 

3880 capprops = {} 

3881 if medianprops is None: 

3882 medianprops = {} 

3883 if meanprops is None: 

3884 meanprops = {} 

3885 if flierprops is None: 

3886 flierprops = {} 

3887 

3888 if patch_artist: 

3889 boxprops['linestyle'] = 'solid' # Not consistent with bxp. 

3890 if 'color' in boxprops: 

3891 boxprops['edgecolor'] = boxprops.pop('color') 

3892 

3893 # if non-default sym value, put it into the flier dictionary 

3894 # the logic for providing the default symbol ('b+') now lives 

3895 # in bxp in the initial value of flierkw 

3896 # handle all of the *sym* related logic here so we only have to pass 

3897 # on the flierprops dict. 

3898 if sym is not None: 

3899 # no-flier case, which should really be done with 

3900 # 'showfliers=False' but none-the-less deal with it to keep back 

3901 # compatibility 

3902 if sym == '': 

3903 # blow away existing dict and make one for invisible markers 

3904 flierprops = dict(linestyle='none', marker='', color='none') 

3905 # turn the fliers off just to be safe 

3906 showfliers = False 

3907 # now process the symbol string 

3908 else: 

3909 # process the symbol string 

3910 # discarded linestyle 

3911 _, marker, color = _process_plot_format(sym) 

3912 # if we have a marker, use it 

3913 if marker is not None: 

3914 flierprops['marker'] = marker 

3915 # if we have a color, use it 

3916 if color is not None: 

3917 # assume that if color is passed in the user want 

3918 # filled symbol, if the users want more control use 

3919 # flierprops 

3920 flierprops['color'] = color 

3921 flierprops['markerfacecolor'] = color 

3922 flierprops['markeredgecolor'] = color 

3923 

3924 # replace medians if necessary: 

3925 if usermedians is not None: 

3926 if (len(np.ravel(usermedians)) != len(bxpstats) or 

3927 np.shape(usermedians)[0] != len(bxpstats)): 

3928 raise ValueError( 

3929 "'usermedians' and 'x' have different lengths") 

3930 else: 

3931 # reassign medians as necessary 

3932 for stats, med in zip(bxpstats, usermedians): 

3933 if med is not None: 

3934 stats['med'] = med 

3935 

3936 if conf_intervals is not None: 

3937 if len(conf_intervals) != len(bxpstats): 

3938 raise ValueError( 

3939 "'conf_intervals' and 'x' have different lengths") 

3940 else: 

3941 for stats, ci in zip(bxpstats, conf_intervals): 

3942 if ci is not None: 

3943 if len(ci) != 2: 

3944 raise ValueError('each confidence interval must ' 

3945 'have two values') 

3946 else: 

3947 if ci[0] is not None: 

3948 stats['cilo'] = ci[0] 

3949 if ci[1] is not None: 

3950 stats['cihi'] = ci[1] 

3951 

3952 artists = self.bxp(bxpstats, positions=positions, widths=widths, 

3953 vert=vert, patch_artist=patch_artist, 

3954 shownotches=notch, showmeans=showmeans, 

3955 showcaps=showcaps, showbox=showbox, 

3956 boxprops=boxprops, flierprops=flierprops, 

3957 medianprops=medianprops, meanprops=meanprops, 

3958 meanline=meanline, showfliers=showfliers, 

3959 capprops=capprops, whiskerprops=whiskerprops, 

3960 manage_ticks=manage_ticks, zorder=zorder, 

3961 capwidths=capwidths) 

3962 return artists 

3963 

3964 def bxp(self, bxpstats, positions=None, widths=None, vert=True, 

3965 patch_artist=False, shownotches=False, showmeans=False, 

3966 showcaps=True, showbox=True, showfliers=True, 

3967 boxprops=None, whiskerprops=None, flierprops=None, 

3968 medianprops=None, capprops=None, meanprops=None, 

3969 meanline=False, manage_ticks=True, zorder=None, 

3970 capwidths=None): 

3971 """ 

3972 Drawing function for box and whisker plots. 

3973 

3974 Make a box and whisker plot for each column of *x* or each 

3975 vector in sequence *x*. The box extends from the lower to 

3976 upper quartile values of the data, with a line at the median. 

3977 The whiskers extend from the box to show the range of the 

3978 data. Flier points are those past the end of the whiskers. 

3979 

3980 Parameters 

3981 ---------- 

3982 bxpstats : list of dicts 

3983 A list of dictionaries containing stats for each boxplot. 

3984 Required keys are: 

3985 

3986 - ``med``: Median (scalar). 

3987 - ``q1``, ``q3``: First & third quartiles (scalars). 

3988 - ``whislo``, ``whishi``: Lower & upper whisker positions (scalars). 

3989 

3990 Optional keys are: 

3991 

3992 - ``mean``: Mean (scalar). Needed if ``showmeans=True``. 

3993 - ``fliers``: Data beyond the whiskers (array-like). 

3994 Needed if ``showfliers=True``. 

3995 - ``cilo``, ``cihi``: Lower & upper confidence intervals 

3996 about the median. Needed if ``shownotches=True``. 

3997 - ``label``: Name of the dataset (str). If available, 

3998 this will be used a tick label for the boxplot 

3999 

4000 positions : array-like, default: [1, 2, ..., n] 

4001 The positions of the boxes. The ticks and limits 

4002 are automatically set to match the positions. 

4003 

4004 widths : float or array-like, default: None 

4005 The widths of the boxes. The default is 

4006 ``clip(0.15*(distance between extreme positions), 0.15, 0.5)``. 

4007 

4008 capwidths : float or array-like, default: None 

4009 Either a scalar or a vector and sets the width of each cap. 

4010 The default is ``0.5*(with of the box)``, see *widths*. 

4011 

4012 vert : bool, default: True 

4013 If `True` (default), makes the boxes vertical. 

4014 If `False`, makes horizontal boxes. 

4015 

4016 patch_artist : bool, default: False 

4017 If `False` produces boxes with the `.Line2D` artist. 

4018 If `True` produces boxes with the `~matplotlib.patches.Patch` artist. 

4019 

4020 shownotches, showmeans, showcaps, showbox, showfliers : bool 

4021 Whether to draw the CI notches, the mean value (both default to 

4022 False), the caps, the box, and the fliers (all three default to 

4023 True). 

4024 

4025 boxprops, whiskerprops, capprops, flierprops, medianprops, meanprops :\ 

4026 dict, optional 

4027 Artist properties for the boxes, whiskers, caps, fliers, medians, and 

4028 means. 

4029 

4030 meanline : bool, default: False 

4031 If `True` (and *showmeans* is `True`), will try to render the mean 

4032 as a line spanning the full width of the box according to 

4033 *meanprops*. Not recommended if *shownotches* is also True. 

4034 Otherwise, means will be shown as points. 

4035 

4036 manage_ticks : bool, default: True 

4037 If True, the tick locations and labels will be adjusted to match the 

4038 boxplot positions. 

4039 

4040 zorder : float, default: ``Line2D.zorder = 2`` 

4041 The zorder of the resulting boxplot. 

4042 

4043 Returns 

4044 ------- 

4045 dict 

4046 A dictionary mapping each component of the boxplot to a list 

4047 of the `.Line2D` instances created. That dictionary has the 

4048 following keys (assuming vertical boxplots): 

4049 

4050 - ``boxes``: main bodies of the boxplot showing the quartiles, and 

4051 the median's confidence intervals if enabled. 

4052 - ``medians``: horizontal lines at the median of each box. 

4053 - ``whiskers``: vertical lines up to the last non-outlier data. 

4054 - ``caps``: horizontal lines at the ends of the whiskers. 

4055 - ``fliers``: points representing data beyond the whiskers (fliers). 

4056 - ``means``: points or lines representing the means. 

4057 

4058 Examples 

4059 -------- 

4060 .. plot:: gallery/statistics/bxp.py 

4061 """ 

4062 

4063 # lists of artists to be output 

4064 whiskers = [] 

4065 caps = [] 

4066 boxes = [] 

4067 medians = [] 

4068 means = [] 

4069 fliers = [] 

4070 

4071 # empty list of xticklabels 

4072 datalabels = [] 

4073 

4074 # Use default zorder if none specified 

4075 if zorder is None: 

4076 zorder = mlines.Line2D.zorder 

4077 

4078 zdelta = 0.1 

4079 

4080 def merge_kw_rc(subkey, explicit, zdelta=0, usemarker=True): 

4081 d = {k.split('.')[-1]: v for k, v in mpl.rcParams.items() 

4082 if k.startswith(f'boxplot.{subkey}props')} 

4083 d['zorder'] = zorder + zdelta 

4084 if not usemarker: 

4085 d['marker'] = '' 

4086 d.update(cbook.normalize_kwargs(explicit, mlines.Line2D)) 

4087 return d 

4088 

4089 box_kw = { 

4090 'linestyle': mpl.rcParams['boxplot.boxprops.linestyle'], 

4091 'linewidth': mpl.rcParams['boxplot.boxprops.linewidth'], 

4092 'edgecolor': mpl.rcParams['boxplot.boxprops.color'], 

4093 'facecolor': ('white' if mpl.rcParams['_internal.classic_mode'] 

4094 else mpl.rcParams['patch.facecolor']), 

4095 'zorder': zorder, 

4096 **cbook.normalize_kwargs(boxprops, mpatches.PathPatch) 

4097 } if patch_artist else merge_kw_rc('box', boxprops, usemarker=False) 

4098 whisker_kw = merge_kw_rc('whisker', whiskerprops, usemarker=False) 

4099 cap_kw = merge_kw_rc('cap', capprops, usemarker=False) 

4100 flier_kw = merge_kw_rc('flier', flierprops) 

4101 median_kw = merge_kw_rc('median', medianprops, zdelta, usemarker=False) 

4102 mean_kw = merge_kw_rc('mean', meanprops, zdelta) 

4103 removed_prop = 'marker' if meanline else 'linestyle' 

4104 # Only remove the property if it's not set explicitly as a parameter. 

4105 if meanprops is None or removed_prop not in meanprops: 

4106 mean_kw[removed_prop] = '' 

4107 

4108 # vertical or horizontal plot? 

4109 maybe_swap = slice(None) if vert else slice(None, None, -1) 

4110 

4111 def do_plot(xs, ys, **kwargs): 

4112 return self.plot(*[xs, ys][maybe_swap], **kwargs)[0] 

4113 

4114 def do_patch(xs, ys, **kwargs): 

4115 path = mpath.Path._create_closed( 

4116 np.column_stack([xs, ys][maybe_swap])) 

4117 patch = mpatches.PathPatch(path, **kwargs) 

4118 self.add_artist(patch) 

4119 return patch 

4120 

4121 # input validation 

4122 N = len(bxpstats) 

4123 datashape_message = ("List of boxplot statistics and `{0}` " 

4124 "values must have same the length") 

4125 # check position 

4126 if positions is None: 

4127 positions = list(range(1, N + 1)) 

4128 elif len(positions) != N: 

4129 raise ValueError(datashape_message.format("positions")) 

4130 

4131 positions = np.array(positions) 

4132 if len(positions) > 0 and not isinstance(positions[0], Number): 

4133 raise TypeError("positions should be an iterable of numbers") 

4134 

4135 # width 

4136 if widths is None: 

4137 widths = [np.clip(0.15 * np.ptp(positions), 0.15, 0.5)] * N 

4138 elif np.isscalar(widths): 

4139 widths = [widths] * N 

4140 elif len(widths) != N: 

4141 raise ValueError(datashape_message.format("widths")) 

4142 

4143 # capwidth 

4144 if capwidths is None: 

4145 capwidths = 0.5 * np.array(widths) 

4146 elif np.isscalar(capwidths): 

4147 capwidths = [capwidths] * N 

4148 elif len(capwidths) != N: 

4149 raise ValueError(datashape_message.format("capwidths")) 

4150 

4151 for pos, width, stats, capwidth in zip(positions, widths, bxpstats, 

4152 capwidths): 

4153 # try to find a new label 

4154 datalabels.append(stats.get('label', pos)) 

4155 

4156 # whisker coords 

4157 whis_x = [pos, pos] 

4158 whislo_y = [stats['q1'], stats['whislo']] 

4159 whishi_y = [stats['q3'], stats['whishi']] 

4160 # cap coords 

4161 cap_left = pos - capwidth * 0.5 

4162 cap_right = pos + capwidth * 0.5 

4163 cap_x = [cap_left, cap_right] 

4164 cap_lo = np.full(2, stats['whislo']) 

4165 cap_hi = np.full(2, stats['whishi']) 

4166 # box and median coords 

4167 box_left = pos - width * 0.5 

4168 box_right = pos + width * 0.5 

4169 med_y = [stats['med'], stats['med']] 

4170 # notched boxes 

4171 if shownotches: 

4172 notch_left = pos - width * 0.25 

4173 notch_right = pos + width * 0.25 

4174 box_x = [box_left, box_right, box_right, notch_right, 

4175 box_right, box_right, box_left, box_left, notch_left, 

4176 box_left, box_left] 

4177 box_y = [stats['q1'], stats['q1'], stats['cilo'], 

4178 stats['med'], stats['cihi'], stats['q3'], 

4179 stats['q3'], stats['cihi'], stats['med'], 

4180 stats['cilo'], stats['q1']] 

4181 med_x = [notch_left, notch_right] 

4182 # plain boxes 

4183 else: 

4184 box_x = [box_left, box_right, box_right, box_left, box_left] 

4185 box_y = [stats['q1'], stats['q1'], stats['q3'], stats['q3'], 

4186 stats['q1']] 

4187 med_x = [box_left, box_right] 

4188 

4189 # maybe draw the box 

4190 if showbox: 

4191 do_box = do_patch if patch_artist else do_plot 

4192 boxes.append(do_box(box_x, box_y, **box_kw)) 

4193 # draw the whiskers 

4194 whiskers.append(do_plot(whis_x, whislo_y, **whisker_kw)) 

4195 whiskers.append(do_plot(whis_x, whishi_y, **whisker_kw)) 

4196 # maybe draw the caps 

4197 if showcaps: 

4198 caps.append(do_plot(cap_x, cap_lo, **cap_kw)) 

4199 caps.append(do_plot(cap_x, cap_hi, **cap_kw)) 

4200 # draw the medians 

4201 medians.append(do_plot(med_x, med_y, **median_kw)) 

4202 # maybe draw the means 

4203 if showmeans: 

4204 if meanline: 

4205 means.append(do_plot( 

4206 [box_left, box_right], [stats['mean'], stats['mean']], 

4207 **mean_kw 

4208 )) 

4209 else: 

4210 means.append(do_plot([pos], [stats['mean']], **mean_kw)) 

4211 # maybe draw the fliers 

4212 if showfliers: 

4213 flier_x = np.full(len(stats['fliers']), pos, dtype=np.float64) 

4214 flier_y = stats['fliers'] 

4215 fliers.append(do_plot(flier_x, flier_y, **flier_kw)) 

4216 

4217 if manage_ticks: 

4218 axis_name = "x" if vert else "y" 

4219 interval = getattr(self.dataLim, f"interval{axis_name}") 

4220 axis = getattr(self, f"{axis_name}axis") 

4221 positions = axis.convert_units(positions) 

4222 # The 0.5 additional padding ensures reasonable-looking boxes 

4223 # even when drawing a single box. We set the sticky edge to 

4224 # prevent margins expansion, in order to match old behavior (back 

4225 # when separate calls to boxplot() would completely reset the axis 

4226 # limits regardless of what was drawn before). The sticky edges 

4227 # are attached to the median lines, as they are always present. 

4228 interval[:] = (min(interval[0], min(positions) - .5), 

4229 max(interval[1], max(positions) + .5)) 

4230 for median, position in zip(medians, positions): 

4231 getattr(median.sticky_edges, axis_name).extend( 

4232 [position - .5, position + .5]) 

4233 # Modified from Axis.set_ticks and Axis.set_ticklabels. 

4234 locator = axis.get_major_locator() 

4235 if not isinstance(axis.get_major_locator(), 

4236 mticker.FixedLocator): 

4237 locator = mticker.FixedLocator([]) 

4238 axis.set_major_locator(locator) 

4239 locator.locs = np.array([*locator.locs, *positions]) 

4240 formatter = axis.get_major_formatter() 

4241 if not isinstance(axis.get_major_formatter(), 

4242 mticker.FixedFormatter): 

4243 formatter = mticker.FixedFormatter([]) 

4244 axis.set_major_formatter(formatter) 

4245 formatter.seq = [*formatter.seq, *datalabels] 

4246 

4247 self._request_autoscale_view() 

4248 

4249 return dict(whiskers=whiskers, caps=caps, boxes=boxes, 

4250 medians=medians, fliers=fliers, means=means) 

4251 

4252 @staticmethod 

4253 def _parse_scatter_color_args(c, edgecolors, kwargs, xsize, 

4254 get_next_color_func): 

4255 """ 

4256 Helper function to process color related arguments of `.Axes.scatter`. 

4257 

4258 Argument precedence for facecolors: 

4259 

4260 - c (if not None) 

4261 - kwargs['facecolor'] 

4262 - kwargs['facecolors'] 

4263 - kwargs['color'] (==kwcolor) 

4264 - 'b' if in classic mode else the result of ``get_next_color_func()`` 

4265 

4266 Argument precedence for edgecolors: 

4267 

4268 - kwargs['edgecolor'] 

4269 - edgecolors (is an explicit kw argument in scatter()) 

4270 - kwargs['color'] (==kwcolor) 

4271 - 'face' if not in classic mode else None 

4272 

4273 Parameters 

4274 ---------- 

4275 c : color or sequence or sequence of color or None 

4276 See argument description of `.Axes.scatter`. 

4277 edgecolors : color or sequence of color or {'face', 'none'} or None 

4278 See argument description of `.Axes.scatter`. 

4279 kwargs : dict 

4280 Additional kwargs. If these keys exist, we pop and process them: 

4281 'facecolors', 'facecolor', 'edgecolor', 'color' 

4282 Note: The dict is modified by this function. 

4283 xsize : int 

4284 The size of the x and y arrays passed to `.Axes.scatter`. 

4285 get_next_color_func : callable 

4286 A callable that returns a color. This color is used as facecolor 

4287 if no other color is provided. 

4288 

4289 Note, that this is a function rather than a fixed color value to 

4290 support conditional evaluation of the next color. As of the 

4291 current implementation obtaining the next color from the 

4292 property cycle advances the cycle. This must only happen if we 

4293 actually use the color, which will only be decided within this 

4294 method. 

4295 

4296 Returns 

4297 ------- 

4298 c 

4299 The input *c* if it was not *None*, else a color derived from the 

4300 other inputs or defaults. 

4301 colors : array(N, 4) or None 

4302 The facecolors as RGBA values, or *None* if a colormap is used. 

4303 edgecolors 

4304 The edgecolor. 

4305 

4306 """ 

4307 facecolors = kwargs.pop('facecolors', None) 

4308 facecolors = kwargs.pop('facecolor', facecolors) 

4309 edgecolors = kwargs.pop('edgecolor', edgecolors) 

4310 

4311 kwcolor = kwargs.pop('color', None) 

4312 

4313 if kwcolor is not None and c is not None: 

4314 raise ValueError("Supply a 'c' argument or a 'color'" 

4315 " kwarg but not both; they differ but" 

4316 " their functionalities overlap.") 

4317 

4318 if kwcolor is not None: 

4319 try: 

4320 mcolors.to_rgba_array(kwcolor) 

4321 except ValueError as err: 

4322 raise ValueError( 

4323 "'color' kwarg must be a color or sequence of color " 

4324 "specs. For a sequence of values to be color-mapped, use " 

4325 "the 'c' argument instead.") from err 

4326 if edgecolors is None: 

4327 edgecolors = kwcolor 

4328 if facecolors is None: 

4329 facecolors = kwcolor 

4330 

4331 if edgecolors is None and not mpl.rcParams['_internal.classic_mode']: 

4332 edgecolors = mpl.rcParams['scatter.edgecolors'] 

4333 

4334 c_was_none = c is None 

4335 if c is None: 

4336 c = (facecolors if facecolors is not None 

4337 else "b" if mpl.rcParams['_internal.classic_mode'] 

4338 else get_next_color_func()) 

4339 c_is_string_or_strings = ( 

4340 isinstance(c, str) 

4341 or (np.iterable(c) and len(c) > 0 

4342 and isinstance(cbook._safe_first_finite(c), str))) 

4343 

4344 def invalid_shape_exception(csize, xsize): 

4345 return ValueError( 

4346 f"'c' argument has {csize} elements, which is inconsistent " 

4347 f"with 'x' and 'y' with size {xsize}.") 

4348 

4349 c_is_mapped = False # Unless proven otherwise below. 

4350 valid_shape = True # Unless proven otherwise below. 

4351 if not c_was_none and kwcolor is None and not c_is_string_or_strings: 

4352 try: # First, does 'c' look suitable for value-mapping? 

4353 c = np.asanyarray(c, dtype=float) 

4354 except ValueError: 

4355 pass # Failed to convert to float array; must be color specs. 

4356 else: 

4357 # handle the documented special case of a 2D array with 1 

4358 # row which as RGB(A) to broadcast. 

4359 if c.shape == (1, 4) or c.shape == (1, 3): 

4360 c_is_mapped = False 

4361 if c.size != xsize: 

4362 valid_shape = False 

4363 # If c can be either mapped values or a RGB(A) color, prefer 

4364 # the former if shapes match, the latter otherwise. 

4365 elif c.size == xsize: 

4366 c = c.ravel() 

4367 c_is_mapped = True 

4368 else: # Wrong size; it must not be intended for mapping. 

4369 if c.shape in ((3,), (4,)): 

4370 _log.warning( 

4371 "*c* argument looks like a single numeric RGB or " 

4372 "RGBA sequence, which should be avoided as value-" 

4373 "mapping will have precedence in case its length " 

4374 "matches with *x* & *y*. Please use the *color* " 

4375 "keyword-argument or provide a 2D array " 

4376 "with a single row if you intend to specify " 

4377 "the same RGB or RGBA value for all points.") 

4378 valid_shape = False 

4379 if not c_is_mapped: 

4380 try: # Is 'c' acceptable as PathCollection facecolors? 

4381 colors = mcolors.to_rgba_array(c) 

4382 except (TypeError, ValueError) as err: 

4383 if "RGBA values should be within 0-1 range" in str(err): 

4384 raise 

4385 else: 

4386 if not valid_shape: 

4387 raise invalid_shape_exception(c.size, xsize) from err 

4388 # Both the mapping *and* the RGBA conversion failed: pretty 

4389 # severe failure => one may appreciate a verbose feedback. 

4390 raise ValueError( 

4391 f"'c' argument must be a color, a sequence of colors, " 

4392 f"or a sequence of numbers, not {c}") from err 

4393 else: 

4394 if len(colors) not in (0, 1, xsize): 

4395 # NB: remember that a single color is also acceptable. 

4396 # Besides *colors* will be an empty array if c == 'none'. 

4397 raise invalid_shape_exception(len(colors), xsize) 

4398 else: 

4399 colors = None # use cmap, norm after collection is created 

4400 return c, colors, edgecolors 

4401 

4402 @_preprocess_data(replace_names=["x", "y", "s", "linewidths", 

4403 "edgecolors", "c", "facecolor", 

4404 "facecolors", "color"], 

4405 label_namer="y") 

4406 @_docstring.interpd 

4407 def scatter(self, x, y, s=None, c=None, marker=None, cmap=None, norm=None, 

4408 vmin=None, vmax=None, alpha=None, linewidths=None, *, 

4409 edgecolors=None, plotnonfinite=False, **kwargs): 

4410 """ 

4411 A scatter plot of *y* vs. *x* with varying marker size and/or color. 

4412 

4413 Parameters 

4414 ---------- 

4415 x, y : float or array-like, shape (n, ) 

4416 The data positions. 

4417 

4418 s : float or array-like, shape (n, ), optional 

4419 The marker size in points**2 (typographic points are 1/72 in.). 

4420 Default is ``rcParams['lines.markersize'] ** 2``. 

4421 

4422 c : array-like or list of colors or color, optional 

4423 The marker colors. Possible values: 

4424 

4425 - A scalar or sequence of n numbers to be mapped to colors using 

4426 *cmap* and *norm*. 

4427 - A 2D array in which the rows are RGB or RGBA. 

4428 - A sequence of colors of length n. 

4429 - A single color format string. 

4430 

4431 Note that *c* should not be a single numeric RGB or RGBA sequence 

4432 because that is indistinguishable from an array of values to be 

4433 colormapped. If you want to specify the same RGB or RGBA value for 

4434 all points, use a 2D array with a single row. Otherwise, value- 

4435 matching will have precedence in case of a size matching with *x* 

4436 and *y*. 

4437 

4438 If you wish to specify a single color for all points 

4439 prefer the *color* keyword argument. 

4440 

4441 Defaults to `None`. In that case the marker color is determined 

4442 by the value of *color*, *facecolor* or *facecolors*. In case 

4443 those are not specified or `None`, the marker color is determined 

4444 by the next color of the ``Axes``' current "shape and fill" color 

4445 cycle. This cycle defaults to :rc:`axes.prop_cycle`. 

4446 

4447 marker : `~.markers.MarkerStyle`, default: :rc:`scatter.marker` 

4448 The marker style. *marker* can be either an instance of the class 

4449 or the text shorthand for a particular marker. 

4450 See :mod:`matplotlib.markers` for more information about marker 

4451 styles. 

4452 

4453 %(cmap_doc)s 

4454 

4455 This parameter is ignored if *c* is RGB(A). 

4456 

4457 %(norm_doc)s 

4458 

4459 This parameter is ignored if *c* is RGB(A). 

4460 

4461 %(vmin_vmax_doc)s 

4462 

4463 This parameter is ignored if *c* is RGB(A). 

4464 

4465 alpha : float, default: None 

4466 The alpha blending value, between 0 (transparent) and 1 (opaque). 

4467 

4468 linewidths : float or array-like, default: :rc:`lines.linewidth` 

4469 The linewidth of the marker edges. Note: The default *edgecolors* 

4470 is 'face'. You may want to change this as well. 

4471 

4472 edgecolors : {'face', 'none', *None*} or color or sequence of color, \ 

4473default: :rc:`scatter.edgecolors` 

4474 The edge color of the marker. Possible values: 

4475 

4476 - 'face': The edge color will always be the same as the face color. 

4477 - 'none': No patch boundary will be drawn. 

4478 - A color or sequence of colors. 

4479 

4480 For non-filled markers, *edgecolors* is ignored. Instead, the color 

4481 is determined like with 'face', i.e. from *c*, *colors*, or 

4482 *facecolors*. 

4483 

4484 plotnonfinite : bool, default: False 

4485 Whether to plot points with nonfinite *c* (i.e. ``inf``, ``-inf`` 

4486 or ``nan``). If ``True`` the points are drawn with the *bad* 

4487 colormap color (see `.Colormap.set_bad`). 

4488 

4489 Returns 

4490 ------- 

4491 `~matplotlib.collections.PathCollection` 

4492 

4493 Other Parameters 

4494 ---------------- 

4495 data : indexable object, optional 

4496 DATA_PARAMETER_PLACEHOLDER 

4497 **kwargs : `~matplotlib.collections.Collection` properties 

4498 

4499 See Also 

4500 -------- 

4501 plot : To plot scatter plots when markers are identical in size and 

4502 color. 

4503 

4504 Notes 

4505 ----- 

4506 * The `.plot` function will be faster for scatterplots where markers 

4507 don't vary in size or color. 

4508 

4509 * Any or all of *x*, *y*, *s*, and *c* may be masked arrays, in which 

4510 case all masks will be combined and only unmasked points will be 

4511 plotted. 

4512 

4513 * Fundamentally, scatter works with 1D arrays; *x*, *y*, *s*, and *c* 

4514 may be input as N-D arrays, but within scatter they will be 

4515 flattened. The exception is *c*, which will be flattened only if its 

4516 size matches the size of *x* and *y*. 

4517 

4518 """ 

4519 # Process **kwargs to handle aliases, conflicts with explicit kwargs: 

4520 x, y = self._process_unit_info([("x", x), ("y", y)], kwargs) 

4521 # np.ma.ravel yields an ndarray, not a masked array, 

4522 # unless its argument is a masked array. 

4523 x = np.ma.ravel(x) 

4524 y = np.ma.ravel(y) 

4525 if x.size != y.size: 

4526 raise ValueError("x and y must be the same size") 

4527 

4528 if s is None: 

4529 s = (20 if mpl.rcParams['_internal.classic_mode'] else 

4530 mpl.rcParams['lines.markersize'] ** 2.0) 

4531 s = np.ma.ravel(s) 

4532 if (len(s) not in (1, x.size) or 

4533 (not np.issubdtype(s.dtype, np.floating) and 

4534 not np.issubdtype(s.dtype, np.integer))): 

4535 raise ValueError( 

4536 "s must be a scalar, " 

4537 "or float array-like with the same size as x and y") 

4538 

4539 # get the original edgecolor the user passed before we normalize 

4540 orig_edgecolor = edgecolors 

4541 if edgecolors is None: 

4542 orig_edgecolor = kwargs.get('edgecolor', None) 

4543 c, colors, edgecolors = \ 

4544 self._parse_scatter_color_args( 

4545 c, edgecolors, kwargs, x.size, 

4546 get_next_color_func=self._get_patches_for_fill.get_next_color) 

4547 

4548 if plotnonfinite and colors is None: 

4549 c = np.ma.masked_invalid(c) 

4550 x, y, s, edgecolors, linewidths = \ 

4551 cbook._combine_masks(x, y, s, edgecolors, linewidths) 

4552 else: 

4553 x, y, s, c, colors, edgecolors, linewidths = \ 

4554 cbook._combine_masks( 

4555 x, y, s, c, colors, edgecolors, linewidths) 

4556 # Unmask edgecolors if it was actually a single RGB or RGBA. 

4557 if (x.size in (3, 4) 

4558 and np.ma.is_masked(edgecolors) 

4559 and not np.ma.is_masked(orig_edgecolor)): 

4560 edgecolors = edgecolors.data 

4561 

4562 scales = s # Renamed for readability below. 

4563 

4564 # load default marker from rcParams 

4565 if marker is None: 

4566 marker = mpl.rcParams['scatter.marker'] 

4567 

4568 if isinstance(marker, mmarkers.MarkerStyle): 

4569 marker_obj = marker 

4570 else: 

4571 marker_obj = mmarkers.MarkerStyle(marker) 

4572 

4573 path = marker_obj.get_path().transformed( 

4574 marker_obj.get_transform()) 

4575 if not marker_obj.is_filled(): 

4576 if orig_edgecolor is not None: 

4577 _api.warn_external( 

4578 f"You passed a edgecolor/edgecolors ({orig_edgecolor!r}) " 

4579 f"for an unfilled marker ({marker!r}). Matplotlib is " 

4580 "ignoring the edgecolor in favor of the facecolor. This " 

4581 "behavior may change in the future." 

4582 ) 

4583 # We need to handle markers that can not be filled (like 

4584 # '+' and 'x') differently than markers that can be 

4585 # filled, but have their fillstyle set to 'none'. This is 

4586 # to get: 

4587 # 

4588 # - respecting the fillestyle if set 

4589 # - maintaining back-compatibility for querying the facecolor of 

4590 # the un-fillable markers. 

4591 # 

4592 # While not an ideal situation, but is better than the 

4593 # alternatives. 

4594 if marker_obj.get_fillstyle() == 'none': 

4595 # promote the facecolor to be the edgecolor 

4596 edgecolors = colors 

4597 # set the facecolor to 'none' (at the last chance) because 

4598 # we can not fill a path if the facecolor is non-null 

4599 # (which is defendable at the renderer level). 

4600 colors = 'none' 

4601 else: 

4602 # if we are not nulling the face color we can do this 

4603 # simpler 

4604 edgecolors = 'face' 

4605 

4606 if linewidths is None: 

4607 linewidths = mpl.rcParams['lines.linewidth'] 

4608 elif np.iterable(linewidths): 

4609 linewidths = [ 

4610 lw if lw is not None else mpl.rcParams['lines.linewidth'] 

4611 for lw in linewidths] 

4612 

4613 offsets = np.ma.column_stack([x, y]) 

4614 

4615 collection = mcoll.PathCollection( 

4616 (path,), scales, 

4617 facecolors=colors, 

4618 edgecolors=edgecolors, 

4619 linewidths=linewidths, 

4620 offsets=offsets, 

4621 offset_transform=kwargs.pop('transform', self.transData), 

4622 alpha=alpha, 

4623 ) 

4624 collection.set_transform(mtransforms.IdentityTransform()) 

4625 if colors is None: 

4626 collection.set_array(c) 

4627 collection.set_cmap(cmap) 

4628 collection.set_norm(norm) 

4629 collection._scale_norm(norm, vmin, vmax) 

4630 else: 

4631 extra_kwargs = { 

4632 'cmap': cmap, 'norm': norm, 'vmin': vmin, 'vmax': vmax 

4633 } 

4634 extra_keys = [k for k, v in extra_kwargs.items() if v is not None] 

4635 if any(extra_keys): 

4636 keys_str = ", ".join(f"'{k}'" for k in extra_keys) 

4637 _api.warn_external( 

4638 "No data for colormapping provided via 'c'. " 

4639 f"Parameters {keys_str} will be ignored") 

4640 collection._internal_update(kwargs) 

4641 

4642 # Classic mode only: 

4643 # ensure there are margins to allow for the 

4644 # finite size of the symbols. In v2.x, margins 

4645 # are present by default, so we disable this 

4646 # scatter-specific override. 

4647 if mpl.rcParams['_internal.classic_mode']: 

4648 if self._xmargin < 0.05 and x.size > 0: 

4649 self.set_xmargin(0.05) 

4650 if self._ymargin < 0.05 and x.size > 0: 

4651 self.set_ymargin(0.05) 

4652 

4653 self.add_collection(collection) 

4654 self._request_autoscale_view() 

4655 

4656 return collection 

4657 

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

4659 @_docstring.dedent_interpd 

4660 def hexbin(self, x, y, C=None, gridsize=100, bins=None, 

4661 xscale='linear', yscale='linear', extent=None, 

4662 cmap=None, norm=None, vmin=None, vmax=None, 

4663 alpha=None, linewidths=None, edgecolors='face', 

4664 reduce_C_function=np.mean, mincnt=None, marginals=False, 

4665 **kwargs): 

4666 """ 

4667 Make a 2D hexagonal binning plot of points *x*, *y*. 

4668 

4669 If *C* is *None*, the value of the hexagon is determined by the number 

4670 of points in the hexagon. Otherwise, *C* specifies values at the 

4671 coordinate (x[i], y[i]). For each hexagon, these values are reduced 

4672 using *reduce_C_function*. 

4673 

4674 Parameters 

4675 ---------- 

4676 x, y : array-like 

4677 The data positions. *x* and *y* must be of the same length. 

4678 

4679 C : array-like, optional 

4680 If given, these values are accumulated in the bins. Otherwise, 

4681 every point has a value of 1. Must be of the same length as *x* 

4682 and *y*. 

4683 

4684 gridsize : int or (int, int), default: 100 

4685 If a single int, the number of hexagons in the *x*-direction. 

4686 The number of hexagons in the *y*-direction is chosen such that 

4687 the hexagons are approximately regular. 

4688 

4689 Alternatively, if a tuple (*nx*, *ny*), the number of hexagons 

4690 in the *x*-direction and the *y*-direction. In the 

4691 *y*-direction, counting is done along vertically aligned 

4692 hexagons, not along the zig-zag chains of hexagons; see the 

4693 following illustration. 

4694 

4695 .. plot:: 

4696 

4697 import numpy 

4698 import matplotlib.pyplot as plt 

4699 

4700 np.random.seed(19680801) 

4701 n= 300 

4702 x = np.random.standard_normal(n) 

4703 y = np.random.standard_normal(n) 

4704 

4705 fig, ax = plt.subplots(figsize=(4, 4)) 

4706 h = ax.hexbin(x, y, gridsize=(5, 3)) 

4707 hx, hy = h.get_offsets().T 

4708 ax.plot(hx[24::3], hy[24::3], 'ro-') 

4709 ax.plot(hx[-3:], hy[-3:], 'ro-') 

4710 ax.set_title('gridsize=(5, 3)') 

4711 ax.axis('off') 

4712 

4713 To get approximately regular hexagons, choose 

4714 :math:`n_x = \\sqrt{3}\\,n_y`. 

4715 

4716 bins : 'log' or int or sequence, default: None 

4717 Discretization of the hexagon values. 

4718 

4719 - If *None*, no binning is applied; the color of each hexagon 

4720 directly corresponds to its count value. 

4721 - If 'log', use a logarithmic scale for the colormap. 

4722 Internally, :math:`log_{10}(i+1)` is used to determine the 

4723 hexagon color. This is equivalent to ``norm=LogNorm()``. 

4724 - If an integer, divide the counts in the specified number 

4725 of bins, and color the hexagons accordingly. 

4726 - If a sequence of values, the values of the lower bound of 

4727 the bins to be used. 

4728 

4729 xscale : {'linear', 'log'}, default: 'linear' 

4730 Use a linear or log10 scale on the horizontal axis. 

4731 

4732 yscale : {'linear', 'log'}, default: 'linear' 

4733 Use a linear or log10 scale on the vertical axis. 

4734 

4735 mincnt : int > 0, default: *None* 

4736 If not *None*, only display cells with more than *mincnt* 

4737 number of points in the cell. 

4738 

4739 marginals : bool, default: *False* 

4740 If marginals is *True*, plot the marginal density as 

4741 colormapped rectangles along the bottom of the x-axis and 

4742 left of the y-axis. 

4743 

4744 extent : 4-tuple of float, default: *None* 

4745 The limits of the bins (xmin, xmax, ymin, ymax). 

4746 The default assigns the limits based on 

4747 *gridsize*, *x*, *y*, *xscale* and *yscale*. 

4748 

4749 If *xscale* or *yscale* is set to 'log', the limits are 

4750 expected to be the exponent for a power of 10. E.g. for 

4751 x-limits of 1 and 50 in 'linear' scale and y-limits 

4752 of 10 and 1000 in 'log' scale, enter (1, 50, 1, 3). 

4753 

4754 Returns 

4755 ------- 

4756 `~matplotlib.collections.PolyCollection` 

4757 A `.PolyCollection` defining the hexagonal bins. 

4758 

4759 - `.PolyCollection.get_offsets` contains a Mx2 array containing 

4760 the x, y positions of the M hexagon centers. 

4761 - `.PolyCollection.get_array` contains the values of the M 

4762 hexagons. 

4763 

4764 If *marginals* is *True*, horizontal 

4765 bar and vertical bar (both PolyCollections) will be attached 

4766 to the return collection as attributes *hbar* and *vbar*. 

4767 

4768 Other Parameters 

4769 ---------------- 

4770 %(cmap_doc)s 

4771 

4772 %(norm_doc)s 

4773 

4774 %(vmin_vmax_doc)s 

4775 

4776 alpha : float between 0 and 1, optional 

4777 The alpha blending value, between 0 (transparent) and 1 (opaque). 

4778 

4779 linewidths : float, default: *None* 

4780 If *None*, defaults to 1.0. 

4781 

4782 edgecolors : {'face', 'none', *None*} or color, default: 'face' 

4783 The color of the hexagon edges. Possible values are: 

4784 

4785 - 'face': Draw the edges in the same color as the fill color. 

4786 - 'none': No edges are drawn. This can sometimes lead to unsightly 

4787 unpainted pixels between the hexagons. 

4788 - *None*: Draw outlines in the default color. 

4789 - An explicit color. 

4790 

4791 reduce_C_function : callable, default: `numpy.mean` 

4792 The function to aggregate *C* within the bins. It is ignored if 

4793 *C* is not given. This must have the signature:: 

4794 

4795 def reduce_C_function(C: array) -> float 

4796 

4797 Commonly used functions are: 

4798 

4799 - `numpy.mean`: average of the points 

4800 - `numpy.sum`: integral of the point values 

4801 - `numpy.amax`: value taken from the largest point 

4802 

4803 data : indexable object, optional 

4804 DATA_PARAMETER_PLACEHOLDER 

4805 

4806 **kwargs : `~matplotlib.collections.PolyCollection` properties 

4807 All other keyword arguments are passed on to `.PolyCollection`: 

4808 

4809 %(PolyCollection:kwdoc)s 

4810 

4811 See Also 

4812 -------- 

4813 hist2d : 2D histogram rectangular bins 

4814 """ 

4815 self._process_unit_info([("x", x), ("y", y)], kwargs, convert=False) 

4816 

4817 x, y, C = cbook.delete_masked_points(x, y, C) 

4818 

4819 # Set the size of the hexagon grid 

4820 if np.iterable(gridsize): 

4821 nx, ny = gridsize 

4822 else: 

4823 nx = gridsize 

4824 ny = int(nx / math.sqrt(3)) 

4825 # Count the number of data in each hexagon 

4826 x = np.asarray(x, float) 

4827 y = np.asarray(y, float) 

4828 

4829 # Will be log()'d if necessary, and then rescaled. 

4830 tx = x 

4831 ty = y 

4832 

4833 if xscale == 'log': 

4834 if np.any(x <= 0.0): 

4835 raise ValueError("x contains non-positive values, so can not " 

4836 "be log-scaled") 

4837 tx = np.log10(tx) 

4838 if yscale == 'log': 

4839 if np.any(y <= 0.0): 

4840 raise ValueError("y contains non-positive values, so can not " 

4841 "be log-scaled") 

4842 ty = np.log10(ty) 

4843 if extent is not None: 

4844 xmin, xmax, ymin, ymax = extent 

4845 else: 

4846 xmin, xmax = (tx.min(), tx.max()) if len(x) else (0, 1) 

4847 ymin, ymax = (ty.min(), ty.max()) if len(y) else (0, 1) 

4848 

4849 # to avoid issues with singular data, expand the min/max pairs 

4850 xmin, xmax = mtransforms.nonsingular(xmin, xmax, expander=0.1) 

4851 ymin, ymax = mtransforms.nonsingular(ymin, ymax, expander=0.1) 

4852 

4853 nx1 = nx + 1 

4854 ny1 = ny + 1 

4855 nx2 = nx 

4856 ny2 = ny 

4857 n = nx1 * ny1 + nx2 * ny2 

4858 

4859 # In the x-direction, the hexagons exactly cover the region from 

4860 # xmin to xmax. Need some padding to avoid roundoff errors. 

4861 padding = 1.e-9 * (xmax - xmin) 

4862 xmin -= padding 

4863 xmax += padding 

4864 sx = (xmax - xmin) / nx 

4865 sy = (ymax - ymin) / ny 

4866 # Positions in hexagon index coordinates. 

4867 ix = (tx - xmin) / sx 

4868 iy = (ty - ymin) / sy 

4869 ix1 = np.round(ix).astype(int) 

4870 iy1 = np.round(iy).astype(int) 

4871 ix2 = np.floor(ix).astype(int) 

4872 iy2 = np.floor(iy).astype(int) 

4873 # flat indices, plus one so that out-of-range points go to position 0. 

4874 i1 = np.where((0 <= ix1) & (ix1 < nx1) & (0 <= iy1) & (iy1 < ny1), 

4875 ix1 * ny1 + iy1 + 1, 0) 

4876 i2 = np.where((0 <= ix2) & (ix2 < nx2) & (0 <= iy2) & (iy2 < ny2), 

4877 ix2 * ny2 + iy2 + 1, 0) 

4878 

4879 d1 = (ix - ix1) ** 2 + 3.0 * (iy - iy1) ** 2 

4880 d2 = (ix - ix2 - 0.5) ** 2 + 3.0 * (iy - iy2 - 0.5) ** 2 

4881 bdist = (d1 < d2) 

4882 

4883 if C is None: # [1:] drops out-of-range points. 

4884 counts1 = np.bincount(i1[bdist], minlength=1 + nx1 * ny1)[1:] 

4885 counts2 = np.bincount(i2[~bdist], minlength=1 + nx2 * ny2)[1:] 

4886 accum = np.concatenate([counts1, counts2]).astype(float) 

4887 if mincnt is not None: 

4888 accum[accum < mincnt] = np.nan 

4889 C = np.ones(len(x)) 

4890 else: 

4891 # store the C values in a list per hexagon index 

4892 Cs_at_i1 = [[] for _ in range(1 + nx1 * ny1)] 

4893 Cs_at_i2 = [[] for _ in range(1 + nx2 * ny2)] 

4894 for i in range(len(x)): 

4895 if bdist[i]: 

4896 Cs_at_i1[i1[i]].append(C[i]) 

4897 else: 

4898 Cs_at_i2[i2[i]].append(C[i]) 

4899 if mincnt is None: 

4900 mincnt = 0 

4901 accum = np.array( 

4902 [reduce_C_function(acc) if len(acc) > mincnt else np.nan 

4903 for Cs_at_i in [Cs_at_i1, Cs_at_i2] 

4904 for acc in Cs_at_i[1:]], # [1:] drops out-of-range points. 

4905 float) 

4906 

4907 good_idxs = ~np.isnan(accum) 

4908 

4909 offsets = np.zeros((n, 2), float) 

4910 offsets[:nx1 * ny1, 0] = np.repeat(np.arange(nx1), ny1) 

4911 offsets[:nx1 * ny1, 1] = np.tile(np.arange(ny1), nx1) 

4912 offsets[nx1 * ny1:, 0] = np.repeat(np.arange(nx2) + 0.5, ny2) 

4913 offsets[nx1 * ny1:, 1] = np.tile(np.arange(ny2), nx2) + 0.5 

4914 offsets[:, 0] *= sx 

4915 offsets[:, 1] *= sy 

4916 offsets[:, 0] += xmin 

4917 offsets[:, 1] += ymin 

4918 # remove accumulation bins with no data 

4919 offsets = offsets[good_idxs, :] 

4920 accum = accum[good_idxs] 

4921 

4922 polygon = [sx, sy / 3] * np.array( 

4923 [[.5, -.5], [.5, .5], [0., 1.], [-.5, .5], [-.5, -.5], [0., -1.]]) 

4924 

4925 if linewidths is None: 

4926 linewidths = [1.0] 

4927 

4928 if xscale == 'log' or yscale == 'log': 

4929 polygons = np.expand_dims(polygon, 0) + np.expand_dims(offsets, 1) 

4930 if xscale == 'log': 

4931 polygons[:, :, 0] = 10.0 ** polygons[:, :, 0] 

4932 xmin = 10.0 ** xmin 

4933 xmax = 10.0 ** xmax 

4934 self.set_xscale(xscale) 

4935 if yscale == 'log': 

4936 polygons[:, :, 1] = 10.0 ** polygons[:, :, 1] 

4937 ymin = 10.0 ** ymin 

4938 ymax = 10.0 ** ymax 

4939 self.set_yscale(yscale) 

4940 collection = mcoll.PolyCollection( 

4941 polygons, 

4942 edgecolors=edgecolors, 

4943 linewidths=linewidths, 

4944 ) 

4945 else: 

4946 collection = mcoll.PolyCollection( 

4947 [polygon], 

4948 edgecolors=edgecolors, 

4949 linewidths=linewidths, 

4950 offsets=offsets, 

4951 offset_transform=mtransforms.AffineDeltaTransform( 

4952 self.transData), 

4953 ) 

4954 

4955 # Set normalizer if bins is 'log' 

4956 if bins == 'log': 

4957 if norm is not None: 

4958 _api.warn_external("Only one of 'bins' and 'norm' arguments " 

4959 f"can be supplied, ignoring bins={bins}") 

4960 else: 

4961 norm = mcolors.LogNorm(vmin=vmin, vmax=vmax) 

4962 vmin = vmax = None 

4963 bins = None 

4964 

4965 # autoscale the norm with current accum values if it hasn't been set 

4966 if norm is not None: 

4967 if norm.vmin is None and norm.vmax is None: 

4968 norm.autoscale(accum) 

4969 

4970 if bins is not None: 

4971 if not np.iterable(bins): 

4972 minimum, maximum = min(accum), max(accum) 

4973 bins -= 1 # one less edge than bins 

4974 bins = minimum + (maximum - minimum) * np.arange(bins) / bins 

4975 bins = np.sort(bins) 

4976 accum = bins.searchsorted(accum) 

4977 

4978 collection.set_array(accum) 

4979 collection.set_cmap(cmap) 

4980 collection.set_norm(norm) 

4981 collection.set_alpha(alpha) 

4982 collection._internal_update(kwargs) 

4983 collection._scale_norm(norm, vmin, vmax) 

4984 

4985 corners = ((xmin, ymin), (xmax, ymax)) 

4986 self.update_datalim(corners) 

4987 self._request_autoscale_view(tight=True) 

4988 

4989 # add the collection last 

4990 self.add_collection(collection, autolim=False) 

4991 if not marginals: 

4992 return collection 

4993 

4994 # Process marginals 

4995 bars = [] 

4996 for zname, z, zmin, zmax, zscale, nbins in [ 

4997 ("x", x, xmin, xmax, xscale, nx), 

4998 ("y", y, ymin, ymax, yscale, 2 * ny), 

4999 ]: 

5000 

5001 if zscale == "log": 

5002 bin_edges = np.geomspace(zmin, zmax, nbins + 1) 

5003 else: 

5004 bin_edges = np.linspace(zmin, zmax, nbins + 1) 

5005 

5006 verts = np.empty((nbins, 4, 2)) 

5007 verts[:, 0, 0] = verts[:, 1, 0] = bin_edges[:-1] 

5008 verts[:, 2, 0] = verts[:, 3, 0] = bin_edges[1:] 

5009 verts[:, 0, 1] = verts[:, 3, 1] = .00 

5010 verts[:, 1, 1] = verts[:, 2, 1] = .05 

5011 if zname == "y": 

5012 verts = verts[:, :, ::-1] # Swap x and y. 

5013 

5014 # Sort z-values into bins defined by bin_edges. 

5015 bin_idxs = np.searchsorted(bin_edges, z) - 1 

5016 values = np.empty(nbins) 

5017 for i in range(nbins): 

5018 # Get C-values for each bin, and compute bin value with 

5019 # reduce_C_function. 

5020 ci = C[bin_idxs == i] 

5021 values[i] = reduce_C_function(ci) if len(ci) > 0 else np.nan 

5022 

5023 mask = ~np.isnan(values) 

5024 verts = verts[mask] 

5025 values = values[mask] 

5026 

5027 trans = getattr(self, f"get_{zname}axis_transform")(which="grid") 

5028 bar = mcoll.PolyCollection( 

5029 verts, transform=trans, edgecolors="face") 

5030 bar.set_array(values) 

5031 bar.set_cmap(cmap) 

5032 bar.set_norm(norm) 

5033 bar.set_alpha(alpha) 

5034 bar._internal_update(kwargs) 

5035 bars.append(self.add_collection(bar, autolim=False)) 

5036 

5037 collection.hbar, collection.vbar = bars 

5038 

5039 def on_changed(collection): 

5040 collection.hbar.set_cmap(collection.get_cmap()) 

5041 collection.hbar.set_cmap(collection.get_cmap()) 

5042 collection.vbar.set_clim(collection.get_clim()) 

5043 collection.vbar.set_clim(collection.get_clim()) 

5044 

5045 collection.callbacks.connect('changed', on_changed) 

5046 

5047 return collection 

5048 

5049 @_docstring.dedent_interpd 

5050 def arrow(self, x, y, dx, dy, **kwargs): 

5051 """ 

5052 Add an arrow to the Axes. 

5053 

5054 This draws an arrow from ``(x, y)`` to ``(x+dx, y+dy)``. 

5055 

5056 Parameters 

5057 ---------- 

5058 %(FancyArrow)s 

5059 

5060 Returns 

5061 ------- 

5062 `.FancyArrow` 

5063 The created `.FancyArrow` object. 

5064 

5065 Notes 

5066 ----- 

5067 The resulting arrow is affected by the Axes aspect ratio and limits. 

5068 This may produce an arrow whose head is not square with its stem. To 

5069 create an arrow whose head is square with its stem, 

5070 use :meth:`annotate` for example: 

5071 

5072 >>> ax.annotate("", xy=(0.5, 0.5), xytext=(0, 0), 

5073 ... arrowprops=dict(arrowstyle="->")) 

5074 

5075 """ 

5076 # Strip away units for the underlying patch since units 

5077 # do not make sense to most patch-like code 

5078 x = self.convert_xunits(x) 

5079 y = self.convert_yunits(y) 

5080 dx = self.convert_xunits(dx) 

5081 dy = self.convert_yunits(dy) 

5082 

5083 a = mpatches.FancyArrow(x, y, dx, dy, **kwargs) 

5084 self.add_patch(a) 

5085 self._request_autoscale_view() 

5086 return a 

5087 

5088 @_docstring.copy(mquiver.QuiverKey.__init__) 

5089 def quiverkey(self, Q, X, Y, U, label, **kwargs): 

5090 qk = mquiver.QuiverKey(Q, X, Y, U, label, **kwargs) 

5091 self.add_artist(qk) 

5092 return qk 

5093 

5094 # Handle units for x and y, if they've been passed 

5095 def _quiver_units(self, args, kwargs): 

5096 if len(args) > 3: 

5097 x, y = args[0:2] 

5098 x, y = self._process_unit_info([("x", x), ("y", y)], kwargs) 

5099 return (x, y) + args[2:] 

5100 return args 

5101 

5102 # args can by a combination if X, Y, U, V, C and all should be replaced 

5103 @_preprocess_data() 

5104 @_docstring.dedent_interpd 

5105 def quiver(self, *args, **kwargs): 

5106 """%(quiver_doc)s""" 

5107 # Make sure units are handled for x and y values 

5108 args = self._quiver_units(args, kwargs) 

5109 q = mquiver.Quiver(self, *args, **kwargs) 

5110 self.add_collection(q, autolim=True) 

5111 self._request_autoscale_view() 

5112 return q 

5113 

5114 # args can be some combination of X, Y, U, V, C and all should be replaced 

5115 @_preprocess_data() 

5116 @_docstring.dedent_interpd 

5117 def barbs(self, *args, **kwargs): 

5118 """%(barbs_doc)s""" 

5119 # Make sure units are handled for x and y values 

5120 args = self._quiver_units(args, kwargs) 

5121 b = mquiver.Barbs(self, *args, **kwargs) 

5122 self.add_collection(b, autolim=True) 

5123 self._request_autoscale_view() 

5124 return b 

5125 

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

5127 # _process_plot_var_args. 

5128 def fill(self, *args, data=None, **kwargs): 

5129 """ 

5130 Plot filled polygons. 

5131 

5132 Parameters 

5133 ---------- 

5134 *args : sequence of x, y, [color] 

5135 Each polygon is defined by the lists of *x* and *y* positions of 

5136 its nodes, optionally followed by a *color* specifier. See 

5137 :mod:`matplotlib.colors` for supported color specifiers. The 

5138 standard color cycle is used for polygons without a color 

5139 specifier. 

5140 

5141 You can plot multiple polygons by providing multiple *x*, *y*, 

5142 *[color]* groups. 

5143 

5144 For example, each of the following is legal:: 

5145 

5146 ax.fill(x, y) # a polygon with default color 

5147 ax.fill(x, y, "b") # a blue polygon 

5148 ax.fill(x, y, x2, y2) # two polygons 

5149 ax.fill(x, y, "b", x2, y2, "r") # a blue and a red polygon 

5150 

5151 data : indexable object, optional 

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

5153 plot in *x* and *y*, e.g.:: 

5154 

5155 ax.fill("time", "signal", 

5156 data={"time": [0, 1, 2], "signal": [0, 1, 0]}) 

5157 

5158 Returns 

5159 ------- 

5160 list of `~matplotlib.patches.Polygon` 

5161 

5162 Other Parameters 

5163 ---------------- 

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

5165 

5166 Notes 

5167 ----- 

5168 Use :meth:`fill_between` if you would like to fill the region between 

5169 two curves. 

5170 """ 

5171 # For compatibility(!), get aliases from Line2D rather than Patch. 

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

5173 # _get_patches_for_fill returns a generator, convert it to a list. 

5174 patches = [*self._get_patches_for_fill(*args, data=data, **kwargs)] 

5175 for poly in patches: 

5176 self.add_patch(poly) 

5177 self._request_autoscale_view() 

5178 return patches 

5179 

5180 def _fill_between_x_or_y( 

5181 self, ind_dir, ind, dep1, dep2=0, *, 

5182 where=None, interpolate=False, step=None, **kwargs): 

5183 # Common implementation between fill_between (*ind_dir*="x") and 

5184 # fill_betweenx (*ind_dir*="y"). *ind* is the independent variable, 

5185 # *dep* the dependent variable. The docstring below is interpolated 

5186 # to generate both methods' docstrings. 

5187 """ 

5188 Fill the area between two {dir} curves. 

5189 

5190 The curves are defined by the points (*{ind}*, *{dep}1*) and (*{ind}*, 

5191 *{dep}2*). This creates one or multiple polygons describing the filled 

5192 area. 

5193 

5194 You may exclude some {dir} sections from filling using *where*. 

5195 

5196 By default, the edges connect the given points directly. Use *step* 

5197 if the filling should be a step function, i.e. constant in between 

5198 *{ind}*. 

5199 

5200 Parameters 

5201 ---------- 

5202 {ind} : array (length N) 

5203 The {ind} coordinates of the nodes defining the curves. 

5204 

5205 {dep}1 : array (length N) or scalar 

5206 The {dep} coordinates of the nodes defining the first curve. 

5207 

5208 {dep}2 : array (length N) or scalar, default: 0 

5209 The {dep} coordinates of the nodes defining the second curve. 

5210 

5211 where : array of bool (length N), optional 

5212 Define *where* to exclude some {dir} regions from being filled. 

5213 The filled regions are defined by the coordinates ``{ind}[where]``. 

5214 More precisely, fill between ``{ind}[i]`` and ``{ind}[i+1]`` if 

5215 ``where[i] and where[i+1]``. Note that this definition implies 

5216 that an isolated *True* value between two *False* values in *where* 

5217 will not result in filling. Both sides of the *True* position 

5218 remain unfilled due to the adjacent *False* values. 

5219 

5220 interpolate : bool, default: False 

5221 This option is only relevant if *where* is used and the two curves 

5222 are crossing each other. 

5223 

5224 Semantically, *where* is often used for *{dep}1* > *{dep}2* or 

5225 similar. By default, the nodes of the polygon defining the filled 

5226 region will only be placed at the positions in the *{ind}* array. 

5227 Such a polygon cannot describe the above semantics close to the 

5228 intersection. The {ind}-sections containing the intersection are 

5229 simply clipped. 

5230 

5231 Setting *interpolate* to *True* will calculate the actual 

5232 intersection point and extend the filled region up to this point. 

5233 

5234 step : {{'pre', 'post', 'mid'}}, optional 

5235 Define *step* if the filling should be a step function, 

5236 i.e. constant in between *{ind}*. The value determines where the 

5237 step will occur: 

5238 

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

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

5241 value ``y[i]``. 

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

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

5244 value ``y[i]``. 

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

5246 

5247 Returns 

5248 ------- 

5249 `.PolyCollection` 

5250 A `.PolyCollection` containing the plotted polygons. 

5251 

5252 Other Parameters 

5253 ---------------- 

5254 data : indexable object, optional 

5255 DATA_PARAMETER_PLACEHOLDER 

5256 

5257 **kwargs 

5258 All other keyword arguments are passed on to `.PolyCollection`. 

5259 They control the `.Polygon` properties: 

5260 

5261 %(PolyCollection:kwdoc)s 

5262 

5263 See Also 

5264 -------- 

5265 fill_between : Fill between two sets of y-values. 

5266 fill_betweenx : Fill between two sets of x-values. 

5267 """ 

5268 

5269 dep_dir = {"x": "y", "y": "x"}[ind_dir] 

5270 

5271 if not mpl.rcParams["_internal.classic_mode"]: 

5272 kwargs = cbook.normalize_kwargs(kwargs, mcoll.Collection) 

5273 if not any(c in kwargs for c in ("color", "facecolor")): 

5274 kwargs["facecolor"] = \ 

5275 self._get_patches_for_fill.get_next_color() 

5276 

5277 # Handle united data, such as dates 

5278 ind, dep1, dep2 = map( 

5279 ma.masked_invalid, self._process_unit_info( 

5280 [(ind_dir, ind), (dep_dir, dep1), (dep_dir, dep2)], kwargs)) 

5281 

5282 for name, array in [ 

5283 (ind_dir, ind), (f"{dep_dir}1", dep1), (f"{dep_dir}2", dep2)]: 

5284 if array.ndim > 1: 

5285 raise ValueError(f"{name!r} is not 1-dimensional") 

5286 

5287 if where is None: 

5288 where = True 

5289 else: 

5290 where = np.asarray(where, dtype=bool) 

5291 if where.size != ind.size: 

5292 raise ValueError(f"where size ({where.size}) does not match " 

5293 f"{ind_dir} size ({ind.size})") 

5294 where = where & ~functools.reduce( 

5295 np.logical_or, map(np.ma.getmaskarray, [ind, dep1, dep2])) 

5296 

5297 ind, dep1, dep2 = np.broadcast_arrays( 

5298 np.atleast_1d(ind), dep1, dep2, subok=True) 

5299 

5300 polys = [] 

5301 for idx0, idx1 in cbook.contiguous_regions(where): 

5302 indslice = ind[idx0:idx1] 

5303 dep1slice = dep1[idx0:idx1] 

5304 dep2slice = dep2[idx0:idx1] 

5305 if step is not None: 

5306 step_func = cbook.STEP_LOOKUP_MAP["steps-" + step] 

5307 indslice, dep1slice, dep2slice = \ 

5308 step_func(indslice, dep1slice, dep2slice) 

5309 

5310 if not len(indslice): 

5311 continue 

5312 

5313 N = len(indslice) 

5314 pts = np.zeros((2 * N + 2, 2)) 

5315 

5316 if interpolate: 

5317 def get_interp_point(idx): 

5318 im1 = max(idx - 1, 0) 

5319 ind_values = ind[im1:idx+1] 

5320 diff_values = dep1[im1:idx+1] - dep2[im1:idx+1] 

5321 dep1_values = dep1[im1:idx+1] 

5322 

5323 if len(diff_values) == 2: 

5324 if np.ma.is_masked(diff_values[1]): 

5325 return ind[im1], dep1[im1] 

5326 elif np.ma.is_masked(diff_values[0]): 

5327 return ind[idx], dep1[idx] 

5328 

5329 diff_order = diff_values.argsort() 

5330 diff_root_ind = np.interp( 

5331 0, diff_values[diff_order], ind_values[diff_order]) 

5332 ind_order = ind_values.argsort() 

5333 diff_root_dep = np.interp( 

5334 diff_root_ind, 

5335 ind_values[ind_order], dep1_values[ind_order]) 

5336 return diff_root_ind, diff_root_dep 

5337 

5338 start = get_interp_point(idx0) 

5339 end = get_interp_point(idx1) 

5340 else: 

5341 # Handle scalar dep2 (e.g. 0): the fill should go all 

5342 # the way down to 0 even if none of the dep1 sample points do. 

5343 start = indslice[0], dep2slice[0] 

5344 end = indslice[-1], dep2slice[-1] 

5345 

5346 pts[0] = start 

5347 pts[N + 1] = end 

5348 

5349 pts[1:N+1, 0] = indslice 

5350 pts[1:N+1, 1] = dep1slice 

5351 pts[N+2:, 0] = indslice[::-1] 

5352 pts[N+2:, 1] = dep2slice[::-1] 

5353 

5354 if ind_dir == "y": 

5355 pts = pts[:, ::-1] 

5356 

5357 polys.append(pts) 

5358 

5359 collection = mcoll.PolyCollection(polys, **kwargs) 

5360 

5361 # now update the datalim and autoscale 

5362 pts = np.row_stack([np.column_stack([ind[where], dep1[where]]), 

5363 np.column_stack([ind[where], dep2[where]])]) 

5364 if ind_dir == "y": 

5365 pts = pts[:, ::-1] 

5366 self.update_datalim(pts, updatex=True, updatey=True) 

5367 self.add_collection(collection, autolim=False) 

5368 self._request_autoscale_view() 

5369 return collection 

5370 

5371 def fill_between(self, x, y1, y2=0, where=None, interpolate=False, 

5372 step=None, **kwargs): 

5373 return self._fill_between_x_or_y( 

5374 "x", x, y1, y2, 

5375 where=where, interpolate=interpolate, step=step, **kwargs) 

5376 

5377 if _fill_between_x_or_y.__doc__: 

5378 fill_between.__doc__ = _fill_between_x_or_y.__doc__.format( 

5379 dir="horizontal", ind="x", dep="y" 

5380 ) 

5381 fill_between = _preprocess_data( 

5382 _docstring.dedent_interpd(fill_between), 

5383 replace_names=["x", "y1", "y2", "where"]) 

5384 

5385 def fill_betweenx(self, y, x1, x2=0, where=None, 

5386 step=None, interpolate=False, **kwargs): 

5387 return self._fill_between_x_or_y( 

5388 "y", y, x1, x2, 

5389 where=where, interpolate=interpolate, step=step, **kwargs) 

5390 

5391 if _fill_between_x_or_y.__doc__: 

5392 fill_betweenx.__doc__ = _fill_between_x_or_y.__doc__.format( 

5393 dir="vertical", ind="y", dep="x" 

5394 ) 

5395 fill_betweenx = _preprocess_data( 

5396 _docstring.dedent_interpd(fill_betweenx), 

5397 replace_names=["y", "x1", "x2", "where"]) 

5398 

5399 #### plotting z(x, y): imshow, pcolor and relatives, contour 

5400 

5401 # Once this deprecation elapses, also move vmin, vmax right after norm, to 

5402 # match the signature of other methods returning ScalarMappables and keep 

5403 # the documentation for *norm*, *vmax* and *vmin* together. 

5404 @_api.make_keyword_only("3.5", "aspect") 

5405 @_preprocess_data() 

5406 @_docstring.interpd 

5407 def imshow(self, X, cmap=None, norm=None, aspect=None, 

5408 interpolation=None, alpha=None, 

5409 vmin=None, vmax=None, origin=None, extent=None, *, 

5410 interpolation_stage=None, filternorm=True, filterrad=4.0, 

5411 resample=None, url=None, **kwargs): 

5412 """ 

5413 Display data as an image, i.e., on a 2D regular raster. 

5414 

5415 The input may either be actual RGB(A) data, or 2D scalar data, which 

5416 will be rendered as a pseudocolor image. For displaying a grayscale 

5417 image set up the colormapping using the parameters 

5418 ``cmap='gray', vmin=0, vmax=255``. 

5419 

5420 The number of pixels used to render an image is set by the Axes size 

5421 and the *dpi* of the figure. This can lead to aliasing artifacts when 

5422 the image is resampled because the displayed image size will usually 

5423 not match the size of *X* (see 

5424 :doc:`/gallery/images_contours_and_fields/image_antialiasing`). 

5425 The resampling can be controlled via the *interpolation* parameter 

5426 and/or :rc:`image.interpolation`. 

5427 

5428 Parameters 

5429 ---------- 

5430 X : array-like or PIL image 

5431 The image data. Supported array shapes are: 

5432 

5433 - (M, N): an image with scalar data. The values are mapped to 

5434 colors using normalization and a colormap. See parameters *norm*, 

5435 *cmap*, *vmin*, *vmax*. 

5436 - (M, N, 3): an image with RGB values (0-1 float or 0-255 int). 

5437 - (M, N, 4): an image with RGBA values (0-1 float or 0-255 int), 

5438 i.e. including transparency. 

5439 

5440 The first two dimensions (M, N) define the rows and columns of 

5441 the image. 

5442 

5443 Out-of-range RGB(A) values are clipped. 

5444 

5445 %(cmap_doc)s 

5446 

5447 This parameter is ignored if *X* is RGB(A). 

5448 

5449 %(norm_doc)s 

5450 

5451 This parameter is ignored if *X* is RGB(A). 

5452 

5453 %(vmin_vmax_doc)s 

5454 

5455 This parameter is ignored if *X* is RGB(A). 

5456 

5457 aspect : {'equal', 'auto'} or float, default: :rc:`image.aspect` 

5458 The aspect ratio of the Axes. This parameter is particularly 

5459 relevant for images since it determines whether data pixels are 

5460 square. 

5461 

5462 This parameter is a shortcut for explicitly calling 

5463 `.Axes.set_aspect`. See there for further details. 

5464 

5465 - 'equal': Ensures an aspect ratio of 1. Pixels will be square 

5466 (unless pixel sizes are explicitly made non-square in data 

5467 coordinates using *extent*). 

5468 - 'auto': The Axes is kept fixed and the aspect is adjusted so 

5469 that the data fit in the Axes. In general, this will result in 

5470 non-square pixels. 

5471 

5472 interpolation : str, default: :rc:`image.interpolation` 

5473 The interpolation method used. 

5474 

5475 Supported values are 'none', 'antialiased', 'nearest', 'bilinear', 

5476 'bicubic', 'spline16', 'spline36', 'hanning', 'hamming', 'hermite', 

5477 'kaiser', 'quadric', 'catrom', 'gaussian', 'bessel', 'mitchell', 

5478 'sinc', 'lanczos', 'blackman'. 

5479 

5480 If *interpolation* is 'none', then no interpolation is performed 

5481 on the Agg, ps, pdf and svg backends. Other backends will fall back 

5482 to 'nearest'. Note that most SVG renderers perform interpolation at 

5483 rendering and that the default interpolation method they implement 

5484 may differ. 

5485 

5486 If *interpolation* is the default 'antialiased', then 'nearest' 

5487 interpolation is used if the image is upsampled by more than a 

5488 factor of three (i.e. the number of display pixels is at least 

5489 three times the size of the data array). If the upsampling rate is 

5490 smaller than 3, or the image is downsampled, then 'hanning' 

5491 interpolation is used to act as an anti-aliasing filter, unless the 

5492 image happens to be upsampled by exactly a factor of two or one. 

5493 

5494 See 

5495 :doc:`/gallery/images_contours_and_fields/interpolation_methods` 

5496 for an overview of the supported interpolation methods, and 

5497 :doc:`/gallery/images_contours_and_fields/image_antialiasing` for 

5498 a discussion of image antialiasing. 

5499 

5500 Some interpolation methods require an additional radius parameter, 

5501 which can be set by *filterrad*. Additionally, the antigrain image 

5502 resize filter is controlled by the parameter *filternorm*. 

5503 

5504 interpolation_stage : {'data', 'rgba'}, default: 'data' 

5505 If 'data', interpolation 

5506 is carried out on the data provided by the user. If 'rgba', the 

5507 interpolation is carried out after the colormapping has been 

5508 applied (visual interpolation). 

5509 

5510 alpha : float or array-like, optional 

5511 The alpha blending value, between 0 (transparent) and 1 (opaque). 

5512 If *alpha* is an array, the alpha blending values are applied pixel 

5513 by pixel, and *alpha* must have the same shape as *X*. 

5514 

5515 origin : {'upper', 'lower'}, default: :rc:`image.origin` 

5516 Place the [0, 0] index of the array in the upper left or lower 

5517 left corner of the Axes. The convention (the default) 'upper' is 

5518 typically used for matrices and images. 

5519 

5520 Note that the vertical axis points upward for 'lower' 

5521 but downward for 'upper'. 

5522 

5523 See the :doc:`/tutorials/intermediate/imshow_extent` tutorial for 

5524 examples and a more detailed description. 

5525 

5526 extent : floats (left, right, bottom, top), optional 

5527 The bounding box in data coordinates that the image will fill. 

5528 The image is stretched individually along x and y to fill the box. 

5529 

5530 The default extent is determined by the following conditions. 

5531 Pixels have unit size in data coordinates. Their centers are on 

5532 integer coordinates, and their center coordinates range from 0 to 

5533 columns-1 horizontally and from 0 to rows-1 vertically. 

5534 

5535 Note that the direction of the vertical axis and thus the default 

5536 values for top and bottom depend on *origin*: 

5537 

5538 - For ``origin == 'upper'`` the default is 

5539 ``(-0.5, numcols-0.5, numrows-0.5, -0.5)``. 

5540 - For ``origin == 'lower'`` the default is 

5541 ``(-0.5, numcols-0.5, -0.5, numrows-0.5)``. 

5542 

5543 See the :doc:`/tutorials/intermediate/imshow_extent` tutorial for 

5544 examples and a more detailed description. 

5545 

5546 filternorm : bool, default: True 

5547 A parameter for the antigrain image resize filter (see the 

5548 antigrain documentation). If *filternorm* is set, the filter 

5549 normalizes integer values and corrects the rounding errors. It 

5550 doesn't do anything with the source floating point values, it 

5551 corrects only integers according to the rule of 1.0 which means 

5552 that any sum of pixel weights must be equal to 1.0. So, the 

5553 filter function must produce a graph of the proper shape. 

5554 

5555 filterrad : float > 0, default: 4.0 

5556 The filter radius for filters that have a radius parameter, i.e. 

5557 when interpolation is one of: 'sinc', 'lanczos' or 'blackman'. 

5558 

5559 resample : bool, default: :rc:`image.resample` 

5560 When *True*, use a full resampling method. When *False*, only 

5561 resample when the output image is larger than the input image. 

5562 

5563 url : str, optional 

5564 Set the url of the created `.AxesImage`. See `.Artist.set_url`. 

5565 

5566 Returns 

5567 ------- 

5568 `~matplotlib.image.AxesImage` 

5569 

5570 Other Parameters 

5571 ---------------- 

5572 data : indexable object, optional 

5573 DATA_PARAMETER_PLACEHOLDER 

5574 

5575 **kwargs : `~matplotlib.artist.Artist` properties 

5576 These parameters are passed on to the constructor of the 

5577 `.AxesImage` artist. 

5578 

5579 See Also 

5580 -------- 

5581 matshow : Plot a matrix or an array as an image. 

5582 

5583 Notes 

5584 ----- 

5585 Unless *extent* is used, pixel centers will be located at integer 

5586 coordinates. In other words: the origin will coincide with the center 

5587 of pixel (0, 0). 

5588 

5589 There are two common representations for RGB images with an alpha 

5590 channel: 

5591 

5592 - Straight (unassociated) alpha: R, G, and B channels represent the 

5593 color of the pixel, disregarding its opacity. 

5594 - Premultiplied (associated) alpha: R, G, and B channels represent 

5595 the color of the pixel, adjusted for its opacity by multiplication. 

5596 

5597 `~matplotlib.pyplot.imshow` expects RGB images adopting the straight 

5598 (unassociated) alpha representation. 

5599 """ 

5600 if aspect is None: 

5601 aspect = mpl.rcParams['image.aspect'] 

5602 self.set_aspect(aspect) 

5603 im = mimage.AxesImage(self, cmap=cmap, norm=norm, 

5604 interpolation=interpolation, origin=origin, 

5605 extent=extent, filternorm=filternorm, 

5606 filterrad=filterrad, resample=resample, 

5607 interpolation_stage=interpolation_stage, 

5608 **kwargs) 

5609 

5610 im.set_data(X) 

5611 im.set_alpha(alpha) 

5612 if im.get_clip_path() is None: 

5613 # image does not already have clipping set, clip to axes patch 

5614 im.set_clip_path(self.patch) 

5615 im._scale_norm(norm, vmin, vmax) 

5616 im.set_url(url) 

5617 

5618 # update ax.dataLim, and, if autoscaling, set viewLim 

5619 # to tightly fit the image, regardless of dataLim. 

5620 im.set_extent(im.get_extent()) 

5621 

5622 self.add_image(im) 

5623 return im 

5624 

5625 def _pcolorargs(self, funcname, *args, shading='auto', **kwargs): 

5626 # - create X and Y if not present; 

5627 # - reshape X and Y as needed if they are 1-D; 

5628 # - check for proper sizes based on `shading` kwarg; 

5629 # - reset shading if shading='auto' to flat or nearest 

5630 # depending on size; 

5631 

5632 _valid_shading = ['gouraud', 'nearest', 'flat', 'auto'] 

5633 try: 

5634 _api.check_in_list(_valid_shading, shading=shading) 

5635 except ValueError: 

5636 _api.warn_external(f"shading value '{shading}' not in list of " 

5637 f"valid values {_valid_shading}. Setting " 

5638 "shading='auto'.") 

5639 shading = 'auto' 

5640 

5641 if len(args) == 1: 

5642 C = np.asanyarray(args[0]) 

5643 nrows, ncols = C.shape 

5644 if shading in ['gouraud', 'nearest']: 

5645 X, Y = np.meshgrid(np.arange(ncols), np.arange(nrows)) 

5646 else: 

5647 X, Y = np.meshgrid(np.arange(ncols + 1), np.arange(nrows + 1)) 

5648 shading = 'flat' 

5649 C = cbook.safe_masked_invalid(C) 

5650 return X, Y, C, shading 

5651 

5652 if len(args) == 3: 

5653 # Check x and y for bad data... 

5654 C = np.asanyarray(args[2]) 

5655 # unit conversion allows e.g. datetime objects as axis values 

5656 X, Y = args[:2] 

5657 X, Y = self._process_unit_info([("x", X), ("y", Y)], kwargs) 

5658 X, Y = [cbook.safe_masked_invalid(a) for a in [X, Y]] 

5659 

5660 if funcname == 'pcolormesh': 

5661 if np.ma.is_masked(X) or np.ma.is_masked(Y): 

5662 raise ValueError( 

5663 'x and y arguments to pcolormesh cannot have ' 

5664 'non-finite values or be of type ' 

5665 'numpy.ma.core.MaskedArray with masked values') 

5666 # safe_masked_invalid() returns an ndarray for dtypes other 

5667 # than floating point. 

5668 if isinstance(X, np.ma.core.MaskedArray): 

5669 X = X.data # strip mask as downstream doesn't like it... 

5670 if isinstance(Y, np.ma.core.MaskedArray): 

5671 Y = Y.data 

5672 nrows, ncols = C.shape 

5673 else: 

5674 raise TypeError(f'{funcname}() takes 1 or 3 positional arguments ' 

5675 f'but {len(args)} were given') 

5676 

5677 Nx = X.shape[-1] 

5678 Ny = Y.shape[0] 

5679 if X.ndim != 2 or X.shape[0] == 1: 

5680 x = X.reshape(1, Nx) 

5681 X = x.repeat(Ny, axis=0) 

5682 if Y.ndim != 2 or Y.shape[1] == 1: 

5683 y = Y.reshape(Ny, 1) 

5684 Y = y.repeat(Nx, axis=1) 

5685 if X.shape != Y.shape: 

5686 raise TypeError(f'Incompatible X, Y inputs to {funcname}; ' 

5687 f'see help({funcname})') 

5688 

5689 if shading == 'auto': 

5690 if ncols == Nx and nrows == Ny: 

5691 shading = 'nearest' 

5692 else: 

5693 shading = 'flat' 

5694 

5695 if shading == 'flat': 

5696 if (Nx, Ny) != (ncols + 1, nrows + 1): 

5697 raise TypeError('Dimensions of C %s are incompatible with' 

5698 ' X (%d) and/or Y (%d); see help(%s)' % ( 

5699 C.shape, Nx, Ny, funcname)) 

5700 else: # ['nearest', 'gouraud']: 

5701 if (Nx, Ny) != (ncols, nrows): 

5702 raise TypeError('Dimensions of C %s are incompatible with' 

5703 ' X (%d) and/or Y (%d); see help(%s)' % ( 

5704 C.shape, Nx, Ny, funcname)) 

5705 if shading == 'nearest': 

5706 # grid is specified at the center, so define corners 

5707 # at the midpoints between the grid centers and then use the 

5708 # flat algorithm. 

5709 def _interp_grid(X): 

5710 # helper for below 

5711 if np.shape(X)[1] > 1: 

5712 dX = np.diff(X, axis=1)/2. 

5713 if not (np.all(dX >= 0) or np.all(dX <= 0)): 

5714 _api.warn_external( 

5715 f"The input coordinates to {funcname} are " 

5716 "interpreted as cell centers, but are not " 

5717 "monotonically increasing or decreasing. " 

5718 "This may lead to incorrectly calculated cell " 

5719 "edges, in which case, please supply " 

5720 f"explicit cell edges to {funcname}.") 

5721 X = np.hstack((X[:, [0]] - dX[:, [0]], 

5722 X[:, :-1] + dX, 

5723 X[:, [-1]] + dX[:, [-1]])) 

5724 else: 

5725 # This is just degenerate, but we can't reliably guess 

5726 # a dX if there is just one value. 

5727 X = np.hstack((X, X)) 

5728 return X 

5729 

5730 if ncols == Nx: 

5731 X = _interp_grid(X) 

5732 Y = _interp_grid(Y) 

5733 if nrows == Ny: 

5734 X = _interp_grid(X.T).T 

5735 Y = _interp_grid(Y.T).T 

5736 shading = 'flat' 

5737 

5738 C = cbook.safe_masked_invalid(C) 

5739 return X, Y, C, shading 

5740 

5741 def _pcolor_grid_deprecation_helper(self): 

5742 grid_active = any(axis._major_tick_kw["gridOn"] 

5743 for axis in self._axis_map.values()) 

5744 # explicit is-True check because get_axisbelow() can also be 'line' 

5745 grid_hidden_by_pcolor = self.get_axisbelow() is True 

5746 if grid_active and not grid_hidden_by_pcolor: 

5747 _api.warn_deprecated( 

5748 "3.5", message="Auto-removal of grids by pcolor() and " 

5749 "pcolormesh() is deprecated since %(since)s and will be " 

5750 "removed %(removal)s; please call grid(False) first.") 

5751 self.grid(False) 

5752 

5753 @_preprocess_data() 

5754 @_docstring.dedent_interpd 

5755 def pcolor(self, *args, shading=None, alpha=None, norm=None, cmap=None, 

5756 vmin=None, vmax=None, **kwargs): 

5757 r""" 

5758 Create a pseudocolor plot with a non-regular rectangular grid. 

5759 

5760 Call signature:: 

5761 

5762 pcolor([X, Y,] C, **kwargs) 

5763 

5764 *X* and *Y* can be used to specify the corners of the quadrilaterals. 

5765 

5766 .. hint:: 

5767 

5768 ``pcolor()`` can be very slow for large arrays. In most 

5769 cases you should use the similar but much faster 

5770 `~.Axes.pcolormesh` instead. See 

5771 :ref:`Differences between pcolor() and pcolormesh() 

5772 <differences-pcolor-pcolormesh>` for a discussion of the 

5773 differences. 

5774 

5775 Parameters 

5776 ---------- 

5777 C : 2D array-like 

5778 The color-mapped values. Color-mapping is controlled by *cmap*, 

5779 *norm*, *vmin*, and *vmax*. 

5780 

5781 X, Y : array-like, optional 

5782 The coordinates of the corners of quadrilaterals of a pcolormesh:: 

5783 

5784 (X[i+1, j], Y[i+1, j]) (X[i+1, j+1], Y[i+1, j+1]) 

5785 +-----+ 

5786 | | 

5787 +-----+ 

5788 (X[i, j], Y[i, j]) (X[i, j+1], Y[i, j+1]) 

5789 

5790 Note that the column index corresponds to the x-coordinate, and 

5791 the row index corresponds to y. For details, see the 

5792 :ref:`Notes <axes-pcolormesh-grid-orientation>` section below. 

5793 

5794 If ``shading='flat'`` the dimensions of *X* and *Y* should be one 

5795 greater than those of *C*, and the quadrilateral is colored due 

5796 to the value at ``C[i, j]``. If *X*, *Y* and *C* have equal 

5797 dimensions, a warning will be raised and the last row and column 

5798 of *C* will be ignored. 

5799 

5800 If ``shading='nearest'``, the dimensions of *X* and *Y* should be 

5801 the same as those of *C* (if not, a ValueError will be raised). The 

5802 color ``C[i, j]`` will be centered on ``(X[i, j], Y[i, j])``. 

5803 

5804 If *X* and/or *Y* are 1-D arrays or column vectors they will be 

5805 expanded as needed into the appropriate 2D arrays, making a 

5806 rectangular grid. 

5807 

5808 shading : {'flat', 'nearest', 'auto'}, default: :rc:`pcolor.shading` 

5809 The fill style for the quadrilateral. Possible values: 

5810 

5811 - 'flat': A solid color is used for each quad. The color of the 

5812 quad (i, j), (i+1, j), (i, j+1), (i+1, j+1) is given by 

5813 ``C[i, j]``. The dimensions of *X* and *Y* should be 

5814 one greater than those of *C*; if they are the same as *C*, 

5815 then a deprecation warning is raised, and the last row 

5816 and column of *C* are dropped. 

5817 - 'nearest': Each grid point will have a color centered on it, 

5818 extending halfway between the adjacent grid centers. The 

5819 dimensions of *X* and *Y* must be the same as *C*. 

5820 - 'auto': Choose 'flat' if dimensions of *X* and *Y* are one 

5821 larger than *C*. Choose 'nearest' if dimensions are the same. 

5822 

5823 See :doc:`/gallery/images_contours_and_fields/pcolormesh_grids` 

5824 for more description. 

5825 

5826 %(cmap_doc)s 

5827 

5828 %(norm_doc)s 

5829 

5830 %(vmin_vmax_doc)s 

5831 

5832 edgecolors : {'none', None, 'face', color, color sequence}, optional 

5833 The color of the edges. Defaults to 'none'. Possible values: 

5834 

5835 - 'none' or '': No edge. 

5836 - *None*: :rc:`patch.edgecolor` will be used. Note that currently 

5837 :rc:`patch.force_edgecolor` has to be True for this to work. 

5838 - 'face': Use the adjacent face color. 

5839 - A color or sequence of colors will set the edge color. 

5840 

5841 The singular form *edgecolor* works as an alias. 

5842 

5843 alpha : float, default: None 

5844 The alpha blending value of the face color, between 0 (transparent) 

5845 and 1 (opaque). Note: The edgecolor is currently not affected by 

5846 this. 

5847 

5848 snap : bool, default: False 

5849 Whether to snap the mesh to pixel boundaries. 

5850 

5851 Returns 

5852 ------- 

5853 `matplotlib.collections.Collection` 

5854 

5855 Other Parameters 

5856 ---------------- 

5857 antialiaseds : bool, default: False 

5858 The default *antialiaseds* is False if the default 

5859 *edgecolors*\ ="none" is used. This eliminates artificial lines 

5860 at patch boundaries, and works regardless of the value of alpha. 

5861 If *edgecolors* is not "none", then the default *antialiaseds* 

5862 is taken from :rc:`patch.antialiased`. 

5863 Stroking the edges may be preferred if *alpha* is 1, but will 

5864 cause artifacts otherwise. 

5865 

5866 data : indexable object, optional 

5867 DATA_PARAMETER_PLACEHOLDER 

5868 

5869 **kwargs 

5870 Additionally, the following arguments are allowed. They are passed 

5871 along to the `~matplotlib.collections.PolyCollection` constructor: 

5872 

5873 %(PolyCollection:kwdoc)s 

5874 

5875 See Also 

5876 -------- 

5877 pcolormesh : for an explanation of the differences between 

5878 pcolor and pcolormesh. 

5879 imshow : If *X* and *Y* are each equidistant, `~.Axes.imshow` can be a 

5880 faster alternative. 

5881 

5882 Notes 

5883 ----- 

5884 **Masked arrays** 

5885 

5886 *X*, *Y* and *C* may be masked arrays. If either ``C[i, j]``, or one 

5887 of the vertices surrounding ``C[i, j]`` (*X* or *Y* at 

5888 ``[i, j], [i+1, j], [i, j+1], [i+1, j+1]``) is masked, nothing is 

5889 plotted. 

5890 

5891 .. _axes-pcolor-grid-orientation: 

5892 

5893 **Grid orientation** 

5894 

5895 The grid orientation follows the standard matrix convention: An array 

5896 *C* with shape (nrows, ncolumns) is plotted with the column number as 

5897 *X* and the row number as *Y*. 

5898 """ 

5899 

5900 if shading is None: 

5901 shading = mpl.rcParams['pcolor.shading'] 

5902 shading = shading.lower() 

5903 X, Y, C, shading = self._pcolorargs('pcolor', *args, shading=shading, 

5904 kwargs=kwargs) 

5905 Ny, Nx = X.shape 

5906 

5907 # convert to MA, if necessary. 

5908 C = ma.asarray(C) 

5909 X = ma.asarray(X) 

5910 Y = ma.asarray(Y) 

5911 

5912 mask = ma.getmaskarray(X) + ma.getmaskarray(Y) 

5913 xymask = (mask[0:-1, 0:-1] + mask[1:, 1:] + 

5914 mask[0:-1, 1:] + mask[1:, 0:-1]) 

5915 # don't plot if C or any of the surrounding vertices are masked. 

5916 mask = ma.getmaskarray(C) + xymask 

5917 

5918 unmask = ~mask 

5919 X1 = ma.filled(X[:-1, :-1])[unmask] 

5920 Y1 = ma.filled(Y[:-1, :-1])[unmask] 

5921 X2 = ma.filled(X[1:, :-1])[unmask] 

5922 Y2 = ma.filled(Y[1:, :-1])[unmask] 

5923 X3 = ma.filled(X[1:, 1:])[unmask] 

5924 Y3 = ma.filled(Y[1:, 1:])[unmask] 

5925 X4 = ma.filled(X[:-1, 1:])[unmask] 

5926 Y4 = ma.filled(Y[:-1, 1:])[unmask] 

5927 npoly = len(X1) 

5928 

5929 xy = np.stack([X1, Y1, X2, Y2, X3, Y3, X4, Y4, X1, Y1], axis=-1) 

5930 verts = xy.reshape((npoly, 5, 2)) 

5931 

5932 C = ma.filled(C[:Ny - 1, :Nx - 1])[unmask] 

5933 

5934 linewidths = (0.25,) 

5935 if 'linewidth' in kwargs: 

5936 kwargs['linewidths'] = kwargs.pop('linewidth') 

5937 kwargs.setdefault('linewidths', linewidths) 

5938 

5939 if 'edgecolor' in kwargs: 

5940 kwargs['edgecolors'] = kwargs.pop('edgecolor') 

5941 ec = kwargs.setdefault('edgecolors', 'none') 

5942 

5943 # aa setting will default via collections to patch.antialiased 

5944 # unless the boundary is not stroked, in which case the 

5945 # default will be False; with unstroked boundaries, aa 

5946 # makes artifacts that are often disturbing. 

5947 if 'antialiased' in kwargs: 

5948 kwargs['antialiaseds'] = kwargs.pop('antialiased') 

5949 if 'antialiaseds' not in kwargs and cbook._str_lower_equal(ec, "none"): 

5950 kwargs['antialiaseds'] = False 

5951 

5952 kwargs.setdefault('snap', False) 

5953 

5954 collection = mcoll.PolyCollection( 

5955 verts, array=C, cmap=cmap, norm=norm, alpha=alpha, **kwargs) 

5956 collection._scale_norm(norm, vmin, vmax) 

5957 self._pcolor_grid_deprecation_helper() 

5958 

5959 x = X.compressed() 

5960 y = Y.compressed() 

5961 

5962 # Transform from native to data coordinates? 

5963 t = collection._transform 

5964 if (not isinstance(t, mtransforms.Transform) and 

5965 hasattr(t, '_as_mpl_transform')): 

5966 t = t._as_mpl_transform(self.axes) 

5967 

5968 if t and any(t.contains_branch_seperately(self.transData)): 

5969 trans_to_data = t - self.transData 

5970 pts = np.vstack([x, y]).T.astype(float) 

5971 transformed_pts = trans_to_data.transform(pts) 

5972 x = transformed_pts[..., 0] 

5973 y = transformed_pts[..., 1] 

5974 

5975 self.add_collection(collection, autolim=False) 

5976 

5977 minx = np.min(x) 

5978 maxx = np.max(x) 

5979 miny = np.min(y) 

5980 maxy = np.max(y) 

5981 collection.sticky_edges.x[:] = [minx, maxx] 

5982 collection.sticky_edges.y[:] = [miny, maxy] 

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

5984 self.update_datalim(corners) 

5985 self._request_autoscale_view() 

5986 return collection 

5987 

5988 @_preprocess_data() 

5989 @_docstring.dedent_interpd 

5990 def pcolormesh(self, *args, alpha=None, norm=None, cmap=None, vmin=None, 

5991 vmax=None, shading=None, antialiased=False, **kwargs): 

5992 """ 

5993 Create a pseudocolor plot with a non-regular rectangular grid. 

5994 

5995 Call signature:: 

5996 

5997 pcolormesh([X, Y,] C, **kwargs) 

5998 

5999 *X* and *Y* can be used to specify the corners of the quadrilaterals. 

6000 

6001 .. hint:: 

6002 

6003 `~.Axes.pcolormesh` is similar to `~.Axes.pcolor`. It is much faster 

6004 and preferred in most cases. For a detailed discussion on the 

6005 differences see :ref:`Differences between pcolor() and pcolormesh() 

6006 <differences-pcolor-pcolormesh>`. 

6007 

6008 Parameters 

6009 ---------- 

6010 C : 2D array-like 

6011 The color-mapped values. Color-mapping is controlled by *cmap*, 

6012 *norm*, *vmin*, and *vmax*. 

6013 

6014 X, Y : array-like, optional 

6015 The coordinates of the corners of quadrilaterals of a pcolormesh:: 

6016 

6017 (X[i+1, j], Y[i+1, j]) (X[i+1, j+1], Y[i+1, j+1]) 

6018 +-----+ 

6019 | | 

6020 +-----+ 

6021 (X[i, j], Y[i, j]) (X[i, j+1], Y[i, j+1]) 

6022 

6023 Note that the column index corresponds to the x-coordinate, and 

6024 the row index corresponds to y. For details, see the 

6025 :ref:`Notes <axes-pcolormesh-grid-orientation>` section below. 

6026 

6027 If ``shading='flat'`` the dimensions of *X* and *Y* should be one 

6028 greater than those of *C*, and the quadrilateral is colored due 

6029 to the value at ``C[i, j]``. If *X*, *Y* and *C* have equal 

6030 dimensions, a warning will be raised and the last row and column 

6031 of *C* will be ignored. 

6032 

6033 If ``shading='nearest'`` or ``'gouraud'``, the dimensions of *X* 

6034 and *Y* should be the same as those of *C* (if not, a ValueError 

6035 will be raised). For ``'nearest'`` the color ``C[i, j]`` is 

6036 centered on ``(X[i, j], Y[i, j])``. For ``'gouraud'``, a smooth 

6037 interpolation is caried out between the quadrilateral corners. 

6038 

6039 If *X* and/or *Y* are 1-D arrays or column vectors they will be 

6040 expanded as needed into the appropriate 2D arrays, making a 

6041 rectangular grid. 

6042 

6043 %(cmap_doc)s 

6044 

6045 %(norm_doc)s 

6046 

6047 %(vmin_vmax_doc)s 

6048 

6049 edgecolors : {'none', None, 'face', color, color sequence}, optional 

6050 The color of the edges. Defaults to 'none'. Possible values: 

6051 

6052 - 'none' or '': No edge. 

6053 - *None*: :rc:`patch.edgecolor` will be used. Note that currently 

6054 :rc:`patch.force_edgecolor` has to be True for this to work. 

6055 - 'face': Use the adjacent face color. 

6056 - A color or sequence of colors will set the edge color. 

6057 

6058 The singular form *edgecolor* works as an alias. 

6059 

6060 alpha : float, default: None 

6061 The alpha blending value, between 0 (transparent) and 1 (opaque). 

6062 

6063 shading : {'flat', 'nearest', 'gouraud', 'auto'}, optional 

6064 The fill style for the quadrilateral; defaults to 

6065 'flat' or :rc:`pcolor.shading`. Possible values: 

6066 

6067 - 'flat': A solid color is used for each quad. The color of the 

6068 quad (i, j), (i+1, j), (i, j+1), (i+1, j+1) is given by 

6069 ``C[i, j]``. The dimensions of *X* and *Y* should be 

6070 one greater than those of *C*; if they are the same as *C*, 

6071 then a deprecation warning is raised, and the last row 

6072 and column of *C* are dropped. 

6073 - 'nearest': Each grid point will have a color centered on it, 

6074 extending halfway between the adjacent grid centers. The 

6075 dimensions of *X* and *Y* must be the same as *C*. 

6076 - 'gouraud': Each quad will be Gouraud shaded: The color of the 

6077 corners (i', j') are given by ``C[i', j']``. The color values of 

6078 the area in between is interpolated from the corner values. 

6079 The dimensions of *X* and *Y* must be the same as *C*. When 

6080 Gouraud shading is used, *edgecolors* is ignored. 

6081 - 'auto': Choose 'flat' if dimensions of *X* and *Y* are one 

6082 larger than *C*. Choose 'nearest' if dimensions are the same. 

6083 

6084 See :doc:`/gallery/images_contours_and_fields/pcolormesh_grids` 

6085 for more description. 

6086 

6087 snap : bool, default: False 

6088 Whether to snap the mesh to pixel boundaries. 

6089 

6090 rasterized : bool, optional 

6091 Rasterize the pcolormesh when drawing vector graphics. This can 

6092 speed up rendering and produce smaller files for large data sets. 

6093 See also :doc:`/gallery/misc/rasterization_demo`. 

6094 

6095 Returns 

6096 ------- 

6097 `matplotlib.collections.QuadMesh` 

6098 

6099 Other Parameters 

6100 ---------------- 

6101 data : indexable object, optional 

6102 DATA_PARAMETER_PLACEHOLDER 

6103 

6104 **kwargs 

6105 Additionally, the following arguments are allowed. They are passed 

6106 along to the `~matplotlib.collections.QuadMesh` constructor: 

6107 

6108 %(QuadMesh:kwdoc)s 

6109 

6110 See Also 

6111 -------- 

6112 pcolor : An alternative implementation with slightly different 

6113 features. For a detailed discussion on the differences see 

6114 :ref:`Differences between pcolor() and pcolormesh() 

6115 <differences-pcolor-pcolormesh>`. 

6116 imshow : If *X* and *Y* are each equidistant, `~.Axes.imshow` can be a 

6117 faster alternative. 

6118 

6119 Notes 

6120 ----- 

6121 **Masked arrays** 

6122 

6123 *C* may be a masked array. If ``C[i, j]`` is masked, the corresponding 

6124 quadrilateral will be transparent. Masking of *X* and *Y* is not 

6125 supported. Use `~.Axes.pcolor` if you need this functionality. 

6126 

6127 .. _axes-pcolormesh-grid-orientation: 

6128 

6129 **Grid orientation** 

6130 

6131 The grid orientation follows the standard matrix convention: An array 

6132 *C* with shape (nrows, ncolumns) is plotted with the column number as 

6133 *X* and the row number as *Y*. 

6134 

6135 .. _differences-pcolor-pcolormesh: 

6136 

6137 **Differences between pcolor() and pcolormesh()** 

6138 

6139 Both methods are used to create a pseudocolor plot of a 2D array 

6140 using quadrilaterals. 

6141 

6142 The main difference lies in the created object and internal data 

6143 handling: 

6144 While `~.Axes.pcolor` returns a `.PolyCollection`, `~.Axes.pcolormesh` 

6145 returns a `.QuadMesh`. The latter is more specialized for the given 

6146 purpose and thus is faster. It should almost always be preferred. 

6147 

6148 There is also a slight difference in the handling of masked arrays. 

6149 Both `~.Axes.pcolor` and `~.Axes.pcolormesh` support masked arrays 

6150 for *C*. However, only `~.Axes.pcolor` supports masked arrays for *X* 

6151 and *Y*. The reason lies in the internal handling of the masked values. 

6152 `~.Axes.pcolor` leaves out the respective polygons from the 

6153 PolyCollection. `~.Axes.pcolormesh` sets the facecolor of the masked 

6154 elements to transparent. You can see the difference when using 

6155 edgecolors. While all edges are drawn irrespective of masking in a 

6156 QuadMesh, the edge between two adjacent masked quadrilaterals in 

6157 `~.Axes.pcolor` is not drawn as the corresponding polygons do not 

6158 exist in the PolyCollection. 

6159 

6160 Another difference is the support of Gouraud shading in 

6161 `~.Axes.pcolormesh`, which is not available with `~.Axes.pcolor`. 

6162 

6163 """ 

6164 if shading is None: 

6165 shading = mpl.rcParams['pcolor.shading'] 

6166 shading = shading.lower() 

6167 kwargs.setdefault('edgecolors', 'none') 

6168 

6169 X, Y, C, shading = self._pcolorargs('pcolormesh', *args, 

6170 shading=shading, kwargs=kwargs) 

6171 coords = np.stack([X, Y], axis=-1) 

6172 # convert to one dimensional array 

6173 C = C.ravel() 

6174 

6175 kwargs.setdefault('snap', mpl.rcParams['pcolormesh.snap']) 

6176 

6177 collection = mcoll.QuadMesh( 

6178 coords, antialiased=antialiased, shading=shading, 

6179 array=C, cmap=cmap, norm=norm, alpha=alpha, **kwargs) 

6180 collection._scale_norm(norm, vmin, vmax) 

6181 self._pcolor_grid_deprecation_helper() 

6182 

6183 coords = coords.reshape(-1, 2) # flatten the grid structure; keep x, y 

6184 

6185 # Transform from native to data coordinates? 

6186 t = collection._transform 

6187 if (not isinstance(t, mtransforms.Transform) and 

6188 hasattr(t, '_as_mpl_transform')): 

6189 t = t._as_mpl_transform(self.axes) 

6190 

6191 if t and any(t.contains_branch_seperately(self.transData)): 

6192 trans_to_data = t - self.transData 

6193 coords = trans_to_data.transform(coords) 

6194 

6195 self.add_collection(collection, autolim=False) 

6196 

6197 minx, miny = np.min(coords, axis=0) 

6198 maxx, maxy = np.max(coords, axis=0) 

6199 collection.sticky_edges.x[:] = [minx, maxx] 

6200 collection.sticky_edges.y[:] = [miny, maxy] 

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

6202 self.update_datalim(corners) 

6203 self._request_autoscale_view() 

6204 return collection 

6205 

6206 @_preprocess_data() 

6207 @_docstring.dedent_interpd 

6208 def pcolorfast(self, *args, alpha=None, norm=None, cmap=None, vmin=None, 

6209 vmax=None, **kwargs): 

6210 """ 

6211 Create a pseudocolor plot with a non-regular rectangular grid. 

6212 

6213 Call signature:: 

6214 

6215 ax.pcolorfast([X, Y], C, /, **kwargs) 

6216 

6217 This method is similar to `~.Axes.pcolor` and `~.Axes.pcolormesh`. 

6218 It's designed to provide the fastest pcolor-type plotting with the 

6219 Agg backend. To achieve this, it uses different algorithms internally 

6220 depending on the complexity of the input grid (regular rectangular, 

6221 non-regular rectangular or arbitrary quadrilateral). 

6222 

6223 .. warning:: 

6224 

6225 This method is experimental. Compared to `~.Axes.pcolor` or 

6226 `~.Axes.pcolormesh` it has some limitations: 

6227 

6228 - It supports only flat shading (no outlines) 

6229 - It lacks support for log scaling of the axes. 

6230 - It does not have a pyplot wrapper. 

6231 

6232 Parameters 

6233 ---------- 

6234 C : array-like 

6235 The image data. Supported array shapes are: 

6236 

6237 - (M, N): an image with scalar data. Color-mapping is controlled 

6238 by *cmap*, *norm*, *vmin*, and *vmax*. 

6239 - (M, N, 3): an image with RGB values (0-1 float or 0-255 int). 

6240 - (M, N, 4): an image with RGBA values (0-1 float or 0-255 int), 

6241 i.e. including transparency. 

6242 

6243 The first two dimensions (M, N) define the rows and columns of 

6244 the image. 

6245 

6246 This parameter can only be passed positionally. 

6247 

6248 X, Y : tuple or array-like, default: ``(0, N)``, ``(0, M)`` 

6249 *X* and *Y* are used to specify the coordinates of the 

6250 quadrilaterals. There are different ways to do this: 

6251 

6252 - Use tuples ``X=(xmin, xmax)`` and ``Y=(ymin, ymax)`` to define 

6253 a *uniform rectangular grid*. 

6254 

6255 The tuples define the outer edges of the grid. All individual 

6256 quadrilaterals will be of the same size. This is the fastest 

6257 version. 

6258 

6259 - Use 1D arrays *X*, *Y* to specify a *non-uniform rectangular 

6260 grid*. 

6261 

6262 In this case *X* and *Y* have to be monotonic 1D arrays of length 

6263 *N+1* and *M+1*, specifying the x and y boundaries of the cells. 

6264 

6265 The speed is intermediate. Note: The grid is checked, and if 

6266 found to be uniform the fast version is used. 

6267 

6268 - Use 2D arrays *X*, *Y* if you need an *arbitrary quadrilateral 

6269 grid* (i.e. if the quadrilaterals are not rectangular). 

6270 

6271 In this case *X* and *Y* are 2D arrays with shape (M + 1, N + 1), 

6272 specifying the x and y coordinates of the corners of the colored 

6273 quadrilaterals. 

6274 

6275 This is the most general, but the slowest to render. It may 

6276 produce faster and more compact output using ps, pdf, and 

6277 svg backends, however. 

6278 

6279 These arguments can only be passed positionally. 

6280 

6281 %(cmap_doc)s 

6282 

6283 This parameter is ignored if *C* is RGB(A). 

6284 

6285 %(norm_doc)s 

6286 

6287 This parameter is ignored if *C* is RGB(A). 

6288 

6289 %(vmin_vmax_doc)s 

6290 

6291 This parameter is ignored if *C* is RGB(A). 

6292 

6293 alpha : float, default: None 

6294 The alpha blending value, between 0 (transparent) and 1 (opaque). 

6295 

6296 snap : bool, default: False 

6297 Whether to snap the mesh to pixel boundaries. 

6298 

6299 Returns 

6300 ------- 

6301 `.AxesImage` or `.PcolorImage` or `.QuadMesh` 

6302 The return type depends on the type of grid: 

6303 

6304 - `.AxesImage` for a regular rectangular grid. 

6305 - `.PcolorImage` for a non-regular rectangular grid. 

6306 - `.QuadMesh` for a non-rectangular grid. 

6307 

6308 Other Parameters 

6309 ---------------- 

6310 data : indexable object, optional 

6311 DATA_PARAMETER_PLACEHOLDER 

6312 

6313 **kwargs 

6314 Supported additional parameters depend on the type of grid. 

6315 See return types of *image* for further description. 

6316 """ 

6317 

6318 C = args[-1] 

6319 nr, nc = np.shape(C)[:2] 

6320 if len(args) == 1: 

6321 style = "image" 

6322 x = [0, nc] 

6323 y = [0, nr] 

6324 elif len(args) == 3: 

6325 x, y = args[:2] 

6326 x = np.asarray(x) 

6327 y = np.asarray(y) 

6328 if x.ndim == 1 and y.ndim == 1: 

6329 if x.size == 2 and y.size == 2: 

6330 style = "image" 

6331 else: 

6332 dx = np.diff(x) 

6333 dy = np.diff(y) 

6334 if (np.ptp(dx) < 0.01 * abs(dx.mean()) and 

6335 np.ptp(dy) < 0.01 * abs(dy.mean())): 

6336 style = "image" 

6337 else: 

6338 style = "pcolorimage" 

6339 elif x.ndim == 2 and y.ndim == 2: 

6340 style = "quadmesh" 

6341 else: 

6342 raise TypeError("arguments do not match valid signatures") 

6343 else: 

6344 raise TypeError("need 1 argument or 3 arguments") 

6345 

6346 if style == "quadmesh": 

6347 # data point in each cell is value at lower left corner 

6348 coords = np.stack([x, y], axis=-1) 

6349 if np.ndim(C) == 2: 

6350 qm_kwargs = {"array": np.ma.ravel(C)} 

6351 elif np.ndim(C) == 3: 

6352 qm_kwargs = {"color": np.ma.reshape(C, (-1, C.shape[-1]))} 

6353 else: 

6354 raise ValueError("C must be 2D or 3D") 

6355 collection = mcoll.QuadMesh( 

6356 coords, **qm_kwargs, 

6357 alpha=alpha, cmap=cmap, norm=norm, 

6358 antialiased=False, edgecolors="none") 

6359 self.add_collection(collection, autolim=False) 

6360 xl, xr, yb, yt = x.min(), x.max(), y.min(), y.max() 

6361 ret = collection 

6362 

6363 else: # It's one of the two image styles. 

6364 extent = xl, xr, yb, yt = x[0], x[-1], y[0], y[-1] 

6365 if style == "image": 

6366 im = mimage.AxesImage( 

6367 self, cmap=cmap, norm=norm, 

6368 data=C, alpha=alpha, extent=extent, 

6369 interpolation='nearest', origin='lower', 

6370 **kwargs) 

6371 elif style == "pcolorimage": 

6372 im = mimage.PcolorImage( 

6373 self, x, y, C, 

6374 cmap=cmap, norm=norm, alpha=alpha, extent=extent, 

6375 **kwargs) 

6376 self.add_image(im) 

6377 ret = im 

6378 

6379 if np.ndim(C) == 2: # C.ndim == 3 is RGB(A) so doesn't need scaling. 

6380 ret._scale_norm(norm, vmin, vmax) 

6381 

6382 if ret.get_clip_path() is None: 

6383 # image does not already have clipping set, clip to axes patch 

6384 ret.set_clip_path(self.patch) 

6385 

6386 ret.sticky_edges.x[:] = [xl, xr] 

6387 ret.sticky_edges.y[:] = [yb, yt] 

6388 self.update_datalim(np.array([[xl, yb], [xr, yt]])) 

6389 self._request_autoscale_view(tight=True) 

6390 return ret 

6391 

6392 @_preprocess_data() 

6393 @_docstring.dedent_interpd 

6394 def contour(self, *args, **kwargs): 

6395 """ 

6396 Plot contour lines. 

6397 

6398 Call signature:: 

6399 

6400 contour([X, Y,] Z, [levels], **kwargs) 

6401 %(contour_doc)s 

6402 """ 

6403 kwargs['filled'] = False 

6404 contours = mcontour.QuadContourSet(self, *args, **kwargs) 

6405 self._request_autoscale_view() 

6406 return contours 

6407 

6408 @_preprocess_data() 

6409 @_docstring.dedent_interpd 

6410 def contourf(self, *args, **kwargs): 

6411 """ 

6412 Plot filled contours. 

6413 

6414 Call signature:: 

6415 

6416 contourf([X, Y,] Z, [levels], **kwargs) 

6417 %(contour_doc)s 

6418 """ 

6419 kwargs['filled'] = True 

6420 contours = mcontour.QuadContourSet(self, *args, **kwargs) 

6421 self._request_autoscale_view() 

6422 return contours 

6423 

6424 def clabel(self, CS, levels=None, **kwargs): 

6425 """ 

6426 Label a contour plot. 

6427 

6428 Adds labels to line contours in given `.ContourSet`. 

6429 

6430 Parameters 

6431 ---------- 

6432 CS : `.ContourSet` instance 

6433 Line contours to label. 

6434 

6435 levels : array-like, optional 

6436 A list of level values, that should be labeled. The list must be 

6437 a subset of ``CS.levels``. If not given, all levels are labeled. 

6438 

6439 **kwargs 

6440 All other parameters are documented in `~.ContourLabeler.clabel`. 

6441 """ 

6442 return CS.clabel(levels, **kwargs) 

6443 

6444 #### Data analysis 

6445 

6446 @_preprocess_data(replace_names=["x", 'weights'], label_namer="x") 

6447 def hist(self, x, bins=None, range=None, density=False, weights=None, 

6448 cumulative=False, bottom=None, histtype='bar', align='mid', 

6449 orientation='vertical', rwidth=None, log=False, 

6450 color=None, label=None, stacked=False, **kwargs): 

6451 """ 

6452 Compute and plot a histogram. 

6453 

6454 This method uses `numpy.histogram` to bin the data in *x* and count the 

6455 number of values in each bin, then draws the distribution either as a 

6456 `.BarContainer` or `.Polygon`. The *bins*, *range*, *density*, and 

6457 *weights* parameters are forwarded to `numpy.histogram`. 

6458 

6459 If the data has already been binned and counted, use `~.bar` or 

6460 `~.stairs` to plot the distribution:: 

6461 

6462 counts, bins = np.histogram(x) 

6463 plt.stairs(counts, bins) 

6464 

6465 Alternatively, plot pre-computed bins and counts using ``hist()`` by 

6466 treating each bin as a single point with a weight equal to its count:: 

6467 

6468 plt.hist(bins[:-1], bins, weights=counts) 

6469 

6470 The data input *x* can be a singular array, a list of datasets of 

6471 potentially different lengths ([*x0*, *x1*, ...]), or a 2D ndarray in 

6472 which each column is a dataset. Note that the ndarray form is 

6473 transposed relative to the list form. If the input is an array, then 

6474 the return value is a tuple (*n*, *bins*, *patches*); if the input is a 

6475 sequence of arrays, then the return value is a tuple 

6476 ([*n0*, *n1*, ...], *bins*, [*patches0*, *patches1*, ...]). 

6477 

6478 Masked arrays are not supported. 

6479 

6480 Parameters 

6481 ---------- 

6482 x : (n,) array or sequence of (n,) arrays 

6483 Input values, this takes either a single array or a sequence of 

6484 arrays which are not required to be of the same length. 

6485 

6486 bins : int or sequence or str, default: :rc:`hist.bins` 

6487 If *bins* is an integer, it defines the number of equal-width bins 

6488 in the range. 

6489 

6490 If *bins* is a sequence, it defines the bin edges, including the 

6491 left edge of the first bin and the right edge of the last bin; 

6492 in this case, bins may be unequally spaced. All but the last 

6493 (righthand-most) bin is half-open. In other words, if *bins* is:: 

6494 

6495 [1, 2, 3, 4] 

6496 

6497 then the first bin is ``[1, 2)`` (including 1, but excluding 2) and 

6498 the second ``[2, 3)``. The last bin, however, is ``[3, 4]``, which 

6499 *includes* 4. 

6500 

6501 If *bins* is a string, it is one of the binning strategies 

6502 supported by `numpy.histogram_bin_edges`: 'auto', 'fd', 'doane', 

6503 'scott', 'stone', 'rice', 'sturges', or 'sqrt'. 

6504 

6505 range : tuple or None, default: None 

6506 The lower and upper range of the bins. Lower and upper outliers 

6507 are ignored. If not provided, *range* is ``(x.min(), x.max())``. 

6508 Range has no effect if *bins* is a sequence. 

6509 

6510 If *bins* is a sequence or *range* is specified, autoscaling 

6511 is based on the specified bin range instead of the 

6512 range of x. 

6513 

6514 density : bool, default: False 

6515 If ``True``, draw and return a probability density: each bin 

6516 will display the bin's raw count divided by the total number of 

6517 counts *and the bin width* 

6518 (``density = counts / (sum(counts) * np.diff(bins))``), 

6519 so that the area under the histogram integrates to 1 

6520 (``np.sum(density * np.diff(bins)) == 1``). 

6521 

6522 If *stacked* is also ``True``, the sum of the histograms is 

6523 normalized to 1. 

6524 

6525 weights : (n,) array-like or None, default: None 

6526 An array of weights, of the same shape as *x*. Each value in 

6527 *x* only contributes its associated weight towards the bin count 

6528 (instead of 1). If *density* is ``True``, the weights are 

6529 normalized, so that the integral of the density over the range 

6530 remains 1. 

6531 

6532 cumulative : bool or -1, default: False 

6533 If ``True``, then a histogram is computed where each bin gives the 

6534 counts in that bin plus all bins for smaller values. The last bin 

6535 gives the total number of datapoints. 

6536 

6537 If *density* is also ``True`` then the histogram is normalized such 

6538 that the last bin equals 1. 

6539 

6540 If *cumulative* is a number less than 0 (e.g., -1), the direction 

6541 of accumulation is reversed. In this case, if *density* is also 

6542 ``True``, then the histogram is normalized such that the first bin 

6543 equals 1. 

6544 

6545 bottom : array-like, scalar, or None, default: None 

6546 Location of the bottom of each bin, ie. bins are drawn from 

6547 ``bottom`` to ``bottom + hist(x, bins)`` If a scalar, the bottom 

6548 of each bin is shifted by the same amount. If an array, each bin 

6549 is shifted independently and the length of bottom must match the 

6550 number of bins. If None, defaults to 0. 

6551 

6552 histtype : {'bar', 'barstacked', 'step', 'stepfilled'}, default: 'bar' 

6553 The type of histogram to draw. 

6554 

6555 - 'bar' is a traditional bar-type histogram. If multiple data 

6556 are given the bars are arranged side by side. 

6557 - 'barstacked' is a bar-type histogram where multiple 

6558 data are stacked on top of each other. 

6559 - 'step' generates a lineplot that is by default unfilled. 

6560 - 'stepfilled' generates a lineplot that is by default filled. 

6561 

6562 align : {'left', 'mid', 'right'}, default: 'mid' 

6563 The horizontal alignment of the histogram bars. 

6564 

6565 - 'left': bars are centered on the left bin edges. 

6566 - 'mid': bars are centered between the bin edges. 

6567 - 'right': bars are centered on the right bin edges. 

6568 

6569 orientation : {'vertical', 'horizontal'}, default: 'vertical' 

6570 If 'horizontal', `~.Axes.barh` will be used for bar-type histograms 

6571 and the *bottom* kwarg will be the left edges. 

6572 

6573 rwidth : float or None, default: None 

6574 The relative width of the bars as a fraction of the bin width. If 

6575 ``None``, automatically compute the width. 

6576 

6577 Ignored if *histtype* is 'step' or 'stepfilled'. 

6578 

6579 log : bool, default: False 

6580 If ``True``, the histogram axis will be set to a log scale. 

6581 

6582 color : color or array-like of colors or None, default: None 

6583 Color or sequence of colors, one per dataset. Default (``None``) 

6584 uses the standard line color sequence. 

6585 

6586 label : str or None, default: None 

6587 String, or sequence of strings to match multiple datasets. Bar 

6588 charts yield multiple patches per dataset, but only the first gets 

6589 the label, so that `~.Axes.legend` will work as expected. 

6590 

6591 stacked : bool, default: False 

6592 If ``True``, multiple data are stacked on top of each other If 

6593 ``False`` multiple data are arranged side by side if histtype is 

6594 'bar' or on top of each other if histtype is 'step' 

6595 

6596 Returns 

6597 ------- 

6598 n : array or list of arrays 

6599 The values of the histogram bins. See *density* and *weights* for a 

6600 description of the possible semantics. If input *x* is an array, 

6601 then this is an array of length *nbins*. If input is a sequence of 

6602 arrays ``[data1, data2, ...]``, then this is a list of arrays with 

6603 the values of the histograms for each of the arrays in the same 

6604 order. The dtype of the array *n* (or of its element arrays) will 

6605 always be float even if no weighting or normalization is used. 

6606 

6607 bins : array 

6608 The edges of the bins. Length nbins + 1 (nbins left edges and right 

6609 edge of last bin). Always a single array even when multiple data 

6610 sets are passed in. 

6611 

6612 patches : `.BarContainer` or list of a single `.Polygon` or list of \ 

6613such objects 

6614 Container of individual artists used to create the histogram 

6615 or list of such containers if there are multiple input datasets. 

6616 

6617 Other Parameters 

6618 ---------------- 

6619 data : indexable object, optional 

6620 DATA_PARAMETER_PLACEHOLDER 

6621 

6622 **kwargs 

6623 `~matplotlib.patches.Patch` properties 

6624 

6625 See Also 

6626 -------- 

6627 hist2d : 2D histogram with rectangular bins 

6628 hexbin : 2D histogram with hexagonal bins 

6629 

6630 Notes 

6631 ----- 

6632 For large numbers of bins (>1000), plotting can be significantly faster 

6633 if *histtype* is set to 'step' or 'stepfilled' rather than 'bar' or 

6634 'barstacked'. 

6635 """ 

6636 # Avoid shadowing the builtin. 

6637 bin_range = range 

6638 from builtins import range 

6639 

6640 if np.isscalar(x): 

6641 x = [x] 

6642 

6643 if bins is None: 

6644 bins = mpl.rcParams['hist.bins'] 

6645 

6646 # Validate string inputs here to avoid cluttering subsequent code. 

6647 _api.check_in_list(['bar', 'barstacked', 'step', 'stepfilled'], 

6648 histtype=histtype) 

6649 _api.check_in_list(['left', 'mid', 'right'], align=align) 

6650 _api.check_in_list(['horizontal', 'vertical'], orientation=orientation) 

6651 

6652 if histtype == 'barstacked' and not stacked: 

6653 stacked = True 

6654 

6655 # Massage 'x' for processing. 

6656 x = cbook._reshape_2D(x, 'x') 

6657 nx = len(x) # number of datasets 

6658 

6659 # Process unit information. _process_unit_info sets the unit and 

6660 # converts the first dataset; then we convert each following dataset 

6661 # one at a time. 

6662 if orientation == "vertical": 

6663 convert_units = self.convert_xunits 

6664 x = [*self._process_unit_info([("x", x[0])], kwargs), 

6665 *map(convert_units, x[1:])] 

6666 else: # horizontal 

6667 convert_units = self.convert_yunits 

6668 x = [*self._process_unit_info([("y", x[0])], kwargs), 

6669 *map(convert_units, x[1:])] 

6670 

6671 if bin_range is not None: 

6672 bin_range = convert_units(bin_range) 

6673 

6674 if not cbook.is_scalar_or_string(bins): 

6675 bins = convert_units(bins) 

6676 

6677 # We need to do to 'weights' what was done to 'x' 

6678 if weights is not None: 

6679 w = cbook._reshape_2D(weights, 'weights') 

6680 else: 

6681 w = [None] * nx 

6682 

6683 if len(w) != nx: 

6684 raise ValueError('weights should have the same shape as x') 

6685 

6686 input_empty = True 

6687 for xi, wi in zip(x, w): 

6688 len_xi = len(xi) 

6689 if wi is not None and len(wi) != len_xi: 

6690 raise ValueError('weights should have the same shape as x') 

6691 if len_xi: 

6692 input_empty = False 

6693 

6694 if color is None: 

6695 color = [self._get_lines.get_next_color() for i in range(nx)] 

6696 else: 

6697 color = mcolors.to_rgba_array(color) 

6698 if len(color) != nx: 

6699 raise ValueError(f"The 'color' keyword argument must have one " 

6700 f"color per dataset, but {nx} datasets and " 

6701 f"{len(color)} colors were provided") 

6702 

6703 hist_kwargs = dict() 

6704 

6705 # if the bin_range is not given, compute without nan numpy 

6706 # does not do this for us when guessing the range (but will 

6707 # happily ignore nans when computing the histogram). 

6708 if bin_range is None: 

6709 xmin = np.inf 

6710 xmax = -np.inf 

6711 for xi in x: 

6712 if len(xi): 

6713 # python's min/max ignore nan, 

6714 # np.minnan returns nan for all nan input 

6715 xmin = min(xmin, np.nanmin(xi)) 

6716 xmax = max(xmax, np.nanmax(xi)) 

6717 if xmin <= xmax: # Only happens if we have seen a finite value. 

6718 bin_range = (xmin, xmax) 

6719 

6720 # If bins are not specified either explicitly or via range, 

6721 # we need to figure out the range required for all datasets, 

6722 # and supply that to np.histogram. 

6723 if not input_empty and len(x) > 1: 

6724 if weights is not None: 

6725 _w = np.concatenate(w) 

6726 else: 

6727 _w = None 

6728 bins = np.histogram_bin_edges( 

6729 np.concatenate(x), bins, bin_range, _w) 

6730 else: 

6731 hist_kwargs['range'] = bin_range 

6732 

6733 density = bool(density) 

6734 if density and not stacked: 

6735 hist_kwargs['density'] = density 

6736 

6737 # List to store all the top coordinates of the histograms 

6738 tops = [] # Will have shape (n_datasets, n_bins). 

6739 # Loop through datasets 

6740 for i in range(nx): 

6741 # this will automatically overwrite bins, 

6742 # so that each histogram uses the same bins 

6743 m, bins = np.histogram(x[i], bins, weights=w[i], **hist_kwargs) 

6744 tops.append(m) 

6745 tops = np.array(tops, float) # causes problems later if it's an int 

6746 bins = np.array(bins, float) # causes problems if float16 

6747 if stacked: 

6748 tops = tops.cumsum(axis=0) 

6749 # If a stacked density plot, normalize so the area of all the 

6750 # stacked histograms together is 1 

6751 if density: 

6752 tops = (tops / np.diff(bins)) / tops[-1].sum() 

6753 if cumulative: 

6754 slc = slice(None) 

6755 if isinstance(cumulative, Number) and cumulative < 0: 

6756 slc = slice(None, None, -1) 

6757 if density: 

6758 tops = (tops * np.diff(bins))[:, slc].cumsum(axis=1)[:, slc] 

6759 else: 

6760 tops = tops[:, slc].cumsum(axis=1)[:, slc] 

6761 

6762 patches = [] 

6763 

6764 if histtype.startswith('bar'): 

6765 

6766 totwidth = np.diff(bins) 

6767 

6768 if rwidth is not None: 

6769 dr = np.clip(rwidth, 0, 1) 

6770 elif (len(tops) > 1 and 

6771 ((not stacked) or mpl.rcParams['_internal.classic_mode'])): 

6772 dr = 0.8 

6773 else: 

6774 dr = 1.0 

6775 

6776 if histtype == 'bar' and not stacked: 

6777 width = dr * totwidth / nx 

6778 dw = width 

6779 boffset = -0.5 * dr * totwidth * (1 - 1 / nx) 

6780 elif histtype == 'barstacked' or stacked: 

6781 width = dr * totwidth 

6782 boffset, dw = 0.0, 0.0 

6783 

6784 if align == 'mid': 

6785 boffset += 0.5 * totwidth 

6786 elif align == 'right': 

6787 boffset += totwidth 

6788 

6789 if orientation == 'horizontal': 

6790 _barfunc = self.barh 

6791 bottom_kwarg = 'left' 

6792 else: # orientation == 'vertical' 

6793 _barfunc = self.bar 

6794 bottom_kwarg = 'bottom' 

6795 

6796 for m, c in zip(tops, color): 

6797 if bottom is None: 

6798 bottom = np.zeros(len(m)) 

6799 if stacked: 

6800 height = m - bottom 

6801 else: 

6802 height = m 

6803 bars = _barfunc(bins[:-1]+boffset, height, width, 

6804 align='center', log=log, 

6805 color=c, **{bottom_kwarg: bottom}) 

6806 patches.append(bars) 

6807 if stacked: 

6808 bottom = m 

6809 boffset += dw 

6810 # Remove stickies from all bars but the lowest ones, as otherwise 

6811 # margin expansion would be unable to cross the stickies in the 

6812 # middle of the bars. 

6813 for bars in patches[1:]: 

6814 for patch in bars: 

6815 patch.sticky_edges.x[:] = patch.sticky_edges.y[:] = [] 

6816 

6817 elif histtype.startswith('step'): 

6818 # these define the perimeter of the polygon 

6819 x = np.zeros(4 * len(bins) - 3) 

6820 y = np.zeros(4 * len(bins) - 3) 

6821 

6822 x[0:2*len(bins)-1:2], x[1:2*len(bins)-1:2] = bins, bins[:-1] 

6823 x[2*len(bins)-1:] = x[1:2*len(bins)-1][::-1] 

6824 

6825 if bottom is None: 

6826 bottom = 0 

6827 

6828 y[1:2*len(bins)-1:2] = y[2:2*len(bins):2] = bottom 

6829 y[2*len(bins)-1:] = y[1:2*len(bins)-1][::-1] 

6830 

6831 if log: 

6832 if orientation == 'horizontal': 

6833 self.set_xscale('log', nonpositive='clip') 

6834 else: # orientation == 'vertical' 

6835 self.set_yscale('log', nonpositive='clip') 

6836 

6837 if align == 'left': 

6838 x -= 0.5*(bins[1]-bins[0]) 

6839 elif align == 'right': 

6840 x += 0.5*(bins[1]-bins[0]) 

6841 

6842 # If fill kwarg is set, it will be passed to the patch collection, 

6843 # overriding this 

6844 fill = (histtype == 'stepfilled') 

6845 

6846 xvals, yvals = [], [] 

6847 for m in tops: 

6848 if stacked: 

6849 # top of the previous polygon becomes the bottom 

6850 y[2*len(bins)-1:] = y[1:2*len(bins)-1][::-1] 

6851 # set the top of this polygon 

6852 y[1:2*len(bins)-1:2] = y[2:2*len(bins):2] = m + bottom 

6853 

6854 # The starting point of the polygon has not yet been 

6855 # updated. So far only the endpoint was adjusted. This 

6856 # assignment closes the polygon. The redundant endpoint is 

6857 # later discarded (for step and stepfilled). 

6858 y[0] = y[-1] 

6859 

6860 if orientation == 'horizontal': 

6861 xvals.append(y.copy()) 

6862 yvals.append(x.copy()) 

6863 else: 

6864 xvals.append(x.copy()) 

6865 yvals.append(y.copy()) 

6866 

6867 # stepfill is closed, step is not 

6868 split = -1 if fill else 2 * len(bins) 

6869 # add patches in reverse order so that when stacking, 

6870 # items lower in the stack are plotted on top of 

6871 # items higher in the stack 

6872 for x, y, c in reversed(list(zip(xvals, yvals, color))): 

6873 patches.append(self.fill( 

6874 x[:split], y[:split], 

6875 closed=True if fill else None, 

6876 facecolor=c, 

6877 edgecolor=None if fill else c, 

6878 fill=fill if fill else None, 

6879 zorder=None if fill else mlines.Line2D.zorder)) 

6880 for patch_list in patches: 

6881 for patch in patch_list: 

6882 if orientation == 'vertical': 

6883 patch.sticky_edges.y.append(0) 

6884 elif orientation == 'horizontal': 

6885 patch.sticky_edges.x.append(0) 

6886 

6887 # we return patches, so put it back in the expected order 

6888 patches.reverse() 

6889 

6890 # If None, make all labels None (via zip_longest below); otherwise, 

6891 # cast each element to str, but keep a single str as it. 

6892 labels = [] if label is None else np.atleast_1d(np.asarray(label, str)) 

6893 for patch, lbl in itertools.zip_longest(patches, labels): 

6894 if patch: 

6895 p = patch[0] 

6896 p._internal_update(kwargs) 

6897 if lbl is not None: 

6898 p.set_label(lbl) 

6899 for p in patch[1:]: 

6900 p._internal_update(kwargs) 

6901 p.set_label('_nolegend_') 

6902 

6903 if nx == 1: 

6904 return tops[0], bins, patches[0] 

6905 else: 

6906 patch_type = ("BarContainer" if histtype.startswith("bar") 

6907 else "list[Polygon]") 

6908 return tops, bins, cbook.silent_list(patch_type, patches) 

6909 

6910 @_preprocess_data() 

6911 def stairs(self, values, edges=None, *, 

6912 orientation='vertical', baseline=0, fill=False, **kwargs): 

6913 """ 

6914 A stepwise constant function as a line with bounding edges 

6915 or a filled plot. 

6916 

6917 Parameters 

6918 ---------- 

6919 values : array-like 

6920 The step heights. 

6921 

6922 edges : array-like 

6923 The edge positions, with ``len(edges) == len(vals) + 1``, 

6924 between which the curve takes on vals values. 

6925 

6926 orientation : {'vertical', 'horizontal'}, default: 'vertical' 

6927 The direction of the steps. Vertical means that *values* are along 

6928 the y-axis, and edges are along the x-axis. 

6929 

6930 baseline : float, array-like or None, default: 0 

6931 The bottom value of the bounding edges or when 

6932 ``fill=True``, position of lower edge. If *fill* is 

6933 True or an array is passed to *baseline*, a closed 

6934 path is drawn. 

6935 

6936 fill : bool, default: False 

6937 Whether the area under the step curve should be filled. 

6938 

6939 Returns 

6940 ------- 

6941 StepPatch : `matplotlib.patches.StepPatch` 

6942 

6943 Other Parameters 

6944 ---------------- 

6945 data : indexable object, optional 

6946 DATA_PARAMETER_PLACEHOLDER 

6947 

6948 **kwargs 

6949 `~matplotlib.patches.StepPatch` properties 

6950 

6951 """ 

6952 

6953 if 'color' in kwargs: 

6954 _color = kwargs.pop('color') 

6955 else: 

6956 _color = self._get_lines.get_next_color() 

6957 if fill: 

6958 kwargs.setdefault('linewidth', 0) 

6959 kwargs.setdefault('facecolor', _color) 

6960 else: 

6961 kwargs.setdefault('edgecolor', _color) 

6962 

6963 if edges is None: 

6964 edges = np.arange(len(values) + 1) 

6965 

6966 edges, values, baseline = self._process_unit_info( 

6967 [("x", edges), ("y", values), ("y", baseline)], kwargs) 

6968 

6969 patch = mpatches.StepPatch(values, 

6970 edges, 

6971 baseline=baseline, 

6972 orientation=orientation, 

6973 fill=fill, 

6974 **kwargs) 

6975 self.add_patch(patch) 

6976 if baseline is None: 

6977 baseline = 0 

6978 if orientation == 'vertical': 

6979 patch.sticky_edges.y.append(np.min(baseline)) 

6980 self.update_datalim([(edges[0], np.min(baseline))]) 

6981 else: 

6982 patch.sticky_edges.x.append(np.min(baseline)) 

6983 self.update_datalim([(np.min(baseline), edges[0])]) 

6984 self._request_autoscale_view() 

6985 return patch 

6986 

6987 @_preprocess_data(replace_names=["x", "y", "weights"]) 

6988 @_docstring.dedent_interpd 

6989 def hist2d(self, x, y, bins=10, range=None, density=False, weights=None, 

6990 cmin=None, cmax=None, **kwargs): 

6991 """ 

6992 Make a 2D histogram plot. 

6993 

6994 Parameters 

6995 ---------- 

6996 x, y : array-like, shape (n, ) 

6997 Input values 

6998 

6999 bins : None or int or [int, int] or array-like or [array, array] 

7000 

7001 The bin specification: 

7002 

7003 - If int, the number of bins for the two dimensions 

7004 (nx=ny=bins). 

7005 - If ``[int, int]``, the number of bins in each dimension 

7006 (nx, ny = bins). 

7007 - If array-like, the bin edges for the two dimensions 

7008 (x_edges=y_edges=bins). 

7009 - If ``[array, array]``, the bin edges in each dimension 

7010 (x_edges, y_edges = bins). 

7011 

7012 The default value is 10. 

7013 

7014 range : array-like shape(2, 2), optional 

7015 The leftmost and rightmost edges of the bins along each dimension 

7016 (if not specified explicitly in the bins parameters): ``[[xmin, 

7017 xmax], [ymin, ymax]]``. All values outside of this range will be 

7018 considered outliers and not tallied in the histogram. 

7019 

7020 density : bool, default: False 

7021 Normalize histogram. See the documentation for the *density* 

7022 parameter of `~.Axes.hist` for more details. 

7023 

7024 weights : array-like, shape (n, ), optional 

7025 An array of values w_i weighing each sample (x_i, y_i). 

7026 

7027 cmin, cmax : float, default: None 

7028 All bins that has count less than *cmin* or more than *cmax* will 

7029 not be displayed (set to NaN before passing to imshow) and these 

7030 count values in the return value count histogram will also be set 

7031 to nan upon return. 

7032 

7033 Returns 

7034 ------- 

7035 h : 2D array 

7036 The bi-dimensional histogram of samples x and y. Values in x are 

7037 histogrammed along the first dimension and values in y are 

7038 histogrammed along the second dimension. 

7039 xedges : 1D array 

7040 The bin edges along the x axis. 

7041 yedges : 1D array 

7042 The bin edges along the y axis. 

7043 image : `~.matplotlib.collections.QuadMesh` 

7044 

7045 Other Parameters 

7046 ---------------- 

7047 %(cmap_doc)s 

7048 

7049 %(norm_doc)s 

7050 

7051 %(vmin_vmax_doc)s 

7052 

7053 alpha : ``0 <= scalar <= 1`` or ``None``, optional 

7054 The alpha blending value. 

7055 

7056 data : indexable object, optional 

7057 DATA_PARAMETER_PLACEHOLDER 

7058 

7059 **kwargs 

7060 Additional parameters are passed along to the 

7061 `~.Axes.pcolormesh` method and `~matplotlib.collections.QuadMesh` 

7062 constructor. 

7063 

7064 See Also 

7065 -------- 

7066 hist : 1D histogram plotting 

7067 hexbin : 2D histogram with hexagonal bins 

7068 

7069 Notes 

7070 ----- 

7071 - Currently ``hist2d`` calculates its own axis limits, and any limits 

7072 previously set are ignored. 

7073 - Rendering the histogram with a logarithmic color scale is 

7074 accomplished by passing a `.colors.LogNorm` instance to the *norm* 

7075 keyword argument. Likewise, power-law normalization (similar 

7076 in effect to gamma correction) can be accomplished with 

7077 `.colors.PowerNorm`. 

7078 """ 

7079 

7080 h, xedges, yedges = np.histogram2d(x, y, bins=bins, range=range, 

7081 density=density, weights=weights) 

7082 

7083 if cmin is not None: 

7084 h[h < cmin] = None 

7085 if cmax is not None: 

7086 h[h > cmax] = None 

7087 

7088 pc = self.pcolormesh(xedges, yedges, h.T, **kwargs) 

7089 self.set_xlim(xedges[0], xedges[-1]) 

7090 self.set_ylim(yedges[0], yedges[-1]) 

7091 

7092 return h, xedges, yedges, pc 

7093 

7094 @_preprocess_data(replace_names=["x"]) 

7095 @_docstring.dedent_interpd 

7096 def psd(self, x, NFFT=None, Fs=None, Fc=None, detrend=None, 

7097 window=None, noverlap=None, pad_to=None, 

7098 sides=None, scale_by_freq=None, return_line=None, **kwargs): 

7099 r""" 

7100 Plot the power spectral density. 

7101 

7102 The power spectral density :math:`P_{xx}` by Welch's average 

7103 periodogram method. The vector *x* is divided into *NFFT* length 

7104 segments. Each segment is detrended by function *detrend* and 

7105 windowed by function *window*. *noverlap* gives the length of 

7106 the overlap between segments. The :math:`|\mathrm{fft}(i)|^2` 

7107 of each segment :math:`i` are averaged to compute :math:`P_{xx}`, 

7108 with a scaling to correct for power loss due to windowing. 

7109 

7110 If len(*x*) < *NFFT*, it will be zero padded to *NFFT*. 

7111 

7112 Parameters 

7113 ---------- 

7114 x : 1-D array or sequence 

7115 Array or sequence containing the data 

7116 

7117 %(Spectral)s 

7118 

7119 %(PSD)s 

7120 

7121 noverlap : int, default: 0 (no overlap) 

7122 The number of points of overlap between segments. 

7123 

7124 Fc : int, default: 0 

7125 The center frequency of *x*, which offsets the x extents of the 

7126 plot to reflect the frequency range used when a signal is acquired 

7127 and then filtered and downsampled to baseband. 

7128 

7129 return_line : bool, default: False 

7130 Whether to include the line object plotted in the returned values. 

7131 

7132 Returns 

7133 ------- 

7134 Pxx : 1-D array 

7135 The values for the power spectrum :math:`P_{xx}` before scaling 

7136 (real valued). 

7137 

7138 freqs : 1-D array 

7139 The frequencies corresponding to the elements in *Pxx*. 

7140 

7141 line : `~matplotlib.lines.Line2D` 

7142 The line created by this function. 

7143 Only returned if *return_line* is True. 

7144 

7145 Other Parameters 

7146 ---------------- 

7147 data : indexable object, optional 

7148 DATA_PARAMETER_PLACEHOLDER 

7149 

7150 **kwargs 

7151 Keyword arguments control the `.Line2D` properties: 

7152 

7153 %(Line2D:kwdoc)s 

7154 

7155 See Also 

7156 -------- 

7157 specgram 

7158 Differs in the default overlap; in not returning the mean of the 

7159 segment periodograms; in returning the times of the segments; and 

7160 in plotting a colormap instead of a line. 

7161 magnitude_spectrum 

7162 Plots the magnitude spectrum. 

7163 csd 

7164 Plots the spectral density between two signals. 

7165 

7166 Notes 

7167 ----- 

7168 For plotting, the power is plotted as 

7169 :math:`10\log_{10}(P_{xx})` for decibels, though *Pxx* itself 

7170 is returned. 

7171 

7172 References 

7173 ---------- 

7174 Bendat & Piersol -- Random Data: Analysis and Measurement Procedures, 

7175 John Wiley & Sons (1986) 

7176 """ 

7177 if Fc is None: 

7178 Fc = 0 

7179 

7180 pxx, freqs = mlab.psd(x=x, NFFT=NFFT, Fs=Fs, detrend=detrend, 

7181 window=window, noverlap=noverlap, pad_to=pad_to, 

7182 sides=sides, scale_by_freq=scale_by_freq) 

7183 freqs += Fc 

7184 

7185 if scale_by_freq in (None, True): 

7186 psd_units = 'dB/Hz' 

7187 else: 

7188 psd_units = 'dB' 

7189 

7190 line = self.plot(freqs, 10 * np.log10(pxx), **kwargs) 

7191 self.set_xlabel('Frequency') 

7192 self.set_ylabel('Power Spectral Density (%s)' % psd_units) 

7193 self.grid(True) 

7194 

7195 vmin, vmax = self.get_ybound() 

7196 step = max(10 * int(np.log10(vmax - vmin)), 1) 

7197 ticks = np.arange(math.floor(vmin), math.ceil(vmax) + 1, step) 

7198 self.set_yticks(ticks) 

7199 

7200 if return_line is None or not return_line: 

7201 return pxx, freqs 

7202 else: 

7203 return pxx, freqs, line 

7204 

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

7206 @_docstring.dedent_interpd 

7207 def csd(self, x, y, NFFT=None, Fs=None, Fc=None, detrend=None, 

7208 window=None, noverlap=None, pad_to=None, 

7209 sides=None, scale_by_freq=None, return_line=None, **kwargs): 

7210 r""" 

7211 Plot the cross-spectral density. 

7212 

7213 The cross spectral density :math:`P_{xy}` by Welch's average 

7214 periodogram method. The vectors *x* and *y* are divided into 

7215 *NFFT* length segments. Each segment is detrended by function 

7216 *detrend* and windowed by function *window*. *noverlap* gives 

7217 the length of the overlap between segments. The product of 

7218 the direct FFTs of *x* and *y* are averaged over each segment 

7219 to compute :math:`P_{xy}`, with a scaling to correct for power 

7220 loss due to windowing. 

7221 

7222 If len(*x*) < *NFFT* or len(*y*) < *NFFT*, they will be zero 

7223 padded to *NFFT*. 

7224 

7225 Parameters 

7226 ---------- 

7227 x, y : 1-D arrays or sequences 

7228 Arrays or sequences containing the data. 

7229 

7230 %(Spectral)s 

7231 

7232 %(PSD)s 

7233 

7234 noverlap : int, default: 0 (no overlap) 

7235 The number of points of overlap between segments. 

7236 

7237 Fc : int, default: 0 

7238 The center frequency of *x*, which offsets the x extents of the 

7239 plot to reflect the frequency range used when a signal is acquired 

7240 and then filtered and downsampled to baseband. 

7241 

7242 return_line : bool, default: False 

7243 Whether to include the line object plotted in the returned values. 

7244 

7245 Returns 

7246 ------- 

7247 Pxy : 1-D array 

7248 The values for the cross spectrum :math:`P_{xy}` before scaling 

7249 (complex valued). 

7250 

7251 freqs : 1-D array 

7252 The frequencies corresponding to the elements in *Pxy*. 

7253 

7254 line : `~matplotlib.lines.Line2D` 

7255 The line created by this function. 

7256 Only returned if *return_line* is True. 

7257 

7258 Other Parameters 

7259 ---------------- 

7260 data : indexable object, optional 

7261 DATA_PARAMETER_PLACEHOLDER 

7262 

7263 **kwargs 

7264 Keyword arguments control the `.Line2D` properties: 

7265 

7266 %(Line2D:kwdoc)s 

7267 

7268 See Also 

7269 -------- 

7270 psd : is equivalent to setting ``y = x``. 

7271 

7272 Notes 

7273 ----- 

7274 For plotting, the power is plotted as 

7275 :math:`10 \log_{10}(P_{xy})` for decibels, though :math:`P_{xy}` itself 

7276 is returned. 

7277 

7278 References 

7279 ---------- 

7280 Bendat & Piersol -- Random Data: Analysis and Measurement Procedures, 

7281 John Wiley & Sons (1986) 

7282 """ 

7283 if Fc is None: 

7284 Fc = 0 

7285 

7286 pxy, freqs = mlab.csd(x=x, y=y, NFFT=NFFT, Fs=Fs, detrend=detrend, 

7287 window=window, noverlap=noverlap, pad_to=pad_to, 

7288 sides=sides, scale_by_freq=scale_by_freq) 

7289 # pxy is complex 

7290 freqs += Fc 

7291 

7292 line = self.plot(freqs, 10 * np.log10(np.abs(pxy)), **kwargs) 

7293 self.set_xlabel('Frequency') 

7294 self.set_ylabel('Cross Spectrum Magnitude (dB)') 

7295 self.grid(True) 

7296 

7297 vmin, vmax = self.get_ybound() 

7298 step = max(10 * int(np.log10(vmax - vmin)), 1) 

7299 ticks = np.arange(math.floor(vmin), math.ceil(vmax) + 1, step) 

7300 self.set_yticks(ticks) 

7301 

7302 if return_line is None or not return_line: 

7303 return pxy, freqs 

7304 else: 

7305 return pxy, freqs, line 

7306 

7307 @_preprocess_data(replace_names=["x"]) 

7308 @_docstring.dedent_interpd 

7309 def magnitude_spectrum(self, x, Fs=None, Fc=None, window=None, 

7310 pad_to=None, sides=None, scale=None, 

7311 **kwargs): 

7312 """ 

7313 Plot the magnitude spectrum. 

7314 

7315 Compute the magnitude spectrum of *x*. Data is padded to a 

7316 length of *pad_to* and the windowing function *window* is applied to 

7317 the signal. 

7318 

7319 Parameters 

7320 ---------- 

7321 x : 1-D array or sequence 

7322 Array or sequence containing the data. 

7323 

7324 %(Spectral)s 

7325 

7326 %(Single_Spectrum)s 

7327 

7328 scale : {'default', 'linear', 'dB'} 

7329 The scaling of the values in the *spec*. 'linear' is no scaling. 

7330 'dB' returns the values in dB scale, i.e., the dB amplitude 

7331 (20 * log10). 'default' is 'linear'. 

7332 

7333 Fc : int, default: 0 

7334 The center frequency of *x*, which offsets the x extents of the 

7335 plot to reflect the frequency range used when a signal is acquired 

7336 and then filtered and downsampled to baseband. 

7337 

7338 Returns 

7339 ------- 

7340 spectrum : 1-D array 

7341 The values for the magnitude spectrum before scaling (real valued). 

7342 

7343 freqs : 1-D array 

7344 The frequencies corresponding to the elements in *spectrum*. 

7345 

7346 line : `~matplotlib.lines.Line2D` 

7347 The line created by this function. 

7348 

7349 Other Parameters 

7350 ---------------- 

7351 data : indexable object, optional 

7352 DATA_PARAMETER_PLACEHOLDER 

7353 

7354 **kwargs 

7355 Keyword arguments control the `.Line2D` properties: 

7356 

7357 %(Line2D:kwdoc)s 

7358 

7359 See Also 

7360 -------- 

7361 psd 

7362 Plots the power spectral density. 

7363 angle_spectrum 

7364 Plots the angles of the corresponding frequencies. 

7365 phase_spectrum 

7366 Plots the phase (unwrapped angle) of the corresponding frequencies. 

7367 specgram 

7368 Can plot the magnitude spectrum of segments within the signal in a 

7369 colormap. 

7370 """ 

7371 if Fc is None: 

7372 Fc = 0 

7373 

7374 spec, freqs = mlab.magnitude_spectrum(x=x, Fs=Fs, window=window, 

7375 pad_to=pad_to, sides=sides) 

7376 freqs += Fc 

7377 

7378 yunits = _api.check_getitem( 

7379 {None: 'energy', 'default': 'energy', 'linear': 'energy', 

7380 'dB': 'dB'}, 

7381 scale=scale) 

7382 if yunits == 'energy': 

7383 Z = spec 

7384 else: # yunits == 'dB' 

7385 Z = 20. * np.log10(spec) 

7386 

7387 line, = self.plot(freqs, Z, **kwargs) 

7388 self.set_xlabel('Frequency') 

7389 self.set_ylabel('Magnitude (%s)' % yunits) 

7390 

7391 return spec, freqs, line 

7392 

7393 @_preprocess_data(replace_names=["x"]) 

7394 @_docstring.dedent_interpd 

7395 def angle_spectrum(self, x, Fs=None, Fc=None, window=None, 

7396 pad_to=None, sides=None, **kwargs): 

7397 """ 

7398 Plot the angle spectrum. 

7399 

7400 Compute the angle spectrum (wrapped phase spectrum) of *x*. 

7401 Data is padded to a length of *pad_to* and the windowing function 

7402 *window* is applied to the signal. 

7403 

7404 Parameters 

7405 ---------- 

7406 x : 1-D array or sequence 

7407 Array or sequence containing the data. 

7408 

7409 %(Spectral)s 

7410 

7411 %(Single_Spectrum)s 

7412 

7413 Fc : int, default: 0 

7414 The center frequency of *x*, which offsets the x extents of the 

7415 plot to reflect the frequency range used when a signal is acquired 

7416 and then filtered and downsampled to baseband. 

7417 

7418 Returns 

7419 ------- 

7420 spectrum : 1-D array 

7421 The values for the angle spectrum in radians (real valued). 

7422 

7423 freqs : 1-D array 

7424 The frequencies corresponding to the elements in *spectrum*. 

7425 

7426 line : `~matplotlib.lines.Line2D` 

7427 The line created by this function. 

7428 

7429 Other Parameters 

7430 ---------------- 

7431 data : indexable object, optional 

7432 DATA_PARAMETER_PLACEHOLDER 

7433 

7434 **kwargs 

7435 Keyword arguments control the `.Line2D` properties: 

7436 

7437 %(Line2D:kwdoc)s 

7438 

7439 See Also 

7440 -------- 

7441 magnitude_spectrum 

7442 Plots the magnitudes of the corresponding frequencies. 

7443 phase_spectrum 

7444 Plots the unwrapped version of this function. 

7445 specgram 

7446 Can plot the angle spectrum of segments within the signal in a 

7447 colormap. 

7448 """ 

7449 if Fc is None: 

7450 Fc = 0 

7451 

7452 spec, freqs = mlab.angle_spectrum(x=x, Fs=Fs, window=window, 

7453 pad_to=pad_to, sides=sides) 

7454 freqs += Fc 

7455 

7456 lines = self.plot(freqs, spec, **kwargs) 

7457 self.set_xlabel('Frequency') 

7458 self.set_ylabel('Angle (radians)') 

7459 

7460 return spec, freqs, lines[0] 

7461 

7462 @_preprocess_data(replace_names=["x"]) 

7463 @_docstring.dedent_interpd 

7464 def phase_spectrum(self, x, Fs=None, Fc=None, window=None, 

7465 pad_to=None, sides=None, **kwargs): 

7466 """ 

7467 Plot the phase spectrum. 

7468 

7469 Compute the phase spectrum (unwrapped angle spectrum) of *x*. 

7470 Data is padded to a length of *pad_to* and the windowing function 

7471 *window* is applied to the signal. 

7472 

7473 Parameters 

7474 ---------- 

7475 x : 1-D array or sequence 

7476 Array or sequence containing the data 

7477 

7478 %(Spectral)s 

7479 

7480 %(Single_Spectrum)s 

7481 

7482 Fc : int, default: 0 

7483 The center frequency of *x*, which offsets the x extents of the 

7484 plot to reflect the frequency range used when a signal is acquired 

7485 and then filtered and downsampled to baseband. 

7486 

7487 Returns 

7488 ------- 

7489 spectrum : 1-D array 

7490 The values for the phase spectrum in radians (real valued). 

7491 

7492 freqs : 1-D array 

7493 The frequencies corresponding to the elements in *spectrum*. 

7494 

7495 line : `~matplotlib.lines.Line2D` 

7496 The line created by this function. 

7497 

7498 Other Parameters 

7499 ---------------- 

7500 data : indexable object, optional 

7501 DATA_PARAMETER_PLACEHOLDER 

7502 

7503 **kwargs 

7504 Keyword arguments control the `.Line2D` properties: 

7505 

7506 %(Line2D:kwdoc)s 

7507 

7508 See Also 

7509 -------- 

7510 magnitude_spectrum 

7511 Plots the magnitudes of the corresponding frequencies. 

7512 angle_spectrum 

7513 Plots the wrapped version of this function. 

7514 specgram 

7515 Can plot the phase spectrum of segments within the signal in a 

7516 colormap. 

7517 """ 

7518 if Fc is None: 

7519 Fc = 0 

7520 

7521 spec, freqs = mlab.phase_spectrum(x=x, Fs=Fs, window=window, 

7522 pad_to=pad_to, sides=sides) 

7523 freqs += Fc 

7524 

7525 lines = self.plot(freqs, spec, **kwargs) 

7526 self.set_xlabel('Frequency') 

7527 self.set_ylabel('Phase (radians)') 

7528 

7529 return spec, freqs, lines[0] 

7530 

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

7532 @_docstring.dedent_interpd 

7533 def cohere(self, x, y, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none, 

7534 window=mlab.window_hanning, noverlap=0, pad_to=None, 

7535 sides='default', scale_by_freq=None, **kwargs): 

7536 r""" 

7537 Plot the coherence between *x* and *y*. 

7538 

7539 Coherence is the normalized cross spectral density: 

7540 

7541 .. math:: 

7542 

7543 C_{xy} = \frac{|P_{xy}|^2}{P_{xx}P_{yy}} 

7544 

7545 Parameters 

7546 ---------- 

7547 %(Spectral)s 

7548 

7549 %(PSD)s 

7550 

7551 noverlap : int, default: 0 (no overlap) 

7552 The number of points of overlap between blocks. 

7553 

7554 Fc : int, default: 0 

7555 The center frequency of *x*, which offsets the x extents of the 

7556 plot to reflect the frequency range used when a signal is acquired 

7557 and then filtered and downsampled to baseband. 

7558 

7559 Returns 

7560 ------- 

7561 Cxy : 1-D array 

7562 The coherence vector. 

7563 

7564 freqs : 1-D array 

7565 The frequencies for the elements in *Cxy*. 

7566 

7567 Other Parameters 

7568 ---------------- 

7569 data : indexable object, optional 

7570 DATA_PARAMETER_PLACEHOLDER 

7571 

7572 **kwargs 

7573 Keyword arguments control the `.Line2D` properties: 

7574 

7575 %(Line2D:kwdoc)s 

7576 

7577 References 

7578 ---------- 

7579 Bendat & Piersol -- Random Data: Analysis and Measurement Procedures, 

7580 John Wiley & Sons (1986) 

7581 """ 

7582 cxy, freqs = mlab.cohere(x=x, y=y, NFFT=NFFT, Fs=Fs, detrend=detrend, 

7583 window=window, noverlap=noverlap, 

7584 scale_by_freq=scale_by_freq, sides=sides, 

7585 pad_to=pad_to) 

7586 freqs += Fc 

7587 

7588 self.plot(freqs, cxy, **kwargs) 

7589 self.set_xlabel('Frequency') 

7590 self.set_ylabel('Coherence') 

7591 self.grid(True) 

7592 

7593 return cxy, freqs 

7594 

7595 @_preprocess_data(replace_names=["x"]) 

7596 @_docstring.dedent_interpd 

7597 def specgram(self, x, NFFT=None, Fs=None, Fc=None, detrend=None, 

7598 window=None, noverlap=None, 

7599 cmap=None, xextent=None, pad_to=None, sides=None, 

7600 scale_by_freq=None, mode=None, scale=None, 

7601 vmin=None, vmax=None, **kwargs): 

7602 """ 

7603 Plot a spectrogram. 

7604 

7605 Compute and plot a spectrogram of data in *x*. Data are split into 

7606 *NFFT* length segments and the spectrum of each section is 

7607 computed. The windowing function *window* is applied to each 

7608 segment, and the amount of overlap of each segment is 

7609 specified with *noverlap*. The spectrogram is plotted as a colormap 

7610 (using imshow). 

7611 

7612 Parameters 

7613 ---------- 

7614 x : 1-D array or sequence 

7615 Array or sequence containing the data. 

7616 

7617 %(Spectral)s 

7618 

7619 %(PSD)s 

7620 

7621 mode : {'default', 'psd', 'magnitude', 'angle', 'phase'} 

7622 What sort of spectrum to use. Default is 'psd', which takes the 

7623 power spectral density. 'magnitude' returns the magnitude 

7624 spectrum. 'angle' returns the phase spectrum without unwrapping. 

7625 'phase' returns the phase spectrum with unwrapping. 

7626 

7627 noverlap : int, default: 128 

7628 The number of points of overlap between blocks. 

7629 

7630 scale : {'default', 'linear', 'dB'} 

7631 The scaling of the values in the *spec*. 'linear' is no scaling. 

7632 'dB' returns the values in dB scale. When *mode* is 'psd', 

7633 this is dB power (10 * log10). Otherwise this is dB amplitude 

7634 (20 * log10). 'default' is 'dB' if *mode* is 'psd' or 

7635 'magnitude' and 'linear' otherwise. This must be 'linear' 

7636 if *mode* is 'angle' or 'phase'. 

7637 

7638 Fc : int, default: 0 

7639 The center frequency of *x*, which offsets the x extents of the 

7640 plot to reflect the frequency range used when a signal is acquired 

7641 and then filtered and downsampled to baseband. 

7642 

7643 cmap : `.Colormap`, default: :rc:`image.cmap` 

7644 

7645 xextent : *None* or (xmin, xmax) 

7646 The image extent along the x-axis. The default sets *xmin* to the 

7647 left border of the first bin (*spectrum* column) and *xmax* to the 

7648 right border of the last bin. Note that for *noverlap>0* the width 

7649 of the bins is smaller than those of the segments. 

7650 

7651 data : indexable object, optional 

7652 DATA_PARAMETER_PLACEHOLDER 

7653 

7654 **kwargs 

7655 Additional keyword arguments are passed on to `~.axes.Axes.imshow` 

7656 which makes the specgram image. The origin keyword argument 

7657 is not supported. 

7658 

7659 Returns 

7660 ------- 

7661 spectrum : 2D array 

7662 Columns are the periodograms of successive segments. 

7663 

7664 freqs : 1-D array 

7665 The frequencies corresponding to the rows in *spectrum*. 

7666 

7667 t : 1-D array 

7668 The times corresponding to midpoints of segments (i.e., the columns 

7669 in *spectrum*). 

7670 

7671 im : `.AxesImage` 

7672 The image created by imshow containing the spectrogram. 

7673 

7674 See Also 

7675 -------- 

7676 psd 

7677 Differs in the default overlap; in returning the mean of the 

7678 segment periodograms; in not returning times; and in generating a 

7679 line plot instead of colormap. 

7680 magnitude_spectrum 

7681 A single spectrum, similar to having a single segment when *mode* 

7682 is 'magnitude'. Plots a line instead of a colormap. 

7683 angle_spectrum 

7684 A single spectrum, similar to having a single segment when *mode* 

7685 is 'angle'. Plots a line instead of a colormap. 

7686 phase_spectrum 

7687 A single spectrum, similar to having a single segment when *mode* 

7688 is 'phase'. Plots a line instead of a colormap. 

7689 

7690 Notes 

7691 ----- 

7692 The parameters *detrend* and *scale_by_freq* do only apply when *mode* 

7693 is set to 'psd'. 

7694 """ 

7695 if NFFT is None: 

7696 NFFT = 256 # same default as in mlab.specgram() 

7697 if Fc is None: 

7698 Fc = 0 # same default as in mlab._spectral_helper() 

7699 if noverlap is None: 

7700 noverlap = 128 # same default as in mlab.specgram() 

7701 if Fs is None: 

7702 Fs = 2 # same default as in mlab._spectral_helper() 

7703 

7704 if mode == 'complex': 

7705 raise ValueError('Cannot plot a complex specgram') 

7706 

7707 if scale is None or scale == 'default': 

7708 if mode in ['angle', 'phase']: 

7709 scale = 'linear' 

7710 else: 

7711 scale = 'dB' 

7712 elif mode in ['angle', 'phase'] and scale == 'dB': 

7713 raise ValueError('Cannot use dB scale with angle or phase mode') 

7714 

7715 spec, freqs, t = mlab.specgram(x=x, NFFT=NFFT, Fs=Fs, 

7716 detrend=detrend, window=window, 

7717 noverlap=noverlap, pad_to=pad_to, 

7718 sides=sides, 

7719 scale_by_freq=scale_by_freq, 

7720 mode=mode) 

7721 

7722 if scale == 'linear': 

7723 Z = spec 

7724 elif scale == 'dB': 

7725 if mode is None or mode == 'default' or mode == 'psd': 

7726 Z = 10. * np.log10(spec) 

7727 else: 

7728 Z = 20. * np.log10(spec) 

7729 else: 

7730 raise ValueError(f'Unknown scale {scale!r}') 

7731 

7732 Z = np.flipud(Z) 

7733 

7734 if xextent is None: 

7735 # padding is needed for first and last segment: 

7736 pad_xextent = (NFFT-noverlap) / Fs / 2 

7737 xextent = np.min(t) - pad_xextent, np.max(t) + pad_xextent 

7738 xmin, xmax = xextent 

7739 freqs += Fc 

7740 extent = xmin, xmax, freqs[0], freqs[-1] 

7741 

7742 if 'origin' in kwargs: 

7743 raise TypeError("specgram() got an unexpected keyword argument " 

7744 "'origin'") 

7745 

7746 im = self.imshow(Z, cmap, extent=extent, vmin=vmin, vmax=vmax, 

7747 origin='upper', **kwargs) 

7748 self.axis('auto') 

7749 

7750 return spec, freqs, t, im 

7751 

7752 @_docstring.dedent_interpd 

7753 def spy(self, Z, precision=0, marker=None, markersize=None, 

7754 aspect='equal', origin="upper", **kwargs): 

7755 """ 

7756 Plot the sparsity pattern of a 2D array. 

7757 

7758 This visualizes the non-zero values of the array. 

7759 

7760 Two plotting styles are available: image and marker. Both 

7761 are available for full arrays, but only the marker style 

7762 works for `scipy.sparse.spmatrix` instances. 

7763 

7764 **Image style** 

7765 

7766 If *marker* and *markersize* are *None*, `~.Axes.imshow` is used. Any 

7767 extra remaining keyword arguments are passed to this method. 

7768 

7769 **Marker style** 

7770 

7771 If *Z* is a `scipy.sparse.spmatrix` or *marker* or *markersize* are 

7772 *None*, a `.Line2D` object will be returned with the value of marker 

7773 determining the marker type, and any remaining keyword arguments 

7774 passed to `~.Axes.plot`. 

7775 

7776 Parameters 

7777 ---------- 

7778 Z : (M, N) array-like 

7779 The array to be plotted. 

7780 

7781 precision : float or 'present', default: 0 

7782 If *precision* is 0, any non-zero value will be plotted. Otherwise, 

7783 values of :math:`|Z| > precision` will be plotted. 

7784 

7785 For `scipy.sparse.spmatrix` instances, you can also 

7786 pass 'present'. In this case any value present in the array 

7787 will be plotted, even if it is identically zero. 

7788 

7789 aspect : {'equal', 'auto', None} or float, default: 'equal' 

7790 The aspect ratio of the Axes. This parameter is particularly 

7791 relevant for images since it determines whether data pixels are 

7792 square. 

7793 

7794 This parameter is a shortcut for explicitly calling 

7795 `.Axes.set_aspect`. See there for further details. 

7796 

7797 - 'equal': Ensures an aspect ratio of 1. Pixels will be square. 

7798 - 'auto': The Axes is kept fixed and the aspect is adjusted so 

7799 that the data fit in the Axes. In general, this will result in 

7800 non-square pixels. 

7801 - *None*: Use :rc:`image.aspect`. 

7802 

7803 origin : {'upper', 'lower'}, default: :rc:`image.origin` 

7804 Place the [0, 0] index of the array in the upper left or lower left 

7805 corner of the Axes. The convention 'upper' is typically used for 

7806 matrices and images. 

7807 

7808 Returns 

7809 ------- 

7810 `~matplotlib.image.AxesImage` or `.Line2D` 

7811 The return type depends on the plotting style (see above). 

7812 

7813 Other Parameters 

7814 ---------------- 

7815 **kwargs 

7816 The supported additional parameters depend on the plotting style. 

7817 

7818 For the image style, you can pass the following additional 

7819 parameters of `~.Axes.imshow`: 

7820 

7821 - *cmap* 

7822 - *alpha* 

7823 - *url* 

7824 - any `.Artist` properties (passed on to the `.AxesImage`) 

7825 

7826 For the marker style, you can pass any `.Line2D` property except 

7827 for *linestyle*: 

7828 

7829 %(Line2D:kwdoc)s 

7830 """ 

7831 if marker is None and markersize is None and hasattr(Z, 'tocoo'): 

7832 marker = 's' 

7833 _api.check_in_list(["upper", "lower"], origin=origin) 

7834 if marker is None and markersize is None: 

7835 Z = np.asarray(Z) 

7836 mask = np.abs(Z) > precision 

7837 

7838 if 'cmap' not in kwargs: 

7839 kwargs['cmap'] = mcolors.ListedColormap(['w', 'k'], 

7840 name='binary') 

7841 if 'interpolation' in kwargs: 

7842 raise TypeError( 

7843 "spy() got an unexpected keyword argument 'interpolation'") 

7844 if 'norm' not in kwargs: 

7845 kwargs['norm'] = mcolors.NoNorm() 

7846 ret = self.imshow(mask, interpolation='nearest', 

7847 aspect=aspect, origin=origin, 

7848 **kwargs) 

7849 else: 

7850 if hasattr(Z, 'tocoo'): 

7851 c = Z.tocoo() 

7852 if precision == 'present': 

7853 y = c.row 

7854 x = c.col 

7855 else: 

7856 nonzero = np.abs(c.data) > precision 

7857 y = c.row[nonzero] 

7858 x = c.col[nonzero] 

7859 else: 

7860 Z = np.asarray(Z) 

7861 nonzero = np.abs(Z) > precision 

7862 y, x = np.nonzero(nonzero) 

7863 if marker is None: 

7864 marker = 's' 

7865 if markersize is None: 

7866 markersize = 10 

7867 if 'linestyle' in kwargs: 

7868 raise TypeError( 

7869 "spy() got an unexpected keyword argument 'linestyle'") 

7870 ret = mlines.Line2D( 

7871 x, y, linestyle='None', marker=marker, markersize=markersize, 

7872 **kwargs) 

7873 self.add_line(ret) 

7874 nr, nc = Z.shape 

7875 self.set_xlim(-0.5, nc - 0.5) 

7876 if origin == "upper": 

7877 self.set_ylim(nr - 0.5, -0.5) 

7878 else: 

7879 self.set_ylim(-0.5, nr - 0.5) 

7880 self.set_aspect(aspect) 

7881 self.title.set_y(1.05) 

7882 if origin == "upper": 

7883 self.xaxis.tick_top() 

7884 else: # lower 

7885 self.xaxis.tick_bottom() 

7886 self.xaxis.set_ticks_position('both') 

7887 self.xaxis.set_major_locator( 

7888 mticker.MaxNLocator(nbins=9, steps=[1, 2, 5, 10], integer=True)) 

7889 self.yaxis.set_major_locator( 

7890 mticker.MaxNLocator(nbins=9, steps=[1, 2, 5, 10], integer=True)) 

7891 return ret 

7892 

7893 def matshow(self, Z, **kwargs): 

7894 """ 

7895 Plot the values of a 2D matrix or array as color-coded image. 

7896 

7897 The matrix will be shown the way it would be printed, with the first 

7898 row at the top. Row and column numbering is zero-based. 

7899 

7900 Parameters 

7901 ---------- 

7902 Z : (M, N) array-like 

7903 The matrix to be displayed. 

7904 

7905 Returns 

7906 ------- 

7907 `~matplotlib.image.AxesImage` 

7908 

7909 Other Parameters 

7910 ---------------- 

7911 **kwargs : `~matplotlib.axes.Axes.imshow` arguments 

7912 

7913 See Also 

7914 -------- 

7915 imshow : More general function to plot data on a 2D regular raster. 

7916 

7917 Notes 

7918 ----- 

7919 This is just a convenience function wrapping `.imshow` to set useful 

7920 defaults for displaying a matrix. In particular: 

7921 

7922 - Set ``origin='upper'``. 

7923 - Set ``interpolation='nearest'``. 

7924 - Set ``aspect='equal'``. 

7925 - Ticks are placed to the left and above. 

7926 - Ticks are formatted to show integer indices. 

7927 

7928 """ 

7929 Z = np.asanyarray(Z) 

7930 kw = {'origin': 'upper', 

7931 'interpolation': 'nearest', 

7932 'aspect': 'equal', # (already the imshow default) 

7933 **kwargs} 

7934 im = self.imshow(Z, **kw) 

7935 self.title.set_y(1.05) 

7936 self.xaxis.tick_top() 

7937 self.xaxis.set_ticks_position('both') 

7938 self.xaxis.set_major_locator( 

7939 mticker.MaxNLocator(nbins=9, steps=[1, 2, 5, 10], integer=True)) 

7940 self.yaxis.set_major_locator( 

7941 mticker.MaxNLocator(nbins=9, steps=[1, 2, 5, 10], integer=True)) 

7942 return im 

7943 

7944 @_preprocess_data(replace_names=["dataset"]) 

7945 def violinplot(self, dataset, positions=None, vert=True, widths=0.5, 

7946 showmeans=False, showextrema=True, showmedians=False, 

7947 quantiles=None, points=100, bw_method=None): 

7948 """ 

7949 Make a violin plot. 

7950 

7951 Make a violin plot for each column of *dataset* or each vector in 

7952 sequence *dataset*. Each filled area extends to represent the 

7953 entire data range, with optional lines at the mean, the median, 

7954 the minimum, the maximum, and user-specified quantiles. 

7955 

7956 Parameters 

7957 ---------- 

7958 dataset : Array or a sequence of vectors. 

7959 The input data. 

7960 

7961 positions : array-like, default: [1, 2, ..., n] 

7962 The positions of the violins. The ticks and limits are 

7963 automatically set to match the positions. 

7964 

7965 vert : bool, default: True. 

7966 If true, creates a vertical violin plot. 

7967 Otherwise, creates a horizontal violin plot. 

7968 

7969 widths : array-like, default: 0.5 

7970 Either a scalar or a vector that sets the maximal width of 

7971 each violin. The default is 0.5, which uses about half of the 

7972 available horizontal space. 

7973 

7974 showmeans : bool, default: False 

7975 If `True`, will toggle rendering of the means. 

7976 

7977 showextrema : bool, default: True 

7978 If `True`, will toggle rendering of the extrema. 

7979 

7980 showmedians : bool, default: False 

7981 If `True`, will toggle rendering of the medians. 

7982 

7983 quantiles : array-like, default: None 

7984 If not None, set a list of floats in interval [0, 1] for each violin, 

7985 which stands for the quantiles that will be rendered for that 

7986 violin. 

7987 

7988 points : int, default: 100 

7989 Defines the number of points to evaluate each of the 

7990 gaussian kernel density estimations at. 

7991 

7992 bw_method : str, scalar or callable, optional 

7993 The method used to calculate the estimator bandwidth. This can be 

7994 'scott', 'silverman', a scalar constant or a callable. If a 

7995 scalar, this will be used directly as `kde.factor`. If a 

7996 callable, it should take a `matplotlib.mlab.GaussianKDE` instance as 

7997 its only parameter and return a scalar. If None (default), 'scott' 

7998 is used. 

7999 

8000 data : indexable object, optional 

8001 DATA_PARAMETER_PLACEHOLDER 

8002 

8003 Returns 

8004 ------- 

8005 dict 

8006 A dictionary mapping each component of the violinplot to a 

8007 list of the corresponding collection instances created. The 

8008 dictionary has the following keys: 

8009 

8010 - ``bodies``: A list of the `~.collections.PolyCollection` 

8011 instances containing the filled area of each violin. 

8012 

8013 - ``cmeans``: A `~.collections.LineCollection` instance that marks 

8014 the mean values of each of the violin's distribution. 

8015 

8016 - ``cmins``: A `~.collections.LineCollection` instance that marks 

8017 the bottom of each violin's distribution. 

8018 

8019 - ``cmaxes``: A `~.collections.LineCollection` instance that marks 

8020 the top of each violin's distribution. 

8021 

8022 - ``cbars``: A `~.collections.LineCollection` instance that marks 

8023 the centers of each violin's distribution. 

8024 

8025 - ``cmedians``: A `~.collections.LineCollection` instance that 

8026 marks the median values of each of the violin's distribution. 

8027 

8028 - ``cquantiles``: A `~.collections.LineCollection` instance created 

8029 to identify the quantile values of each of the violin's 

8030 distribution. 

8031 

8032 """ 

8033 

8034 def _kde_method(X, coords): 

8035 # Unpack in case of e.g. Pandas or xarray object 

8036 X = cbook._unpack_to_numpy(X) 

8037 # fallback gracefully if the vector contains only one value 

8038 if np.all(X[0] == X): 

8039 return (X[0] == coords).astype(float) 

8040 kde = mlab.GaussianKDE(X, bw_method) 

8041 return kde.evaluate(coords) 

8042 

8043 vpstats = cbook.violin_stats(dataset, _kde_method, points=points, 

8044 quantiles=quantiles) 

8045 return self.violin(vpstats, positions=positions, vert=vert, 

8046 widths=widths, showmeans=showmeans, 

8047 showextrema=showextrema, showmedians=showmedians) 

8048 

8049 def violin(self, vpstats, positions=None, vert=True, widths=0.5, 

8050 showmeans=False, showextrema=True, showmedians=False): 

8051 """ 

8052 Drawing function for violin plots. 

8053 

8054 Draw a violin plot for each column of *vpstats*. Each filled area 

8055 extends to represent the entire data range, with optional lines at the 

8056 mean, the median, the minimum, the maximum, and the quantiles values. 

8057 

8058 Parameters 

8059 ---------- 

8060 vpstats : list of dicts 

8061 A list of dictionaries containing stats for each violin plot. 

8062 Required keys are: 

8063 

8064 - ``coords``: A list of scalars containing the coordinates that 

8065 the violin's kernel density estimate were evaluated at. 

8066 

8067 - ``vals``: A list of scalars containing the values of the 

8068 kernel density estimate at each of the coordinates given 

8069 in *coords*. 

8070 

8071 - ``mean``: The mean value for this violin's dataset. 

8072 

8073 - ``median``: The median value for this violin's dataset. 

8074 

8075 - ``min``: The minimum value for this violin's dataset. 

8076 

8077 - ``max``: The maximum value for this violin's dataset. 

8078 

8079 Optional keys are: 

8080 

8081 - ``quantiles``: A list of scalars containing the quantile values 

8082 for this violin's dataset. 

8083 

8084 positions : array-like, default: [1, 2, ..., n] 

8085 The positions of the violins. The ticks and limits are 

8086 automatically set to match the positions. 

8087 

8088 vert : bool, default: True. 

8089 If true, plots the violins vertically. 

8090 Otherwise, plots the violins horizontally. 

8091 

8092 widths : array-like, default: 0.5 

8093 Either a scalar or a vector that sets the maximal width of 

8094 each violin. The default is 0.5, which uses about half of the 

8095 available horizontal space. 

8096 

8097 showmeans : bool, default: False 

8098 If true, will toggle rendering of the means. 

8099 

8100 showextrema : bool, default: True 

8101 If true, will toggle rendering of the extrema. 

8102 

8103 showmedians : bool, default: False 

8104 If true, will toggle rendering of the medians. 

8105 

8106 Returns 

8107 ------- 

8108 dict 

8109 A dictionary mapping each component of the violinplot to a 

8110 list of the corresponding collection instances created. The 

8111 dictionary has the following keys: 

8112 

8113 - ``bodies``: A list of the `~.collections.PolyCollection` 

8114 instances containing the filled area of each violin. 

8115 

8116 - ``cmeans``: A `~.collections.LineCollection` instance that marks 

8117 the mean values of each of the violin's distribution. 

8118 

8119 - ``cmins``: A `~.collections.LineCollection` instance that marks 

8120 the bottom of each violin's distribution. 

8121 

8122 - ``cmaxes``: A `~.collections.LineCollection` instance that marks 

8123 the top of each violin's distribution. 

8124 

8125 - ``cbars``: A `~.collections.LineCollection` instance that marks 

8126 the centers of each violin's distribution. 

8127 

8128 - ``cmedians``: A `~.collections.LineCollection` instance that 

8129 marks the median values of each of the violin's distribution. 

8130 

8131 - ``cquantiles``: A `~.collections.LineCollection` instance created 

8132 to identify the quantiles values of each of the violin's 

8133 distribution. 

8134 """ 

8135 

8136 # Statistical quantities to be plotted on the violins 

8137 means = [] 

8138 mins = [] 

8139 maxes = [] 

8140 medians = [] 

8141 quantiles = [] 

8142 

8143 qlens = [] # Number of quantiles in each dataset. 

8144 

8145 artists = {} # Collections to be returned 

8146 

8147 N = len(vpstats) 

8148 datashape_message = ("List of violinplot statistics and `{0}` " 

8149 "values must have the same length") 

8150 

8151 # Validate positions 

8152 if positions is None: 

8153 positions = range(1, N + 1) 

8154 elif len(positions) != N: 

8155 raise ValueError(datashape_message.format("positions")) 

8156 

8157 # Validate widths 

8158 if np.isscalar(widths): 

8159 widths = [widths] * N 

8160 elif len(widths) != N: 

8161 raise ValueError(datashape_message.format("widths")) 

8162 

8163 # Calculate ranges for statistics lines (shape (2, N)). 

8164 line_ends = [[-0.25], [0.25]] * np.array(widths) + positions 

8165 

8166 # Colors. 

8167 if mpl.rcParams['_internal.classic_mode']: 

8168 fillcolor = 'y' 

8169 linecolor = 'r' 

8170 else: 

8171 fillcolor = linecolor = self._get_lines.get_next_color() 

8172 

8173 # Check whether we are rendering vertically or horizontally 

8174 if vert: 

8175 fill = self.fill_betweenx 

8176 perp_lines = functools.partial(self.hlines, colors=linecolor) 

8177 par_lines = functools.partial(self.vlines, colors=linecolor) 

8178 else: 

8179 fill = self.fill_between 

8180 perp_lines = functools.partial(self.vlines, colors=linecolor) 

8181 par_lines = functools.partial(self.hlines, colors=linecolor) 

8182 

8183 # Render violins 

8184 bodies = [] 

8185 for stats, pos, width in zip(vpstats, positions, widths): 

8186 # The 0.5 factor reflects the fact that we plot from v-p to v+p. 

8187 vals = np.array(stats['vals']) 

8188 vals = 0.5 * width * vals / vals.max() 

8189 bodies += [fill(stats['coords'], -vals + pos, vals + pos, 

8190 facecolor=fillcolor, alpha=0.3)] 

8191 means.append(stats['mean']) 

8192 mins.append(stats['min']) 

8193 maxes.append(stats['max']) 

8194 medians.append(stats['median']) 

8195 q = stats.get('quantiles') # a list of floats, or None 

8196 if q is None: 

8197 q = [] 

8198 quantiles.extend(q) 

8199 qlens.append(len(q)) 

8200 artists['bodies'] = bodies 

8201 

8202 if showmeans: # Render means 

8203 artists['cmeans'] = perp_lines(means, *line_ends) 

8204 if showextrema: # Render extrema 

8205 artists['cmaxes'] = perp_lines(maxes, *line_ends) 

8206 artists['cmins'] = perp_lines(mins, *line_ends) 

8207 artists['cbars'] = par_lines(positions, mins, maxes) 

8208 if showmedians: # Render medians 

8209 artists['cmedians'] = perp_lines(medians, *line_ends) 

8210 if quantiles: # Render quantiles: each width is repeated qlen times. 

8211 artists['cquantiles'] = perp_lines( 

8212 quantiles, *np.repeat(line_ends, qlens, axis=1)) 

8213 

8214 return artists 

8215 

8216 # Methods that are entirely implemented in other modules. 

8217 

8218 table = mtable.table 

8219 

8220 # args can by either Y or y1, y2, ... and all should be replaced 

8221 stackplot = _preprocess_data()(mstack.stackplot) 

8222 

8223 streamplot = _preprocess_data( 

8224 replace_names=["x", "y", "u", "v", "start_points"])(mstream.streamplot) 

8225 

8226 tricontour = mtri.tricontour 

8227 tricontourf = mtri.tricontourf 

8228 tripcolor = mtri.tripcolor 

8229 triplot = mtri.triplot 

8230 

8231 def _get_aspect_ratio(self): 

8232 """ 

8233 Convenience method to calculate the aspect ratio of the axes in 

8234 the display coordinate system. 

8235 """ 

8236 figure_size = self.get_figure().get_size_inches() 

8237 ll, ur = self.get_position() * figure_size 

8238 width, height = ur - ll 

8239 return height / (width * self.get_data_ratio())