1from __future__ import (absolute_import, division, print_function, 2 unicode_literals) 3 4import six 5from six.moves import xrange, zip, zip_longest 6 7import functools 8import itertools 9import logging 10import math 11import warnings 12 13import numpy as np 14from numpy import ma 15 16import matplotlib 17from matplotlib import _preprocess_data 18 19import matplotlib.cbook as cbook 20import matplotlib.collections as mcoll 21import matplotlib.colors as mcolors 22import matplotlib.contour as mcontour 23import matplotlib.category as _ # <-registers a category unit converter 24import matplotlib.dates as _ # <-registers a date unit converter 25import matplotlib.docstring as docstring 26import matplotlib.image as mimage 27import matplotlib.legend as mlegend 28import matplotlib.lines as mlines 29import matplotlib.markers as mmarkers 30import matplotlib.mlab as mlab 31import matplotlib.path as mpath 32import matplotlib.patches as mpatches 33import matplotlib.quiver as mquiver 34import matplotlib.stackplot as mstack 35import matplotlib.streamplot as mstream 36import matplotlib.table as mtable 37import matplotlib.text as mtext 38import matplotlib.ticker as mticker 39import matplotlib.transforms as mtransforms 40import matplotlib.tri as mtri 41from matplotlib.cbook import ( 42 _backports, mplDeprecation, warn_deprecated, 43 STEP_LOOKUP_MAP, iterable, safe_first_element) 44from matplotlib.container import BarContainer, ErrorbarContainer, StemContainer 45from matplotlib.axes._base import _AxesBase, _process_plot_format 46 47_log = logging.getLogger(__name__) 48 49rcParams = matplotlib.rcParams 50 51_alias_map = {'color': ['c'], 52 'linewidth': ['lw'], 53 'linestyle': ['ls'], 54 'facecolor': ['fc'], 55 'edgecolor': ['ec'], 56 'markerfacecolor': ['mfc'], 57 'markeredgecolor': ['mec'], 58 'markeredgewidth': ['mew'], 59 'markersize': ['ms'], 60 } 61 62 63def _plot_args_replacer(args, data): 64 if len(args) == 1: 65 return ["y"] 66 elif len(args) == 2: 67 # this can be two cases: x,y or y,c 68 if not args[1] in data: 69 # this is not in data, so just assume that it is something which 70 # will not get replaced (color spec or array like). 71 return ["y", "c"] 72 # it's data, but could be a color code like 'ro' or 'b--' 73 # -> warn the user in that case... 74 try: 75 _process_plot_format(args[1]) 76 except ValueError: 77 pass 78 else: 79 warnings.warn( 80 "Second argument {!r} is ambiguous: could be a color spec but " 81 "is in data; using as data. Either rename the entry in data " 82 "or use three arguments to plot.".format(args[1]), 83 RuntimeWarning, stacklevel=3) 84 return ["x", "y"] 85 elif len(args) == 3: 86 return ["x", "y", "c"] 87 else: 88 raise ValueError("Using arbitrary long args with data is not " 89 "supported due to ambiguity of arguments.\nUse " 90 "multiple plotting calls instead.") 91 92 93# The axes module contains all the wrappers to plotting functions. 94# All the other methods should go in the _AxesBase class. 95 96class Axes(_AxesBase): 97 """ 98 The :class:`Axes` contains most of the figure elements: 99 :class:`~matplotlib.axis.Axis`, :class:`~matplotlib.axis.Tick`, 100 :class:`~matplotlib.lines.Line2D`, :class:`~matplotlib.text.Text`, 101 :class:`~matplotlib.patches.Polygon`, etc., and sets the 102 coordinate system. 103 104 The :class:`Axes` instance supports callbacks through a callbacks 105 attribute which is a :class:`~matplotlib.cbook.CallbackRegistry` 106 instance. The events you can connect to are 'xlim_changed' and 107 'ylim_changed' and the callback will be called with func(*ax*) 108 where *ax* is the :class:`Axes` instance. 109 """ 110 ### Labelling, legend and texts 111 112 aname = 'Axes' 113 114 def get_title(self, loc="center"): 115 """ 116 Get an axes title. 117 118 Get one of the three available axes titles. The available titles 119 are positioned above the axes in the center, flush with the left 120 edge, and flush with the right edge. 121 122 Parameters 123 ---------- 124 loc : {'center', 'left', 'right'}, str, optional 125 Which title to get, defaults to 'center'. 126 127 Returns 128 ------- 129 title : str 130 The title text string. 131 132 """ 133 try: 134 title = {'left': self._left_title, 135 'center': self.title, 136 'right': self._right_title}[loc.lower()] 137 except KeyError: 138 raise ValueError("'%s' is not a valid location" % loc) 139 return title.get_text() 140 141 def set_title(self, label, fontdict=None, loc="center", pad=None, 142 **kwargs): 143 """ 144 Set a title for the axes. 145 146 Set one of the three available axes titles. The available titles 147 are positioned above the axes in the center, flush with the left 148 edge, and flush with the right edge. 149 150 Parameters 151 ---------- 152 label : str 153 Text to use for the title 154 155 fontdict : dict 156 A dictionary controlling the appearance of the title text, 157 the default `fontdict` is:: 158 159 {'fontsize': rcParams['axes.titlesize'], 160 'fontweight' : rcParams['axes.titleweight'], 161 'verticalalignment': 'baseline', 162 'horizontalalignment': loc} 163 164 loc : {'center', 'left', 'right'}, str, optional 165 Which title to set, defaults to 'center' 166 167 pad : float 168 The offset of the title from the top of the axes, in points. 169 Default is ``None`` to use rcParams['axes.titlepad']. 170 171 Returns 172 ------- 173 text : :class:`~matplotlib.text.Text` 174 The matplotlib text instance representing the title 175 176 Other Parameters 177 ---------------- 178 **kwargs : `~matplotlib.text.Text` properties 179 Other keyword arguments are text properties, see 180 :class:`~matplotlib.text.Text` for a list of valid text 181 properties. 182 """ 183 try: 184 title = {'left': self._left_title, 185 'center': self.title, 186 'right': self._right_title}[loc.lower()] 187 except KeyError: 188 raise ValueError("'%s' is not a valid location" % loc) 189 default = { 190 'fontsize': rcParams['axes.titlesize'], 191 'fontweight': rcParams['axes.titleweight'], 192 'verticalalignment': 'baseline', 193 'horizontalalignment': loc.lower()} 194 if pad is None: 195 pad = rcParams['axes.titlepad'] 196 self._set_title_offset_trans(float(pad)) 197 title.set_text(label) 198 title.update(default) 199 if fontdict is not None: 200 title.update(fontdict) 201 title.update(kwargs) 202 return title 203 204 def get_xlabel(self): 205 """ 206 Get the xlabel text string. 207 """ 208 label = self.xaxis.get_label() 209 return label.get_text() 210 211 def set_xlabel(self, xlabel, fontdict=None, labelpad=None, **kwargs): 212 """ 213 Set the label for the x-axis. 214 215 Parameters 216 ---------- 217 xlabel : str 218 The label text. 219 220 labelpad : scalar, optional, default: None 221 Spacing in points between the label and the x-axis. 222 223 Other Parameters 224 ---------------- 225 **kwargs : `.Text` properties 226 `.Text` properties control the appearance of the label. 227 228 See also 229 -------- 230 text : for information on how override and the optional args work 231 """ 232 if labelpad is not None: 233 self.xaxis.labelpad = labelpad 234 return self.xaxis.set_label_text(xlabel, fontdict, **kwargs) 235 236 def get_ylabel(self): 237 """ 238 Get the ylabel text string. 239 """ 240 label = self.yaxis.get_label() 241 return label.get_text() 242 243 def set_ylabel(self, ylabel, fontdict=None, labelpad=None, **kwargs): 244 """ 245 Set the label for the y-axis. 246 247 Parameters 248 ---------- 249 ylabel : str 250 The label text. 251 252 labelpad : scalar, optional, default: None 253 Spacing in points between the label and the y-axis. 254 255 Other Parameters 256 ---------------- 257 **kwargs : `.Text` properties 258 `.Text` properties control the appearance of the label. 259 260 See also 261 -------- 262 text : for information on how override and the optional args work 263 264 """ 265 if labelpad is not None: 266 self.yaxis.labelpad = labelpad 267 return self.yaxis.set_label_text(ylabel, fontdict, **kwargs) 268 269 def get_legend_handles_labels(self, legend_handler_map=None): 270 """ 271 Return handles and labels for legend 272 273 ``ax.legend()`` is equivalent to :: 274 275 h, l = ax.get_legend_handles_labels() 276 ax.legend(h, l) 277 278 """ 279 280 # pass through to legend. 281 handles, labels = mlegend._get_legend_handles_labels([self], 282 legend_handler_map) 283 return handles, labels 284 285 @docstring.dedent_interpd 286 def legend(self, *args, **kwargs): 287 """ 288 Places a legend on the axes. 289 290 Call signatures:: 291 292 legend() 293 legend(labels) 294 legend(handles, labels) 295 296 The call signatures correspond to three different ways how to use 297 this method. 298 299 **1. Automatic detection of elements to be shown in the legend** 300 301 The elements to be added to the legend are automatically determined, 302 when you do not pass in any extra arguments. 303 304 In this case, the labels are taken from the artist. You can specify 305 them either at artist creation or by calling the 306 :meth:`~.Artist.set_label` method on the artist:: 307 308 line, = ax.plot([1, 2, 3], label='Inline label') 309 ax.legend() 310 311 or:: 312 313 line.set_label('Label via method') 314 line, = ax.plot([1, 2, 3]) 315 ax.legend() 316 317 Specific lines can be excluded from the automatic legend element 318 selection by defining a label starting with an underscore. 319 This is default for all artists, so calling `Axes.legend` without 320 any arguments and without setting the labels manually will result in 321 no legend being drawn. 322 323 324 **2. Labeling existing plot elements** 325 326 To make a legend for lines which already exist on the axes 327 (via plot for instance), simply call this function with an iterable 328 of strings, one for each legend item. For example:: 329 330 ax.plot([1, 2, 3]) 331 ax.legend(['A simple line']) 332 333 Note: This way of using is discouraged, because the relation between 334 plot elements and labels is only implicit by their order and can 335 easily be mixed up. 336 337 338 **3. Explicitly defining the elements in the legend** 339 340 For full control of which artists have a legend entry, it is possible 341 to pass an iterable of legend artists followed by an iterable of 342 legend labels respectively:: 343 344 legend((line1, line2, line3), ('label1', 'label2', 'label3')) 345 346 Parameters 347 ---------- 348 349 handles : sequence of `.Artist`, optional 350 A list of Artists (lines, patches) to be added to the legend. 351 Use this together with *labels*, if you need full control on what 352 is shown in the legend and the automatic mechanism described above 353 is not sufficient. 354 355 The length of handles and labels should be the same in this 356 case. If they are not, they are truncated to the smaller length. 357 358 labels : sequence of strings, optional 359 A list of labels to show next to the artists. 360 Use this together with *handles*, if you need full control on what 361 is shown in the legend and the automatic mechanism described above 362 is not sufficient. 363 364 Other Parameters 365 ---------------- 366 367 loc : int or string or pair of floats, default: 'upper right' 368 The location of the legend. Possible codes are: 369 370 =============== ============= 371 Location String Location Code 372 =============== ============= 373 'best' 0 374 'upper right' 1 375 'upper left' 2 376 'lower left' 3 377 'lower right' 4 378 'right' 5 379 'center left' 6 380 'center right' 7 381 'lower center' 8 382 'upper center' 9 383 'center' 10 384 =============== ============= 385 386 387 Alternatively can be a 2-tuple giving ``x, y`` of the lower-left 388 corner of the legend in axes coordinates (in which case 389 ``bbox_to_anchor`` will be ignored). 390 391 bbox_to_anchor : `.BboxBase` or pair of floats 392 Specify any arbitrary location for the legend in `bbox_transform` 393 coordinates (default Axes coordinates). 394 395 For example, to put the legend's upper right hand corner in the 396 center of the axes the following keywords can be used:: 397 398 loc='upper right', bbox_to_anchor=(0.5, 0.5) 399 400 ncol : integer 401 The number of columns that the legend has. Default is 1. 402 403 prop : None or :class:`matplotlib.font_manager.FontProperties` or dict 404 The font properties of the legend. If None (default), the current 405 :data:`matplotlib.rcParams` will be used. 406 407 fontsize : int or float or {'xx-small', 'x-small', 'small', 'medium', \ 408'large', 'x-large', 'xx-large'} 409 Controls the font size of the legend. If the value is numeric the 410 size will be the absolute font size in points. String values are 411 relative to the current default font size. This argument is only 412 used if `prop` is not specified. 413 414 numpoints : None or int 415 The number of marker points in the legend when creating a legend 416 entry for a `.Line2D` (line). 417 Default is ``None``, which will take the value from 418 :rc:`legend.numpoints`. 419 420 scatterpoints : None or int 421 The number of marker points in the legend when creating 422 a legend entry for a `.PathCollection` (scatter plot). 423 Default is ``None``, which will take the value from 424 :rc:`legend.scatterpoints`. 425 426 scatteryoffsets : iterable of floats 427 The vertical offset (relative to the font size) for the markers 428 created for a scatter plot legend entry. 0.0 is at the base the 429 legend text, and 1.0 is at the top. To draw all markers at the 430 same height, set to ``[0.5]``. Default is ``[0.375, 0.5, 0.3125]``. 431 432 markerscale : None or int or float 433 The relative size of legend markers compared with the originally 434 drawn ones. 435 Default is ``None``, which will take the value from 436 :rc:`legend.markerscale`. 437 438 markerfirst : bool 439 If *True*, legend marker is placed to the left of the legend label. 440 If *False*, legend marker is placed to the right of the legend 441 label. 442 Default is *True*. 443 444 frameon : None or bool 445 Control whether the legend should be drawn on a patch 446 (frame). 447 Default is ``None``, which will take the value from 448 :rc:`legend.frameon`. 449 450 fancybox : None or bool 451 Control whether round edges should be enabled around the 452 :class:`~matplotlib.patches.FancyBboxPatch` which makes up the 453 legend's background. 454 Default is ``None``, which will take the value from 455 :rc:`legend.fancybox`. 456 457 shadow : None or bool 458 Control whether to draw a shadow behind the legend. 459 Default is ``None``, which will take the value from 460 :rc:`legend.shadow`. 461 462 framealpha : None or float 463 Control the alpha transparency of the legend's background. 464 Default is ``None``, which will take the value from 465 :rc:`legend.framealpha`. If shadow is activated and 466 *framealpha* is ``None``, the default value is ignored. 467 468 facecolor : None or "inherit" or a color spec 469 Control the legend's background color. 470 Default is ``None``, which will take the value from 471 :rc:`legend.facecolor`. If ``"inherit"``, it will take 472 :rc:`axes.facecolor`. 473 474 edgecolor : None or "inherit" or a color spec 475 Control the legend's background patch edge color. 476 Default is ``None``, which will take the value from 477 :rc:`legend.edgecolor` If ``"inherit"``, it will take 478 :rc:`axes.edgecolor`. 479 480 mode : {"expand", None} 481 If `mode` is set to ``"expand"`` the legend will be horizontally 482 expanded to fill the axes area (or `bbox_to_anchor` if defines 483 the legend's size). 484 485 bbox_transform : None or :class:`matplotlib.transforms.Transform` 486 The transform for the bounding box (`bbox_to_anchor`). For a value 487 of ``None`` (default) the Axes' 488 :data:`~matplotlib.axes.Axes.transAxes` transform will be used. 489 490 title : str or None 491 The legend's title. Default is no title (``None``). 492 493 borderpad : float or None 494 The fractional whitespace inside the legend border. 495 Measured in font-size units. 496 Default is ``None``, which will take the value from 497 :rc:`legend.borderpad`. 498 499 labelspacing : float or None 500 The vertical space between the legend entries. 501 Measured in font-size units. 502 Default is ``None``, which will take the value from 503 :rc:`legend.labelspacing`. 504 505 handlelength : float or None 506 The length of the legend handles. 507 Measured in font-size units. 508 Default is ``None``, which will take the value from 509 :rc:`legend.handlelength`. 510 511 handletextpad : float or None 512 The pad between the legend handle and text. 513 Measured in font-size units. 514 Default is ``None``, which will take the value from 515 :rc:`legend.handletextpad`. 516 517 borderaxespad : float or None 518 The pad between the axes and legend border. 519 Measured in font-size units. 520 Default is ``None``, which will take the value from 521 :rc:`legend.borderaxespad`. 522 523 columnspacing : float or None 524 The spacing between columns. 525 Measured in font-size units. 526 Default is ``None``, which will take the value from 527 :rc:`legend.columnspacing`. 528 529 handler_map : dict or None 530 The custom dictionary mapping instances or types to a legend 531 handler. This `handler_map` updates the default handler map 532 found at :func:`matplotlib.legend.Legend.get_legend_handler_map`. 533 534 Returns 535 ------- 536 537 :class:`matplotlib.legend.Legend` instance 538 539 Notes 540 ----- 541 542 Not all kinds of artist are supported by the legend command. See 543 :doc:`/tutorials/intermediate/legend_guide` for details. 544 545 Examples 546 -------- 547 548 .. plot:: gallery/api/legend.py 549 550 """ 551 handles, labels, extra_args, kwargs = mlegend._parse_legend_args( 552 [self], 553 *args, 554 **kwargs) 555 if len(extra_args): 556 raise TypeError('legend only accepts two non-keyword arguments') 557 self.legend_ = mlegend.Legend(self, handles, labels, **kwargs) 558 self.legend_._remove_method = lambda h: setattr(self, 'legend_', None) 559 return self.legend_ 560 561 def text(self, x, y, s, fontdict=None, withdash=False, **kwargs): 562 """ 563 Add text to the axes. 564 565 Add the text *s* to the axes at location *x*, *y* in data coordinates. 566 567 Parameters 568 ---------- 569 x, y : scalars 570 The position to place the text. By default, this is in data 571 coordinates. The coordinate system can be changed using the 572 *transform* parameter. 573 574 s : str 575 The text. 576 577 fontdict : dictionary, optional, default: None 578 A dictionary to override the default text properties. If fontdict 579 is None, the defaults are determined by your rc parameters. 580 581 withdash : boolean, optional, default: False 582 Creates a `~matplotlib.text.TextWithDash` instance instead of a 583 `~matplotlib.text.Text` instance. 584 585 Returns 586 ------- 587 text : `.Text` 588 The created `.Text` instance. 589 590 Other Parameters 591 ---------------- 592 **kwargs : `~matplotlib.text.Text` properties. 593 Other miscellaneous text parameters. 594 595 Examples 596 -------- 597 Individual keyword arguments can be used to override any given 598 parameter:: 599 600 >>> text(x, y, s, fontsize=12) 601 602 The default transform specifies that text is in data coords, 603 alternatively, you can specify text in axis coords (0,0 is 604 lower-left and 1,1 is upper-right). The example below places 605 text in the center of the axes:: 606 607 >>> text(0.5, 0.5, 'matplotlib', horizontalalignment='center', 608 ... verticalalignment='center', transform=ax.transAxes) 609 610 You can put a rectangular box around the text instance (e.g., to 611 set a background color) by using the keyword `bbox`. `bbox` is 612 a dictionary of `~matplotlib.patches.Rectangle` 613 properties. For example:: 614 615 >>> text(x, y, s, bbox=dict(facecolor='red', alpha=0.5)) 616 """ 617 default = { 618 'verticalalignment': 'baseline', 619 'horizontalalignment': 'left', 620 'transform': self.transData, 621 'clip_on': False} 622 623 # At some point if we feel confident that TextWithDash 624 # is robust as a drop-in replacement for Text and that 625 # the performance impact of the heavier-weight class 626 # isn't too significant, it may make sense to eliminate 627 # the withdash kwarg and simply delegate whether there's 628 # a dash to TextWithDash and dashlength. 629 if withdash: 630 t = mtext.TextWithDash( 631 x=x, y=y, text=s) 632 else: 633 t = mtext.Text( 634 x=x, y=y, text=s) 635 636 t.update(default) 637 if fontdict is not None: 638 t.update(fontdict) 639 t.update(kwargs) 640 641 t.set_clip_path(self.patch) 642 self._add_text(t) 643 return t 644 645 @docstring.dedent_interpd 646 def annotate(self, *args, **kwargs): 647 a = mtext.Annotation(*args, **kwargs) 648 a.set_transform(mtransforms.IdentityTransform()) 649 if 'clip_on' in kwargs: 650 a.set_clip_path(self.patch) 651 self._add_text(a) 652 return a 653 annotate.__doc__ = mtext.Annotation.__init__.__doc__ 654 #### Lines and spans 655 656 @docstring.dedent_interpd 657 def axhline(self, y=0, xmin=0, xmax=1, **kwargs): 658 """ 659 Add a horizontal line across the axis. 660 661 Parameters 662 ---------- 663 y : scalar, optional, default: 0 664 y position in data coordinates of the horizontal line. 665 666 xmin : scalar, optional, default: 0 667 Should be between 0 and 1, 0 being the far left of the plot, 1 the 668 far right of the plot. 669 670 xmax : scalar, optional, default: 1 671 Should be between 0 and 1, 0 being the far left of the plot, 1 the 672 far right of the plot. 673 674 Returns 675 ------- 676 line : :class:`~matplotlib.lines.Line2D` 677 678 Other Parameters 679 ---------------- 680 **kwargs : 681 Valid kwargs are :class:`~matplotlib.lines.Line2D` properties, 682 with the exception of 'transform': 683 684 %(Line2D)s 685 686 See also 687 -------- 688 hlines : Add horizontal lines in data coordinates. 689 axhspan : Add a horizontal span (rectangle) across the axis. 690 691 Examples 692 -------- 693 694 * draw a thick red hline at 'y' = 0 that spans the xrange:: 695 696 >>> axhline(linewidth=4, color='r') 697 698 * draw a default hline at 'y' = 1 that spans the xrange:: 699 700 >>> axhline(y=1) 701 702 * draw a default hline at 'y' = .5 that spans the middle half of 703 the xrange:: 704 705 >>> axhline(y=.5, xmin=0.25, xmax=0.75) 706 707 """ 708 if "transform" in kwargs: 709 raise ValueError( 710 "'transform' is not allowed as a kwarg;" 711 + "axhline generates its own transform.") 712 ymin, ymax = self.get_ybound() 713 714 # We need to strip away the units for comparison with 715 # non-unitized bounds 716 self._process_unit_info(ydata=y, kwargs=kwargs) 717 yy = self.convert_yunits(y) 718 scaley = (yy < ymin) or (yy > ymax) 719 720 trans = self.get_yaxis_transform(which='grid') 721 l = mlines.Line2D([xmin, xmax], [y, y], transform=trans, **kwargs) 722 self.add_line(l) 723 self.autoscale_view(scalex=False, scaley=scaley) 724 return l 725 726 @docstring.dedent_interpd 727 def axvline(self, x=0, ymin=0, ymax=1, **kwargs): 728 """ 729 Add a vertical line across the axes. 730 731 Parameters 732 ---------- 733 x : scalar, optional, default: 0 734 x position in data coordinates of the vertical line. 735 736 ymin : scalar, optional, default: 0 737 Should be between 0 and 1, 0 being the bottom of the plot, 1 the 738 top of the plot. 739 740 ymax : scalar, optional, default: 1 741 Should be between 0 and 1, 0 being the bottom of the plot, 1 the 742 top of the plot. 743 744 Returns 745 ------- 746 line : :class:`~matplotlib.lines.Line2D` 747 748 Other Parameters 749 ---------------- 750 **kwargs : 751 Valid kwargs are :class:`~matplotlib.lines.Line2D` properties, 752 with the exception of 'transform': 753 754 %(Line2D)s 755 756 Examples 757 -------- 758 * draw a thick red vline at *x* = 0 that spans the yrange:: 759 760 >>> axvline(linewidth=4, color='r') 761 762 * draw a default vline at *x* = 1 that spans the yrange:: 763 764 >>> axvline(x=1) 765 766 * draw a default vline at *x* = .5 that spans the middle half of 767 the yrange:: 768 769 >>> axvline(x=.5, ymin=0.25, ymax=0.75) 770 771 See also 772 -------- 773 vlines : Add vertical lines in data coordinates. 774 axvspan : Add a vertical span (rectangle) across the axis. 775 """ 776 777 if "transform" in kwargs: 778 raise ValueError( 779 "'transform' is not allowed as a kwarg;" 780 + "axvline generates its own transform.") 781 xmin, xmax = self.get_xbound() 782 783 # We need to strip away the units for comparison with 784 # non-unitized bounds 785 self._process_unit_info(xdata=x, kwargs=kwargs) 786 xx = self.convert_xunits(x) 787 scalex = (xx < xmin) or (xx > xmax) 788 789 trans = self.get_xaxis_transform(which='grid') 790 l = mlines.Line2D([x, x], [ymin, ymax], transform=trans, **kwargs) 791 self.add_line(l) 792 self.autoscale_view(scalex=scalex, scaley=False) 793 return l 794 795 @docstring.dedent_interpd 796 def axhspan(self, ymin, ymax, xmin=0, xmax=1, **kwargs): 797 """ 798 Add a horizontal span (rectangle) across the axis. 799 800 Draw a horizontal span (rectangle) from *ymin* to *ymax*. 801 With the default values of *xmin* = 0 and *xmax* = 1, this 802 always spans the xrange, regardless of the xlim settings, even 803 if you change them, e.g., with the :meth:`set_xlim` command. 804 That is, the horizontal extent is in axes coords: 0=left, 805 0.5=middle, 1.0=right but the *y* location is in data 806 coordinates. 807 808 Parameters 809 ---------- 810 ymin : float 811 Lower limit of the horizontal span in data units. 812 ymax : float 813 Upper limit of the horizontal span in data units. 814 xmin : float, optional, default: 0 815 Lower limit of the vertical span in axes (relative 816 0-1) units. 817 xmax : float, optional, default: 1 818 Upper limit of the vertical span in axes (relative 819 0-1) units. 820 821 Returns 822 ------- 823 Polygon : `~matplotlib.patches.Polygon` 824 825 Other Parameters 826 ---------------- 827 **kwargs : `~matplotlib.patches.Polygon` properties. 828 829 %(Polygon)s 830 831 See Also 832 -------- 833 axvspan : Add a vertical span across the axes. 834 """ 835 trans = self.get_yaxis_transform(which='grid') 836 837 # process the unit information 838 self._process_unit_info([xmin, xmax], [ymin, ymax], kwargs=kwargs) 839 840 # first we need to strip away the units 841 xmin, xmax = self.convert_xunits([xmin, xmax]) 842 ymin, ymax = self.convert_yunits([ymin, ymax]) 843 844 verts = (xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin) 845 p = mpatches.Polygon(verts, **kwargs) 846 p.set_transform(trans) 847 self.add_patch(p) 848 self.autoscale_view(scalex=False) 849 return p 850 851 def axvspan(self, xmin, xmax, ymin=0, ymax=1, **kwargs): 852 """ 853 Add a vertical span (rectangle) across the axes. 854 855 Draw a vertical span (rectangle) from `xmin` to `xmax`. With 856 the default values of `ymin` = 0 and `ymax` = 1. This always 857 spans the yrange, regardless of the ylim settings, even if you 858 change them, e.g., with the :meth:`set_ylim` command. That is, 859 the vertical extent is in axes coords: 0=bottom, 0.5=middle, 860 1.0=top but the y location is in data coordinates. 861 862 Parameters 863 ---------- 864 xmin : scalar 865 Number indicating the first X-axis coordinate of the vertical 866 span rectangle in data units. 867 xmax : scalar 868 Number indicating the second X-axis coordinate of the vertical 869 span rectangle in data units. 870 ymin : scalar, optional 871 Number indicating the first Y-axis coordinate of the vertical 872 span rectangle in relative Y-axis units (0-1). Default to 0. 873 ymax : scalar, optional 874 Number indicating the second Y-axis coordinate of the vertical 875 span rectangle in relative Y-axis units (0-1). Default to 1. 876 877 Returns 878 ------- 879 rectangle : matplotlib.patches.Polygon 880 Vertical span (rectangle) from (xmin, ymin) to (xmax, ymax). 881 882 Other Parameters 883 ---------------- 884 **kwargs 885 Optional parameters are properties of the class 886 matplotlib.patches.Polygon. 887 888 See Also 889 -------- 890 axhspan : Add a horizontal span across the axes. 891 892 Examples 893 -------- 894 Draw a vertical, green, translucent rectangle from x = 1.25 to 895 x = 1.55 that spans the yrange of the axes. 896 897 >>> axvspan(1.25, 1.55, facecolor='g', alpha=0.5) 898 899 """ 900 trans = self.get_xaxis_transform(which='grid') 901 902 # process the unit information 903 self._process_unit_info([xmin, xmax], [ymin, ymax], kwargs=kwargs) 904 905 # first we need to strip away the units 906 xmin, xmax = self.convert_xunits([xmin, xmax]) 907 ymin, ymax = self.convert_yunits([ymin, ymax]) 908 909 verts = [(xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin)] 910 p = mpatches.Polygon(verts, **kwargs) 911 p.set_transform(trans) 912 self.add_patch(p) 913 self.autoscale_view(scaley=False) 914 return p 915 916 @_preprocess_data(replace_names=["y", "xmin", "xmax", "colors"], 917 label_namer="y") 918 def hlines(self, y, xmin, xmax, colors='k', linestyles='solid', 919 label='', **kwargs): 920 """ 921 Plot horizontal lines at each *y* from *xmin* to *xmax*. 922 923 Parameters 924 ---------- 925 y : scalar or sequence of scalar 926 y-indexes where to plot the lines. 927 928 xmin, xmax : scalar or 1D array_like 929 Respective beginning and end of each line. If scalars are 930 provided, all lines will have same length. 931 932 colors : array_like of colors, optional, default: 'k' 933 934 linestyles : ['solid' | 'dashed' | 'dashdot' | 'dotted'], optional 935 936 label : string, optional, default: '' 937 938 Returns 939 ------- 940 lines : `~matplotlib.collections.LineCollection` 941 942 Other Parameters 943 ---------------- 944 **kwargs : `~matplotlib.collections.LineCollection` properties. 945 946 See also 947 -------- 948 vlines : vertical lines 949 axhline: horizontal line across the axes 950 """ 951 952 # We do the conversion first since not all unitized data is uniform 953 # process the unit information 954 self._process_unit_info([xmin, xmax], y, kwargs=kwargs) 955 y = self.convert_yunits(y) 956 xmin = self.convert_xunits(xmin) 957 xmax = self.convert_xunits(xmax) 958 959 if not iterable(y): 960 y = [y] 961 if not iterable(xmin): 962 xmin = [xmin] 963 if not iterable(xmax): 964 xmax = [xmax] 965 966 y, xmin, xmax = cbook.delete_masked_points(y, xmin, xmax) 967 968 y = np.ravel(y) 969 xmin = np.resize(xmin, y.shape) 970 xmax = np.resize(xmax, y.shape) 971 972 verts = [((thisxmin, thisy), (thisxmax, thisy)) 973 for thisxmin, thisxmax, thisy in zip(xmin, xmax, y)] 974 lines = mcoll.LineCollection(verts, colors=colors, 975 linestyles=linestyles, label=label) 976 self.add_collection(lines, autolim=False) 977 lines.update(kwargs) 978 979 if len(y) > 0: 980 minx = min(xmin.min(), xmax.min()) 981 maxx = max(xmin.max(), xmax.max()) 982 miny = y.min() 983 maxy = y.max() 984 985 corners = (minx, miny), (maxx, maxy) 986 987 self.update_datalim(corners) 988 self.autoscale_view() 989 990 return lines 991 992 @_preprocess_data(replace_names=["x", "ymin", "ymax", "colors"], 993 label_namer="x") 994 def vlines(self, x, ymin, ymax, colors='k', linestyles='solid', 995 label='', **kwargs): 996 """ 997 Plot vertical lines. 998 999 Plot vertical lines at each *x* from *ymin* to *ymax*. 1000 1001 Parameters 1002 ---------- 1003 x : scalar or 1D array_like 1004 x-indexes where to plot the lines. 1005 1006 ymin, ymax : scalar or 1D array_like 1007 Respective beginning and end of each line. If scalars are 1008 provided, all lines will have same length. 1009 1010 colors : array_like of colors, optional, default: 'k' 1011 1012 linestyles : ['solid' | 'dashed' | 'dashdot' | 'dotted'], optional 1013 1014 label : string, optional, default: '' 1015 1016 Returns 1017 ------- 1018 lines : `~matplotlib.collections.LineCollection` 1019 1020 Other Parameters 1021 ---------------- 1022 **kwargs : `~matplotlib.collections.LineCollection` properties. 1023 1024 See also 1025 -------- 1026 hlines : horizontal lines 1027 axvline: vertical line across the axes 1028 """ 1029 1030 self._process_unit_info(xdata=x, ydata=[ymin, ymax], kwargs=kwargs) 1031 1032 # We do the conversion first since not all unitized data is uniform 1033 x = self.convert_xunits(x) 1034 ymin = self.convert_yunits(ymin) 1035 ymax = self.convert_yunits(ymax) 1036 1037 if not iterable(x): 1038 x = [x] 1039 if not iterable(ymin): 1040 ymin = [ymin] 1041 if not iterable(ymax): 1042 ymax = [ymax] 1043 1044 x, ymin, ymax = cbook.delete_masked_points(x, ymin, ymax) 1045 1046 x = np.ravel(x) 1047 ymin = np.resize(ymin, x.shape) 1048 ymax = np.resize(ymax, x.shape) 1049 1050 verts = [((thisx, thisymin), (thisx, thisymax)) 1051 for thisx, thisymin, thisymax in zip(x, ymin, ymax)] 1052 lines = mcoll.LineCollection(verts, colors=colors, 1053 linestyles=linestyles, label=label) 1054 self.add_collection(lines, autolim=False) 1055 lines.update(kwargs) 1056 1057 if len(x) > 0: 1058 minx = x.min() 1059 maxx = x.max() 1060 miny = min(ymin.min(), ymax.min()) 1061 maxy = max(ymin.max(), ymax.max()) 1062 1063 corners = (minx, miny), (maxx, maxy) 1064 self.update_datalim(corners) 1065 self.autoscale_view() 1066 1067 return lines 1068 1069 @_preprocess_data(replace_names=["positions", "lineoffsets", 1070 "linelengths", "linewidths", 1071 "colors", "linestyles"], 1072 label_namer=None) 1073 @docstring.dedent_interpd 1074 def eventplot(self, positions, orientation='horizontal', lineoffsets=1, 1075 linelengths=1, linewidths=None, colors=None, 1076 linestyles='solid', **kwargs): 1077 """ 1078 Plot identical parallel lines at the given positions. 1079 1080 *positions* should be a 1D or 2D array-like object, with each row 1081 corresponding to a row or column of lines. 1082 1083 This type of plot is commonly used in neuroscience for representing 1084 neural events, where it is usually called a spike raster, dot raster, 1085 or raster plot. 1086 1087 However, it is useful in any situation where you wish to show the 1088 timing or position of multiple sets of discrete events, such as the 1089 arrival times of people to a business on each day of the month or the 1090 date of hurricanes each year of the last century. 1091 1092 Parameters 1093 ---------- 1094 positions : 1D or 2D array-like object 1095 Each value is an event. If *positions* is a 2D array-like, each 1096 row corresponds to a row or a column of lines (depending on the 1097 *orientation* parameter). 1098 1099 orientation : {'horizontal', 'vertical'}, optional 1100 Controls the direction of the event collections: 1101 1102 - 'horizontal' : the lines are arranged horizontally in rows, 1103 and are vertical. 1104 - 'vertical' : the lines are arranged vertically in columns, 1105 and are horizontal. 1106 1107 lineoffsets : scalar or sequence of scalars, optional, default: 1 1108 The offset of the center of the lines from the origin, in the 1109 direction orthogonal to *orientation*. 1110 1111 linelengths : scalar or sequence of scalars, optional, default: 1 1112 The total height of the lines (i.e. the lines stretches from 1113 ``lineoffset - linelength/2`` to ``lineoffset + linelength/2``). 1114 1115 linewidths : scalar, scalar sequence or None, optional, default: None 1116 The line width(s) of the event lines, in points. If it is None, 1117 defaults to its rcParams setting. 1118 1119 colors : color, sequence of colors or None, optional, default: None 1120 The color(s) of the event lines. If it is None, defaults to its 1121 rcParams setting. 1122 1123 linestyles : str or tuple or a sequence of such values, optional 1124 Default is 'solid'. Valid strings are ['solid', 'dashed', 1125 'dashdot', 'dotted', '-', '--', '-.', ':']. Dash tuples 1126 should be of the form:: 1127 1128 (offset, onoffseq), 1129 1130 where *onoffseq* is an even length tuple of on and off ink 1131 in points. 1132 1133 **kwargs : optional 1134 Other keyword arguments are line collection properties. See 1135 :class:`~matplotlib.collections.LineCollection` for a list of 1136 the valid properties. 1137 1138 Returns 1139 ------- 1140 1141 list : A list of :class:`~.collections.EventCollection` objects. 1142 Contains the :class:`~.collections.EventCollection` that 1143 were added. 1144 1145 Notes 1146 ----- 1147 1148 For *linelengths*, *linewidths*, *colors*, and *linestyles*, if only 1149 a single value is given, that value is applied to all lines. If an 1150 array-like is given, it must have the same length as *positions*, and 1151 each value will be applied to the corresponding row of the array. 1152 1153 Examples 1154 -------- 1155 1156 .. plot:: gallery/lines_bars_and_markers/eventplot_demo.py 1157 """ 1158 self._process_unit_info(xdata=positions, 1159 ydata=[lineoffsets, linelengths], 1160 kwargs=kwargs) 1161 1162 # We do the conversion first since not all unitized data is uniform 1163 positions = self.convert_xunits(positions) 1164 lineoffsets = self.convert_yunits(lineoffsets) 1165 linelengths = self.convert_yunits(linelengths) 1166 1167 if not iterable(positions): 1168 positions = [positions] 1169 elif any(iterable(position) for position in positions): 1170 positions = [np.asanyarray(position) for position in positions] 1171 else: 1172 positions = [np.asanyarray(positions)] 1173 1174 if len(positions) == 0: 1175 return [] 1176 1177 # prevent 'singular' keys from **kwargs dict from overriding the effect 1178 # of 'plural' keyword arguments (e.g. 'color' overriding 'colors') 1179 colors = cbook.local_over_kwdict(colors, kwargs, 'color') 1180 linewidths = cbook.local_over_kwdict(linewidths, kwargs, 'linewidth') 1181 linestyles = cbook.local_over_kwdict(linestyles, kwargs, 'linestyle') 1182 1183 if not iterable(lineoffsets): 1184 lineoffsets = [lineoffsets] 1185 if not iterable(linelengths): 1186 linelengths = [linelengths] 1187 if not iterable(linewidths): 1188 linewidths = [linewidths] 1189 if not iterable(colors): 1190 colors = [colors] 1191 if hasattr(linestyles, 'lower') or not iterable(linestyles): 1192 linestyles = [linestyles] 1193 1194 lineoffsets = np.asarray(lineoffsets) 1195 linelengths = np.asarray(linelengths) 1196 linewidths = np.asarray(linewidths) 1197 1198 if len(lineoffsets) == 0: 1199 lineoffsets = [None] 1200 if len(linelengths) == 0: 1201 linelengths = [None] 1202 if len(linewidths) == 0: 1203 lineoffsets = [None] 1204 if len(linewidths) == 0: 1205 lineoffsets = [None] 1206 if len(colors) == 0: 1207 colors = [None] 1208 try: 1209 # Early conversion of the colors into RGBA values to take care 1210 # of cases like colors='0.5' or colors='C1'. (Issue #8193) 1211 colors = mcolors.to_rgba_array(colors) 1212 except ValueError: 1213 # Will fail if any element of *colors* is None. But as long 1214 # as len(colors) == 1 or len(positions), the rest of the 1215 # code should process *colors* properly. 1216 pass 1217 1218 if len(lineoffsets) == 1 and len(positions) != 1: 1219 lineoffsets = np.tile(lineoffsets, len(positions)) 1220 lineoffsets[0] = 0 1221 lineoffsets = np.cumsum(lineoffsets) 1222 if len(linelengths) == 1: 1223 linelengths = np.tile(linelengths, len(positions)) 1224 if len(linewidths) == 1: 1225 linewidths = np.tile(linewidths, len(positions)) 1226 if len(colors) == 1: 1227 colors = list(colors) 1228 colors = colors * len(positions) 1229 if len(linestyles) == 1: 1230 linestyles = [linestyles] * len(positions) 1231 1232 if len(lineoffsets) != len(positions): 1233 raise ValueError('lineoffsets and positions are unequal sized ' 1234 'sequences') 1235 if len(linelengths) != len(positions): 1236 raise ValueError('linelengths and positions are unequal sized ' 1237 'sequences') 1238 if len(linewidths) != len(positions): 1239 raise ValueError('linewidths and positions are unequal sized ' 1240 'sequences') 1241 if len(colors) != len(positions): 1242 raise ValueError('colors and positions are unequal sized ' 1243 'sequences') 1244 if len(linestyles) != len(positions): 1245 raise ValueError('linestyles and positions are unequal sized ' 1246 'sequences') 1247 1248 colls = [] 1249 for position, lineoffset, linelength, linewidth, color, linestyle in \ 1250 zip(positions, lineoffsets, linelengths, linewidths, 1251 colors, linestyles): 1252 coll = mcoll.EventCollection(position, 1253 orientation=orientation, 1254 lineoffset=lineoffset, 1255 linelength=linelength, 1256 linewidth=linewidth, 1257 color=color, 1258 linestyle=linestyle) 1259 self.add_collection(coll, autolim=False) 1260 coll.update(kwargs) 1261 colls.append(coll) 1262 1263 if len(positions) > 0: 1264 # try to get min/max 1265 min_max = [(np.min(_p), np.max(_p)) for _p in positions 1266 if len(_p) > 0] 1267 # if we have any non-empty positions, try to autoscale 1268 if len(min_max) > 0: 1269 mins, maxes = zip(*min_max) 1270 minpos = np.min(mins) 1271 maxpos = np.max(maxes) 1272 1273 minline = (lineoffsets - linelengths).min() 1274 maxline = (lineoffsets + linelengths).max() 1275 1276 if (orientation is not None and 1277 orientation.lower() == "vertical"): 1278 corners = (minline, minpos), (maxline, maxpos) 1279 else: # "horizontal", None or "none" (see EventCollection) 1280 corners = (minpos, minline), (maxpos, maxline) 1281 self.update_datalim(corners) 1282 self.autoscale_view() 1283 1284 return colls 1285 1286 # ### Basic plotting 1287 # The label_naming happens in `matplotlib.axes._base._plot_args` 1288 @_preprocess_data(replace_names=["x", "y"], 1289 positional_parameter_names=_plot_args_replacer, 1290 label_namer=None) 1291 @docstring.dedent_interpd 1292 def plot(self, *args, **kwargs): 1293 """ 1294 Plot y versus x as lines and/or markers. 1295 1296 Call signatures:: 1297 1298 plot([x], y, [fmt], data=None, **kwargs) 1299 plot([x], y, [fmt], [x2], y2, [fmt2], ..., **kwargs) 1300 1301 The coordinates of the points or line nodes are given by *x*, *y*. 1302 1303 The optional parameter *fmt* is a convenient way for defining basic 1304 formatting like color, marker and linestyle. It's a shortcut string 1305 notation described in the *Notes* section below. 1306 1307 >>> plot(x, y) # plot x and y using default line style and color 1308 >>> plot(x, y, 'bo') # plot x and y using blue circle markers 1309 >>> plot(y) # plot y using x as index array 0..N-1 1310 >>> plot(y, 'r+') # ditto, but with red plusses 1311 1312 You can use `.Line2D` properties as keyword arguments for more 1313 control on the appearance. Line properties and *fmt* can be mixed. 1314 The following two calls yield identical results: 1315 1316 >>> plot(x, y, 'go--', linewidth=2, markersize=12) 1317 >>> plot(x, y, color='green', marker='o', linestyle='dashed', 1318 linewidth=2, markersize=12) 1319 1320 When conflicting with *fmt*, keyword arguments take precedence. 1321 1322 **Plotting labelled data** 1323 1324 There's a convenient way for plotting objects with labelled data (i.e. 1325 data that can be accessed by index ``obj['y']``). Instead of giving 1326 the data in *x* and *y*, you can provide the object in the *data* 1327 parameter and just give the labels for *x* and *y*:: 1328 1329 >>> plot('xlabel', 'ylabel', data=obj) 1330 1331 All indexable objects are supported. This could e.g. be a `dict`, a 1332 `pandas.DataFame` or a structured numpy array. 1333 1334 1335 **Plotting multiple sets of data** 1336 1337 There are various ways to plot multiple sets of data. 1338 1339 - The most straight forward way is just to call `plot` multiple times. 1340 Example: 1341 1342 >>> plot(x1, y1, 'bo') 1343 >>> plot(x2, y2, 'go') 1344 1345 - Alternatively, if your data is already a 2d array, you can pass it 1346 directly to *x*, *y*. A separate data set will be drawn for every 1347 column. 1348 1349 Example: an array ``a`` where the first column represents the *x* 1350 values and the other columns are the *y* columns:: 1351 1352 >>> plot(a[0], a[1:]) 1353 1354 - The third way is to specify multiple sets of *[x]*, *y*, *[fmt]* 1355 groups:: 1356 1357 >>> plot(x1, y1, 'g^', x2, y2, 'g-') 1358 1359 In this case, any additional keyword argument applies to all 1360 datasets. Also this syntax cannot be combined with the *data* 1361 parameter. 1362 1363 By default, each line is assigned a different style specified by a 1364 'style cycle'. The *fmt* and line property parameters are only 1365 necessary if you want explicit deviations from these defaults. 1366 Alternatively, you can also change the style cycle using the 1367 'axes.prop_cycle' rcParam. 1368 1369 Parameters 1370 ---------- 1371 x, y : array-like or scalar 1372 The horizontal / vertical coordinates of the data points. 1373 *x* values are optional. If not given, they default to 1374 ``[0, ..., N-1]``. 1375 1376 Commonly, these parameters are arrays of length N. However, 1377 scalars are supported as well (equivalent to an array with 1378 constant value). 1379 1380 The parameters can also be 2-dimensional. Then, the columns 1381 represent separate data sets. 1382 1383 fmt : str, optional 1384 A format string, e.g. 'ro' for red circles. See the *Notes* 1385 section for a full description of the format strings. 1386 1387 Format strings are just an abbreviation for quickly setting 1388 basic line properties. All of these and more can also be 1389 controlled by keyword arguments. 1390 1391 data : indexable object, optional 1392 An object with labelled data. If given, provide the label names to 1393 plot in *x* and *y*. 1394 1395 .. note:: 1396 Technically there's a slight ambiguity in calls where the 1397 second label is a valid *fmt*. `plot('n', 'o', data=obj)` 1398 could be `plt(x, y)` or `plt(y, fmt)`. In such cases, 1399 the former interpretation is chosen, but a warning is issued. 1400 You may suppress the warning by adding an empty format string 1401 `plot('n', 'o', '', data=obj)`. 1402 1403 1404 Other Parameters 1405 ---------------- 1406 scalex, scaley : bool, optional, default: True 1407 These parameters determined if the view limits are adapted to 1408 the data limits. The values are passed on to `autoscale_view`. 1409 1410 **kwargs : `.Line2D` properties, optional 1411 *kwargs* are used to specify properties like a line label (for 1412 auto legends), linewidth, antialiasing, marker face color. 1413 Example:: 1414 1415 >>> plot([1,2,3], [1,2,3], 'go-', label='line 1', linewidth=2) 1416 >>> plot([1,2,3], [1,4,9], 'rs', label='line 2') 1417 1418 If you make multiple lines with one plot command, the kwargs 1419 apply to all those lines. 1420 1421 Here is a list of available `.Line2D` properties: 1422 1423 %(Line2D)s 1424 1425 Returns 1426 ------- 1427 lines 1428 A list of `.Line2D` objects representing the plotted data. 1429 1430 1431 See Also 1432 -------- 1433 scatter : XY scatter plot with markers of variing size and/or color ( 1434 sometimes also called bubble chart). 1435 1436 1437 Notes 1438 ----- 1439 **Format Strings** 1440 1441 A format string consists of a part for color, marker and line:: 1442 1443 fmt = '[color][marker][line]' 1444 1445 Each of them is optional. If not provided, the value from the style 1446 cycle is used. Exception: If ``line`` is given, but no ``marker``, 1447 the data will be a line without markers. 1448 1449 **Colors** 1450 1451 The following color abbreviations are supported: 1452 1453 ============= =============================== 1454 character color 1455 ============= =============================== 1456 ``'b'`` blue 1457 ``'g'`` green 1458 ``'r'`` red 1459 ``'c'`` cyan 1460 ``'m'`` magenta 1461 ``'y'`` yellow 1462 ``'k'`` black 1463 ``'w'`` white 1464 ============= =============================== 1465 1466 If the color is the only part of the format string, you can 1467 additionally use any `matplotlib.colors` spec, e.g. full names 1468 (``'green'``) or hex strings (``'#008000'``). 1469 1470 **Markers** 1471 1472 ============= =============================== 1473 character description 1474 ============= =============================== 1475 ``'.'`` point marker 1476 ``','`` pixel marker 1477 ``'o'`` circle marker 1478 ``'v'`` triangle_down marker 1479 ``'^'`` triangle_up marker 1480 ``'<'`` triangle_left marker 1481 ``'>'`` triangle_right marker 1482 ``'1'`` tri_down marker 1483 ``'2'`` tri_up marker 1484 ``'3'`` tri_left marker 1485 ``'4'`` tri_right marker 1486 ``'s'`` square marker 1487 ``'p'`` pentagon marker 1488 ``'*'`` star marker 1489 ``'h'`` hexagon1 marker 1490 ``'H'`` hexagon2 marker 1491 ``'+'`` plus marker 1492 ``'x'`` x marker 1493 ``'D'`` diamond marker 1494 ``'d'`` thin_diamond marker 1495 ``'|'`` vline marker 1496 ``'_'`` hline marker 1497 ============= =============================== 1498 1499 **Line Styles** 1500 1501 ============= =============================== 1502 character description 1503 ============= =============================== 1504 ``'-'`` solid line style 1505 ``'--'`` dashed line style 1506 ``'-.'`` dash-dot line style 1507 ``':'`` dotted line style 1508 ============= =============================== 1509 1510 Example format strings:: 1511 1512 'b' # blue markers with default shape 1513 'ro' # red circles 1514 'g-' # green solid line 1515 '--' # dashed line with default color 1516 'k^:' # black triangle_up markers connected by a dotted line 1517 1518 """ 1519 scalex = kwargs.pop('scalex', True) 1520 scaley = kwargs.pop('scaley', True) 1521 1522 if not self._hold: 1523 self.cla() 1524 lines = [] 1525 1526 kwargs = cbook.normalize_kwargs(kwargs, _alias_map) 1527 1528 for line in self._get_lines(*args, **kwargs): 1529 self.add_line(line) 1530 lines.append(line) 1531 1532 self.autoscale_view(scalex=scalex, scaley=scaley) 1533 return lines 1534 1535 @_preprocess_data(replace_names=["x", "y"], label_namer="y") 1536 @docstring.dedent_interpd 1537 def plot_date(self, x, y, fmt='o', tz=None, xdate=True, ydate=False, 1538 **kwargs): 1539 """ 1540 Plot data that contains dates. 1541 1542 Similar to `.plot`, this plots *y* vs. *x* as lines or markers. 1543 However, the axis labels are formatted as dates depending on *xdate* 1544 and *ydate*. 1545 1546 Parameters 1547 ---------- 1548 x, y : array-like 1549 The coordinates of the data points. If *xdate* or *ydate* is 1550 *True*, the respective values *x* or *y* are interpreted as 1551 :ref:`Matplotlib dates <date-format>`. 1552 1553 fmt : str, optional 1554 The plot format string. For details, see the corresponding 1555 parameter in `.plot`. 1556 1557 tz : [ *None* | timezone string | :class:`tzinfo` instance] 1558 The time zone to use in labeling dates. If *None*, defaults to 1559 rcParam ``timezone``. 1560 1561 xdate : bool, optional, default: True 1562 If *True*, the *x*-axis will be interpreted as Matplotlib dates. 1563 1564 ydate : bool, optional, default: False 1565 If *True*, the *y*-axis will be interpreted as Matplotlib dates. 1566 1567 1568 Returns 1569 ------- 1570 lines 1571 A list of `~.Line2D` objects representing the plotted data. 1572 1573 1574 Other Parameters 1575 ---------------- 1576 **kwargs 1577 Keyword arguments control the :class:`~matplotlib.lines.Line2D` 1578 properties: 1579 1580 %(Line2D)s 1581 1582 1583 See Also 1584 -------- 1585 matplotlib.dates : Helper functions on dates. 1586 matplotlib.dates.date2num : Convert dates to num. 1587 matplotlib.dates.num2date : Convert num to dates. 1588 matplotlib.dates.drange : Create an equally spaced sequence of dates. 1589 1590 1591 Notes 1592 ----- 1593 If you are using custom date tickers and formatters, it may be 1594 necessary to set the formatters/locators after the call to 1595 `.plot_date`. `.plot_date` will set the default tick locator to 1596 `.AutoDateLocator` (if the tick locator is not already set to a 1597 `.DateLocator` instance) and the default tick formatter to 1598 `.AutoDateFormatter` (if the tick formatter is not already set to a 1599 `.DateFormatter` instance). 1600 """ 1601 1602 if not self._hold: 1603 self.cla() 1604 1605 if xdate: 1606 self.xaxis_date(tz) 1607 if ydate: 1608 self.yaxis_date(tz) 1609 1610 ret = self.plot(x, y, fmt, **kwargs) 1611 1612 self.autoscale_view() 1613 1614 return ret 1615 1616 # @_preprocess_data() # let 'plot' do the unpacking.. 1617 @docstring.dedent_interpd 1618 def loglog(self, *args, **kwargs): 1619 """ 1620 Make a plot with log scaling on both the x and y axis. 1621 1622 Call signatures:: 1623 1624 loglog([x], y, [fmt], data=None, **kwargs) 1625 loglog([x], y, [fmt], [x2], y2, [fmt2], ..., **kwargs) 1626 1627 This is just a thin wrapper around `.plot` which additionally changes 1628 both the x-axis and the y-axis to log scaling. All of the concepts and 1629 parameters of plot can be used here as well. 1630 1631 The additional parameters *basex/y*, *subsx/y* and *nonposx/y* control 1632 the x/y-axis properties. They are just forwarded to `.Axes.set_xscale` 1633 and `.Axes.set_yscale`. 1634 1635 Parameters 1636 ---------- 1637 basex, basey : scalar, optional, default 10 1638 Base of the x/y logarithm. 1639 1640 subsx, subsy : sequence, optional 1641 The location of the minor x/y ticks. If *None*, reasonable 1642 locations are automatically chosen depending on the number of 1643 decades in the plot. 1644 See `.Axes.set_xscale` / `.Axes.set_yscale` for details. 1645 1646 nonposx, nonposy : {'mask', 'clip'}, optional, default 'mask' 1647 Non-positive values in x or y can be masked as invalid, or clipped 1648 to a very small positive number. 1649 1650 Returns 1651 ------- 1652 lines 1653 A list of `~.Line2D` objects representing the plotted data. 1654 1655 Other Parameters 1656 ---------------- 1657 **kwargs 1658 All parameters supported by `.plot`. 1659 """ 1660 if not self._hold: 1661 self.cla() 1662 1663 dx = {k: kwargs.pop(k) for k in ['basex', 'subsx', 'nonposx'] 1664 if k in kwargs} 1665 dy = {k: kwargs.pop(k) for k in ['basey', 'subsy', 'nonposy'] 1666 if k in kwargs} 1667 1668 self.set_xscale('log', **dx) 1669 self.set_yscale('log', **dy) 1670 1671 b = self._hold 1672 self._hold = True # we've already processed the hold 1673 l = self.plot(*args, **kwargs) 1674 self._hold = b # restore the hold 1675 1676 return l 1677 1678 # @_preprocess_data() # let 'plot' do the unpacking.. 1679 @docstring.dedent_interpd 1680 def semilogx(self, *args, **kwargs): 1681 """ 1682 Make a plot with log scaling on the x axis. 1683 1684 Call signatures:: 1685 1686 semilogx([x], y, [fmt], data=None, **kwargs) 1687 semilogx([x], y, [fmt], [x2], y2, [fmt2], ..., **kwargs) 1688 1689 This is just a thin wrapper around `.plot` which additionally changes 1690 the x-axis to log scaling. All of the concepts and parameters of plot 1691 can be used here as well. 1692 1693 The additional parameters *basex*, *subsx* and *nonposx* control the 1694 x-axis properties. They are just forwarded to `.Axes.set_xscale`. 1695 1696 Parameters 1697 ---------- 1698 basex : scalar, optional, default 10 1699 Base of the x logarithm. 1700 1701 subsx : array_like, optional 1702 The location of the minor xticks. If *None*, reasonable locations 1703 are automatically chosen depending on the number of decades in the 1704 plot. See `.Axes.set_xscale` for details. 1705 1706 nonposx : {'mask', 'clip'}, optional, default 'mask' 1707 Non-positive values in x can be masked as invalid, or clipped to a 1708 very small positive number. 1709 1710 Returns 1711 ------- 1712 lines 1713 A list of `~.Line2D` objects representing the plotted data. 1714 1715 Other Parameters 1716 ---------------- 1717 **kwargs 1718 All parameters supported by `.plot`. 1719 """ 1720 if not self._hold: 1721 self.cla() 1722 d = {k: kwargs.pop(k) for k in ['basex', 'subsx', 'nonposx'] 1723 if k in kwargs} 1724 1725 self.set_xscale('log', **d) 1726 b = self._hold 1727 self._hold = True # we've already processed the hold 1728 l = self.plot(*args, **kwargs) 1729 self._hold = b # restore the hold 1730 return l 1731 1732 # @_preprocess_data() # let 'plot' do the unpacking.. 1733 @docstring.dedent_interpd 1734 def semilogy(self, *args, **kwargs): 1735 """ 1736 Make a plot with log scaling on the y axis. 1737 1738 Call signatures:: 1739 1740 semilogy([x], y, [fmt], data=None, **kwargs) 1741 semilogy([x], y, [fmt], [x2], y2, [fmt2], ..., **kwargs) 1742 1743 This is just a thin wrapper around `.plot` which additionally changes 1744 the y-axis to log scaling. All of the concepts and parameters of plot 1745 can be used here as well. 1746 1747 The additional parameters *basey*, *subsy* and *nonposy* control the 1748 y-axis properties. They are just forwarded to `.Axes.set_yscale`. 1749 1750 Parameters 1751 ---------- 1752 basey : scalar, optional, default 10 1753 Base of the y logarithm. 1754 1755 subsy : array_like, optional 1756 The location of the minor yticks. If *None*, reasonable locations 1757 are automatically chosen depending on the number of decades in the 1758 plot. See `.Axes.set_yscale` for details. 1759 1760 nonposy : {'mask', 'clip'}, optional, default 'mask' 1761 Non-positive values in y can be masked as invalid, or clipped to a 1762 very small positive number. 1763 1764 Returns 1765 ------- 1766 lines 1767 A list of `~.Line2D` objects representing the plotted data. 1768 1769 Other Parameters 1770 ---------------- 1771 **kwargs 1772 All parameters supported by `.plot`. 1773 """ 1774 if not self._hold: 1775 self.cla() 1776 d = {k: kwargs.pop(k) for k in ['basey', 'subsy', 'nonposy'] 1777 if k in kwargs} 1778 self.set_yscale('log', **d) 1779 b = self._hold 1780 self._hold = True # we've already processed the hold 1781 l = self.plot(*args, **kwargs) 1782 self._hold = b # restore the hold 1783 1784 return l 1785 1786 @_preprocess_data(replace_names=["x"], label_namer="x") 1787 def acorr(self, x, **kwargs): 1788 """ 1789 Plot the autocorrelation of *x*. 1790 1791 Parameters 1792 ---------- 1793 1794 x : sequence of scalar 1795 1796 hold : bool, optional, *deprecated*, default: True 1797 1798 detrend : callable, optional, default: `mlab.detrend_none` 1799 *x* is detrended by the *detrend* callable. Default is no 1800 normalization. 1801 1802 normed : bool, optional, default: True 1803 If ``True``, input vectors are normalised to unit length. 1804 1805 usevlines : bool, optional, default: True 1806 If ``True``, `Axes.vlines` is used to plot the vertical lines from 1807 the origin to the acorr. Otherwise, `Axes.plot` is used. 1808 1809 maxlags : integer, optional, default: 10 1810 Number of lags to show. If ``None``, will return all 1811 ``2 * len(x) - 1`` lags. 1812 1813 Returns 1814 ------- 1815 lags : array (lenth ``2*maxlags+1``) 1816 lag vector. 1817 c : array (length ``2*maxlags+1``) 1818 auto correlation vector. 1819 line : `.LineCollection` or `.Line2D` 1820 `.Artist` added to the axes of the correlation. 1821 1822 `.LineCollection` if *usevlines* is True 1823 `.Line2D` if *usevlines* is False 1824 b : `.Line2D` or None 1825 Horizontal line at 0 if *usevlines* is True 1826 None *usevlines* is False 1827 1828 Other Parameters 1829 ---------------- 1830 linestyle : `~matplotlib.lines.Line2D` prop, optional, default: None 1831 Only used if usevlines is ``False``. 1832 1833 marker : string, optional, default: 'o' 1834 1835 Notes 1836 ----- 1837 The cross correlation is performed with :func:`numpy.correlate` with 1838 ``mode = 2``. 1839 """ 1840 if "hold" in kwargs: 1841 warnings.warn("the 'hold' kwarg is deprecated", mplDeprecation) 1842 return self.xcorr(x, x, **kwargs) 1843 1844 @_preprocess_data(replace_names=["x", "y"], label_namer="y") 1845 def xcorr(self, x, y, normed=True, detrend=mlab.detrend_none, 1846 usevlines=True, maxlags=10, **kwargs): 1847 r""" 1848 Plot the cross correlation between *x* and *y*. 1849 1850 The correlation with lag k is defined as sum_n x[n+k] * conj(y[n]). 1851 1852 Parameters 1853 ---------- 1854 x : sequence of scalars of length n 1855 1856 y : sequence of scalars of length n 1857 1858 hold : bool, optional, *deprecated*, default: True 1859 1860 detrend : callable, optional, default: `mlab.detrend_none` 1861 *x* is detrended by the *detrend* callable. Default is no 1862 normalization. 1863 1864 normed : bool, optional, default: True 1865 If ``True``, input vectors are normalised to unit length. 1866 1867 usevlines : bool, optional, default: True 1868 If ``True``, `Axes.vlines` is used to plot the vertical lines from 1869 the origin to the acorr. Otherwise, `Axes.plot` is used. 1870 1871 maxlags : int, optional 1872 Number of lags to show. If None, will return all ``2 * len(x) - 1`` 1873 lags. Default is 10. 1874 1875 Returns 1876 ------- 1877 lags : array (lenth ``2*maxlags+1``) 1878 lag vector. 1879 c : array (length ``2*maxlags+1``) 1880 auto correlation vector. 1881 line : `.LineCollection` or `.Line2D` 1882 `.Artist` added to the axes of the correlation 1883 1884 `.LineCollection` if *usevlines* is True 1885 `.Line2D` if *usevlines* is False 1886 b : `.Line2D` or None 1887 Horizontal line at 0 if *usevlines* is True 1888 None *usevlines* is False 1889 1890 Other Parameters 1891 ---------------- 1892 linestyle : `~matplotlib.lines.Line2D` property, optional 1893 Only used if usevlines is ``False``. 1894 1895 marker : string, optional 1896 Default is 'o'. 1897 1898 Notes 1899 ----- 1900 The cross correlation is performed with :func:`numpy.correlate` with 1901 ``mode = 2``. 1902 """ 1903 if "hold" in kwargs: 1904 warnings.warn("the 'hold' kwarg is deprecated", mplDeprecation) 1905 1906 Nx = len(x) 1907 if Nx != len(y): 1908 raise ValueError('x and y must be equal length') 1909 1910 x = detrend(np.asarray(x)) 1911 y = detrend(np.asarray(y)) 1912 1913 correls = np.correlate(x, y, mode=2) 1914 1915 if normed: 1916 correls /= np.sqrt(np.dot(x, x) * np.dot(y, y)) 1917 1918 if maxlags is None: 1919 maxlags = Nx - 1 1920 1921 if maxlags >= Nx or maxlags < 1: 1922 raise ValueError('maxlags must be None or strictly ' 1923 'positive < %d' % Nx) 1924 1925 lags = np.arange(-maxlags, maxlags + 1) 1926 correls = correls[Nx - 1 - maxlags:Nx + maxlags] 1927 1928 if usevlines: 1929 a = self.vlines(lags, [0], correls, **kwargs) 1930 # Make label empty so only vertical lines get a legend entry 1931 kwargs.pop('label', '') 1932 b = self.axhline(**kwargs) 1933 else: 1934 kwargs.setdefault('marker', 'o') 1935 kwargs.setdefault('linestyle', 'None') 1936 a, = self.plot(lags, correls, **kwargs) 1937 b = None 1938 return lags, correls, a, b 1939 1940 #### Specialized plotting 1941 1942 @_preprocess_data(replace_names=["x", "y"], label_namer="y") 1943 def step(self, x, y, *args, **kwargs): 1944 """ 1945 Make a step plot. 1946 1947 Call signatures:: 1948 1949 step(x, y, [fmt], *, data=None, where='pre', **kwargs) 1950 step(x, y, [fmt], x2, y2, [fmt2], ..., *, where='pre', **kwargs) 1951 1952 This is just a thin wrapper around `.plot` which changes some 1953 formatting options. Most of the concepts and parameters of plot can be 1954 used here as well. 1955 1956 Parameters 1957 ---------- 1958 x : array_like 1959 1-D sequence of x positions. It is assumed, but not checked, that 1960 it is uniformly increasing. 1961 1962 y : array_like 1963 1-D sequence of y levels. 1964 1965 fmt : str, optional 1966 A format string, e.g. 'g' for a green line. See `.plot` for a more 1967 detailed description. 1968 1969 Note: While full format strings are accepted, it is recommended to 1970 only specify the color. Line styles are currently ignored (use 1971 the keyword argument *linestyle* instead). Markers are accepted 1972 and plotted on the given positions, however, this is a rarely 1973 needed feature for step plots. 1974 1975 data : indexable object, optional 1976 An object with labelled data. If given, provide the label names to 1977 plot in *x* and *y*. 1978 1979 where : {'pre', 'post', 'mid'}, optional, default 'pre' 1980 Define where the steps should be placed: 1981 1982 - 'pre': The y value is continued constantly to the left from 1983 every *x* position, i.e. the interval ``(x[i-1], x[i]]`` has the 1984 value ``y[i]``. 1985 - 'post': The y value is continued constantly to the right from 1986 every *x* position, i.e. the interval ``[x[i], x[i+1])`` has the 1987 value ``y[i]``. 1988 - 'mid': Steps occur half-way between the *x* positions. 1989 1990 Returns 1991 ------- 1992 lines 1993 A list of `.Line2D` objects representing the plotted data. 1994 1995 Other Parameters 1996 ---------------- 1997 **kwargs 1998 Additional parameters are the same as those for `.plot`. 1999 2000 Notes 2001 ----- 2002 .. [notes section required to get data note injection right] 2003 """ 2004 where = kwargs.pop('where', 'pre') 2005 if where not in ('pre', 'post', 'mid'): 2006 raise ValueError("'where' argument to step must be " 2007 "'pre', 'post' or 'mid'") 2008 usr_linestyle = kwargs.pop('linestyle', '') 2009 kwargs['linestyle'] = 'steps-' + where + usr_linestyle 2010 2011 return self.plot(x, y, *args, **kwargs) 2012 2013 @_preprocess_data(replace_names=["x", "left", 2014 "height", "width", 2015 "y", "bottom", 2016 "color", "edgecolor", "linewidth", 2017 "tick_label", "xerr", "yerr", 2018 "ecolor"], 2019 label_namer=None, 2020 replace_all_args=True 2021 ) 2022 @docstring.dedent_interpd 2023 def bar(self, *args, **kwargs): 2024 r""" 2025 Make a bar plot. 2026 2027 Call signatures:: 2028 2029 bar(x, height, *, align='center', **kwargs) 2030 bar(x, height, width, *, align='center', **kwargs) 2031 bar(x, height, width, bottom, *, align='center', **kwargs) 2032 2033 The bars are positioned at *x* with the given *align* ment. Their 2034 dimensions are given by *width* and *height*. The vertical baseline 2035 is *bottom* (default 0). 2036 2037 Each of *x*, *height*, *width*, and *bottom* may either be a scalar 2038 applying to all bars, or it may be a sequence of length N providing a 2039 separate value for each bar. 2040 2041 2042 Parameters 2043 ---------- 2044 x : sequence of scalars 2045 The x coordinates of the bars. See also *align* for the 2046 alignment of the bars to the coordinates. 2047 2048 height : scalar or sequence of scalars 2049 The height(s) of the bars. 2050 2051 width : scalar or array-like, optional 2052 The width(s) of the bars (default: 0.8). 2053 2054 bottom : scalar or array-like, optional 2055 The y coordinate(s) of the bars bases (default: 0). 2056 2057 align : {'center', 'edge'}, optional, default: 'center' 2058 Alignment of the bars to the *x* coordinates: 2059 2060 - 'center': Center the base on the *x* positions. 2061 - 'edge': Align the left edges of the bars with the *x* positions. 2062 2063 To align the bars on the right edge pass a negative *width* and 2064 ``align='edge'``. 2065 2066 Returns 2067 ------- 2068 container : `.BarContainer` 2069 Container with all the bars and optionally errorbars. 2070 2071 Other Parameters 2072 ---------------- 2073 color : scalar or array-like, optional 2074 The colors of the bar faces. 2075 2076 edgecolor : scalar or array-like, optional 2077 The colors of the bar edges. 2078 2079 linewidth : scalar or array-like, optional 2080 Width of the bar edge(s). If 0, don't draw edges. 2081 2082 tick_label : string or array-like, optional 2083 The tick labels of the bars. 2084 Default: None (Use default numeric labels.) 2085 2086 xerr, yerr : scalar or array-like of shape(N,) or shape(2,N), optional 2087 If not *None*, add horizontal / vertical errorbars to the bar tips. 2088 The values are +/- sizes relative to the data: 2089 2090 - scalar: symmetric +/- values for all bars 2091 - shape(N,): symmetric +/- values for each bar 2092 - shape(2,N): Separate - and + values for each bar. First row 2093 contains the lower errors, the second row contains the 2094 upper errors. 2095 - *None*: No errorbar. (Default) 2096 2097 See :doc:`/gallery/statistics/errorbar_features` 2098 for an example on the usage of ``xerr`` and ``yerr``. 2099 2100 ecolor : scalar or array-like, optional, default: 'black' 2101 The line color of the errorbars. 2102 2103 capsize : scalar, optional 2104 The length of the error bar caps in points. 2105 Default: None, which will take the value from 2106 :rc:`errorbar.capsize`. 2107 2108 error_kw : dict, optional 2109 Dictionary of kwargs to be passed to the `~.Axes.errorbar` 2110 method. Values of *ecolor* or *capsize* defined here take 2111 precedence over the independent kwargs. 2112 2113 log : bool, optional, default: False 2114 If *True*, set the y-axis to be log scale. 2115 2116 orientation : {'vertical', 'horizontal'}, optional 2117 *This is for internal use only.* Please use `barh` for 2118 horizontal bar plots. Default: 'vertical'. 2119 2120 See also 2121 -------- 2122 barh: Plot a horizontal bar plot. 2123 2124 Notes 2125 ----- 2126 The optional arguments *color*, *edgecolor*, *linewidth*, 2127 *xerr*, and *yerr* can be either scalars or sequences of 2128 length equal to the number of bars. This enables you to use 2129 bar as the basis for stacked bar charts, or candlestick plots. 2130 Detail: *xerr* and *yerr* are passed directly to 2131 :meth:`errorbar`, so they can also have shape 2xN for 2132 independent specification of lower and upper errors. 2133 2134 Other optional kwargs: 2135 2136 %(Rectangle)s 2137 2138 """ 2139 kwargs = cbook.normalize_kwargs(kwargs, mpatches._patch_alias_map) 2140 # this is using the lambdas to do the arg/kwarg unpacking rather 2141 # than trying to re-implement all of that logic our selves. 2142 matchers = [ 2143 (lambda x, height, width=0.8, bottom=None, **kwargs: 2144 (False, x, height, width, bottom, kwargs)), 2145 (lambda left, height, width=0.8, bottom=None, **kwargs: 2146 (True, left, height, width, bottom, kwargs)), 2147 ] 2148 exps = [] 2149 for matcher in matchers: 2150 try: 2151 dp, x, height, width, y, kwargs = matcher(*args, **kwargs) 2152 except TypeError as e: 2153 # This can only come from a no-match as there is 2154 # no other logic in the matchers. 2155 exps.append(e) 2156 else: 2157 break 2158 else: 2159 raise exps[0] 2160 # if we matched the second-case, then the user passed in 2161 # left=val as a kwarg which we want to deprecate 2162 if dp: 2163 warnings.warn( 2164 "The *left* kwarg to `bar` is deprecated use *x* instead. " 2165 "Support for *left* will be removed in Matplotlib 3.0", 2166 mplDeprecation, stacklevel=2) 2167 if not self._hold: 2168 self.cla() 2169 color = kwargs.pop('color', None) 2170 if color is None: 2171 color = self._get_patches_for_fill.get_next_color() 2172 edgecolor = kwargs.pop('edgecolor', None) 2173 linewidth = kwargs.pop('linewidth', None) 2174 2175 # Because xerr and yerr will be passed to errorbar, 2176 # most dimension checking and processing will be left 2177 # to the errorbar method. 2178 xerr = kwargs.pop('xerr', None) 2179 yerr = kwargs.pop('yerr', None) 2180 error_kw = kwargs.pop('error_kw', dict()) 2181 ecolor = kwargs.pop('ecolor', 'k') 2182 capsize = kwargs.pop('capsize', rcParams["errorbar.capsize"]) 2183 error_kw.setdefault('ecolor', ecolor) 2184 error_kw.setdefault('capsize', capsize) 2185 2186 if rcParams['_internal.classic_mode']: 2187 align = kwargs.pop('align', 'edge') 2188 else: 2189 align = kwargs.pop('align', 'center') 2190 2191 orientation = kwargs.pop('orientation', 'vertical') 2192 log = kwargs.pop('log', False) 2193 label = kwargs.pop('label', '') 2194 tick_labels = kwargs.pop('tick_label', None) 2195 2196 adjust_ylim = False 2197 adjust_xlim = False 2198 2199 if orientation == 'vertical': 2200 if y is None: 2201 if self.get_yscale() == 'log': 2202 adjust_ylim = True 2203 y = 0 2204 2205 elif orientation == 'horizontal': 2206 if x is None: 2207 if self.get_xscale() == 'log': 2208 adjust_xlim = True 2209 x = 0 2210 2211 if orientation == 'vertical': 2212 self._process_unit_info(xdata=x, ydata=height, kwargs=kwargs) 2213 if log: 2214 self.set_yscale('log', nonposy='clip') 2215 elif orientation == 'horizontal': 2216 self._process_unit_info(xdata=width, ydata=y, kwargs=kwargs) 2217 if log: 2218 self.set_xscale('log', nonposx='clip') 2219 else: 2220 raise ValueError('invalid orientation: %s' % orientation) 2221 2222 # lets do some conversions now since some types cannot be 2223 # subtracted uniformly 2224 if self.xaxis is not None: 2225 x = self.convert_xunits(x) 2226 width = self.convert_xunits(width) 2227 if xerr is not None: 2228 xerr = self.convert_xunits(xerr) 2229 2230 if self.yaxis is not None: 2231 y = self.convert_yunits(y) 2232 height = self.convert_yunits(height) 2233 if yerr is not None: 2234 yerr = self.convert_yunits(yerr) 2235 2236 x, height, width, y, linewidth = np.broadcast_arrays( 2237 # Make args iterable too. 2238 np.atleast_1d(x), height, width, y, linewidth) 2239 2240 # Now that units have been converted, set the tick locations. 2241 if orientation == 'vertical': 2242 tick_label_axis = self.xaxis 2243 tick_label_position = x 2244 elif orientation == 'horizontal': 2245 tick_label_axis = self.yaxis 2246 tick_label_position = y 2247 2248 linewidth = itertools.cycle(np.atleast_1d(linewidth)) 2249 color = itertools.chain(itertools.cycle(mcolors.to_rgba_array(color)), 2250 # Fallback if color == "none". 2251 itertools.repeat([0, 0, 0, 0])) 2252 if edgecolor is None: 2253 edgecolor = itertools.repeat(None) 2254 else: 2255 edgecolor = itertools.chain( 2256 itertools.cycle(mcolors.to_rgba_array(edgecolor)), 2257 # Fallback if edgecolor == "none". 2258 itertools.repeat([0, 0, 0, 0])) 2259 2260 # We will now resolve the alignment and really have 2261 # left, bottom, width, height vectors 2262 if align == 'center': 2263 if orientation == 'vertical': 2264 left = x - width / 2 2265 bottom = y 2266 elif orientation == 'horizontal': 2267 bottom = y - height / 2 2268 left = x 2269 elif align == 'edge': 2270 left = x 2271 bottom = y 2272 else: 2273 raise ValueError('invalid alignment: %s' % align) 2274 2275 patches = [] 2276 args = zip(left, bottom, width, height, color, edgecolor, linewidth) 2277 for l, b, w, h, c, e, lw in args: 2278 r = mpatches.Rectangle( 2279 xy=(l, b), width=w, height=h, 2280 facecolor=c, 2281 edgecolor=e, 2282 linewidth=lw, 2283 label='_nolegend_', 2284 ) 2285 r.update(kwargs) 2286 r.get_path()._interpolation_steps = 100 2287 if orientation == 'vertical': 2288 r.sticky_edges.y.append(b) 2289 elif orientation == 'horizontal': 2290 r.sticky_edges.x.append(l) 2291 self.add_patch(r) 2292 patches.append(r) 2293 2294 holdstate = self._hold 2295 self._hold = True # ensure hold is on before plotting errorbars 2296 2297 if xerr is not None or yerr is not None: 2298 if orientation == 'vertical': 2299 # using list comps rather than arrays to preserve unit info 2300 ex = [l + 0.5 * w for l, w in zip(left, width)] 2301 ey = [b + h for b, h in zip(bottom, height)] 2302 2303 elif orientation == 'horizontal': 2304 # using list comps rather than arrays to preserve unit info 2305 ex = [l + w for l, w in zip(left, width)] 2306 ey = [b + 0.5 * h for b, h in zip(bottom, height)] 2307 2308 error_kw.setdefault("label", '_nolegend_') 2309 2310 errorbar = self.errorbar(ex, ey, 2311 yerr=yerr, xerr=xerr, 2312 fmt='none', **error_kw) 2313 else: 2314 errorbar = None 2315 2316 self._hold = holdstate # restore previous hold state 2317 2318 if adjust_xlim: 2319 xmin, xmax = self.dataLim.intervalx 2320 xmin = min(w for w in width if w > 0) 2321 if xerr is not None: 2322 xmin = xmin - np.max(xerr) 2323 xmin = max(xmin * 0.9, 1e-100) 2324 self.dataLim.intervalx = (xmin, xmax) 2325 2326 if adjust_ylim: 2327 ymin, ymax = self.dataLim.intervaly 2328 ymin = min(h for h in height if h > 0) 2329 if yerr is not None: 2330 ymin = ymin - np.max(yerr) 2331 ymin = max(ymin * 0.9, 1e-100) 2332 self.dataLim.intervaly = (ymin, ymax) 2333 self.autoscale_view() 2334 2335 bar_container = BarContainer(patches, errorbar, label=label) 2336 self.add_container(bar_container) 2337 2338 if tick_labels is not None: 2339 tick_labels = _backports.broadcast_to(tick_labels, len(patches)) 2340 tick_label_axis.set_ticks(tick_label_position) 2341 tick_label_axis.set_ticklabels(tick_labels) 2342 2343 return bar_container 2344 2345 @docstring.dedent_interpd 2346 def barh(self, *args, **kwargs): 2347 r""" 2348 Make a horizontal bar plot. 2349 2350 Call signatures:: 2351 2352 bar(y, width, *, align='center', **kwargs) 2353 bar(y, width, height, *, align='center', **kwargs) 2354 bar(y, width, height, left, *, align='center', **kwargs) 2355 2356 The bars are positioned at *y* with the given *align*. Their 2357 dimensions are given by *width* and *height*. The horizontal baseline 2358 is *left* (default 0). 2359 2360 Each of *y*, *width*, *height*, and *left* may either be a scalar 2361 applying to all bars, or it may be a sequence of length N providing a 2362 separate value for each bar. 2363 2364 2365 Parameters 2366 ---------- 2367 y : scalar or array-like 2368 The y coordinates of the bars. See also *align* for the 2369 alignment of the bars to the coordinates. 2370 2371 width : scalar or array-like 2372 The width(s) of the bars. 2373 2374 height : sequence of scalars, optional, default: 0.8 2375 The heights of the bars. 2376 2377 left : sequence of scalars 2378 The x coordinates of the left sides of the bars (default: 0). 2379 2380 align : {'center', 'edge'}, optional, default: 'center' 2381 Alignment of the base to the *y* coordinates*: 2382 2383 - 'center': Center the bars on the *y* positions. 2384 - 'edge': Align the bottom edges of the bars with the *y* 2385 positions. 2386 2387 To align the bars on the top edge pass a negative *height* and 2388 ``align='edge'``. 2389 2390 Returns 2391 ------- 2392 container : `.BarContainer` 2393 Container with all the bars and optionally errorbars. 2394 2395 Other Parameters 2396 ---------------- 2397 color : scalar or array-like, optional 2398 The colors of the bar faces. 2399 2400 edgecolor : scalar or array-like, optional 2401 The colors of the bar edges. 2402 2403 linewidth : scalar or array-like, optional 2404 Width of the bar edge(s). If 0, don't draw edges. 2405 2406 tick_label : string or array-like, optional 2407 The tick labels of the bars. 2408 Default: None (Use default numeric labels.) 2409 2410 xerr, yerr : scalar or array-like of shape(N,) or shape(2,N), optional 2411 If not ``None``, add horizontal / vertical errorbars to the 2412 bar tips. The values are +/- sizes relative to the data: 2413 2414 - scalar: symmetric +/- values for all bars 2415 - shape(N,): symmetric +/- values for each bar 2416 - shape(2,N): Separate - and + values for each bar. First row 2417 contains the lower errors, the second row contains the 2418 upper errors. 2419 - *None*: No errorbar. (default) 2420 2421 See :doc:`/gallery/statistics/errorbar_features` 2422 for an example on the usage of ``xerr`` and ``yerr``. 2423 2424 ecolor : scalar or array-like, optional, default: 'black' 2425 The line color of the errorbars. 2426 2427 capsize : scalar, optional 2428 The length of the error bar caps in points. 2429 Default: None, which will take the value from 2430 :rc:`errorbar.capsize`. 2431 2432 error_kw : dict, optional 2433 Dictionary of kwargs to be passed to the `~.Axes.errorbar` 2434 method. Values of *ecolor* or *capsize* defined here take 2435 precedence over the independent kwargs. 2436 2437 log : bool, optional, default: False 2438 If ``True``, set the x-axis to be log scale. 2439 2440 See also 2441 -------- 2442 bar: Plot a vertical bar plot. 2443 2444 Notes 2445 ----- 2446 The optional arguments *color*, *edgecolor*, *linewidth*, 2447 *xerr*, and *yerr* can be either scalars or sequences of 2448 length equal to the number of bars. This enables you to use 2449 bar as the basis for stacked bar charts, or candlestick plots. 2450 Detail: *xerr* and *yerr* are passed directly to 2451 :meth:`errorbar`, so they can also have shape 2xN for 2452 independent specification of lower and upper errors. 2453 2454 Other optional kwargs: 2455 2456 %(Rectangle)s 2457 2458 """ 2459 # this is using the lambdas to do the arg/kwarg unpacking rather 2460 # than trying to re-implement all of that logic our selves. 2461 matchers = [ 2462 (lambda y, width, height=0.8, left=None, **kwargs: 2463 (False, y, width, height, left, kwargs)), 2464 (lambda bottom, width, height=0.8, left=None, **kwargs: 2465 (True, bottom, width, height, left, kwargs)), 2466 ] 2467 excs = [] 2468 for matcher in matchers: 2469 try: 2470 dp, y, width, height, left, kwargs = matcher(*args, **kwargs) 2471 except TypeError as e: 2472 # This can only come from a no-match as there is 2473 # no other logic in the matchers. 2474 excs.append(e) 2475 else: 2476 break 2477 else: 2478 raise excs[0] 2479 2480 if dp: 2481 warnings.warn( 2482 "The *bottom* kwarg to `barh` is deprecated use *y* instead. " 2483 "Support for *bottom* will be removed in Matplotlib 3.0", 2484 mplDeprecation, stacklevel=2) 2485 kwargs.setdefault('orientation', 'horizontal') 2486 patches = self.bar(x=left, height=height, width=width, 2487 bottom=y, **kwargs) 2488 return patches 2489 2490 @_preprocess_data(label_namer=None) 2491 @docstring.dedent_interpd 2492 def broken_barh(self, xranges, yrange, **kwargs): 2493 """ 2494 Plot a horizontal sequence of rectangles. 2495 2496 A rectangle is drawn for each element of *xranges*. All rectangles 2497 have the same vertical position and size defined by *yrange*. 2498 2499 This is a convenience function for instantiating a 2500 `.BrokenBarHCollection`, adding it to the axes and autoscaling the 2501 view. 2502 2503 Parameters 2504 ---------- 2505 xranges : sequence of tuples (*xmin*, *xwidth*) 2506 The x-positions and extends of the rectangles. For each tuple 2507 (*xmin*, *xwidth*) a rectangle is drawn from *xmin* to *xmin* + 2508 *xwidth*. 2509 yranges : (*ymin*, *ymax*) 2510 The y-position and extend for all the rectangles. 2511 2512 Other Parameters 2513 ---------------- 2514 **kwargs : :class:`.BrokenBarHCollection` properties 2515 2516 Each *kwarg* can be either a single argument applying to all 2517 rectangles, e.g.:: 2518 2519 facecolors='black' 2520 2521 or a sequence of arguments over which is cycled, e.g.:: 2522 2523 facecolors=('black', 'blue') 2524 2525 would create interleaving black and blue rectangles. 2526 2527 Supported keywords: 2528 2529 %(BrokenBarHCollection)s 2530 2531 Returns 2532 ------- 2533 collection : A :class:`~.collections.BrokenBarHCollection` 2534 2535 Notes 2536 ----- 2537 .. [Notes section required for data comment. See #10189.] 2538 2539 """ 2540 # process the unit information 2541 if len(xranges): 2542 xdata = cbook.safe_first_element(xranges) 2543 else: 2544 xdata = None 2545 if len(yrange): 2546 ydata = cbook.safe_first_element(yrange) 2547 else: 2548 ydata = None 2549 self._process_unit_info(xdata=xdata, 2550 ydata=ydata, 2551 kwargs=kwargs) 2552 xranges = self.convert_xunits(xranges) 2553 yrange = self.convert_yunits(yrange) 2554 2555 col = mcoll.BrokenBarHCollection(xranges, yrange, **kwargs) 2556 self.add_collection(col, autolim=True) 2557 self.autoscale_view() 2558 2559 return col 2560 2561 @_preprocess_data(replace_all_args=True, label_namer=None) 2562 def stem(self, *args, **kwargs): 2563 """ 2564 Create a stem plot. 2565 2566 A stem plot plots vertical lines at each *x* location from the baseline 2567 to *y*, and places a marker there. 2568 2569 Call signature:: 2570 2571 stem([x,] y, linefmt=None, markerfmt=None, basefmt=None) 2572 2573 The x-positions are optional. The formats may be provided either as 2574 positional or as keyword-arguments. 2575 2576 Parameters 2577 ---------- 2578 x : array-like, optional 2579 The x-positions of the stems. Default: (0, 1, ..., len(y) - 1). 2580 2581 y : array-like 2582 The y-values of the stem heads. 2583 2584 linefmt : str, optional 2585 A string defining the properties of the vertical lines. Usually, 2586 this will be a color or a color and a linestyle: 2587 2588 ========= ============= 2589 Character Line Style 2590 ========= ============= 2591 ``'-'`` solid line 2592 ``'--'`` dashed line 2593 ``'-.'`` dash-dot line 2594 ``':'`` dotted line 2595 ========= ============= 2596 2597 Default: 'C0-', i.e. solid line with the first color of the color 2598 cycle. 2599 2600 Note: While it is technically possible to specify valid formats 2601 other than color or color and linestyle (e.g. 'rx' or '-.'), this 2602 is beyond the intention of the method and will most likely not 2603 result in a reasonable reasonable plot. 2604 2605 markerfmt : str, optional 2606 A string defining the properties of the markers at the stem heads. 2607 Default: 'C0o', i.e. filled circles with the first color of the 2608 color cycle. 2609 2610 basefmt : str, optional 2611 A format string defining the properties of the baseline. 2612 2613 Default: 'C3-' ('C2-' in classic mode). 2614 2615 bottom : float, optional, default: 0 2616 The y-position of the baseline. 2617 2618 label : str, optional, default: None 2619 The label to use for the stems in legends. 2620 2621 2622 Other Parameters 2623 ---------------- 2624 **kwargs 2625 No other parameters are supported. They are currently ignored 2626 silently for backward compatibility. This behavior is deprecated. 2627 Future versions will not accept any other parameters and will 2628 raise a TypeError instead. 2629 2630 2631 Returns 2632 ------- 2633 container : :class:`~matplotlib.container.StemContainer` 2634 The container may be treated like a tuple 2635 (*markerline*, *stemlines*, *baseline*) 2636 2637 2638 Notes 2639 ----- 2640 2641 .. seealso:: 2642 The MATLAB function 2643 `stem <http://www.mathworks.com/help/techdoc/ref/stem.html>`_ 2644 which inspired this method. 2645 2646 """ 2647 2648 # kwargs handling 2649 # We would like to have a signature with explicit kewords: 2650 # stem(*args, linefmt=None, markerfmt=None, basefmt=None, 2651 # bottom=0, label=None) 2652 # Unfortunately, this is not supported in Python 2.x. There, *args 2653 # can only exist after keyword arguments. 2654 linefmt = kwargs.pop('linefmt', None) 2655 markerfmt = kwargs.pop('markerfmt', None) 2656 basefmt = kwargs.pop('basefmt', None) 2657 bottom = kwargs.pop('bottom', None) 2658 if bottom is None: 2659 bottom = 0 2660 label = kwargs.pop('label', None) 2661 if kwargs: 2662 warn_deprecated(since='2.2', 2663 message="stem() got an unexpected keyword " 2664 "argument '%s'. This will raise a " 2665 "TypeError in future versions." % ( 2666 next(k for k in kwargs), ) 2667 ) 2668 2669 remember_hold = self._hold 2670 if not self._hold: 2671 self.cla() 2672 self._hold = True 2673 2674 # Assume there's at least one data array 2675 y = np.asarray(args[0]) 2676 args = args[1:] 2677 2678 # Try a second one 2679 try: 2680 second = np.asarray(args[0], dtype=float) 2681 x, y = y, second 2682 args = args[1:] 2683 except (IndexError, ValueError): 2684 # The second array doesn't make sense, or it doesn't exist 2685 second = np.arange(len(y)) 2686 x = second 2687 2688 # defaults for formats 2689 if linefmt is None: 2690 try: 2691 # fallback to positional argument 2692 linefmt = args[0] 2693 except IndexError: 2694 linecolor = 'C0' 2695 linemarker = 'None' 2696 linestyle = '-' 2697 else: 2698 linestyle, linemarker, linecolor = \ 2699 _process_plot_format(linefmt) 2700 else: 2701 linestyle, linemarker, linecolor = _process_plot_format(linefmt) 2702 2703 if markerfmt is None: 2704 try: 2705 # fallback to positional argument 2706 markerfmt = args[1] 2707 except IndexError: 2708 markercolor = 'C0' 2709 markermarker = 'o' 2710 markerstyle = 'None' 2711 else: 2712 markerstyle, markermarker, markercolor = \ 2713 _process_plot_format(markerfmt) 2714 else: 2715 markerstyle, markermarker, markercolor = \ 2716 _process_plot_format(markerfmt) 2717 2718 if basefmt is None: 2719 try: 2720 # fallback to positional argument 2721 basefmt = args[2] 2722 except IndexError: 2723 if rcParams['_internal.classic_mode']: 2724 basecolor = 'C2' 2725 else: 2726 basecolor = 'C3' 2727 basemarker = 'None' 2728 basestyle = '-' 2729 else: 2730 basestyle, basemarker, basecolor = \ 2731 _process_plot_format(basefmt) 2732 else: 2733 basestyle, basemarker, basecolor = _process_plot_format(basefmt) 2734 2735 markerline, = self.plot(x, y, color=markercolor, linestyle=markerstyle, 2736 marker=markermarker, label="_nolegend_") 2737 2738 stemlines = [] 2739 for thisx, thisy in zip(x, y): 2740 l, = self.plot([thisx, thisx], [bottom, thisy], 2741 color=linecolor, linestyle=linestyle, 2742 marker=linemarker, label="_nolegend_") 2743 stemlines.append(l) 2744 2745 baseline, = self.plot([np.min(x), np.max(x)], [bottom, bottom], 2746 color=basecolor, linestyle=basestyle, 2747 marker=basemarker, label="_nolegend_") 2748 2749 self._hold = remember_hold 2750 2751 stem_container = StemContainer((markerline, stemlines, baseline), 2752 label=label) 2753 self.add_container(stem_container) 2754 2755 return stem_container 2756 2757 @_preprocess_data(replace_names=["x", "explode", "labels", "colors"], 2758 label_namer=None) 2759 def pie(self, x, explode=None, labels=None, colors=None, 2760 autopct=None, pctdistance=0.6, shadow=False, labeldistance=1.1, 2761 startangle=None, radius=None, counterclock=True, 2762 wedgeprops=None, textprops=None, center=(0, 0), 2763 frame=False, rotatelabels=False): 2764 """ 2765 Plot a pie chart. 2766 2767 Make a pie chart of array *x*. The fractional area of each wedge is 2768 given by ``x/sum(x)``. If ``sum(x) < 1``, then the values of *x* give 2769 the fractional area directly and the array will not be normalized. The 2770 resulting pie will have an empty wedge of size ``1 - sum(x)``. 2771 2772 The wedges are plotted counterclockwise, by default starting from the 2773 x-axis. 2774 2775 Parameters 2776 ---------- 2777 x : array-like 2778 The wedge sizes. 2779 2780 explode : array-like, optional, default: None 2781 If not *None*, is a ``len(x)`` array which specifies the fraction 2782 of the radius with which to offset each wedge. 2783 2784 labels : list, optional, default: None 2785 A sequence of strings providing the labels for each wedge 2786 2787 colors : array-like, optional, default: None 2788 A sequence of matplotlib color args through which the pie chart 2789 will cycle. If *None*, will use the colors in the currently 2790 active cycle. 2791 2792 autopct : None (default), string, or function, optional 2793 If not *None*, is a string or function used to label the wedges 2794 with their numeric value. The label will be placed inside the 2795 wedge. If it is a format string, the label will be ``fmt%pct``. 2796 If it is a function, it will be called. 2797 2798 pctdistance : float, optional, default: 0.6 2799 The ratio between the center of each pie slice and the start of 2800 the text generated by *autopct*. Ignored if *autopct* is *None*. 2801 2802 shadow : bool, optional, default: False 2803 Draw a shadow beneath the pie. 2804 2805 labeldistance : float, optional, default: 1.1 2806 The radial distance at which the pie labels are drawn 2807 2808 startangle : float, optional, default: None 2809 If not *None*, rotates the start of the pie chart by *angle* 2810 degrees counterclockwise from the x-axis. 2811 2812 radius : float, optional, default: None 2813 The radius of the pie, if *radius* is *None* it will be set to 1. 2814 2815 counterclock : bool, optional, default: True 2816 Specify fractions direction, clockwise or counterclockwise. 2817 2818 wedgeprops : dict, optional, default: None 2819 Dict of arguments passed to the wedge objects making the pie. 2820 For example, you can pass in ``wedgeprops = {'linewidth': 3}`` 2821 to set the width of the wedge border lines equal to 3. 2822 For more details, look at the doc/arguments of the wedge object. 2823 By default ``clip_on=False``. 2824 2825 textprops : dict, optional, default: None 2826 Dict of arguments to pass to the text objects. 2827 2828 center : list of float, optional, default: (0, 0) 2829 Center position of the chart. Takes value (0, 0) or is a sequence 2830 of 2 scalars. 2831 2832 frame : bool, optional, default: False 2833 Plot axes frame with the chart if true. 2834 2835 rotatelabels : bool, optional, default: False 2836 Rotate each label to the angle of the corresponding slice if true. 2837 2838 Returns 2839 ------- 2840 patches : list 2841 A sequence of :class:`matplotlib.patches.Wedge` instances 2842 2843 texts : list 2844 A list of the label :class:`matplotlib.text.Text` instances. 2845 2846 autotexts : list 2847 A list of :class:`~matplotlib.text.Text` instances for the numeric 2848 labels. This will only be returned if the parameter *autopct* is 2849 not *None*. 2850 2851 Notes 2852 ----- 2853 The pie chart will probably look best if the figure and axes are 2854 square, or the Axes aspect is equal. 2855 """ 2856 x = np.array(x, np.float32) 2857 2858 sx = x.sum() 2859 if sx > 1: 2860 x /= sx 2861 2862 if labels is None: 2863 labels = [''] * len(x) 2864 if explode is None: 2865 explode = [0] * len(x) 2866 if len(x) != len(labels): 2867 raise ValueError("'label' must be of length 'x'") 2868 if len(x) != len(explode): 2869 raise ValueError("'explode' must be of length 'x'") 2870 if colors is None: 2871 get_next_color = self._get_patches_for_fill.get_next_color 2872 else: 2873 color_cycle = itertools.cycle(colors) 2874 2875 def get_next_color(): 2876 return next(color_cycle) 2877 2878 if radius is None: 2879 radius = 1 2880 2881 # Starting theta1 is the start fraction of the circle 2882 if startangle is None: 2883 theta1 = 0 2884 else: 2885 theta1 = startangle / 360.0 2886 2887 # set default values in wedge_prop 2888 if wedgeprops is None: 2889 wedgeprops = {} 2890 wedgeprops.setdefault('clip_on', False) 2891 2892 if textprops is None: 2893 textprops = {} 2894 textprops.setdefault('clip_on', False) 2895 2896 texts = [] 2897 slices = [] 2898 autotexts = [] 2899 2900 i = 0 2901 for frac, label, expl in zip(x, labels, explode): 2902 x, y = center 2903 theta2 = (theta1 + frac) if counterclock else (theta1 - frac) 2904 thetam = 2 * np.pi * 0.5 * (theta1 + theta2) 2905 x += expl * math.cos(thetam) 2906 y += expl * math.sin(thetam) 2907 2908 w = mpatches.Wedge((x, y), radius, 360. * min(theta1, theta2), 2909 360. * max(theta1, theta2), 2910 facecolor=get_next_color(), 2911 **wedgeprops) 2912 slices.append(w) 2913 self.add_patch(w) 2914 w.set_label(label) 2915 2916 if shadow: 2917 # make sure to add a shadow after the call to 2918 # add_patch so the figure and transform props will be 2919 # set 2920 shad = mpatches.Shadow(w, -0.02, -0.02) 2921 shad.set_zorder(0.9 * w.get_zorder()) 2922 shad.set_label('_nolegend_') 2923 self.add_patch(shad) 2924 2925 xt = x + labeldistance * radius * math.cos(thetam) 2926 yt = y + labeldistance * radius * math.sin(thetam) 2927 label_alignment_h = xt > 0 and 'left' or 'right' 2928 label_alignment_v = 'center' 2929 label_rotation = 'horizontal' 2930 if rotatelabels: 2931 label_alignment_v = yt > 0 and 'bottom' or 'top' 2932 label_rotation = np.rad2deg(thetam) + (0 if xt > 0 else 180) 2933 2934 t = self.text(xt, yt, label, 2935 size=rcParams['xtick.labelsize'], 2936 horizontalalignment=label_alignment_h, 2937 verticalalignment=label_alignment_v, 2938 rotation=label_rotation, 2939 **textprops) 2940 2941 texts.append(t) 2942 2943 if autopct is not None: 2944 xt = x + pctdistance * radius * math.cos(thetam) 2945 yt = y + pctdistance * radius * math.sin(thetam) 2946 if isinstance(autopct, six.string_types): 2947 s = autopct % (100. * frac) 2948 elif callable(autopct): 2949 s = autopct(100. * frac) 2950 else: 2951 raise TypeError( 2952 'autopct must be callable or a format string') 2953 2954 t = self.text(xt, yt, s, 2955 horizontalalignment='center', 2956 verticalalignment='center', 2957 **textprops) 2958 2959 autotexts.append(t) 2960 2961 theta1 = theta2 2962 i += 1 2963 2964 if not frame: 2965 self.set_frame_on(False) 2966 2967 self.set_xlim((-1.25 + center[0], 2968 1.25 + center[0])) 2969 self.set_ylim((-1.25 + center[1], 2970 1.25 + center[1])) 2971 self.set_xticks([]) 2972 self.set_yticks([]) 2973 2974 if autopct is None: 2975 return slices, texts 2976 else: 2977 return slices, texts, autotexts 2978 2979 @_preprocess_data(replace_names=["x", "y", "xerr", "yerr"], 2980 label_namer="y") 2981 @docstring.dedent_interpd 2982 def errorbar(self, x, y, yerr=None, xerr=None, 2983 fmt='', ecolor=None, elinewidth=None, capsize=None, 2984 barsabove=False, lolims=False, uplims=False, 2985 xlolims=False, xuplims=False, errorevery=1, capthick=None, 2986 **kwargs): 2987 """ 2988 Plot y versus x as lines and/or markers with attached errorbars. 2989 2990 *x*, *y* define the data locations, *xerr*, *yerr* define the errorbar 2991 sizes. By default, this draws the data markers/lines as well the 2992 errorbars. Use fmt='none' to draw errorbars without any data markers. 2993 2994 Parameters 2995 ---------- 2996 x, y : scalar or array-like 2997 The data positions. 2998 2999 xerr, yerr : scalar or array-like, shape(N,) or shape(2,N), optional 3000 The errorbar sizes: 3001 3002 - scalar: Symmetric +/- values for all data points. 3003 - shape(N,): Symmetric +/-values for each data point. 3004 - shape(2,N): Separate - and + values for each bar. First row 3005 contains the lower errors, the second row contains the 3006 upper errors. 3007 - *None*: No errorbar. 3008 3009 See :doc:`/gallery/statistics/errorbar_features` 3010 for an example on the usage of ``xerr`` and ``yerr``. 3011 3012 fmt : plot format string, optional, default: '' 3013 The format for the data points / data lines. See `.plot` for 3014 details. 3015 3016 Use 'none' (case insensitive) to plot errorbars without any data 3017 markers. 3018 3019 ecolor : mpl color, optional, default: None 3020 A matplotlib color arg which gives the color the errorbar lines. 3021 If None, use the color of the line connecting the markers. 3022 3023 elinewidth : scalar, optional, default: None 3024 The linewidth of the errorbar lines. If None, the linewidth of 3025 the current style is used. 3026 3027 capsize : scalar, optional, default: None 3028 The length of the error bar caps in points. If None, it will take 3029 the value from :rc:`errorbar.capsize`. 3030 3031 capthick : scalar, optional, default: None 3032 An alias to the keyword argument *markeredgewidth* (a.k.a. *mew*). 3033 This setting is a more sensible name for the property that 3034 controls the thickness of the error bar cap in points. For 3035 backwards compatibility, if *mew* or *markeredgewidth* are given, 3036 then they will over-ride *capthick*. This may change in future 3037 releases. 3038 3039 barsabove : bool, optional, default: False 3040 If True, will plot the errorbars above the plot 3041 symbols. Default is below. 3042 3043 lolims, uplims, xlolims, xuplims : bool, optional, default: None 3044 These arguments can be used to indicate that a value gives only 3045 upper/lower limits. In that case a caret symbol is used to 3046 indicate this. *lims*-arguments may be of the same type as *xerr* 3047 and *yerr*. To use limits with inverted axes, :meth:`set_xlim` 3048 or :meth:`set_ylim` must be called before :meth:`errorbar`. 3049 3050 errorevery : positive integer, optional, default: 1 3051 Subsamples the errorbars. e.g., if errorevery=5, errorbars for 3052 every 5-th datapoint will be plotted. The data plot itself still 3053 shows all data points. 3054 3055 Returns 3056 ------- 3057 container : :class:`~.container.ErrorbarContainer` 3058 The container contains: 3059 3060 - plotline: :class:`~matplotlib.lines.Line2D` instance of 3061 x, y plot markers and/or line. 3062 - caplines: A tuple of :class:`~matplotlib.lines.Line2D` instances 3063 of the error bar caps. 3064 - barlinecols: A tuple of 3065 :class:`~matplotlib.collections.LineCollection` with the 3066 horizontal and vertical error ranges. 3067 3068 Other Parameters 3069 ---------------- 3070 **kwargs : 3071 All other keyword arguments are passed on to the plot 3072 command for the markers. For example, this code makes big red 3073 squares with thick green edges:: 3074 3075 x,y,yerr = rand(3,10) 3076 errorbar(x, y, yerr, marker='s', mfc='red', 3077 mec='green', ms=20, mew=4) 3078 3079 where *mfc*, *mec*, *ms* and *mew* are aliases for the longer 3080 property names, *markerfacecolor*, *markeredgecolor*, *markersize* 3081 and *markeredgewidth*. 3082 3083 Valid kwargs for the marker properties are `.Lines2D` properties: 3084 3085 %(Line2D)s 3086 3087 Notes 3088 ----- 3089 .. [Notes section required for data comment. See #10189.] 3090 3091 """ 3092 kwargs = cbook.normalize_kwargs(kwargs, _alias_map) 3093 # anything that comes in as 'None', drop so the default thing 3094 # happens down stream 3095 kwargs = {k: v for k, v in kwargs.items() if v is not None} 3096 kwargs.setdefault('zorder', 2) 3097 3098 if errorevery < 1: 3099 raise ValueError( 3100 'errorevery has to be a strictly positive integer') 3101 3102 self._process_unit_info(xdata=x, ydata=y, kwargs=kwargs) 3103 if not self._hold: 3104 self.cla() 3105 holdstate = self._hold 3106 self._hold = True 3107 3108 plot_line = (fmt.lower() != 'none') 3109 label = kwargs.pop("label", None) 3110 3111 if fmt == '': 3112 fmt_style_kwargs = {} 3113 else: 3114 fmt_style_kwargs = {k: v for k, v in 3115 zip(('linestyle', 'marker', 'color'), 3116 _process_plot_format(fmt)) if v is not None} 3117 if fmt == 'none': 3118 # Remove alpha=0 color that _process_plot_format returns 3119 fmt_style_kwargs.pop('color') 3120 3121 if ('color' in kwargs or 'color' in fmt_style_kwargs or 3122 ecolor is not None): 3123 base_style = {} 3124 if 'color' in kwargs: 3125 base_style['color'] = kwargs.pop('color') 3126 else: 3127 base_style = next(self._get_lines.prop_cycler) 3128 3129 base_style['label'] = '_nolegend_' 3130 base_style.update(fmt_style_kwargs) 3131 if 'color' not in base_style: 3132 base_style['color'] = 'C0' 3133 if ecolor is None: 3134 ecolor = base_style['color'] 3135 # make sure all the args are iterable; use lists not arrays to 3136 # preserve units 3137 if not iterable(x): 3138 x = [x] 3139 3140 if not iterable(y): 3141 y = [y] 3142 3143 if xerr is not None: 3144 if not iterable(xerr): 3145 xerr = [xerr] * len(x) 3146 3147 if yerr is not None: 3148 if not iterable(yerr): 3149 yerr = [yerr] * len(y) 3150 3151 # make the style dict for the 'normal' plot line 3152 plot_line_style = dict(base_style) 3153 plot_line_style.update(**kwargs) 3154 if barsabove: 3155 plot_line_style['zorder'] = kwargs['zorder'] - .1 3156 else: 3157 plot_line_style['zorder'] = kwargs['zorder'] + .1 3158 3159 # make the style dict for the line collections (the bars) 3160 eb_lines_style = dict(base_style) 3161 eb_lines_style.pop('marker', None) 3162 eb_lines_style.pop('linestyle', None) 3163 eb_lines_style['color'] = ecolor 3164 3165 if elinewidth: 3166 eb_lines_style['linewidth'] = elinewidth 3167 elif 'linewidth' in kwargs: 3168 eb_lines_style['linewidth'] = kwargs['linewidth'] 3169 3170 for key in ('transform', 'alpha', 'zorder', 'rasterized'): 3171 if key in kwargs: 3172 eb_lines_style[key] = kwargs[key] 3173 3174 # set up cap style dictionary 3175 eb_cap_style = dict(base_style) 3176 # eject any marker information from format string 3177 eb_cap_style.pop('marker', None) 3178 eb_lines_style.pop('markerfacecolor', None) 3179 eb_lines_style.pop('markeredgewidth', None) 3180 eb_lines_style.pop('markeredgecolor', None) 3181 eb_cap_style.pop('ls', None) 3182 eb_cap_style['linestyle'] = 'none' 3183 if capsize is None: 3184 capsize = rcParams["errorbar.capsize"] 3185 if capsize > 0: 3186 eb_cap_style['markersize'] = 2. * capsize 3187 if capthick is not None: 3188 eb_cap_style['markeredgewidth'] = capthick 3189 3190 # For backwards-compat, allow explicit setting of 3191 # 'markeredgewidth' to over-ride capthick. 3192 for key in ('markeredgewidth', 'transform', 'alpha', 3193 'zorder', 'rasterized'): 3194 if key in kwargs: 3195 eb_cap_style[key] = kwargs[key] 3196 eb_cap_style['color'] = ecolor 3197 3198 data_line = None 3199 if plot_line: 3200 data_line = mlines.Line2D(x, y, **plot_line_style) 3201 self.add_line(data_line) 3202 3203 barcols = [] 3204 caplines = [] 3205 3206 # arrays fine here, they are booleans and hence not units 3207 def _bool_asarray_helper(d, expected): 3208 if not iterable(d): 3209 return np.asarray([d] * expected, bool) 3210 else: 3211 return np.asarray(d, bool) 3212 3213 lolims = _bool_asarray_helper(lolims, len(x)) 3214 uplims = _bool_asarray_helper(uplims, len(x)) 3215 xlolims = _bool_asarray_helper(xlolims, len(x)) 3216 xuplims = _bool_asarray_helper(xuplims, len(x)) 3217 3218 everymask = np.arange(len(x)) % errorevery == 0 3219 3220 def xywhere(xs, ys, mask): 3221 """ 3222 return xs[mask], ys[mask] where mask is True but xs and 3223 ys are not arrays 3224 """ 3225 assert len(xs) == len(ys) 3226 assert len(xs) == len(mask) 3227 xs = [thisx for thisx, b in zip(xs, mask) if b] 3228 ys = [thisy for thisy, b in zip(ys, mask) if b] 3229 return xs, ys 3230 3231 def extract_err(err, data): 3232 '''private function to compute error bars 3233 3234 Parameters 3235 ---------- 3236 err : iterable 3237 xerr or yerr from errorbar 3238 data : iterable 3239 x or y from errorbar 3240 ''' 3241 try: 3242 a, b = err 3243 except (TypeError, ValueError): 3244 pass 3245 else: 3246 if iterable(a) and iterable(b): 3247 # using list comps rather than arrays to preserve units 3248 low = [thisx - thiserr for (thisx, thiserr) 3249 in cbook.safezip(data, a)] 3250 high = [thisx + thiserr for (thisx, thiserr) 3251 in cbook.safezip(data, b)] 3252 return low, high 3253 # Check if xerr is scalar or symmetric. Asymmetric is handled 3254 # above. This prevents Nx2 arrays from accidentally 3255 # being accepted, when the user meant the 2xN transpose. 3256 # special case for empty lists 3257 if len(err) > 1: 3258 fe = safe_first_element(err) 3259 if (len(err) != len(data) or np.size(fe) > 1): 3260 raise ValueError("err must be [ scalar | N, Nx1 " 3261 "or 2xN array-like ]") 3262 # using list comps rather than arrays to preserve units 3263 low = [thisx - thiserr for (thisx, thiserr) 3264 in cbook.safezip(data, err)] 3265 high = [thisx + thiserr for (thisx, thiserr) 3266 in cbook.safezip(data, err)] 3267 return low, high 3268 3269 if xerr is not None: 3270 left, right = extract_err(xerr, x) 3271 # select points without upper/lower limits in x and 3272 # draw normal errorbars for these points 3273 noxlims = ~(xlolims | xuplims) 3274 if noxlims.any() or len(noxlims) == 0: 3275 yo, _ = xywhere(y, right, noxlims & everymask) 3276 lo, ro = xywhere(left, right, noxlims & everymask) 3277 barcols.append(self.hlines(yo, lo, ro, **eb_lines_style)) 3278 if capsize > 0: 3279 caplines.append(mlines.Line2D(lo, yo, marker='|', 3280 **eb_cap_style)) 3281 caplines.append(mlines.Line2D(ro, yo, marker='|', 3282 **eb_cap_style)) 3283 3284 if xlolims.any(): 3285 yo, _ = xywhere(y, right, xlolims & everymask) 3286 lo, ro = xywhere(x, right, xlolims & everymask) 3287 barcols.append(self.hlines(yo, lo, ro, **eb_lines_style)) 3288 rightup, yup = xywhere(right, y, xlolims & everymask) 3289 if self.xaxis_inverted(): 3290 marker = mlines.CARETLEFTBASE 3291 else: 3292 marker = mlines.CARETRIGHTBASE 3293 caplines.append( 3294 mlines.Line2D(rightup, yup, ls='None', marker=marker, 3295 **eb_cap_style)) 3296 if capsize > 0: 3297 xlo, ylo = xywhere(x, y, xlolims & everymask) 3298 caplines.append(mlines.Line2D(xlo, ylo, marker='|', 3299 **eb_cap_style)) 3300 3301 if xuplims.any(): 3302 yo, _ = xywhere(y, right, xuplims & everymask) 3303 lo, ro = xywhere(left, x, xuplims & everymask) 3304 barcols.append(self.hlines(yo, lo, ro, **eb_lines_style)) 3305 leftlo, ylo = xywhere(left, y, xuplims & everymask) 3306 if self.xaxis_inverted(): 3307 marker = mlines.CARETRIGHTBASE 3308 else: 3309 marker = mlines.CARETLEFTBASE 3310 caplines.append( 3311 mlines.Line2D(leftlo, ylo, ls='None', marker=marker, 3312 **eb_cap_style)) 3313 if capsize > 0: 3314 xup, yup = xywhere(x, y, xuplims & everymask) 3315 caplines.append(mlines.Line2D(xup, yup, marker='|', 3316 **eb_cap_style)) 3317 3318 if yerr is not None: 3319 lower, upper = extract_err(yerr, y) 3320 # select points without upper/lower limits in y and 3321 # draw normal errorbars for these points 3322 noylims = ~(lolims | uplims) 3323 if noylims.any() or len(noylims) == 0: 3324 xo, _ = xywhere(x, lower, noylims & everymask) 3325 lo, uo = xywhere(lower, upper, noylims & everymask) 3326 barcols.append(self.vlines(xo, lo, uo, **eb_lines_style)) 3327 if capsize > 0: 3328 caplines.append(mlines.Line2D(xo, lo, marker='_', 3329 **eb_cap_style)) 3330 caplines.append(mlines.Line2D(xo, uo, marker='_', 3331 **eb_cap_style)) 3332 3333 if lolims.any(): 3334 xo, _ = xywhere(x, lower, lolims & everymask) 3335 lo, uo = xywhere(y, upper, lolims & everymask) 3336 barcols.append(self.vlines(xo, lo, uo, **eb_lines_style)) 3337 xup, upperup = xywhere(x, upper, lolims & everymask) 3338 if self.yaxis_inverted(): 3339 marker = mlines.CARETDOWNBASE 3340 else: 3341 marker = mlines.CARETUPBASE 3342 caplines.append( 3343 mlines.Line2D(xup, upperup, ls='None', marker=marker, 3344 **eb_cap_style)) 3345 if capsize > 0: 3346 xlo, ylo = xywhere(x, y, lolims & everymask) 3347 caplines.append(mlines.Line2D(xlo, ylo, marker='_', 3348 **eb_cap_style)) 3349 3350 if uplims.any(): 3351 xo, _ = xywhere(x, lower, uplims & everymask) 3352 lo, uo = xywhere(lower, y, uplims & everymask) 3353 barcols.append(self.vlines(xo, lo, uo, **eb_lines_style)) 3354 xlo, lowerlo = xywhere(x, lower, uplims & everymask) 3355 if self.yaxis_inverted(): 3356 marker = mlines.CARETUPBASE 3357 else: 3358 marker = mlines.CARETDOWNBASE 3359 caplines.append( 3360 mlines.Line2D(xlo, lowerlo, ls='None', marker=marker, 3361 **eb_cap_style)) 3362 if capsize > 0: 3363 xup, yup = xywhere(x, y, uplims & everymask) 3364 caplines.append(mlines.Line2D(xup, yup, marker='_', 3365 **eb_cap_style)) 3366 for l in caplines: 3367 self.add_line(l) 3368 3369 self.autoscale_view() 3370 self._hold = holdstate 3371 3372 errorbar_container = ErrorbarContainer((data_line, tuple(caplines), 3373 tuple(barcols)), 3374 has_xerr=(xerr is not None), 3375 has_yerr=(yerr is not None), 3376 label=label) 3377 self.containers.append(errorbar_container) 3378 3379 return errorbar_container # (l0, caplines, barcols) 3380 3381 @_preprocess_data(label_namer=None) 3382 def boxplot(self, x, notch=None, sym=None, vert=None, whis=None, 3383 positions=None, widths=None, patch_artist=None, 3384 bootstrap=None, usermedians=None, conf_intervals=None, 3385 meanline=None, showmeans=None, showcaps=None, 3386 showbox=None, showfliers=None, boxprops=None, 3387 labels=None, flierprops=None, medianprops=None, 3388 meanprops=None, capprops=None, whiskerprops=None, 3389 manage_xticks=True, autorange=False, zorder=None): 3390 """ 3391 Make a box and whisker plot. 3392 3393 Make a box and whisker plot for each column of ``x`` or each 3394 vector in sequence ``x``. The box extends from the lower to 3395 upper quartile values of the data, with a line at the median. 3396 The whiskers extend from the box to show the range of the 3397 data. Flier points are those past the end of the whiskers. 3398 3399 Parameters 3400 ---------- 3401 x : Array or a sequence of vectors. 3402 The input data. 3403 3404 notch : bool, optional (False) 3405 If `True`, will produce a notched box plot. Otherwise, a 3406 rectangular boxplot is produced. The notches represent the 3407 confidence interval (CI) around the median. See the entry 3408 for the ``bootstrap`` parameter for information regarding 3409 how the locations of the notches are computed. 3410 3411 .. note:: 3412 3413 In cases where the values of the CI are less than the 3414 lower quartile or greater than the upper quartile, the 3415 notches will extend beyond the box, giving it a 3416 distinctive "flipped" appearance. This is expected 3417 behavior and consistent with other statistical 3418 visualization packages. 3419 3420 sym : str, optional 3421 The default symbol for flier points. Enter an empty string 3422 ('') if you don't want to show fliers. If `None`, then the 3423 fliers default to 'b+' If you want more control use the 3424 flierprops kwarg. 3425 3426 vert : bool, optional (True) 3427 If `True` (default), makes the boxes vertical. If `False`, 3428 everything is drawn horizontally. 3429 3430 whis : float, sequence, or string (default = 1.5) 3431 As a float, determines the reach of the whiskers to the beyond the 3432 first and third quartiles. In other words, where IQR is the 3433 interquartile range (`Q3-Q1`), the upper whisker will extend to 3434 last datum less than `Q3 + whis*IQR`). Similarly, the lower whisker 3435 will extend to the first datum greater than `Q1 - whis*IQR`. 3436 Beyond the whiskers, data 3437 are considered outliers and are plotted as individual 3438 points. Set this to an unreasonably high value to force the 3439 whiskers to show the min and max values. Alternatively, set 3440 this to an ascending sequence of percentile (e.g., [5, 95]) 3441 to set the whiskers at specific percentiles of the data. 3442 Finally, ``whis`` can be the string ``'range'`` to force the 3443 whiskers to the min and max of the data. 3444 3445 bootstrap : int, optional 3446 Specifies whether to bootstrap the confidence intervals 3447 around the median for notched boxplots. If ``bootstrap`` is 3448 None, no bootstrapping is performed, and notches are 3449 calculated using a Gaussian-based asymptotic approximation 3450 (see McGill, R., Tukey, J.W., and Larsen, W.A., 1978, and 3451 Kendall and Stuart, 1967). Otherwise, bootstrap specifies 3452 the number of times to bootstrap the median to determine its 3453 95% confidence intervals. Values between 1000 and 10000 are 3454 recommended. 3455 3456 usermedians : array-like, optional 3457 An array or sequence whose first dimension (or length) is 3458 compatible with ``x``. This overrides the medians computed 3459 by matplotlib for each element of ``usermedians`` that is not 3460 `None`. When an element of ``usermedians`` is None, the median 3461 will be computed by matplotlib as normal. 3462 3463 conf_intervals : array-like, optional 3464 Array or sequence whose first dimension (or length) is 3465 compatible with ``x`` and whose second dimension is 2. When 3466 the an element of ``conf_intervals`` is not None, the 3467 notch locations computed by matplotlib are overridden 3468 (provided ``notch`` is `True`). When an element of 3469 ``conf_intervals`` is `None`, the notches are computed by the 3470 method specified by the other kwargs (e.g., ``bootstrap``). 3471 3472 positions : array-like, optional 3473 Sets the positions of the boxes. The ticks and limits are 3474 automatically set to match the positions. Defaults to 3475 `range(1, N+1)` where N is the number of boxes to be drawn. 3476 3477 widths : scalar or array-like 3478 Sets the width of each box either with a scalar or a 3479 sequence. The default is 0.5, or ``0.15*(distance between 3480 extreme positions)``, if that is smaller. 3481 3482 patch_artist : bool, optional (False) 3483 If `False` produces boxes with the Line2D artist. Otherwise, 3484 boxes and drawn with Patch artists. 3485 3486 labels : sequence, optional 3487 Labels for each dataset. Length must be compatible with 3488 dimensions of ``x``. 3489 3490 manage_xticks : bool, optional (True) 3491 If the function should adjust the xlim and xtick locations. 3492 3493 autorange : bool, optional (False) 3494 When `True` and the data are distributed such that the 25th and 3495 75th percentiles are equal, ``whis`` is set to ``'range'`` such 3496 that the whisker ends are at the minimum and maximum of the 3497 data. 3498 3499 meanline : bool, optional (False) 3500 If `True` (and ``showmeans`` is `True`), will try to render 3501 the mean as a line spanning the full width of the box 3502 according to ``meanprops`` (see below). Not recommended if 3503 ``shownotches`` is also True. Otherwise, means will be shown 3504 as points. 3505 3506 zorder : scalar, optional (None) 3507 Sets the zorder of the boxplot. 3508 3509 Other Parameters 3510 ---------------- 3511 showcaps : bool, optional (True) 3512 Show the caps on the ends of whiskers. 3513 showbox : bool, optional (True) 3514 Show the central box. 3515 showfliers : bool, optional (True) 3516 Show the outliers beyond the caps. 3517 showmeans : bool, optional (False) 3518 Show the arithmetic means. 3519 capprops : dict, optional (None) 3520 Specifies the style of the caps. 3521 boxprops : dict, optional (None) 3522 Specifies the style of the box. 3523 whiskerprops : dict, optional (None) 3524 Specifies the style of the whiskers. 3525 flierprops : dict, optional (None) 3526 Specifies the style of the fliers. 3527 medianprops : dict, optional (None) 3528 Specifies the style of the median. 3529 meanprops : dict, optional (None) 3530 Specifies the style of the mean. 3531 3532 Returns 3533 ------- 3534 result : dict 3535 A dictionary mapping each component of the boxplot to a list 3536 of the :class:`matplotlib.lines.Line2D` instances 3537 created. That dictionary has the following keys (assuming 3538 vertical boxplots): 3539 3540 - ``boxes``: the main body of the boxplot showing the 3541 quartiles and the median's confidence intervals if 3542 enabled. 3543 3544 - ``medians``: horizontal lines at the median of each box. 3545 3546 - ``whiskers``: the vertical lines extending to the most 3547 extreme, non-outlier data points. 3548 3549 - ``caps``: the horizontal lines at the ends of the 3550 whiskers. 3551 3552 - ``fliers``: points representing data that extend beyond 3553 the whiskers (fliers). 3554 3555 - ``means``: points or lines representing the means. 3556 3557 Notes 3558 ----- 3559 .. [Notes section required for data comment. See #10189.] 3560 3561 """ 3562 3563 # If defined in matplotlibrc, apply the value from rc file 3564 # Overridden if argument is passed 3565 if whis is None: 3566 whis = rcParams['boxplot.whiskers'] 3567 if bootstrap is None: 3568 bootstrap = rcParams['boxplot.bootstrap'] 3569 3570 bxpstats = cbook.boxplot_stats(x, whis=whis, bootstrap=bootstrap, 3571 labels=labels, autorange=autorange) 3572 if notch is None: 3573 notch = rcParams['boxplot.notch'] 3574 if vert is None: 3575 vert = rcParams['boxplot.vertical'] 3576 if patch_artist is None: 3577 patch_artist = rcParams['boxplot.patchartist'] 3578 if meanline is None: 3579 meanline = rcParams['boxplot.meanline'] 3580 if showmeans is None: 3581 showmeans = rcParams['boxplot.showmeans'] 3582 if showcaps is None: 3583 showcaps = rcParams['boxplot.showcaps'] 3584 if showbox is None: 3585 showbox = rcParams['boxplot.showbox'] 3586 if showfliers is None: 3587 showfliers = rcParams['boxplot.showfliers'] 3588 3589 def _update_dict(dictionary, rc_name, properties): 3590 """ Loads properties in the dictionary from rc file if not already 3591 in the dictionary""" 3592 rc_str = 'boxplot.{0}.{1}' 3593 if dictionary is None: 3594 dictionary = dict() 3595 for prop_dict in properties: 3596 dictionary.setdefault(prop_dict, 3597 rcParams[rc_str.format(rc_name, prop_dict)]) 3598 return dictionary 3599 3600 # Common property dictionnaries loading from rc 3601 flier_props = ['color', 'marker', 'markerfacecolor', 'markeredgecolor', 3602 'markersize', 'linestyle', 'linewidth'] 3603 default_props = ['color', 'linewidth', 'linestyle'] 3604 3605 boxprops = _update_dict(boxprops, 'boxprops', default_props) 3606 whiskerprops = _update_dict(whiskerprops, 'whiskerprops', 3607 default_props) 3608 capprops = _update_dict(capprops, 'capprops', default_props) 3609 medianprops = _update_dict(medianprops, 'medianprops', default_props) 3610 meanprops = _update_dict(meanprops, 'meanprops', default_props) 3611 flierprops = _update_dict(flierprops, 'flierprops', flier_props) 3612 3613 if patch_artist: 3614 boxprops['linestyle'] = 'solid' 3615 boxprops['edgecolor'] = boxprops.pop('color') 3616 3617 # if non-default sym value, put it into the flier dictionary 3618 # the logic for providing the default symbol ('b+') now lives 3619 # in bxp in the initial value of final_flierprops 3620 # handle all of the `sym` related logic here so we only have to pass 3621 # on the flierprops dict. 3622 if sym is not None: 3623 # no-flier case, which should really be done with 3624 # 'showfliers=False' but none-the-less deal with it to keep back 3625 # compatibility 3626 if sym == '': 3627 # blow away existing dict and make one for invisible markers 3628 flierprops = dict(linestyle='none', marker='', color='none') 3629 # turn the fliers off just to be safe 3630 showfliers = False 3631 # now process the symbol string 3632 else: 3633 # process the symbol string 3634 # discarded linestyle 3635 _, marker, color = _process_plot_format(sym) 3636 # if we have a marker, use it 3637 if marker is not None: 3638 flierprops['marker'] = marker 3639 # if we have a color, use it 3640 if color is not None: 3641 # assume that if color is passed in the user want 3642 # filled symbol, if the users want more control use 3643 # flierprops 3644 flierprops['color'] = color 3645 flierprops['markerfacecolor'] = color 3646 flierprops['markeredgecolor'] = color 3647 3648 # replace medians if necessary: 3649 if usermedians is not None: 3650 if (len(np.ravel(usermedians)) != len(bxpstats) or 3651 np.shape(usermedians)[0] != len(bxpstats)): 3652 raise ValueError('usermedians length not compatible with x') 3653 else: 3654 # reassign medians as necessary 3655 for stats, med in zip(bxpstats, usermedians): 3656 if med is not None: 3657 stats['med'] = med 3658 3659 if conf_intervals is not None: 3660 if np.shape(conf_intervals)[0] != len(bxpstats): 3661 err_mess = 'conf_intervals length not compatible with x' 3662 raise ValueError(err_mess) 3663 else: 3664 for stats, ci in zip(bxpstats, conf_intervals): 3665 if ci is not None: 3666 if len(ci) != 2: 3667 raise ValueError('each confidence interval must ' 3668 'have two values') 3669 else: 3670 if ci[0] is not None: 3671 stats['cilo'] = ci[0] 3672 if ci[1] is not None: 3673 stats['cihi'] = ci[1] 3674 3675 artists = self.bxp(bxpstats, positions=positions, widths=widths, 3676 vert=vert, patch_artist=patch_artist, 3677 shownotches=notch, showmeans=showmeans, 3678 showcaps=showcaps, showbox=showbox, 3679 boxprops=boxprops, flierprops=flierprops, 3680 medianprops=medianprops, meanprops=meanprops, 3681 meanline=meanline, showfliers=showfliers, 3682 capprops=capprops, whiskerprops=whiskerprops, 3683 manage_xticks=manage_xticks, zorder=zorder) 3684 return artists 3685 3686 def bxp(self, bxpstats, positions=None, widths=None, vert=True, 3687 patch_artist=False, shownotches=False, showmeans=False, 3688 showcaps=True, showbox=True, showfliers=True, 3689 boxprops=None, whiskerprops=None, flierprops=None, 3690 medianprops=None, capprops=None, meanprops=None, 3691 meanline=False, manage_xticks=True, zorder=None): 3692 """ 3693 Drawing function for box and whisker plots. 3694 3695 Make a box and whisker plot for each column of *x* or each 3696 vector in sequence *x*. The box extends from the lower to 3697 upper quartile values of the data, with a line at the median. 3698 The whiskers extend from the box to show the range of the 3699 data. Flier points are those past the end of the whiskers. 3700 3701 Parameters 3702 ---------- 3703 3704 bxpstats : list of dicts 3705 A list of dictionaries containing stats for each boxplot. 3706 Required keys are: 3707 3708 - ``med``: The median (scalar float). 3709 3710 - ``q1``: The first quartile (25th percentile) (scalar 3711 float). 3712 3713 - ``q3``: The third quartile (75th percentile) (scalar 3714 float). 3715 3716 - ``whislo``: Lower bound of the lower whisker (scalar 3717 float). 3718 3719 - ``whishi``: Upper bound of the upper whisker (scalar 3720 float). 3721 3722 Optional keys are: 3723 3724 - ``mean``: The mean (scalar float). Needed if 3725 ``showmeans=True``. 3726 3727 - ``fliers``: Data beyond the whiskers (sequence of floats). 3728 Needed if ``showfliers=True``. 3729 3730 - ``cilo`` & ``cihi``: Lower and upper confidence intervals 3731 about the median. Needed if ``shownotches=True``. 3732 3733 - ``label``: Name of the dataset (string). If available, 3734 this will be used a tick label for the boxplot 3735 3736 positions : array-like, default = [1, 2, ..., n] 3737 Sets the positions of the boxes. The ticks and limits 3738 are automatically set to match the positions. 3739 3740 widths : array-like, default = None 3741 Either a scalar or a vector and sets the width of each 3742 box. The default is ``0.15*(distance between extreme 3743 positions)``, clipped to no less than 0.15 and no more than 3744 0.5. 3745 3746 vert : bool, default = False 3747 If `True` (default), makes the boxes vertical. If `False`, 3748 makes horizontal boxes. 3749 3750 patch_artist : bool, default = False 3751 If `False` produces boxes with the 3752 `~matplotlib.lines.Line2D` artist. If `True` produces boxes 3753 with the `~matplotlib.patches.Patch` artist. 3754 3755 shownotches : bool, default = False 3756 If `False` (default), produces a rectangular box plot. 3757 If `True`, will produce a notched box plot 3758 3759 showmeans : bool, default = False 3760 If `True`, will toggle on the rendering of the means 3761 3762 showcaps : bool, default = True 3763 If `True`, will toggle on the rendering of the caps 3764 3765 showbox : bool, default = True 3766 If `True`, will toggle on the rendering of the box 3767 3768 showfliers : bool, default = True 3769 If `True`, will toggle on the rendering of the fliers 3770 3771 boxprops : dict or None (default) 3772 If provided, will set the plotting style of the boxes 3773 3774 whiskerprops : dict or None (default) 3775 If provided, will set the plotting style of the whiskers 3776 3777 capprops : dict or None (default) 3778 If provided, will set the plotting style of the caps 3779 3780 flierprops : dict or None (default) 3781 If provided will set the plotting style of the fliers 3782 3783 medianprops : dict or None (default) 3784 If provided, will set the plotting style of the medians 3785 3786 meanprops : dict or None (default) 3787 If provided, will set the plotting style of the means 3788 3789 meanline : bool, default = False 3790 If `True` (and *showmeans* is `True`), will try to render the mean 3791 as a line spanning the full width of the box according to 3792 *meanprops*. Not recommended if *shownotches* is also True. 3793 Otherwise, means will be shown as points. 3794 3795 manage_xticks : bool, default = True 3796 If the function should adjust the xlim and xtick locations. 3797 3798 zorder : scalar, default = None 3799 The zorder of the resulting boxplot 3800 3801 Returns 3802 ------- 3803 result : dict 3804 A dictionary mapping each component of the boxplot to a list 3805 of the :class:`matplotlib.lines.Line2D` instances 3806 created. That dictionary has the following keys (assuming 3807 vertical boxplots): 3808 3809 - ``boxes``: the main body of the boxplot showing the 3810 quartiles and the median's confidence intervals if 3811 enabled. 3812 3813 - ``medians``: horizontal lines at the median of each box. 3814 3815 - ``whiskers``: the vertical lines extending to the most 3816 extreme, non-outlier data points. 3817 3818 - ``caps``: the horizontal lines at the ends of the 3819 whiskers. 3820 3821 - ``fliers``: points representing data that extend beyond 3822 the whiskers (fliers). 3823 3824 - ``means``: points or lines representing the means. 3825 3826 Examples 3827 -------- 3828 3829 .. plot:: gallery/statistics/bxp.py 3830 3831 """ 3832 # lists of artists to be output 3833 whiskers = [] 3834 caps = [] 3835 boxes = [] 3836 medians = [] 3837 means = [] 3838 fliers = [] 3839 3840 # empty list of xticklabels 3841 datalabels = [] 3842 3843 # Use default zorder if none specified 3844 if zorder is None: 3845 zorder = mlines.Line2D.zorder 3846 3847 zdelta = 0.1 3848 # box properties 3849 if patch_artist: 3850 final_boxprops = dict( 3851 linestyle=rcParams['boxplot.boxprops.linestyle'], 3852 edgecolor=rcParams['boxplot.boxprops.color'], 3853 facecolor=rcParams['patch.facecolor'], 3854 linewidth=rcParams['boxplot.boxprops.linewidth'] 3855 ) 3856 if rcParams['_internal.classic_mode']: 3857 final_boxprops['facecolor'] = 'white' 3858 else: 3859 final_boxprops = dict( 3860 linestyle=rcParams['boxplot.boxprops.linestyle'], 3861 color=rcParams['boxplot.boxprops.color'], 3862 ) 3863 3864 final_boxprops['zorder'] = zorder 3865 if boxprops is not None: 3866 final_boxprops.update(boxprops) 3867 3868 # other (cap, whisker) properties 3869 final_whiskerprops = dict( 3870 linestyle=rcParams['boxplot.whiskerprops.linestyle'], 3871 linewidth=rcParams['boxplot.whiskerprops.linewidth'], 3872 color=rcParams['boxplot.whiskerprops.color'], 3873 ) 3874 3875 final_capprops = dict( 3876 linestyle=rcParams['boxplot.capprops.linestyle'], 3877 linewidth=rcParams['boxplot.capprops.linewidth'], 3878 color=rcParams['boxplot.capprops.color'], 3879 ) 3880 3881 final_capprops['zorder'] = zorder 3882 if capprops is not None: 3883 final_capprops.update(capprops) 3884 3885 final_whiskerprops['zorder'] = zorder 3886 if whiskerprops is not None: 3887 final_whiskerprops.update(whiskerprops) 3888 3889 # set up the default flier properties 3890 final_flierprops = dict( 3891 linestyle=rcParams['boxplot.flierprops.linestyle'], 3892 linewidth=rcParams['boxplot.flierprops.linewidth'], 3893 color=rcParams['boxplot.flierprops.color'], 3894 marker=rcParams['boxplot.flierprops.marker'], 3895 markerfacecolor=rcParams['boxplot.flierprops.markerfacecolor'], 3896 markeredgecolor=rcParams['boxplot.flierprops.markeredgecolor'], 3897 markersize=rcParams['boxplot.flierprops.markersize'], 3898 ) 3899 3900 final_flierprops['zorder'] = zorder 3901 # flier (outlier) properties 3902 if flierprops is not None: 3903 final_flierprops.update(flierprops) 3904 3905 # median line properties 3906 final_medianprops = dict( 3907 linestyle=rcParams['boxplot.medianprops.linestyle'], 3908 linewidth=rcParams['boxplot.medianprops.linewidth'], 3909 color=rcParams['boxplot.medianprops.color'], 3910 ) 3911 final_medianprops['zorder'] = zorder + zdelta 3912 if medianprops is not None: 3913 final_medianprops.update(medianprops) 3914 3915 # mean (line or point) properties 3916 if meanline: 3917 final_meanprops = dict( 3918 linestyle=rcParams['boxplot.meanprops.linestyle'], 3919 linewidth=rcParams['boxplot.meanprops.linewidth'], 3920 color=rcParams['boxplot.meanprops.color'], 3921 ) 3922 else: 3923 final_meanprops = dict( 3924 linestyle='', 3925 marker=rcParams['boxplot.meanprops.marker'], 3926 markerfacecolor=rcParams['boxplot.meanprops.markerfacecolor'], 3927 markeredgecolor=rcParams['boxplot.meanprops.markeredgecolor'], 3928 markersize=rcParams['boxplot.meanprops.markersize'], 3929 ) 3930 final_meanprops['zorder'] = zorder + zdelta 3931 if meanprops is not None: 3932 final_meanprops.update(meanprops) 3933 3934 def to_vc(xs, ys): 3935 # convert arguments to verts and codes, append (0, 0) (ignored). 3936 verts = np.append(np.column_stack([xs, ys]), [(0, 0)], 0) 3937 codes = ([mpath.Path.MOVETO] 3938 + [mpath.Path.LINETO] * (len(verts) - 2) 3939 + [mpath.Path.CLOSEPOLY]) 3940 return verts, codes 3941 3942 def patch_list(xs, ys, **kwargs): 3943 verts, codes = to_vc(xs, ys) 3944 path = mpath.Path(verts, codes) 3945 patch = mpatches.PathPatch(path, **kwargs) 3946 self.add_artist(patch) 3947 return [patch] 3948 3949 # vertical or horizontal plot? 3950 if vert: 3951 def doplot(*args, **kwargs): 3952 return self.plot(*args, **kwargs) 3953 3954 def dopatch(xs, ys, **kwargs): 3955 return patch_list(xs, ys, **kwargs) 3956 3957 else: 3958 def doplot(*args, **kwargs): 3959 shuffled = [] 3960 for i in xrange(0, len(args), 2): 3961 shuffled.extend([args[i + 1], args[i]]) 3962 return self.plot(*shuffled, **kwargs) 3963 3964 def dopatch(xs, ys, **kwargs): 3965 xs, ys = ys, xs # flip X, Y 3966 return patch_list(xs, ys, **kwargs) 3967 3968 # input validation 3969 N = len(bxpstats) 3970 datashape_message = ("List of boxplot statistics and `{0}` " 3971 "values must have same the length") 3972 # check position 3973 if positions is None: 3974 positions = list(xrange(1, N + 1)) 3975 elif len(positions) != N: 3976 raise ValueError(datashape_message.format("positions")) 3977 3978 # width 3979 if widths is None: 3980 widths = [np.clip(0.15 * np.ptp(positions), 0.15, 0.5)] * N 3981 elif np.isscalar(widths): 3982 widths = [widths] * N 3983 elif len(widths) != N: 3984 raise ValueError(datashape_message.format("widths")) 3985 3986 # check and save the `hold` state of the current axes 3987 if not self._hold: 3988 self.cla() 3989 holdStatus = self._hold 3990 for pos, width, stats in zip(positions, widths, bxpstats): 3991 # try to find a new label 3992 datalabels.append(stats.get('label', pos)) 3993 3994 # whisker coords 3995 whisker_x = np.ones(2) * pos 3996 whiskerlo_y = np.array([stats['q1'], stats['whislo']]) 3997 whiskerhi_y = np.array([stats['q3'], stats['whishi']]) 3998 3999 # cap coords 4000 cap_left = pos - width * 0.25 4001 cap_right = pos + width * 0.25 4002 cap_x = np.array([cap_left, cap_right]) 4003 cap_lo = np.ones(2) * stats['whislo'] 4004 cap_hi = np.ones(2) * stats['whishi'] 4005 4006 # box and median coords 4007 box_left = pos - width * 0.5 4008 box_right = pos + width * 0.5 4009 med_y = [stats['med'], stats['med']] 4010 4011 # notched boxes 4012 if shownotches: 4013 box_x = [box_left, box_right, box_right, cap_right, box_right, 4014 box_right, box_left, box_left, cap_left, box_left, 4015 box_left] 4016 box_y = [stats['q1'], stats['q1'], stats['cilo'], 4017 stats['med'], stats['cihi'], stats['q3'], 4018 stats['q3'], stats['cihi'], stats['med'], 4019 stats['cilo'], stats['q1']] 4020 med_x = cap_x 4021 4022 # plain boxes 4023 else: 4024 box_x = [box_left, box_right, box_right, box_left, box_left] 4025 box_y = [stats['q1'], stats['q1'], stats['q3'], stats['q3'], 4026 stats['q1']] 4027 med_x = [box_left, box_right] 4028 4029 # maybe draw the box: 4030 if showbox: 4031 if patch_artist: 4032 boxes.extend(dopatch(box_x, box_y, **final_boxprops)) 4033 else: 4034 boxes.extend(doplot(box_x, box_y, **final_boxprops)) 4035 4036 # draw the whiskers 4037 whiskers.extend(doplot( 4038 whisker_x, whiskerlo_y, **final_whiskerprops 4039 )) 4040 whiskers.extend(doplot( 4041 whisker_x, whiskerhi_y, **final_whiskerprops 4042 )) 4043 4044 # maybe draw the caps: 4045 if showcaps: 4046 caps.extend(doplot(cap_x, cap_lo, **final_capprops)) 4047 caps.extend(doplot(cap_x, cap_hi, **final_capprops)) 4048 4049 # draw the medians 4050 medians.extend(doplot(med_x, med_y, **final_medianprops)) 4051 4052 # maybe draw the means 4053 if showmeans: 4054 if meanline: 4055 means.extend(doplot( 4056 [box_left, box_right], [stats['mean'], stats['mean']], 4057 **final_meanprops 4058 )) 4059 else: 4060 means.extend(doplot( 4061 [pos], [stats['mean']], **final_meanprops 4062 )) 4063 4064 # maybe draw the fliers 4065 if showfliers: 4066 # fliers coords 4067 flier_x = np.ones(len(stats['fliers'])) * pos 4068 flier_y = stats['fliers'] 4069 4070 fliers.extend(doplot( 4071 flier_x, flier_y, **final_flierprops 4072 )) 4073 4074 # fix our axes/ticks up a little 4075 if vert: 4076 setticks = self.set_xticks 4077 setlim = self.set_xlim 4078 setlabels = self.set_xticklabels 4079 else: 4080 setticks = self.set_yticks 4081 setlim = self.set_ylim 4082 setlabels = self.set_yticklabels 4083 4084 if manage_xticks: 4085 newlimits = min(positions) - 0.5, max(positions) + 0.5 4086 setlim(newlimits) 4087 setticks(positions) 4088 setlabels(datalabels) 4089 4090 # reset hold status 4091 self._hold = holdStatus 4092 4093 return dict(whiskers=whiskers, caps=caps, boxes=boxes, 4094 medians=medians, fliers=fliers, means=means) 4095 4096 @_preprocess_data(replace_names=["x", "y", "s", "linewidths", 4097 "edgecolors", "c", "facecolor", 4098 "facecolors", "color"], 4099 label_namer="y") 4100 def scatter(self, x, y, s=None, c=None, marker=None, cmap=None, norm=None, 4101 vmin=None, vmax=None, alpha=None, linewidths=None, 4102 verts=None, edgecolors=None, 4103 **kwargs): 4104 """ 4105 A scatter plot of *y* vs *x* with varying marker size and/or color. 4106 4107 Parameters 4108 ---------- 4109 x, y : array_like, shape (n, ) 4110 The data positions. 4111 4112 s : scalar or array_like, shape (n, ), optional 4113 The marker size in points**2. 4114 Default is ``rcParams['lines.markersize'] ** 2``. 4115 4116 c : color, sequence, or sequence of color, optional, default: 'b' 4117 The marker color. Possible values: 4118 4119 - A single color format string. 4120 - A sequence of color specifications of length n. 4121 - A sequence of n numbers to be mapped to colors using *cmap* and 4122 *norm*. 4123 - A 2-D array in which the rows are RGB or RGBA. 4124 4125 Note that *c* should not be a single numeric RGB or RGBA sequence 4126 because that is indistinguishable from an array of values to be 4127 colormapped. If you want to specify the same RGB or RGBA value for 4128 all points, use a 2-D array with a single row. 4129 4130 marker : `~matplotlib.markers.MarkerStyle`, optional, default: 'o' 4131 The marker style. *marker* can be either an instance of the class 4132 or the text shorthand for a particular marker. 4133 See `~matplotlib.markers` for more information marker styles. 4134 4135 cmap : `~matplotlib.colors.Colormap`, optional, default: None 4136 A `.Colormap` instance or registered colormap name. *cmap* is only 4137 used if *c* is an array of floats. If ``None``, defaults to rc 4138 ``image.cmap``. 4139 4140 norm : `~matplotlib.colors.Normalize`, optional, default: None 4141 A `.Normalize` instance is used to scale luminance data to 0, 1. 4142 *norm* is only used if *c* is an array of floats. If *None*, use 4143 the default `.colors.Normalize`. 4144 4145 vmin, vmax : scalar, optional, default: None 4146 *vmin* and *vmax* are used in conjunction with *norm* to normalize 4147 luminance data. If None, the respective min and max of the color 4148 array is used. *vmin* and *vmax* are ignored if you pass a *norm* 4149 instance. 4150 4151 alpha : scalar, optional, default: None 4152 The alpha blending value, between 0 (transparent) and 1 (opaque). 4153 4154 linewidths : scalar or array_like, optional, default: None 4155 The linewidth of the marker edges. Note: The default *edgecolors* 4156 is 'face'. You may want to change this as well. 4157 If *None*, defaults to rcParams ``lines.linewidth``. 4158 4159 verts : sequence of (x, y), optional 4160 If *marker* is *None*, these vertices will be used to construct 4161 the marker. The center of the marker is located at (0, 0) in 4162 normalized units. The overall marker is rescaled by *s*. 4163 4164 edgecolors : color or sequence of color, optional, default: 'face' 4165 The edge color of the marker. Possible values: 4166 4167 - 'face': The edge color will always be the same as the face color. 4168 - 'none': No patch boundary will be drawn. 4169 - A matplotib color. 4170 4171 For non-filled markers, the *edgecolors* kwarg is ignored and 4172 forced to 'face' internally. 4173 4174 Returns 4175 ------- 4176 paths : `~matplotlib.collections.PathCollection` 4177 4178 Other Parameters 4179 ---------------- 4180 **kwargs : `~matplotlib.collections.Collection` properties 4181 4182 See Also 4183 -------- 4184 plot : To plot scatter plots when markers are identical in size and 4185 color. 4186 4187 Notes 4188 ----- 4189 4190 * The `.plot` function will be faster for scatterplots where markers 4191 don't vary in size or color. 4192 4193 * Any or all of *x*, *y*, *s*, and *c* may be masked arrays, in which 4194 case all masks will be combined and only unmasked points will be 4195 plotted. 4196 4197 * Fundamentally, scatter works with 1-D arrays; *x*, *y*, *s*, and *c* 4198 may be input as 2-D arrays, but within scatter they will be 4199 flattened. The exception is *c*, which will be flattened only if its 4200 size matches the size of *x* and *y*. 4201 4202 """ 4203 4204 if not self._hold: 4205 self.cla() 4206 4207 # Process **kwargs to handle aliases, conflicts with explicit kwargs: 4208 4209 facecolors = None 4210 edgecolors = kwargs.pop('edgecolor', edgecolors) 4211 fc = kwargs.pop('facecolors', None) 4212 fc = kwargs.pop('facecolor', fc) 4213 if fc is not None: 4214 facecolors = fc 4215 co = kwargs.pop('color', None) 4216 if co is not None: 4217 try: 4218 mcolors.to_rgba_array(co) 4219 except ValueError: 4220 raise ValueError("'color' kwarg must be an mpl color" 4221 " spec or sequence of color specs.\n" 4222 "For a sequence of values to be" 4223 " color-mapped, use the 'c' kwarg instead.") 4224 if edgecolors is None: 4225 edgecolors = co 4226 if facecolors is None: 4227 facecolors = co 4228 if c is not None: 4229 raise ValueError("Supply a 'c' kwarg or a 'color' kwarg" 4230 " but not both; they differ but" 4231 " their functionalities overlap.") 4232 if c is None: 4233 if facecolors is not None: 4234 c = facecolors 4235 else: 4236 if rcParams['_internal.classic_mode']: 4237 c = 'b' # The original default 4238 else: 4239 c = self._get_patches_for_fill.get_next_color() 4240 c_none = True 4241 else: 4242 c_none = False 4243 4244 if edgecolors is None and not rcParams['_internal.classic_mode']: 4245 edgecolors = 'face' 4246 4247 self._process_unit_info(xdata=x, ydata=y, kwargs=kwargs) 4248 x = self.convert_xunits(x) 4249 y = self.convert_yunits(y) 4250 4251 # np.ma.ravel yields an ndarray, not a masked array, 4252 # unless its argument is a masked array. 4253 xy_shape = (np.shape(x), np.shape(y)) 4254 x = np.ma.ravel(x) 4255 y = np.ma.ravel(y) 4256 if x.size != y.size: 4257 raise ValueError("x and y must be the same size") 4258 4259 if s is None: 4260 if rcParams['_internal.classic_mode']: 4261 s = 20 4262 else: 4263 s = rcParams['lines.markersize'] ** 2.0 4264 4265 s = np.ma.ravel(s) # This doesn't have to match x, y in size. 4266 4267 # After this block, c_array will be None unless 4268 # c is an array for mapping. The potential ambiguity 4269 # with a sequence of 3 or 4 numbers is resolved in 4270 # favor of mapping, not rgb or rgba. 4271 if c_none or co is not None: 4272 c_array = None 4273 else: 4274 try: 4275 c_array = np.asanyarray(c, dtype=float) 4276 if c_array.shape in xy_shape: 4277 c = np.ma.ravel(c_array) 4278 else: 4279 # Wrong size; it must not be intended for mapping. 4280 c_array = None 4281 except ValueError: 4282 # Failed to make a floating-point array; c must be color specs. 4283 c_array = None 4284 4285 if c_array is None: 4286 try: 4287 # must be acceptable as PathCollection facecolors 4288 colors = mcolors.to_rgba_array(c) 4289 except ValueError: 4290 # c not acceptable as PathCollection facecolor 4291 raise ValueError("c of shape {} not acceptable as a color " 4292 "sequence for x with size {}, y with size {}" 4293 .format(c.shape, x.size, y.size)) 4294 else: 4295 colors = None # use cmap, norm after collection is created 4296 4297 # `delete_masked_points` only modifies arguments of the same length as 4298 # `x`. 4299 x, y, s, c, colors, edgecolors, linewidths =\ 4300 cbook.delete_masked_points( 4301 x, y, s, c, colors, edgecolors, linewidths) 4302 4303 scales = s # Renamed for readability below. 4304 4305 # to be API compatible 4306 if marker is None and verts is not None: 4307 marker = (verts, 0) 4308 verts = None 4309 4310 # load default marker from rcParams 4311 if marker is None: 4312 marker = rcParams['scatter.marker'] 4313 4314 if isinstance(marker, mmarkers.MarkerStyle): 4315 marker_obj = marker 4316 else: 4317 marker_obj = mmarkers.MarkerStyle(marker) 4318 4319 path = marker_obj.get_path().transformed( 4320 marker_obj.get_transform()) 4321 if not marker_obj.is_filled(): 4322 edgecolors = 'face' 4323 linewidths = rcParams['lines.linewidth'] 4324 4325 offsets = np.column_stack([x, y]) 4326 4327 collection = mcoll.PathCollection( 4328 (path,), scales, 4329 facecolors=colors, 4330 edgecolors=edgecolors, 4331 linewidths=linewidths, 4332 offsets=offsets, 4333 transOffset=kwargs.pop('transform', self.transData), 4334 alpha=alpha 4335 ) 4336 collection.set_transform(mtransforms.IdentityTransform()) 4337 collection.update(kwargs) 4338 4339 if colors is None: 4340 if norm is not None and not isinstance(norm, mcolors.Normalize): 4341 raise ValueError( 4342 "'norm' must be an instance of 'mcolors.Normalize'") 4343 collection.set_array(np.asarray(c)) 4344 collection.set_cmap(cmap) 4345 collection.set_norm(norm) 4346 4347 if vmin is not None or vmax is not None: 4348 collection.set_clim(vmin, vmax) 4349 else: 4350 collection.autoscale_None() 4351 4352 # Classic mode only: 4353 # ensure there are margins to allow for the 4354 # finite size of the symbols. In v2.x, margins 4355 # are present by default, so we disable this 4356 # scatter-specific override. 4357 if rcParams['_internal.classic_mode']: 4358 if self._xmargin < 0.05 and x.size > 0: 4359 self.set_xmargin(0.05) 4360 if self._ymargin < 0.05 and x.size > 0: 4361 self.set_ymargin(0.05) 4362 4363 self.add_collection(collection) 4364 self.autoscale_view() 4365 4366 return collection 4367 4368 @_preprocess_data(replace_names=["x", "y"], label_namer="y") 4369 @docstring.dedent_interpd 4370 def hexbin(self, x, y, C=None, gridsize=100, bins=None, 4371 xscale='linear', yscale='linear', extent=None, 4372 cmap=None, norm=None, vmin=None, vmax=None, 4373 alpha=None, linewidths=None, edgecolors='face', 4374 reduce_C_function=np.mean, mincnt=None, marginals=False, 4375 **kwargs): 4376 """ 4377 Make a hexagonal binning plot. 4378 4379 Make a hexagonal binning plot of *x* versus *y*, where *x*, 4380 *y* are 1-D sequences of the same length, *N*. If *C* is *None* 4381 (the default), this is a histogram of the number of occurrences 4382 of the observations at (x[i],y[i]). 4383 4384 If *C* is specified, it specifies values at the coordinate 4385 (x[i],y[i]). These values are accumulated for each hexagonal 4386 bin and then reduced according to *reduce_C_function*, which 4387 defaults to numpy's mean function (np.mean). (If *C* is 4388 specified, it must also be a 1-D sequence of the same length 4389 as *x* and *y*.) 4390 4391 Parameters 4392 ---------- 4393 x, y : array or masked array 4394 4395 C : array or masked array, optional, default is *None* 4396 4397 gridsize : int or (int, int), optional, default is 100 4398 The number of hexagons in the *x*-direction, default is 4399 100. The corresponding number of hexagons in the 4400 *y*-direction is chosen such that the hexagons are 4401 approximately regular. Alternatively, gridsize can be a 4402 tuple with two elements specifying the number of hexagons 4403 in the *x*-direction and the *y*-direction. 4404 4405 bins : {'log'} or int or sequence, optional, default is *None* 4406 If *None*, no binning is applied; the color of each hexagon 4407 directly corresponds to its count value. 4408 4409 If 'log', use a logarithmic scale for the color 4410 map. Internally, :math:`log_{10}(i+1)` is used to 4411 determine the hexagon color. 4412 4413 If an integer, divide the counts in the specified number 4414 of bins, and color the hexagons accordingly. 4415 4416 If a sequence of values, the values of the lower bound of 4417 the bins to be used. 4418 4419 xscale : {'linear', 'log'}, optional, default is 'linear' 4420 Use a linear or log10 scale on the horizontal axis. 4421 4422 yscale : {'linear', 'log'}, optional, default is 'linear' 4423 Use a linear or log10 scale on the vertical axis. 4424 4425 mincnt : int > 0, optional, default is *None* 4426 If not *None*, only display cells with more than *mincnt* 4427 number of points in the cell 4428 4429 marginals : bool, optional, default is *False* 4430 if marginals is *True*, plot the marginal density as 4431 colormapped rectagles along the bottom of the x-axis and 4432 left of the y-axis 4433 4434 extent : scalar, optional, default is *None* 4435 The limits of the bins. The default assigns the limits 4436 based on *gridsize*, *x*, *y*, *xscale* and *yscale*. 4437 4438 If *xscale* or *yscale* is set to 'log', the limits are 4439 expected to be the exponent for a power of 10. E.g. for 4440 x-limits of 1 and 50 in 'linear' scale and y-limits 4441 of 10 and 1000 in 'log' scale, enter (1, 50, 1, 3). 4442 4443 Order of scalars is (left, right, bottom, top). 4444 4445 Other Parameters 4446 ---------------- 4447 cmap : object, optional, default is *None* 4448 a :class:`matplotlib.colors.Colormap` instance. If *None*, 4449 defaults to rc ``image.cmap``. 4450 4451 norm : object, optional, default is *None* 4452 :class:`matplotlib.colors.Normalize` instance is used to 4453 scale luminance data to 0,1. 4454 4455 vmin, vmax : scalar, optional, default is *None* 4456 *vmin* and *vmax* are used in conjunction with *norm* to 4457 normalize luminance data. If *None*, the min and max of the 4458 color array *C* are used. Note if you pass a norm instance 4459 your settings for *vmin* and *vmax* will be ignored. 4460 4461 alpha : scalar between 0 and 1, optional, default is *None* 4462 the alpha value for the patches 4463 4464 linewidths : scalar, optional, default is *None* 4465 If *None*, defaults to 1.0. 4466 4467 edgecolors : {'face', 'none', *None*} or color, optional 4468 4469 If 'face' (the default), draws the edges in the same color as the 4470 fill color. 4471 4472 If 'none', no edge is drawn; this can sometimes lead to unsightly 4473 unpainted pixels between the hexagons. 4474 4475 If *None*, draws outlines in the default color. 4476 4477 If a matplotlib color arg, draws outlines in the specified color. 4478 4479 Returns 4480 ------- 4481 object 4482 a :class:`~matplotlib.collections.PolyCollection` instance; use 4483 :meth:`~matplotlib.collections.PolyCollection.get_array` on 4484 this :class:`~matplotlib.collections.PolyCollection` to get 4485 the counts in each hexagon. 4486 4487 If *marginals* is *True*, horizontal 4488 bar and vertical bar (both PolyCollections) will be attached 4489 to the return collection as attributes *hbar* and *vbar*. 4490 4491 Notes 4492 ----- 4493 The standard descriptions of all the 4494 :class:`~matplotlib.collections.Collection` parameters: 4495 4496 %(Collection)s 4497 4498 """ 4499 4500 if not self._hold: 4501 self.cla() 4502 4503 self._process_unit_info(xdata=x, ydata=y, kwargs=kwargs) 4504 4505 x, y, C = cbook.delete_masked_points(x, y, C) 4506 4507 # Set the size of the hexagon grid 4508 if iterable(gridsize): 4509 nx, ny = gridsize 4510 else: 4511 nx = gridsize 4512 ny = int(nx / math.sqrt(3)) 4513 # Count the number of data in each hexagon 4514 x = np.array(x, float) 4515 y = np.array(y, float) 4516 if xscale == 'log': 4517 if np.any(x <= 0.0): 4518 raise ValueError("x contains non-positive values, so can not" 4519 " be log-scaled") 4520 x = np.log10(x) 4521 if yscale == 'log': 4522 if np.any(y <= 0.0): 4523 raise ValueError("y contains non-positive values, so can not" 4524 " be log-scaled") 4525 y = np.log10(y) 4526 if extent is not None: 4527 xmin, xmax, ymin, ymax = extent 4528 else: 4529 xmin, xmax = (np.min(x), np.max(x)) if len(x) else (0, 1) 4530 ymin, ymax = (np.min(y), np.max(y)) if len(y) else (0, 1) 4531 4532 # to avoid issues with singular data, expand the min/max pairs 4533 xmin, xmax = mtransforms.nonsingular(xmin, xmax, expander=0.1) 4534 ymin, ymax = mtransforms.nonsingular(ymin, ymax, expander=0.1) 4535 4536 # In the x-direction, the hexagons exactly cover the region from 4537 # xmin to xmax. Need some padding to avoid roundoff errors. 4538 padding = 1.e-9 * (xmax - xmin) 4539 xmin -= padding 4540 xmax += padding 4541 sx = (xmax - xmin) / nx 4542 sy = (ymax - ymin) / ny 4543 4544 if marginals: 4545 xorig = x.copy() 4546 yorig = y.copy() 4547 4548 x = (x - xmin) / sx 4549 y = (y - ymin) / sy 4550 ix1 = np.round(x).astype(int) 4551 iy1 = np.round(y).astype(int) 4552 ix2 = np.floor(x).astype(int) 4553 iy2 = np.floor(y).astype(int) 4554 4555 nx1 = nx + 1 4556 ny1 = ny + 1 4557 nx2 = nx 4558 ny2 = ny 4559 n = nx1 * ny1 + nx2 * ny2 4560 4561 d1 = (x - ix1) ** 2 + 3.0 * (y - iy1) ** 2 4562 d2 = (x - ix2 - 0.5) ** 2 + 3.0 * (y - iy2 - 0.5) ** 2 4563 bdist = (d1 < d2) 4564 if C is None: 4565 lattice1 = np.zeros((nx1, ny1)) 4566 lattice2 = np.zeros((nx2, ny2)) 4567 4568 cond1 = (0 <= ix1) * (ix1 < nx1) * (0 <= iy1) * (iy1 < ny1) 4569 cond2 = (0 <= ix2) * (ix2 < nx2) * (0 <= iy2) * (iy2 < ny2) 4570 4571 cond1 *= bdist 4572 cond2 *= np.logical_not(bdist) 4573 ix1, iy1 = ix1[cond1], iy1[cond1] 4574 ix2, iy2 = ix2[cond2], iy2[cond2] 4575 4576 for ix, iy in zip(ix1, iy1): 4577 lattice1[ix, iy] += 1 4578 for ix, iy in zip(ix2, iy2): 4579 lattice2[ix, iy] += 1 4580 4581 # threshold 4582 if mincnt is not None: 4583 lattice1[lattice1 < mincnt] = np.nan 4584 lattice2[lattice2 < mincnt] = np.nan 4585 accum = np.hstack((lattice1.ravel(), 4586 lattice2.ravel())) 4587 good_idxs = ~np.isnan(accum) 4588 4589 else: 4590 if mincnt is None: 4591 mincnt = 0 4592 4593 # create accumulation arrays 4594 lattice1 = np.empty((nx1, ny1), dtype=object) 4595 for i in xrange(nx1): 4596 for j in xrange(ny1): 4597 lattice1[i, j] = [] 4598 lattice2 = np.empty((nx2, ny2), dtype=object) 4599 for i in xrange(nx2): 4600 for j in xrange(ny2): 4601 lattice2[i, j] = [] 4602 4603 for i in xrange(len(x)): 4604 if bdist[i]: 4605 if 0 <= ix1[i] < nx1 and 0 <= iy1[i] < ny1: 4606 lattice1[ix1[i], iy1[i]].append(C[i]) 4607 else: 4608 if 0 <= ix2[i] < nx2 and 0 <= iy2[i] < ny2: 4609 lattice2[ix2[i], iy2[i]].append(C[i]) 4610 4611 for i in xrange(nx1): 4612 for j in xrange(ny1): 4613 vals = lattice1[i, j] 4614 if len(vals) > mincnt: 4615 lattice1[i, j] = reduce_C_function(vals) 4616 else: 4617 lattice1[i, j] = np.nan 4618 for i in xrange(nx2): 4619 for j in xrange(ny2): 4620 vals = lattice2[i, j] 4621 if len(vals) > mincnt: 4622 lattice2[i, j] = reduce_C_function(vals) 4623 else: 4624 lattice2[i, j] = np.nan 4625 4626 accum = np.hstack((lattice1.astype(float).ravel(), 4627 lattice2.astype(float).ravel())) 4628 good_idxs = ~np.isnan(accum) 4629 4630 offsets = np.zeros((n, 2), float) 4631 offsets[:nx1 * ny1, 0] = np.repeat(np.arange(nx1), ny1) 4632 offsets[:nx1 * ny1, 1] = np.tile(np.arange(ny1), nx1) 4633 offsets[nx1 * ny1:, 0] = np.repeat(np.arange(nx2) + 0.5, ny2) 4634 offsets[nx1 * ny1:, 1] = np.tile(np.arange(ny2), nx2) + 0.5 4635 offsets[:, 0] *= sx 4636 offsets[:, 1] *= sy 4637 offsets[:, 0] += xmin 4638 offsets[:, 1] += ymin 4639 # remove accumulation bins with no data 4640 offsets = offsets[good_idxs, :] 4641 accum = accum[good_idxs] 4642 4643 polygon = np.zeros((6, 2), float) 4644 polygon[:, 0] = sx * np.array([0.5, 0.5, 0.0, -0.5, -0.5, 0.0]) 4645 polygon[:, 1] = sy * np.array([-0.5, 0.5, 1.0, 0.5, -0.5, -1.0]) / 3.0 4646 4647 if linewidths is None: 4648 linewidths = [1.0] 4649 4650 if xscale == 'log' or yscale == 'log': 4651 polygons = np.expand_dims(polygon, 0) + np.expand_dims(offsets, 1) 4652 if xscale == 'log': 4653 polygons[:, :, 0] = 10.0 ** polygons[:, :, 0] 4654 xmin = 10.0 ** xmin 4655 xmax = 10.0 ** xmax 4656 self.set_xscale(xscale) 4657 if yscale == 'log': 4658 polygons[:, :, 1] = 10.0 ** polygons[:, :, 1] 4659 ymin = 10.0 ** ymin 4660 ymax = 10.0 ** ymax 4661 self.set_yscale(yscale) 4662 collection = mcoll.PolyCollection( 4663 polygons, 4664 edgecolors=edgecolors, 4665 linewidths=linewidths, 4666 ) 4667 else: 4668 collection = mcoll.PolyCollection( 4669 [polygon], 4670 edgecolors=edgecolors, 4671 linewidths=linewidths, 4672 offsets=offsets, 4673 transOffset=mtransforms.IdentityTransform(), 4674 offset_position="data" 4675 ) 4676 4677 if isinstance(norm, mcolors.LogNorm): 4678 if (accum == 0).any(): 4679 # make sure we have not zeros 4680 accum += 1 4681 4682 # autoscale the norm with curren accum values if it hasn't 4683 # been set 4684 if norm is not None: 4685 if norm.vmin is None and norm.vmax is None: 4686 norm.autoscale(accum) 4687 4688 # Transform accum if needed 4689 if bins == 'log': 4690 accum = np.log10(accum + 1) 4691 elif bins is not None: 4692 if not iterable(bins): 4693 minimum, maximum = min(accum), max(accum) 4694 bins -= 1 # one less edge than bins 4695 bins = minimum + (maximum - minimum) * np.arange(bins) / bins 4696 bins = np.sort(bins) 4697 accum = bins.searchsorted(accum) 4698 4699 if norm is not None and not isinstance(norm, mcolors.Normalize): 4700 raise ValueError( 4701 "'norm' must be an instance of 'mcolors.Normalize'") 4702 collection.set_array(accum) 4703 collection.set_cmap(cmap) 4704 collection.set_norm(norm) 4705 collection.set_alpha(alpha) 4706 collection.update(kwargs) 4707 4708 if vmin is not None or vmax is not None: 4709 collection.set_clim(vmin, vmax) 4710 else: 4711 collection.autoscale_None() 4712 4713 corners = ((xmin, ymin), (xmax, ymax)) 4714 self.update_datalim(corners) 4715 collection.sticky_edges.x[:] = [xmin, xmax] 4716 collection.sticky_edges.y[:] = [ymin, ymax] 4717 self.autoscale_view(tight=True) 4718 4719 # add the collection last 4720 self.add_collection(collection, autolim=False) 4721 if not marginals: 4722 return collection 4723 4724 if C is None: 4725 C = np.ones(len(x)) 4726 4727 def coarse_bin(x, y, coarse): 4728 ind = coarse.searchsorted(x).clip(0, len(coarse) - 1) 4729 mus = np.zeros(len(coarse)) 4730 for i in range(len(coarse)): 4731 yi = y[ind == i] 4732 if len(yi) > 0: 4733 mu = reduce_C_function(yi) 4734 else: 4735 mu = np.nan 4736 mus[i] = mu 4737 return mus 4738 4739 coarse = np.linspace(xmin, xmax, gridsize) 4740 4741 xcoarse = coarse_bin(xorig, C, coarse) 4742 valid = ~np.isnan(xcoarse) 4743 verts, values = [], [] 4744 for i, val in enumerate(xcoarse): 4745 thismin = coarse[i] 4746 if i < len(coarse) - 1: 4747 thismax = coarse[i + 1] 4748 else: 4749 thismax = thismin + np.diff(coarse)[-1] 4750 4751 if not valid[i]: 4752 continue 4753 4754 verts.append([(thismin, 0), 4755 (thismin, 0.05), 4756 (thismax, 0.05), 4757 (thismax, 0)]) 4758 values.append(val) 4759 4760 values = np.array(values) 4761 trans = self.get_xaxis_transform(which='grid') 4762 4763 hbar = mcoll.PolyCollection(verts, transform=trans, edgecolors='face') 4764 4765 hbar.set_array(values) 4766 hbar.set_cmap(cmap) 4767 hbar.set_norm(norm) 4768 hbar.set_alpha(alpha) 4769 hbar.update(kwargs) 4770 self.add_collection(hbar, autolim=False) 4771 4772 coarse = np.linspace(ymin, ymax, gridsize) 4773 ycoarse = coarse_bin(yorig, C, coarse) 4774 valid = ~np.isnan(ycoarse) 4775 verts, values = [], [] 4776 for i, val in enumerate(ycoarse): 4777 thismin = coarse[i] 4778 if i < len(coarse) - 1: 4779 thismax = coarse[i + 1] 4780 else: 4781 thismax = thismin + np.diff(coarse)[-1] 4782 if not valid[i]: 4783 continue 4784 verts.append([(0, thismin), (0.0, thismax), 4785 (0.05, thismax), (0.05, thismin)]) 4786 values.append(val) 4787 4788 values = np.array(values) 4789 4790 trans = self.get_yaxis_transform(which='grid') 4791 4792 vbar = mcoll.PolyCollection(verts, transform=trans, edgecolors='face') 4793 vbar.set_array(values) 4794 vbar.set_cmap(cmap) 4795 vbar.set_norm(norm) 4796 vbar.set_alpha(alpha) 4797 vbar.update(kwargs) 4798 self.add_collection(vbar, autolim=False) 4799 4800 collection.hbar = hbar 4801 collection.vbar = vbar 4802 4803 def on_changed(collection): 4804 hbar.set_cmap(collection.get_cmap()) 4805 hbar.set_clim(collection.get_clim()) 4806 vbar.set_cmap(collection.get_cmap()) 4807 vbar.set_clim(collection.get_clim()) 4808 4809 collection.callbacksSM.connect('changed', on_changed) 4810 4811 return collection 4812 4813 @docstring.dedent_interpd 4814 def arrow(self, x, y, dx, dy, **kwargs): 4815 """ 4816 Add an arrow to the axes. 4817 4818 This draws an arrow from ``(x, y)`` to ``(x+dx, y+dy)``. 4819 4820 Parameters 4821 ---------- 4822 x, y : float 4823 The x/y-coordinate of the arrow base. 4824 dx, dy : float 4825 The length of the arrow along x/y-direction. 4826 4827 Returns 4828 ------- 4829 arrow : `.FancyArrow` 4830 The created `.FancyArrow` object. 4831 4832 Other Parameters 4833 ---------------- 4834 **kwargs 4835 Optional kwargs (inherited from `.FancyArrow` patch) control the 4836 arrow construction and properties: 4837 4838 %(FancyArrow)s 4839 4840 Notes 4841 ----- 4842 The resulting arrow is affected by the axes aspect ratio and limits. 4843 This may produce an arrow whose head is not square with its stem. To 4844 create an arrow whose head is square with its stem, 4845 use :meth:`annotate` for example: 4846 4847 >>> ax.annotate("", xy=(0.5, 0.5), xytext=(0, 0), 4848 ... arrowprops=dict(arrowstyle="->")) 4849 4850 """ 4851 # Strip away units for the underlying patch since units 4852 # do not make sense to most patch-like code 4853 x = self.convert_xunits(x) 4854 y = self.convert_yunits(y) 4855 dx = self.convert_xunits(dx) 4856 dy = self.convert_yunits(dy) 4857 4858 a = mpatches.FancyArrow(x, y, dx, dy, **kwargs) 4859 self.add_artist(a) 4860 return a 4861 4862 def quiverkey(self, *args, **kw): 4863 qk = mquiver.QuiverKey(*args, **kw) 4864 self.add_artist(qk) 4865 return qk 4866 quiverkey.__doc__ = mquiver.QuiverKey.quiverkey_doc 4867 4868 # Handle units for x and y, if they've been passed 4869 def _quiver_units(self, args, kw): 4870 if len(args) > 3: 4871 x, y = args[0:2] 4872 self._process_unit_info(xdata=x, ydata=y, kwargs=kw) 4873 x = self.convert_xunits(x) 4874 y = self.convert_yunits(y) 4875 return (x, y) + args[2:] 4876 return args 4877 4878 # args can by a combination if X, Y, U, V, C and all should be replaced 4879 @_preprocess_data(replace_all_args=True, label_namer=None) 4880 def quiver(self, *args, **kw): 4881 if not self._hold: 4882 self.cla() 4883 4884 # Make sure units are handled for x and y values 4885 args = self._quiver_units(args, kw) 4886 4887 q = mquiver.Quiver(self, *args, **kw) 4888 4889 self.add_collection(q, autolim=True) 4890 self.autoscale_view() 4891 return q 4892 quiver.__doc__ = mquiver.Quiver.quiver_doc 4893 4894 # args can by either Y or y1,y2,... and all should be replaced 4895 @_preprocess_data(replace_all_args=True, label_namer=None) 4896 def stackplot(self, x, *args, **kwargs): 4897 return mstack.stackplot(self, x, *args, **kwargs) 4898 stackplot.__doc__ = mstack.stackplot.__doc__ 4899 4900 @_preprocess_data(replace_names=["x", "y", "u", "v", "start_points"], 4901 label_namer=None) 4902 def streamplot(self, x, y, u, v, density=1, linewidth=None, color=None, 4903 cmap=None, norm=None, arrowsize=1, arrowstyle='-|>', 4904 minlength=0.1, transform=None, zorder=None, 4905 start_points=None, maxlength=4.0, 4906 integration_direction='both'): 4907 if not self._hold: 4908 self.cla() 4909 stream_container = mstream.streamplot( 4910 self, x, y, u, v, 4911 density=density, 4912 linewidth=linewidth, 4913 color=color, 4914 cmap=cmap, 4915 norm=norm, 4916 arrowsize=arrowsize, 4917 arrowstyle=arrowstyle, 4918 minlength=minlength, 4919 start_points=start_points, 4920 transform=transform, 4921 zorder=zorder, 4922 maxlength=maxlength, 4923 integration_direction=integration_direction) 4924 return stream_container 4925 streamplot.__doc__ = mstream.streamplot.__doc__ 4926 4927 # args can be some combination of X, Y, U, V, C and all should be replaced 4928 @_preprocess_data(replace_all_args=True, label_namer=None) 4929 @docstring.dedent_interpd 4930 def barbs(self, *args, **kw): 4931 """ 4932 %(barbs_doc)s 4933 """ 4934 if not self._hold: 4935 self.cla() 4936 4937 # Make sure units are handled for x and y values 4938 args = self._quiver_units(args, kw) 4939 4940 b = mquiver.Barbs(self, *args, **kw) 4941 self.add_collection(b, autolim=True) 4942 self.autoscale_view() 4943 return b 4944 4945 @_preprocess_data(replace_names=["x", "y"], label_namer=None, 4946 positional_parameter_names=["x", "y", "c"]) 4947 def fill(self, *args, **kwargs): 4948 """ 4949 Plot filled polygons. 4950 4951 Parameters 4952 ---------- 4953 args : sequence of x, y, [color] 4954 Each polygon is defined by the lists of *x* and *y* positions of 4955 its nodes, optionally followed by by a *color* specifier. See 4956 :mod:`matplotlib.colors` for supported color specifiers. The 4957 standard color cycle is used for polygons without a color 4958 specifier. 4959 4960 You can plot multiple polygons by providing multiple *x*, *y*, 4961 *[color]* groups. 4962 4963 For example, each of the following is legal:: 4964 4965 ax.fill(x, y) # a polygon with default color 4966 ax.fill(x, y, "b") # a blue polygon 4967 ax.fill(x, y, x2, y2) # two polygons 4968 ax.fill(x, y, "b", x2, y2, "r") # a blue and a red polygon 4969 4970 Returns 4971 ------- 4972 a list of :class:`~matplotlib.patches.Polygon` 4973 4974 Other Parameters 4975 ---------------- 4976 **kwargs : :class:`~matplotlib.patches.Polygon` properties 4977 4978 Notes 4979 ----- 4980 Use :meth:`fill_between` if you would like to fill the region between 4981 two curves. 4982 """ 4983 if not self._hold: 4984 self.cla() 4985 4986 kwargs = cbook.normalize_kwargs(kwargs, _alias_map) 4987 4988 patches = [] 4989 for poly in self._get_patches_for_fill(*args, **kwargs): 4990 self.add_patch(poly) 4991 patches.append(poly) 4992 self.autoscale_view() 4993 return patches 4994 4995 @_preprocess_data(replace_names=["x", "y1", "y2", "where"], 4996 label_namer=None) 4997 @docstring.dedent_interpd 4998 def fill_between(self, x, y1, y2=0, where=None, interpolate=False, 4999 step=None, **kwargs): 5000 """ 5001 Fill the area between two horizontal curves. 5002 5003 The curves are defined by the points (*x*, *y1*) and (*x*, *y2*). This 5004 creates one or multiple polygons describing the filled area. 5005 5006 You may exclude some horizontal sections from filling using *where*. 5007 5008 By default, the edges connect the given points directly. Use *step* if 5009 the filling should be a step function, i.e. constant in between *x*. 5010 5011 5012 Parameters 5013 ---------- 5014 x : array (length N) 5015 The x coordinates of the nodes defining the curves. 5016 5017 y1 : array (length N) or scalar 5018 The y coordinates of the nodes defining the first curve. 5019 5020 y2 : array (length N) or scalar, optional, default: 0 5021 The y coordinates of the nodes defining the second curve. 5022 5023 where : array of bool (length N), optional, default: None 5024 Define *where* to exclude some horizontal regions from being 5025 filled. The filled regions are defined by the coordinates 5026 ``x[where]``. More precisely, fill between ``x[i]`` and ``x[i+1]`` 5027 if ``where[i] and where[i+1]``. Note that this definition implies 5028 that an isolated *True* value between two *False* values in 5029 *where* will not result in filling. Both sides of the *True* 5030 position remain unfilled due to the adjacent *False* values. 5031 5032 interpolate : bool, optional 5033 This option is only relvant if *where* is used and the two curves 5034 are crossing each other. 5035 5036 Semantically, *where* is often used for *y1* > *y2* or similar. 5037 By default, the nodes of the polygon defining the filled region 5038 will only be placed at the positions in the *x* array. Such a 5039 polygon cannot describe the above semantics close to the 5040 intersection. The x-sections containing the intersection are 5041 simply clipped. 5042 5043 Setting *interpolate* to *True* will calculate the actual 5044 intersection point and extend the filled region up to this point. 5045 5046 step : {'pre', 'post', 'mid'}, optional 5047 Define *step* if the filling should be a step function, 5048 i.e. constant in between *x*. The value determines where the 5049 step will occur: 5050 5051 - 'pre': The y value is continued constantly to the left from 5052 every *x* position, i.e. the interval ``(x[i-1], x[i]]`` has the 5053 value ``y[i]``. 5054 - 'post': The y value is continued constantly to the right from 5055 every *x* position, i.e. the interval ``[x[i], x[i+1])`` has the 5056 value ``y[i]``. 5057 - 'mid': Steps occur half-way between the *x* positions. 5058 5059 Other Parameters 5060 ---------------- 5061 **kwargs 5062 All other keyword arguments are passed on to `.PolyCollection`. 5063 They control the `.Polygon` properties: 5064 5065 %(PolyCollection)s 5066 5067 Returns 5068 ------- 5069 `.PolyCollection` 5070 A `.PolyCollection` containing the plotted polygons. 5071 5072 See Also 5073 -------- 5074 fill_betweenx : Fill between two sets of x-values. 5075 5076 Notes 5077 ----- 5078 .. [notes section required to get data note injection right] 5079 5080 """ 5081 if not rcParams['_internal.classic_mode']: 5082 color_aliases = mcoll._color_aliases 5083 kwargs = cbook.normalize_kwargs(kwargs, color_aliases) 5084 5085 if not any(c in kwargs for c in ('color', 'facecolors')): 5086 fc = self._get_patches_for_fill.get_next_color() 5087 kwargs['facecolors'] = fc 5088 5089 # Handle united data, such as dates 5090 self._process_unit_info(xdata=x, ydata=y1, kwargs=kwargs) 5091 self._process_unit_info(ydata=y2) 5092 5093 # Convert the arrays so we can work with them 5094 x = ma.masked_invalid(self.convert_xunits(x)) 5095 y1 = ma.masked_invalid(self.convert_yunits(y1)) 5096 y2 = ma.masked_invalid(self.convert_yunits(y2)) 5097 5098 for name, array in [('x', x), ('y1', y1), ('y2', y2)]: 5099 if array.ndim > 1: 5100 raise ValueError('Input passed into argument "%r"' % name + 5101 'is not 1-dimensional.') 5102 5103 if where is None: 5104 where = True 5105 where = where & ~functools.reduce(np.logical_or, 5106 map(np.ma.getmask, [x, y1, y2])) 5107 5108 x, y1, y2 = np.broadcast_arrays(np.atleast_1d(x), y1, y2) 5109 5110 polys = [] 5111 for ind0, ind1 in cbook.contiguous_regions(where): 5112 xslice = x[ind0:ind1] 5113 y1slice = y1[ind0:ind1] 5114 y2slice = y2[ind0:ind1] 5115 if step is not None: 5116 step_func = STEP_LOOKUP_MAP["steps-" + step] 5117 xslice, y1slice, y2slice = step_func(xslice, y1slice, y2slice) 5118 5119 if not len(xslice): 5120 continue 5121 5122 N = len(xslice) 5123 X = np.zeros((2 * N + 2, 2), float) 5124 5125 if interpolate: 5126 def get_interp_point(ind): 5127 im1 = max(ind - 1, 0) 5128 x_values = x[im1:ind + 1] 5129 diff_values = y1[im1:ind + 1] - y2[im1:ind + 1] 5130 y1_values = y1[im1:ind + 1] 5131 5132 if len(diff_values) == 2: 5133 if np.ma.is_masked(diff_values[1]): 5134 return x[im1], y1[im1] 5135 elif np.ma.is_masked(diff_values[0]): 5136 return x[ind], y1[ind] 5137 5138 diff_order = diff_values.argsort() 5139 diff_root_x = np.interp( 5140 0, diff_values[diff_order], x_values[diff_order]) 5141 x_order = x_values.argsort() 5142 diff_root_y = np.interp(diff_root_x, x_values[x_order], 5143 y1_values[x_order]) 5144 return diff_root_x, diff_root_y 5145 5146 start = get_interp_point(ind0) 5147 end = get_interp_point(ind1) 5148 else: 5149 # the purpose of the next two lines is for when y2 is a 5150 # scalar like 0 and we want the fill to go all the way 5151 # down to 0 even if none of the y1 sample points do 5152 start = xslice[0], y2slice[0] 5153 end = xslice[-1], y2slice[-1] 5154 5155 X[0] = start 5156 X[N + 1] = end 5157 5158 X[1:N + 1, 0] = xslice 5159 X[1:N + 1, 1] = y1slice 5160 X[N + 2:, 0] = xslice[::-1] 5161 X[N + 2:, 1] = y2slice[::-1] 5162 5163 polys.append(X) 5164 5165 collection = mcoll.PolyCollection(polys, **kwargs) 5166 5167 # now update the datalim and autoscale 5168 XY1 = np.array([x[where], y1[where]]).T 5169 XY2 = np.array([x[where], y2[where]]).T 5170 self.dataLim.update_from_data_xy(XY1, self.ignore_existing_data_limits, 5171 updatex=True, updatey=True) 5172 self.ignore_existing_data_limits = False 5173 self.dataLim.update_from_data_xy(XY2, self.ignore_existing_data_limits, 5174 updatex=False, updatey=True) 5175 self.add_collection(collection, autolim=False) 5176 self.autoscale_view() 5177 return collection 5178 5179 @_preprocess_data(replace_names=["y", "x1", "x2", "where"], 5180 label_namer=None) 5181 @docstring.dedent_interpd 5182 def fill_betweenx(self, y, x1, x2=0, where=None, 5183 step=None, interpolate=False, **kwargs): 5184 """ 5185 Fill the area between two vertical curves. 5186 5187 The curves are defined by the points (*x1*, *y*) and (*x2*, *y*). This 5188 creates one or multiple polygons describing the filled area. 5189 5190 You may exclude some vertical sections from filling using *where*. 5191 5192 By default, the edges connect the given points directly. Use *step* if 5193 the filling should be a step function, i.e. constant in between *y*. 5194 5195 5196 Parameters 5197 ---------- 5198 y : array (length N) 5199 The y coordinates of the nodes defining the curves. 5200 5201 x1 : array (length N) or scalar 5202 The x coordinates of the nodes defining the first curve. 5203 5204 x2 : array (length N) or scalar, optional, default: 0 5205 The x coordinates of the nodes defining the second curve. 5206 5207 where : array of bool (length N), optional, default: None 5208 Define *where* to exclude some vertical regions from being 5209 filled. The filled regions are defined by the coordinates 5210 ``y[where]``. More precisely, fill between ``y[i]`` and ``y[i+1]`` 5211 if ``where[i] and where[i+1]``. Note that this definition implies 5212 that an isolated *True* value between two *False* values in 5213 *where* will not result in filling. Both sides of the *True* 5214 position remain unfilled due to the adjacent *False* values. 5215 5216 interpolate : bool, optional 5217 This option is only relvant if *where* is used and the two curves 5218 are crossing each other. 5219 5220 Semantically, *where* is often used for *x1* > *x2* or similar. 5221 By default, the nodes of the polygon defining the filled region 5222 will only be placed at the positions in the *y* array. Such a 5223 polygon cannot describe the above semantics close to the 5224 intersection. The y-sections containing the intersecion are 5225 simply clipped. 5226 5227 Setting *interpolate* to *True* will calculate the actual 5228 interscection point and extend the filled region up to this point. 5229 5230 step : {'pre', 'post', 'mid'}, optional 5231 Define *step* if the filling should be a step function, 5232 i.e. constant in between *y*. The value determines where the 5233 step will occur: 5234 5235 - 'pre': The y value is continued constantly to the left from 5236 every *x* position, i.e. the interval ``(x[i-1], x[i]]`` has the 5237 value ``y[i]``. 5238 - 'post': The y value is continued constantly to the right from 5239 every *x* position, i.e. the interval ``[x[i], x[i+1])`` has the 5240 value ``y[i]``. 5241 - 'mid': Steps occur half-way between the *x* positions. 5242 5243 Other Parameters 5244 ---------------- 5245 **kwargs 5246 All other keyword arguments are passed on to `.PolyCollection`. 5247 They control the `.Polygon` properties: 5248 5249 %(PolyCollection)s 5250 5251 Returns 5252 ------- 5253 `.PolyCollection` 5254 A `.PolyCollection` containing the plotted polygons. 5255 5256 See Also 5257 -------- 5258 fill_between : Fill between two sets of y-values. 5259 5260 Notes 5261 ----- 5262 .. [notes section required to get data note injection right] 5263 5264 """ 5265 if not rcParams['_internal.classic_mode']: 5266 color_aliases = mcoll._color_aliases 5267 kwargs = cbook.normalize_kwargs(kwargs, color_aliases) 5268 5269 if not any(c in kwargs for c in ('color', 'facecolors')): 5270 fc = self._get_patches_for_fill.get_next_color() 5271 kwargs['facecolors'] = fc 5272 # Handle united data, such as dates 5273 self._process_unit_info(ydata=y, xdata=x1, kwargs=kwargs) 5274 self._process_unit_info(xdata=x2) 5275 5276 # Convert the arrays so we can work with them 5277 y = ma.masked_invalid(self.convert_yunits(y)) 5278 x1 = ma.masked_invalid(self.convert_xunits(x1)) 5279 x2 = ma.masked_invalid(self.convert_xunits(x2)) 5280 5281 for name, array in [('y', y), ('x1', x1), ('x2', x2)]: 5282 if array.ndim > 1: 5283 raise ValueError('Input passed into argument "%r"' % name + 5284 'is not 1-dimensional.') 5285 5286 if where is None: 5287 where = True 5288 where = where & ~functools.reduce(np.logical_or, 5289 map(np.ma.getmask, [y, x1, x2])) 5290 5291 y, x1, x2 = np.broadcast_arrays(np.atleast_1d(y), x1, x2) 5292 5293 polys = [] 5294 for ind0, ind1 in cbook.contiguous_regions(where): 5295 yslice = y[ind0:ind1] 5296 x1slice = x1[ind0:ind1] 5297 x2slice = x2[ind0:ind1] 5298 if step is not None: 5299 step_func = STEP_LOOKUP_MAP["steps-" + step] 5300 yslice, x1slice, x2slice = step_func(yslice, x1slice, x2slice) 5301 5302 if not len(yslice): 5303 continue 5304 5305 N = len(yslice) 5306 Y = np.zeros((2 * N + 2, 2), float) 5307 if interpolate: 5308 def get_interp_point(ind): 5309 im1 = max(ind - 1, 0) 5310 y_values = y[im1:ind + 1] 5311 diff_values = x1[im1:ind + 1] - x2[im1:ind + 1] 5312 x1_values = x1[im1:ind + 1] 5313 5314 if len(diff_values) == 2: 5315 if np.ma.is_masked(diff_values[1]): 5316 return x1[im1], y[im1] 5317 elif np.ma.is_masked(diff_values[0]): 5318 return x1[ind], y[ind] 5319 5320 diff_order = diff_values.argsort() 5321 diff_root_y = np.interp( 5322 0, diff_values[diff_order], y_values[diff_order]) 5323 y_order = y_values.argsort() 5324 diff_root_x = np.interp(diff_root_y, y_values[y_order], 5325 x1_values[y_order]) 5326 return diff_root_x, diff_root_y 5327 5328 start = get_interp_point(ind0) 5329 end = get_interp_point(ind1) 5330 else: 5331 # the purpose of the next two lines is for when x2 is a 5332 # scalar like 0 and we want the fill to go all the way 5333 # down to 0 even if none of the x1 sample points do 5334 start = x2slice[0], yslice[0] 5335 end = x2slice[-1], yslice[-1] 5336 5337 Y[0] = start 5338 Y[N + 1] = end 5339 5340 Y[1:N + 1, 0] = x1slice 5341 Y[1:N + 1, 1] = yslice 5342 Y[N + 2:, 0] = x2slice[::-1] 5343 Y[N + 2:, 1] = yslice[::-1] 5344 5345 polys.append(Y) 5346 5347 collection = mcoll.PolyCollection(polys, **kwargs) 5348 5349 # now update the datalim and autoscale 5350 X1Y = np.array([x1[where], y[where]]).T 5351 X2Y = np.array([x2[where], y[where]]).T 5352 self.dataLim.update_from_data_xy(X1Y, self.ignore_existing_data_limits, 5353 updatex=True, updatey=True) 5354 self.ignore_existing_data_limits = False 5355 self.dataLim.update_from_data_xy(X2Y, self.ignore_existing_data_limits, 5356 updatex=True, updatey=False) 5357 self.add_collection(collection, autolim=False) 5358 self.autoscale_view() 5359 return collection 5360 5361 #### plotting z(x,y): imshow, pcolor and relatives, contour 5362 @_preprocess_data(label_namer=None) 5363 def imshow(self, X, cmap=None, norm=None, aspect=None, 5364 interpolation=None, alpha=None, vmin=None, vmax=None, 5365 origin=None, extent=None, shape=None, filternorm=1, 5366 filterrad=4.0, imlim=None, resample=None, url=None, **kwargs): 5367 """ 5368 Display an image on the axes. 5369 5370 Parameters 5371 ---------- 5372 X : array_like, shape (n, m) or (n, m, 3) or (n, m, 4) 5373 Display the image in `X` to current axes. `X` may be an 5374 array or a PIL image. If `X` is an array, it 5375 can have the following shapes and types: 5376 5377 - MxN -- values to be mapped (float or int) 5378 - MxNx3 -- RGB (float or uint8) 5379 - MxNx4 -- RGBA (float or uint8) 5380 5381 MxN arrays are mapped to colors based on the `norm` (mapping 5382 scalar to scalar) and the `cmap` (mapping the normed scalar to 5383 a color). 5384 5385 Elements of RGB and RGBA arrays represent pixels of an MxN image. 5386 All values should be in the range [0 .. 1] for floats or 5387 [0 .. 255] for integers. Out-of-range values will be clipped to 5388 these bounds. 5389 5390 cmap : `~matplotlib.colors.Colormap`, optional, default: None 5391 If None, default to rc `image.cmap` value. `cmap` is ignored 5392 if `X` is 3-D, directly specifying RGB(A) values. 5393 5394 aspect : ['auto' | 'equal' | scalar], optional, default: None 5395 If 'auto', changes the image aspect ratio to match that of the 5396 axes. 5397 5398 If 'equal', and `extent` is None, changes the axes aspect ratio to 5399 match that of the image. If `extent` is not `None`, the axes 5400 aspect ratio is changed to match that of the extent. 5401 5402 If None, default to rc ``image.aspect`` value. 5403 5404 interpolation : string, optional, default: None 5405 Acceptable values are 'none', 'nearest', 'bilinear', 'bicubic', 5406 'spline16', 'spline36', 'hanning', 'hamming', 'hermite', 'kaiser', 5407 'quadric', 'catrom', 'gaussian', 'bessel', 'mitchell', 'sinc', 5408 'lanczos' 5409 5410 If `interpolation` is None, default to rc `image.interpolation`. 5411 See also the `filternorm` and `filterrad` parameters. 5412 If `interpolation` is 'none', then no interpolation is performed 5413 on the Agg, ps and pdf backends. Other backends will fall back to 5414 'nearest'. 5415 5416 norm : `~matplotlib.colors.Normalize`, optional, default: None 5417 A `~matplotlib.colors.Normalize` instance is used to scale 5418 a 2-D float `X` input to the (0, 1) range for input to the 5419 `cmap`. If `norm` is None, use the default func:`normalize`. 5420 If `norm` is an instance of `~matplotlib.colors.NoNorm`, 5421 `X` must be an array of integers that index directly into 5422 the lookup table of the `cmap`. 5423 5424 vmin, vmax : scalar, optional, default: None 5425 `vmin` and `vmax` are used in conjunction with norm to normalize 5426 luminance data. Note if you pass a `norm` instance, your 5427 settings for `vmin` and `vmax` will be ignored. 5428 5429 alpha : scalar, optional, default: None 5430 The alpha blending value, between 0 (transparent) and 1 (opaque). 5431 The ``alpha`` argument is ignored for RGBA input data. 5432 5433 origin : ['upper' | 'lower'], optional, default: None 5434 Place the [0,0] index of the array in the upper left or lower left 5435 corner of the axes. If None, default to rc `image.origin`. 5436 5437 extent : scalars (left, right, bottom, top), optional, default: None 5438 The location, in data-coordinates, of the lower-left and 5439 upper-right corners. If `None`, the image is positioned such that 5440 the pixel centers fall on zero-based (row, column) indices. 5441 5442 shape : scalars (columns, rows), optional, default: None 5443 For raw buffer images 5444 5445 filternorm : scalar, optional, default: 1 5446 A parameter for the antigrain image resize filter. From the 5447 antigrain documentation, if `filternorm` = 1, the filter 5448 normalizes integer values and corrects the rounding errors. It 5449 doesn't do anything with the source floating point values, it 5450 corrects only integers according to the rule of 1.0 which means 5451 that any sum of pixel weights must be equal to 1.0. So, the 5452 filter function must produce a graph of the proper shape. 5453 5454 filterrad : scalar, optional, default: 4.0 5455 The filter radius for filters that have a radius parameter, i.e. 5456 when interpolation is one of: 'sinc', 'lanczos' or 'blackman' 5457 5458 Returns 5459 ------- 5460 image : `~matplotlib.image.AxesImage` 5461 5462 Other Parameters 5463 ---------------- 5464 **kwargs : `~matplotlib.artist.Artist` properties. 5465 5466 See also 5467 -------- 5468 matshow : Plot a matrix or an array as an image. 5469 5470 Notes 5471 ----- 5472 Unless *extent* is used, pixel centers will be located at integer 5473 coordinates. In other words: the origin will coincide with the center 5474 of pixel (0, 0). 5475 5476 Two typical representations are used for RGB images with an alpha 5477 channel: 5478 5479 - Straight (unassociated) alpha: R, G, and B channels represent the 5480 color of the pixel, disregarding its opacity. 5481 - Premultiplied (associated) alpha: R, G, and B channels represent 5482 the color of the pixel, adjusted for its opacity by multiplication. 5483 5484 `~matplotlib.pyplot.imshow` expects RGB images adopting the straight 5485 (unassociated) alpha representation. 5486 """ 5487 5488 if not self._hold: 5489 self.cla() 5490 5491 if norm is not None and not isinstance(norm, mcolors.Normalize): 5492 raise ValueError( 5493 "'norm' must be an instance of 'mcolors.Normalize'") 5494 if aspect is None: 5495 aspect = rcParams['image.aspect'] 5496 self.set_aspect(aspect) 5497 im = mimage.AxesImage(self, cmap, norm, interpolation, origin, extent, 5498 filternorm=filternorm, filterrad=filterrad, 5499 resample=resample, **kwargs) 5500 5501 im.set_data(X) 5502 im.set_alpha(alpha) 5503 if im.get_clip_path() is None: 5504 # image does not already have clipping set, clip to axes patch 5505 im.set_clip_path(self.patch) 5506 #if norm is None and shape is None: 5507 # im.set_clim(vmin, vmax) 5508 if vmin is not None or vmax is not None: 5509 im.set_clim(vmin, vmax) 5510 else: 5511 im.autoscale_None() 5512 im.set_url(url) 5513 5514 # update ax.dataLim, and, if autoscaling, set viewLim 5515 # to tightly fit the image, regardless of dataLim. 5516 im.set_extent(im.get_extent()) 5517 5518 self.add_image(im) 5519 return im 5520 5521 @staticmethod 5522 def _pcolorargs(funcname, *args, **kw): 5523 # This takes one kwarg, allmatch. 5524 # If allmatch is True, then the incoming X, Y, C must 5525 # have matching dimensions, taking into account that 5526 # X and Y can be 1-D rather than 2-D. This perfect 5527 # match is required for Gouroud shading. For flat 5528 # shading, X and Y specify boundaries, so we need 5529 # one more boundary than color in each direction. 5530 # For convenience, and consistent with Matlab, we 5531 # discard the last row and/or column of C if necessary 5532 # to meet this condition. This is done if allmatch 5533 # is False. 5534 5535 allmatch = kw.pop("allmatch", False) 5536 5537 if len(args) == 1: 5538 C = np.asanyarray(args[0]) 5539 numRows, numCols = C.shape 5540 if allmatch: 5541 X, Y = np.meshgrid(np.arange(numCols), np.arange(numRows)) 5542 else: 5543 X, Y = np.meshgrid(np.arange(numCols + 1), 5544 np.arange(numRows + 1)) 5545 C = cbook.safe_masked_invalid(C) 5546 return X, Y, C 5547 5548 if len(args) == 3: 5549 # Check x and y for bad data... 5550 C = np.asanyarray(args[2]) 5551 X, Y = [cbook.safe_masked_invalid(a) for a in args[:2]] 5552 if funcname == 'pcolormesh': 5553 if np.ma.is_masked(X) or np.ma.is_masked(Y): 5554 raise ValueError( 5555 'x and y arguments to pcolormesh cannot have ' 5556 'non-finite values or be of type ' 5557 'numpy.ma.core.MaskedArray with masked values') 5558 # safe_masked_invalid() returns an ndarray for dtypes other 5559 # than floating point. 5560 if isinstance(X, np.ma.core.MaskedArray): 5561 X = X.data # strip mask as downstream doesn't like it... 5562 if isinstance(Y, np.ma.core.MaskedArray): 5563 Y = Y.data 5564 numRows, numCols = C.shape 5565 else: 5566 raise TypeError( 5567 'Illegal arguments to %s; see help(%s)' % (funcname, funcname)) 5568 5569 Nx = X.shape[-1] 5570 Ny = Y.shape[0] 5571 if X.ndim != 2 or X.shape[0] == 1: 5572 x = X.reshape(1, Nx) 5573 X = x.repeat(Ny, axis=0) 5574 if Y.ndim != 2 or Y.shape[1] == 1: 5575 y = Y.reshape(Ny, 1) 5576 Y = y.repeat(Nx, axis=1) 5577 if X.shape != Y.shape: 5578 raise TypeError( 5579 'Incompatible X, Y inputs to %s; see help(%s)' % ( 5580 funcname, funcname)) 5581 if allmatch: 5582 if not (Nx == numCols and Ny == numRows): 5583 raise TypeError('Dimensions of C %s are incompatible with' 5584 ' X (%d) and/or Y (%d); see help(%s)' % ( 5585 C.shape, Nx, Ny, funcname)) 5586 else: 5587 if not (numCols in (Nx, Nx - 1) and numRows in (Ny, Ny - 1)): 5588 raise TypeError('Dimensions of C %s are incompatible with' 5589 ' X (%d) and/or Y (%d); see help(%s)' % ( 5590 C.shape, Nx, Ny, funcname)) 5591 C = C[:Ny - 1, :Nx - 1] 5592 C = cbook.safe_masked_invalid(C) 5593 return X, Y, C 5594 5595 @_preprocess_data(label_namer=None) 5596 @docstring.dedent_interpd 5597 def pcolor(self, *args, **kwargs): 5598 r""" 5599 Create a pseudocolor plot with a non-regular rectangular grid. 5600 5601 Call signature:: 5602 5603 pcolor([X, Y,] C, **kwargs) 5604 5605 *X* and *Y* can be used to specify the corners of the quadrilaterals. 5606 5607 .. hint:: 5608 5609 ``pcolor()`` can be very slow for large arrays. In most 5610 cases you should use the the similar but much faster 5611 `~.Axes.pcolormesh` instead. See there for a discussion of the 5612 differences. 5613 5614 Parameters 5615 ---------- 5616 C : array_like 5617 A scalar 2-D array. The values will be color-mapped. 5618 5619 X, Y : array_like, optional 5620 The coordinates of the quadrilateral corners. The quadrilateral 5621 for ``C[i,j]`` has corners at:: 5622 5623 (X[i+1, j], Y[i+1, j]) (X[i+1, j+1], Y[i+1, j+1]) 5624 +--------+ 5625 | C[i,j] | 5626 +--------+ 5627 (X[i, j], Y[i, j]) (X[i, j+1], Y[i, j+1]), 5628 5629 Note that the column index corresponds to the 5630 x-coordinate, and the row index corresponds to y. For 5631 details, see the :ref:`Notes <axes-pcolor-grid-orientation>` 5632 section below. 5633 5634 The dimensions of *X* and *Y* should be one greater than those of 5635 *C*. Alternatively, *X*, *Y* and *C* may have equal dimensions, in 5636 which case the last row and column of *C* will be ignored. 5637 5638 If *X* and/or *Y* are 1-D arrays or column vectors they will be 5639 expanded as needed into the appropriate 2-D arrays, making a 5640 rectangular grid. 5641 5642 cmap : str or `~matplotlib.colors.Colormap`, optional 5643 A Colormap instance or registered colormap name. The colormap 5644 maps the *C* values to colors. Defaults to :rc:`image.cmap`. 5645 5646 norm : `~matplotlib.colors.Normalize`, optional 5647 The Normalize instance scales the data values to the canonical 5648 colormap range [0, 1] for mapping to colors. By default, the data 5649 range is mapped to the colorbar range using linear scaling. 5650 5651 vmin, vmax : scalar, optional, default: None 5652 The colorbar range. If *None*, suitable min/max values are 5653 automatically chosen by the `~.Normalize` instance (defaults to 5654 the respective min/max values of *C* in case of the default linear 5655 scaling). 5656 5657 edgecolors : {'none', None, 'face', color, color sequence}, optional 5658 The color of the edges. Defaults to 'none'. Possible values: 5659 5660 - 'none' or '': No edge. 5661 - *None*: :rc:`patch.edgecolor` will be used. Note that currently 5662 :rc:`patch.force_edgecolor` has to be True for this to work. 5663 - 'face': Use the adjacent face color. 5664 - An mpl color or sequence of colors will set the edge color. 5665 5666 The singular form *edgecolor* works as an alias. 5667 5668 alpha : scalar, optional, default: None 5669 The alpha blending value of the face color, between 0 (transparent) 5670 and 1 (opaque). Note: The edgecolor is currently not affected by 5671 this. 5672 5673 snap : bool, optional, default: False 5674 Whether to snap the mesh to pixel boundaries. 5675 5676 Returns 5677 ------- 5678 collection : `matplotlib.collections.Collection` 5679 5680 Other Parameters 5681 ---------------- 5682 antialiaseds : bool, optional, default: False 5683 The default *antialiaseds* is False if the default 5684 *edgecolors*\ ="none" is used. This eliminates artificial lines 5685 at patch boundaries, and works regardless of the value of alpha. 5686 If *edgecolors* is not "none", then the default *antialiaseds* 5687 is taken from :rc:`patch.antialiased`, which defaults to True. 5688 Stroking the edges may be preferred if *alpha* is 1, but will 5689 cause artifacts otherwise. 5690 5691 **kwargs : 5692 Additionally, the following arguments are allowed. They are passed 5693 along to the `~matplotlib.collections.PolyCollection` constructor: 5694 5695 %(PolyCollection)s 5696 5697 See Also 5698 -------- 5699 pcolormesh : for an explanation of the differences between 5700 pcolor and pcolormesh. 5701 imshow : If *X* and *Y* are each equidistant, `~.Axes.imshow` can be a 5702 faster alternative. 5703 5704 Notes 5705 ----- 5706 5707 **Masked arrays** 5708 5709 *X*, *Y* and *C* may be masked arrays. If either ``C[i, j]``, or one 5710 of the vertices surrounding ``C[i,j]`` (*X* or *Y* at 5711 ``[i, j], [i+1, j], [i, j+1], [i+1, j+1]``) is masked, nothing is 5712 plotted. 5713 5714 .. _axes-pcolor-grid-orientation: 5715 5716 **Grid orientation** 5717 5718 The grid orientation follows the standard matrix convention: An array 5719 *C* with shape (nrows, ncolumns) is plotted with the column number as 5720 *X* and the row number as *Y*. 5721 5722 **Handling of pcolor() end-cases** 5723 5724 ``pcolor()`` displays all columns of *C* if *X* and *Y* are not 5725 specified, or if *X* and *Y* have one more column than *C*. 5726 If *X* and *Y* have the same number of columns as *C* then the last 5727 column of *C* is dropped. Similarly for the rows. 5728 5729 Note: This behavior is different from MATLAB's ``pcolor()``, which 5730 always discards the last row and column of *C*. 5731 """ 5732 5733 if not self._hold: 5734 self.cla() 5735 5736 alpha = kwargs.pop('alpha', None) 5737 norm = kwargs.pop('norm', None) 5738 cmap = kwargs.pop('cmap', None) 5739 vmin = kwargs.pop('vmin', None) 5740 vmax = kwargs.pop('vmax', None) 5741 5742 X, Y, C = self._pcolorargs('pcolor', *args, allmatch=False) 5743 Ny, Nx = X.shape 5744 5745 # unit conversion allows e.g. datetime objects as axis values 5746 self._process_unit_info(xdata=X, ydata=Y, kwargs=kwargs) 5747 X = self.convert_xunits(X) 5748 Y = self.convert_yunits(Y) 5749 5750 # convert to MA, if necessary. 5751 C = ma.asarray(C) 5752 X = ma.asarray(X) 5753 Y = ma.asarray(Y) 5754 5755 mask = ma.getmaskarray(X) + ma.getmaskarray(Y) 5756 xymask = (mask[0:-1, 0:-1] + mask[1:, 1:] + 5757 mask[0:-1, 1:] + mask[1:, 0:-1]) 5758 # don't plot if C or any of the surrounding vertices are masked. 5759 mask = ma.getmaskarray(C) + xymask 5760 5761 newaxis = np.newaxis 5762 compress = np.compress 5763 5764 ravelmask = (mask == 0).ravel() 5765 X1 = compress(ravelmask, ma.filled(X[0:-1, 0:-1]).ravel()) 5766 Y1 = compress(ravelmask, ma.filled(Y[0:-1, 0:-1]).ravel()) 5767 X2 = compress(ravelmask, ma.filled(X[1:, 0:-1]).ravel()) 5768 Y2 = compress(ravelmask, ma.filled(Y[1:, 0:-1]).ravel()) 5769 X3 = compress(ravelmask, ma.filled(X[1:, 1:]).ravel()) 5770 Y3 = compress(ravelmask, ma.filled(Y[1:, 1:]).ravel()) 5771 X4 = compress(ravelmask, ma.filled(X[0:-1, 1:]).ravel()) 5772 Y4 = compress(ravelmask, ma.filled(Y[0:-1, 1:]).ravel()) 5773 npoly = len(X1) 5774 5775 xy = np.concatenate((X1[:, newaxis], Y1[:, newaxis], 5776 X2[:, newaxis], Y2[:, newaxis], 5777 X3[:, newaxis], Y3[:, newaxis], 5778 X4[:, newaxis], Y4[:, newaxis], 5779 X1[:, newaxis], Y1[:, newaxis]), 5780 axis=1) 5781 verts = xy.reshape((npoly, 5, 2)) 5782 5783 C = compress(ravelmask, ma.filled(C[0:Ny - 1, 0:Nx - 1]).ravel()) 5784 5785 linewidths = (0.25,) 5786 if 'linewidth' in kwargs: 5787 kwargs['linewidths'] = kwargs.pop('linewidth') 5788 kwargs.setdefault('linewidths', linewidths) 5789 5790 if 'edgecolor' in kwargs: 5791 kwargs['edgecolors'] = kwargs.pop('edgecolor') 5792 ec = kwargs.setdefault('edgecolors', 'none') 5793 5794 # aa setting will default via collections to patch.antialiased 5795 # unless the boundary is not stroked, in which case the 5796 # default will be False; with unstroked boundaries, aa 5797 # makes artifacts that are often disturbing. 5798 if 'antialiased' in kwargs: 5799 kwargs['antialiaseds'] = kwargs.pop('antialiased') 5800 if 'antialiaseds' not in kwargs and ( 5801 isinstance(ec, six.string_types) and ec.lower() == "none"): 5802 kwargs['antialiaseds'] = False 5803 5804 kwargs.setdefault('snap', False) 5805 5806 collection = mcoll.PolyCollection(verts, **kwargs) 5807 5808 collection.set_alpha(alpha) 5809 collection.set_array(C) 5810 if norm is not None and not isinstance(norm, mcolors.Normalize): 5811 raise ValueError( 5812 "'norm' must be an instance of 'mcolors.Normalize'") 5813 collection.set_cmap(cmap) 5814 collection.set_norm(norm) 5815 collection.set_clim(vmin, vmax) 5816 collection.autoscale_None() 5817 self.grid(False) 5818 5819 x = X.compressed() 5820 y = Y.compressed() 5821 5822 # Transform from native to data coordinates? 5823 t = collection._transform 5824 if (not isinstance(t, mtransforms.Transform) and 5825 hasattr(t, '_as_mpl_transform')): 5826 t = t._as_mpl_transform(self.axes) 5827 5828 if t and any(t.contains_branch_seperately(self.transData)): 5829 trans_to_data = t - self.transData 5830 pts = np.vstack([x, y]).T.astype(float) 5831 transformed_pts = trans_to_data.transform(pts) 5832 x = transformed_pts[..., 0] 5833 y = transformed_pts[..., 1] 5834 5835 self.add_collection(collection, autolim=False) 5836 5837 minx = np.min(x) 5838 maxx = np.max(x) 5839 miny = np.min(y) 5840 maxy = np.max(y) 5841 collection.sticky_edges.x[:] = [minx, maxx] 5842 collection.sticky_edges.y[:] = [miny, maxy] 5843 corners = (minx, miny), (maxx, maxy) 5844 self.update_datalim(corners) 5845 self.autoscale_view() 5846 return collection 5847 5848 @_preprocess_data(label_namer=None) 5849 @docstring.dedent_interpd 5850 def pcolormesh(self, *args, **kwargs): 5851 """ 5852 Create a pseudocolor plot with a non-regular rectangular grid. 5853 5854 Call signature:: 5855 5856 pcolor([X, Y,] C, **kwargs) 5857 5858 *X* and *Y* can be used to specify the corners of the quadrilaterals. 5859 5860 .. note:: 5861 5862 ``pcolormesh()`` is similar to :func:`~Axes.pcolor`. It's much 5863 faster and preferred in most cases. For a detailed discussion on 5864 the differences see 5865 :ref:`Differences between pcolor() and pcolormesh() 5866 <differences-pcolor-pcolormesh>`. 5867 5868 Parameters 5869 ---------- 5870 C : array_like 5871 A scalar 2-D array. The values will be color-mapped. 5872 5873 X, Y : array_like, optional 5874 The coordinates of the quadrilateral corners. The quadrilateral 5875 for ``C[i,j]`` has corners at:: 5876 5877 (X[i+1, j], Y[i+1, j]) (X[i+1, j+1], Y[i+1, j+1]) 5878 +--------+ 5879 | C[i,j] | 5880 +--------+ 5881 (X[i, j], Y[i, j]) (X[i, j+1], Y[i, j+1]), 5882 5883 Note that the column index corresponds to the 5884 x-coordinate, and the row index corresponds to y. For 5885 details, see the :ref:`Notes <axes-pcolormesh-grid-orientation>` 5886 section below. 5887 5888 The dimensions of *X* and *Y* should be one greater than those of 5889 *C*. Alternatively, *X*, *Y* and *C* may have equal dimensions, in 5890 which case the last row and column of *C* will be ignored. 5891 5892 If *X* and/or *Y* are 1-D arrays or column vectors they will be 5893 expanded as needed into the appropriate 2-D arrays, making a 5894 rectangular grid. 5895 5896 cmap : str or `~matplotlib.colors.Colormap`, optional 5897 A Colormap instance or registered colormap name. The colormap 5898 maps the *C* values to colors. Defaults to :rc:`image.cmap`. 5899 5900 norm : `~matplotlib.colors.Normalize`, optional 5901 The Normalize instance scales the data values to the canonical 5902 colormap range [0, 1] for mapping to colors. By default, the data 5903 range is mapped to the colorbar range using linear scaling. 5904 5905 vmin, vmax : scalar, optional, default: None 5906 The colorbar range. If *None*, suitable min/max values are 5907 automatically chosen by the `~.Normalize` instance (defaults to 5908 the respective min/max values of *C* in case of the default linear 5909 scaling). 5910 5911 edgecolors : {'none', None, 'face', color, color sequence}, optional 5912 The color of the edges. Defaults to 'none'. Possible values: 5913 5914 - 'none' or '': No edge. 5915 - *None*: :rc:`patch.edgecolor` will be used. Note that currently 5916 :rc:`patch.force_edgecolor` has to be True for this to work. 5917 - 'face': Use the adjacent face color. 5918 - An mpl color or sequence of colors will set the edge color. 5919 5920 The singular form *edgecolor* works as an alias. 5921 5922 alpha : scalar, optional, default: None 5923 The alpha blending value, between 0 (transparent) and 1 (opaque). 5924 5925 shading : {'flat', 'gouraud'}, optional 5926 The fill style, Possible values: 5927 5928 - 'flat': A solid color is used for each quad. The color of the 5929 quad (i, j), (i+1, j), (i, j+1), (i+1, j+1) is given by 5930 ``C[i,j]``. 5931 - 'gouraud': Each quad will be Gouraud shaded: The color of the 5932 corners (i', j') are given by ``C[i',j']``. The color values of 5933 the area in between is interpolated from the corner values. 5934 When Gouraud shading is used, *edgecolors* is ignored. 5935 5936 snap : bool, optional, default: False 5937 Whether to snap the mesh to pixel boundaries. 5938 5939 Returns 5940 ------- 5941 mesh : `matplotlib.collections.QuadMesh` 5942 5943 Other Parameters 5944 ---------------- 5945 **kwargs 5946 Additionally, the following arguments are allowed. They are passed 5947 along to the `~matplotlib.collections.QuadMesh` constructor: 5948 5949 %(QuadMesh)s 5950 5951 5952 See Also 5953 -------- 5954 pcolor : An alternative implementation with slightly different 5955 features. For a detailed discussion on the differences see 5956 :ref:`Differences between pcolor() and pcolormesh() 5957 <differences-pcolor-pcolormesh>`. 5958 imshow : If *X* and *Y* are each equidistant, `~.Axes.imshow` can be a 5959 faster alternative. 5960 5961 Notes 5962 ----- 5963 5964 **Masked arrays** 5965 5966 *C* may be a masked array. If ``C[i, j]`` is masked, the corresponding 5967 quadrilateral will be transparent. Masking of *X* and *Y* is not 5968 supported. Use `~.Axes.pcolor` if you need this functionality. 5969 5970 .. _axes-pcolormesh-grid-orientation: 5971 5972 **Grid orientation** 5973 5974 The grid orientation follows the standard matrix convention: An array 5975 *C* with shape (nrows, ncolumns) is plotted with the column number as 5976 *X* and the row number as *Y*. 5977 5978 .. _differences-pcolor-pcolormesh: 5979 5980 **Differences between pcolor() and pcolormesh()** 5981 5982 Both methods are used to create a pseudocolor plot of a 2-D array 5983 using quadrilaterals. 5984 5985 The main difference lies in the created object and internal data 5986 handling: 5987 While `~.Axes.pcolor` returns a `.PolyCollection`, `~.Axes.pcolormesh` 5988 returns a `.QuadMesh`. The latter is more specialized for the given 5989 purpose and thus is faster. It should almost always be preferred. 5990 5991 There is also a slight difference in the handling of masked arrays. 5992 Both `~.Axes.pcolor` and `~.Axes.pcolormesh` support masked arrays 5993 for *C*. However, only `~.Axes.pcolor` supports masked arrays for *X* 5994 and *Y*. The reason lies in the internal handling of the masked values. 5995 `~.Axes.pcolor` leaves out the respective polygons from the 5996 PolyCollection. `~.Axes.pcolormesh` sets the facecolor of the masked 5997 elements to transparent. You can see the difference when using 5998 edgecolors. While all edges are drawn irrespective of masking in a 5999 QuadMesh, the edge between two adjacent masked quadrilaterals in 6000 `~.Axes.pcolor` is not drawn as the corresponding polygons do not 6001 exist in the PolyCollection. 6002 6003 Another difference is the support of Gouraud shading in 6004 `~.Axes.pcolormesh`, which is not available with `~.Axes.pcolor`. 6005 6006 """ 6007 if not self._hold: 6008 self.cla() 6009 6010 alpha = kwargs.pop('alpha', None) 6011 norm = kwargs.pop('norm', None) 6012 cmap = kwargs.pop('cmap', None) 6013 vmin = kwargs.pop('vmin', None) 6014 vmax = kwargs.pop('vmax', None) 6015 shading = kwargs.pop('shading', 'flat').lower() 6016 antialiased = kwargs.pop('antialiased', False) 6017 kwargs.setdefault('edgecolors', 'None') 6018 6019 allmatch = (shading == 'gouraud') 6020 6021 X, Y, C = self._pcolorargs('pcolormesh', *args, allmatch=allmatch) 6022 Ny, Nx = X.shape 6023 X = X.ravel() 6024 Y = Y.ravel() 6025 # unit conversion allows e.g. datetime objects as axis values 6026 self._process_unit_info(xdata=X, ydata=Y, kwargs=kwargs) 6027 X = self.convert_xunits(X) 6028 Y = self.convert_yunits(Y) 6029 6030 # convert to one dimensional arrays 6031 C = C.ravel() 6032 coords = np.column_stack((X, Y)).astype(float, copy=False) 6033 collection = mcoll.QuadMesh(Nx - 1, Ny - 1, coords, 6034 antialiased=antialiased, shading=shading, 6035 **kwargs) 6036 collection.set_alpha(alpha) 6037 collection.set_array(C) 6038 if norm is not None and not isinstance(norm, mcolors.Normalize): 6039 raise ValueError( 6040 "'norm' must be an instance of 'mcolors.Normalize'") 6041 collection.set_cmap(cmap) 6042 collection.set_norm(norm) 6043 collection.set_clim(vmin, vmax) 6044 collection.autoscale_None() 6045 6046 self.grid(False) 6047 6048 # Transform from native to data coordinates? 6049 t = collection._transform 6050 if (not isinstance(t, mtransforms.Transform) and 6051 hasattr(t, '_as_mpl_transform')): 6052 t = t._as_mpl_transform(self.axes) 6053 6054 if t and any(t.contains_branch_seperately(self.transData)): 6055 trans_to_data = t - self.transData 6056 coords = trans_to_data.transform(coords) 6057 6058 self.add_collection(collection, autolim=False) 6059 6060 minx, miny = np.min(coords, axis=0) 6061 maxx, maxy = np.max(coords, axis=0) 6062 collection.sticky_edges.x[:] = [minx, maxx] 6063 collection.sticky_edges.y[:] = [miny, maxy] 6064 corners = (minx, miny), (maxx, maxy) 6065 self.update_datalim(corners) 6066 self.autoscale_view() 6067 return collection 6068 6069 @_preprocess_data(label_namer=None) 6070 @docstring.dedent_interpd 6071 def pcolorfast(self, *args, **kwargs): 6072 """ 6073 Create a pseudocolor plot with a non-regular rectangular grid. 6074 6075 Call signatures:: 6076 6077 ax.pcolorfast(C, **kwargs) 6078 ax.pcolorfast(xr, yr, C, **kwargs) 6079 ax.pcolorfast(x, y, C, **kwargs) 6080 ax.pcolorfast(X, Y, C, **kwargs) 6081 6082 This method is similar to ~.Axes.pcolor` and `~.Axes.pcolormesh`. 6083 It's designed to provide the fastest pcolor-type plotting with the 6084 Agg backend. To achieve this, it uses different algorithms internally 6085 depending on the complexity of the input grid (regular rectangular, 6086 non-regular rectangular or arbitrary quadrilateral). 6087 6088 .. warning:: 6089 6090 This method is experimental. Compared to `~.Axes.pcolor` or 6091 `~.Axes.pcolormesh` it has some limitations: 6092 6093 - It supports only flat shading (no outlines) 6094 - It lacks support for log scaling of the axes. 6095 - It does not have a have a pyplot wrapper. 6096 6097 Parameters 6098 ---------- 6099 C : array-like(M, N) 6100 A scalar 2D array. The values will be color-mapped. 6101 *C* may be a masked array. 6102 6103 x, y : tuple or array-like 6104 *X* and *Y* are used to specify the coordinates of the 6105 quadilaterals. There are different ways to do this: 6106 6107 - Use tuples ``xr=(xmin, xmax)`` and ``yr=(ymin, ymax)`` to define 6108 a *uniform rectiangular grid*. 6109 6110 The tuples define the outer edges of the grid. All individual 6111 quadrilaterals will be of the same size. This is the fastest 6112 version. 6113 6114 - Use 1D arrays *x*, *y* to specify a *non-uniform rectangular 6115 grid*. 6116 6117 In this case *x* and *y* have to be monotonic 1D arrays of length 6118 *N+1* and *M+1*, specifying the x and y boundaries of the cells. 6119 6120 The speed is intermediate. Note: The grid is checked, and if 6121 found to be uniform the fast version is used. 6122 6123 - Use 2D arrays *X*, *Y* if you need an *arbitrary quadrilateral 6124 grid* (i.e. if the quadrilaterals are not rectangular). 6125 6126 In this case *X* and *Y* are 2D arrays with shape (M, N), 6127 specifying the x and y coordinates of the corners of the colored 6128 quadrilaterals. See `~.Axes.pcolormesh` for details. 6129 6130 This is the most general, but the slowest to render. It may 6131 produce faster and more compact output using ps, pdf, and 6132 svg backends, however. 6133 6134 Leaving out *x* and *y* defaults to ``xr=(0, N)``, ``yr=(O, M)``. 6135 6136 cmap : str or `~matplotlib.colors.Colormap`, optional 6137 A Colormap instance or registered colormap name. The colormap 6138 maps the *C* values to colors. Defaults to :rc:`image.cmap`. 6139 6140 norm : `~matplotlib.colors.Normalize`, optional 6141 The Normalize instance scales the data values to the canonical 6142 colormap range [0, 1] for mapping to colors. By default, the data 6143 range is mapped to the colorbar range using linear scaling. 6144 6145 vmin, vmax : scalar, optional, default: None 6146 The colorbar range. If *None*, suitable min/max values are 6147 automatically chosen by the `~.Normalize` instance (defaults to 6148 the respective min/max values of *C* in case of the default linear 6149 scaling). 6150 6151 alpha : scalar, optional, default: None 6152 The alpha blending value, between 0 (transparent) and 1 (opaque). 6153 6154 snap : bool, optional, default: False 6155 Whether to snap the mesh to pixel boundaries. 6156 6157 Returns 6158 ------- 6159 image : `.AxesImage` or `.PcolorImage` or `.QuadMesh` 6160 The return type depends on the type of grid: 6161 6162 - `.AxesImage` for a regular rectangular grid. 6163 - `.PcolorImage` for a non-regular rectangular grid. 6164 - `.QuadMesh` for a non-rectangular grid. 6165 6166 Notes 6167 ----- 6168 .. [notes section required to get data note injection right] 6169 6170 """ 6171 6172 if not self._hold: 6173 self.cla() 6174 6175 alpha = kwargs.pop('alpha', None) 6176 norm = kwargs.pop('norm', None) 6177 cmap = kwargs.pop('cmap', None) 6178 vmin = kwargs.pop('vmin', None) 6179 vmax = kwargs.pop('vmax', None) 6180 if norm is not None and not isinstance(norm, mcolors.Normalize): 6181 raise ValueError( 6182 "'norm' must be an instance of 'mcolors.Normalize'") 6183 6184 C = args[-1] 6185 nr, nc = C.shape 6186 if len(args) == 1: 6187 style = "image" 6188 x = [0, nc] 6189 y = [0, nr] 6190 elif len(args) == 3: 6191 x, y = args[:2] 6192 x = np.asarray(x) 6193 y = np.asarray(y) 6194 if x.ndim == 1 and y.ndim == 1: 6195 if x.size == 2 and y.size == 2: 6196 style = "image" 6197 else: 6198 dx = np.diff(x) 6199 dy = np.diff(y) 6200 if (np.ptp(dx) < 0.01 * np.abs(dx.mean()) and 6201 np.ptp(dy) < 0.01 * np.abs(dy.mean())): 6202 style = "image" 6203 else: 6204 style = "pcolorimage" 6205 elif x.ndim == 2 and y.ndim == 2: 6206 style = "quadmesh" 6207 else: 6208 raise TypeError("arguments do not match valid signatures") 6209 else: 6210 raise TypeError("need 1 argument or 3 arguments") 6211 6212 if style == "quadmesh": 6213 6214 # convert to one dimensional arrays 6215 # This should also be moved to the QuadMesh class 6216 6217 # data point in each cell is value at lower left corner 6218 C = ma.ravel(C) 6219 X = x.ravel() 6220 Y = y.ravel() 6221 Nx = nc + 1 6222 Ny = nr + 1 6223 6224 # The following needs to be cleaned up; the renderer 6225 # requires separate contiguous arrays for X and Y, 6226 # but the QuadMesh class requires the 2D array. 6227 coords = np.empty(((Nx * Ny), 2), np.float64) 6228 coords[:, 0] = X 6229 coords[:, 1] = Y 6230 6231 # The QuadMesh class can also be changed to 6232 # handle relevant superclass kwargs; the initializer 6233 # should do much more than it does now. 6234 collection = mcoll.QuadMesh(nc, nr, coords, 0, edgecolors="None") 6235 collection.set_alpha(alpha) 6236 collection.set_array(C) 6237 collection.set_cmap(cmap) 6238 collection.set_norm(norm) 6239 self.add_collection(collection, autolim=False) 6240 xl, xr, yb, yt = X.min(), X.max(), Y.min(), Y.max() 6241 ret = collection 6242 6243 else: # It's one of the two image styles. 6244 xl, xr, yb, yt = x[0], x[-1], y[0], y[-1] 6245 6246 if style == "image": 6247 im = mimage.AxesImage(self, cmap, norm, 6248 interpolation='nearest', 6249 origin='lower', 6250 extent=(xl, xr, yb, yt), 6251 **kwargs) 6252 im.set_data(C) 6253 im.set_alpha(alpha) 6254 elif style == "pcolorimage": 6255 im = mimage.PcolorImage(self, x, y, C, 6256 cmap=cmap, 6257 norm=norm, 6258 alpha=alpha, 6259 **kwargs) 6260 im.set_extent((xl, xr, yb, yt)) 6261 self.add_image(im) 6262 ret = im 6263 6264 if vmin is not None or vmax is not None: 6265 ret.set_clim(vmin, vmax) 6266 else: 6267 ret.autoscale_None() 6268 6269 ret.sticky_edges.x[:] = [xl, xr] 6270 ret.sticky_edges.y[:] = [yb, yt] 6271 self.update_datalim(np.array([[xl, yb], [xr, yt]])) 6272 self.autoscale_view(tight=True) 6273 return ret 6274 6275 @_preprocess_data() 6276 def contour(self, *args, **kwargs): 6277 if not self._hold: 6278 self.cla() 6279 kwargs['filled'] = False 6280 contours = mcontour.QuadContourSet(self, *args, **kwargs) 6281 self.autoscale_view() 6282 return contours 6283 contour.__doc__ = mcontour.QuadContourSet._contour_doc 6284 6285 @_preprocess_data() 6286 def contourf(self, *args, **kwargs): 6287 if not self._hold: 6288 self.cla() 6289 kwargs['filled'] = True 6290 contours = mcontour.QuadContourSet(self, *args, **kwargs) 6291 self.autoscale_view() 6292 return contours 6293 contourf.__doc__ = mcontour.QuadContourSet._contour_doc 6294 6295 def clabel(self, CS, *args, **kwargs): 6296 return CS.clabel(*args, **kwargs) 6297 clabel.__doc__ = mcontour.ContourSet.clabel.__doc__ 6298 6299 @docstring.dedent_interpd 6300 def table(self, **kwargs): 6301 """ 6302 Add a table to the current axes. 6303 6304 Call signature:: 6305 6306 table(cellText=None, cellColours=None, 6307 cellLoc='right', colWidths=None, 6308 rowLabels=None, rowColours=None, rowLoc='left', 6309 colLabels=None, colColours=None, colLoc='center', 6310 loc='bottom', bbox=None) 6311 6312 Returns a :class:`matplotlib.table.Table` instance. Either `cellText` 6313 or `cellColours` must be provided. For finer grained control over 6314 tables, use the :class:`~matplotlib.table.Table` class and add it to 6315 the axes with :meth:`~matplotlib.axes.Axes.add_table`. 6316 6317 Thanks to John Gill for providing the class and table. 6318 6319 kwargs control the :class:`~matplotlib.table.Table` 6320 properties: 6321 6322 %(Table)s 6323 """ 6324 return mtable.table(self, **kwargs) 6325 6326 #### Data analysis 6327 6328 @_preprocess_data(replace_names=["x", 'weights'], label_namer="x") 6329 def hist(self, x, bins=None, range=None, density=None, weights=None, 6330 cumulative=False, bottom=None, histtype='bar', align='mid', 6331 orientation='vertical', rwidth=None, log=False, 6332 color=None, label=None, stacked=False, normed=None, 6333 **kwargs): 6334 """ 6335 Plot a histogram. 6336 6337 Compute and draw the histogram of *x*. The return value is a 6338 tuple (*n*, *bins*, *patches*) or ([*n0*, *n1*, ...], *bins*, 6339 [*patches0*, *patches1*,...]) if the input contains multiple 6340 data. 6341 6342 Multiple data can be provided via *x* as a list of datasets 6343 of potentially different length ([*x0*, *x1*, ...]), or as 6344 a 2-D ndarray in which each column is a dataset. Note that 6345 the ndarray form is transposed relative to the list form. 6346 6347 Masked arrays are not supported at present. 6348 6349 Parameters 6350 ---------- 6351 x : (n,) array or sequence of (n,) arrays 6352 Input values, this takes either a single array or a sequence of 6353 arrays which are not required to be of the same length 6354 6355 bins : integer or sequence or 'auto', optional 6356 If an integer is given, ``bins + 1`` bin edges are calculated and 6357 returned, consistent with :func:`numpy.histogram`. 6358 6359 If `bins` is a sequence, gives bin edges, including left edge of 6360 first bin and right edge of last bin. In this case, `bins` is 6361 returned unmodified. 6362 6363 All but the last (righthand-most) bin is half-open. In other 6364 words, if `bins` is:: 6365 6366 [1, 2, 3, 4] 6367 6368 then the first bin is ``[1, 2)`` (including 1, but excluding 2) and 6369 the second ``[2, 3)``. The last bin, however, is ``[3, 4]``, which 6370 *includes* 4. 6371 6372 Unequally spaced bins are supported if *bins* is a sequence. 6373 6374 If Numpy 1.11 is installed, may also be ``'auto'``. 6375 6376 Default is taken from the rcParam ``hist.bins``. 6377 6378 range : tuple or None, optional 6379 The lower and upper range of the bins. Lower and upper outliers 6380 are ignored. If not provided, *range* is ``(x.min(), x.max())``. 6381 Range has no effect if *bins* is a sequence. 6382 6383 If *bins* is a sequence or *range* is specified, autoscaling 6384 is based on the specified bin range instead of the 6385 range of x. 6386 6387 Default is ``None`` 6388 6389 density : boolean, optional 6390 If ``True``, the first element of the return tuple will 6391 be the counts normalized to form a probability density, i.e., 6392 the area (or integral) under the histogram will sum to 1. 6393 This is achieved by dividing the count by the number of 6394 observations times the bin width and not dividing by the total 6395 number of observations. If *stacked* is also ``True``, the sum of 6396 the histograms is normalized to 1. 6397 6398 Default is ``None`` for both *normed* and *density*. If either is 6399 set, then that value will be used. If neither are set, then the 6400 args will be treated as ``False``. 6401 6402 If both *density* and *normed* are set an error is raised. 6403 6404 weights : (n, ) array_like or None, optional 6405 An array of weights, of the same shape as *x*. Each value in *x* 6406 only contributes its associated weight towards the bin count 6407 (instead of 1). If *normed* or *density* is ``True``, 6408 the weights are normalized, so that the integral of the density 6409 over the range remains 1. 6410 6411 Default is ``None`` 6412 6413 cumulative : boolean, optional 6414 If ``True``, then a histogram is computed where each bin gives the 6415 counts in that bin plus all bins for smaller values. The last bin 6416 gives the total number of datapoints. If *normed* or *density* 6417 is also ``True`` then the histogram is normalized such that the 6418 last bin equals 1. If *cumulative* evaluates to less than 0 6419 (e.g., -1), the direction of accumulation is reversed. 6420 In this case, if *normed* and/or *density* is also ``True``, then 6421 the histogram is normalized such that the first bin equals 1. 6422 6423 Default is ``False`` 6424 6425 bottom : array_like, scalar, or None 6426 Location of the bottom baseline of each bin. If a scalar, 6427 the base line for each bin is shifted by the same amount. 6428 If an array, each bin is shifted independently and the length 6429 of bottom must match the number of bins. If None, defaults to 0. 6430 6431 Default is ``None`` 6432 6433 histtype : {'bar', 'barstacked', 'step', 'stepfilled'}, optional 6434 The type of histogram to draw. 6435 6436 - 'bar' is a traditional bar-type histogram. If multiple data 6437 are given the bars are arranged side by side. 6438 6439 - 'barstacked' is a bar-type histogram where multiple 6440 data are stacked on top of each other. 6441 6442 - 'step' generates a lineplot that is by default 6443 unfilled. 6444 6445 - 'stepfilled' generates a lineplot that is by default 6446 filled. 6447 6448 Default is 'bar' 6449 6450 align : {'left', 'mid', 'right'}, optional 6451 Controls how the histogram is plotted. 6452 6453 - 'left': bars are centered on the left bin edges. 6454 6455 - 'mid': bars are centered between the bin edges. 6456 6457 - 'right': bars are centered on the right bin edges. 6458 6459 Default is 'mid' 6460 6461 orientation : {'horizontal', 'vertical'}, optional 6462 If 'horizontal', `~matplotlib.pyplot.barh` will be used for 6463 bar-type histograms and the *bottom* kwarg will be the left edges. 6464 6465 rwidth : scalar or None, optional 6466 The relative width of the bars as a fraction of the bin width. If 6467 ``None``, automatically compute the width. 6468 6469 Ignored if *histtype* is 'step' or 'stepfilled'. 6470 6471 Default is ``None`` 6472 6473 log : boolean, optional 6474 If ``True``, the histogram axis will be set to a log scale. If 6475 *log* is ``True`` and *x* is a 1D array, empty bins will be 6476 filtered out and only the non-empty ``(n, bins, patches)`` 6477 will be returned. 6478 6479 Default is ``False`` 6480 6481 color : color or array_like of colors or None, optional 6482 Color spec or sequence of color specs, one per dataset. Default 6483 (``None``) uses the standard line color sequence. 6484 6485 Default is ``None`` 6486 6487 label : string or None, optional 6488 String, or sequence of strings to match multiple datasets. Bar 6489 charts yield multiple patches per dataset, but only the first gets 6490 the label, so that the legend command will work as expected. 6491 6492 default is ``None`` 6493 6494 stacked : boolean, optional 6495 If ``True``, multiple data are stacked on top of each other If 6496 ``False`` multiple data are arranged side by side if histtype is 6497 'bar' or on top of each other if histtype is 'step' 6498 6499 Default is ``False`` 6500 6501 normed : bool, optional 6502 Deprecated; use the density keyword argument instead. 6503 6504 Returns 6505 ------- 6506 n : array or list of arrays 6507 The values of the histogram bins. See *normed* or *density* 6508 and *weights* for a description of the possible semantics. 6509 If input *x* is an array, then this is an array of length 6510 *nbins*. If input is a sequence arrays 6511 ``[data1, data2,..]``, then this is a list of arrays with 6512 the values of the histograms for each of the arrays in the 6513 same order. 6514 6515 bins : array 6516 The edges of the bins. Length nbins + 1 (nbins left edges and right 6517 edge of last bin). Always a single array even when multiple data 6518 sets are passed in. 6519 6520 patches : list or list of lists 6521 Silent list of individual patches used to create the histogram 6522 or list of such list if multiple input datasets. 6523 6524 Other Parameters 6525 ---------------- 6526 **kwargs : `~matplotlib.patches.Patch` properties 6527 6528 See also 6529 -------- 6530 hist2d : 2D histograms 6531 6532 Notes 6533 ----- 6534 .. [Notes section required for data comment. See #10189.] 6535 6536 """ 6537 # Avoid shadowing the builtin. 6538 bin_range = range 6539 del range 6540 6541 if not self._hold: 6542 self.cla() 6543 6544 if np.isscalar(x): 6545 x = [x] 6546 6547 if bins is None: 6548 bins = rcParams['hist.bins'] 6549 6550 # Validate string inputs here so we don't have to clutter 6551 # subsequent code. 6552 if histtype not in ['bar', 'barstacked', 'step', 'stepfilled']: 6553 raise ValueError("histtype %s is not recognized" % histtype) 6554 6555 if align not in ['left', 'mid', 'right']: 6556 raise ValueError("align kwarg %s is not recognized" % align) 6557 6558 if orientation not in ['horizontal', 'vertical']: 6559 raise ValueError( 6560 "orientation kwarg %s is not recognized" % orientation) 6561 6562 if histtype == 'barstacked' and not stacked: 6563 stacked = True 6564 6565 if density is not None and normed is not None: 6566 raise ValueError("kwargs 'density' and 'normed' cannot be used " 6567 "simultaneously. " 6568 "Please only use 'density', since 'normed'" 6569 "is deprecated.") 6570 if normed is not None: 6571 warnings.warn("The 'normed' kwarg is deprecated, and has been " 6572 "replaced by the 'density' kwarg.") 6573 6574 # basic input validation 6575 input_empty = np.size(x) == 0 6576 # Massage 'x' for processing. 6577 if input_empty: 6578 x = [np.array([])] 6579 else: 6580 x = cbook._reshape_2D(x, 'x') 6581 nx = len(x) # number of datasets 6582 6583 # Process unit information 6584 # Unit conversion is done individually on each dataset 6585 self._process_unit_info(xdata=x[0], kwargs=kwargs) 6586 x = [self.convert_xunits(xi) for xi in x] 6587 6588 if bin_range is not None: 6589 bin_range = self.convert_xunits(bin_range) 6590 6591 # Check whether bins or range are given explicitly. 6592 binsgiven = (cbook.iterable(bins) or bin_range is not None) 6593 6594 # We need to do to 'weights' what was done to 'x' 6595 if weights is not None: 6596 w = cbook._reshape_2D(weights, 'weights') 6597 else: 6598 w = [None] * nx 6599 6600 if len(w) != nx: 6601 raise ValueError('weights should have the same shape as x') 6602 6603 for xi, wi in zip(x, w): 6604 if wi is not None and len(wi) != len(xi): 6605 raise ValueError( 6606 'weights should have the same shape as x') 6607 6608 if color is None: 6609 color = [self._get_lines.get_next_color() for i in xrange(nx)] 6610 else: 6611 color = mcolors.to_rgba_array(color) 6612 if len(color) != nx: 6613 raise ValueError("color kwarg must have one color per dataset") 6614 6615 # If bins are not specified either explicitly or via range, 6616 # we need to figure out the range required for all datasets, 6617 # and supply that to np.histogram. 6618 if not binsgiven and not input_empty: 6619 xmin = np.inf 6620 xmax = -np.inf 6621 for xi in x: 6622 if len(xi) > 0: 6623 xmin = min(xmin, xi.min()) 6624 xmax = max(xmax, xi.max()) 6625 bin_range = (xmin, xmax) 6626 density = bool(density) or bool(normed) 6627 if density and not stacked: 6628 hist_kwargs = dict(range=bin_range, density=density) 6629 else: 6630 hist_kwargs = dict(range=bin_range) 6631 6632 # List to store all the top coordinates of the histograms 6633 tops = [] 6634 mlast = None 6635 # Loop through datasets 6636 for i in xrange(nx): 6637 # this will automatically overwrite bins, 6638 # so that each histogram uses the same bins 6639 m, bins = np.histogram(x[i], bins, weights=w[i], **hist_kwargs) 6640 m = m.astype(float) # causes problems later if it's an int 6641 if mlast is None: 6642 mlast = np.zeros(len(bins)-1, m.dtype) 6643 if stacked: 6644 m += mlast 6645 mlast[:] = m 6646 tops.append(m) 6647 6648 # If a stacked density plot, normalize so the area of all the stacked 6649 # histograms together is 1 6650 if stacked and density: 6651 db = np.diff(bins) 6652 for m in tops: 6653 m[:] = (m / db) / tops[-1].sum() 6654 if cumulative: 6655 slc = slice(None) 6656 if cbook.is_numlike(cumulative) and cumulative < 0: 6657 slc = slice(None, None, -1) 6658 6659 if density: 6660 tops = [(m * np.diff(bins))[slc].cumsum()[slc] for m in tops] 6661 else: 6662 tops = [m[slc].cumsum()[slc] for m in tops] 6663 6664 patches = [] 6665 6666 # Save autoscale state for later restoration; turn autoscaling 6667 # off so we can do it all a single time at the end, instead 6668 # of having it done by bar or fill and then having to be redone. 6669 _saved_autoscalex = self.get_autoscalex_on() 6670 _saved_autoscaley = self.get_autoscaley_on() 6671 self.set_autoscalex_on(False) 6672 self.set_autoscaley_on(False) 6673 6674 if histtype.startswith('bar'): 6675 6676 totwidth = np.diff(bins) 6677 6678 if rwidth is not None: 6679 dr = np.clip(rwidth, 0, 1) 6680 elif (len(tops) > 1 and 6681 ((not stacked) or rcParams['_internal.classic_mode'])): 6682 dr = 0.8 6683 else: 6684 dr = 1.0 6685 6686 if histtype == 'bar' and not stacked: 6687 width = dr * totwidth / nx 6688 dw = width 6689 boffset = -0.5 * dr * totwidth * (1 - 1 / nx) 6690 elif histtype == 'barstacked' or stacked: 6691 width = dr * totwidth 6692 boffset, dw = 0.0, 0.0 6693 6694 if align == 'mid' or align == 'edge': 6695 boffset += 0.5 * totwidth 6696 elif align == 'right': 6697 boffset += totwidth 6698 6699 if orientation == 'horizontal': 6700 _barfunc = self.barh 6701 bottom_kwarg = 'left' 6702 else: # orientation == 'vertical' 6703 _barfunc = self.bar 6704 bottom_kwarg = 'bottom' 6705 6706 for m, c in zip(tops, color): 6707 if bottom is None: 6708 bottom = np.zeros(len(m)) 6709 if stacked: 6710 height = m - bottom 6711 else: 6712 height = m 6713 patch = _barfunc(bins[:-1]+boffset, height, width, 6714 align='center', log=log, 6715 color=c, **{bottom_kwarg: bottom}) 6716 patches.append(patch) 6717 if stacked: 6718 bottom[:] = m 6719 boffset += dw 6720 6721 elif histtype.startswith('step'): 6722 # these define the perimeter of the polygon 6723 x = np.zeros(4 * len(bins) - 3) 6724 y = np.zeros(4 * len(bins) - 3) 6725 6726 x[0:2*len(bins)-1:2], x[1:2*len(bins)-1:2] = bins, bins[:-1] 6727 x[2*len(bins)-1:] = x[1:2*len(bins)-1][::-1] 6728 6729 if bottom is None: 6730 bottom = np.zeros(len(bins) - 1) 6731 6732 y[1:2*len(bins)-1:2], y[2:2*len(bins):2] = bottom, bottom 6733 y[2*len(bins)-1:] = y[1:2*len(bins)-1][::-1] 6734 6735 if log: 6736 if orientation == 'horizontal': 6737 self.set_xscale('log', nonposx='clip') 6738 logbase = self.xaxis._scale.base 6739 else: # orientation == 'vertical' 6740 self.set_yscale('log', nonposy='clip') 6741 logbase = self.yaxis._scale.base 6742 6743 # Setting a minimum of 0 results in problems for log plots 6744 if np.min(bottom) > 0: 6745 minimum = np.min(bottom) 6746 elif density or weights is not None: 6747 # For data that is normed to form a probability density, 6748 # set to minimum data value / logbase 6749 # (gives 1 full tick-label unit for the lowest filled bin) 6750 ndata = np.array(tops) 6751 minimum = (np.min(ndata[ndata > 0])) / logbase 6752 else: 6753 # For non-normed (density = False) data, 6754 # set the min to 1 / log base, 6755 # again so that there is 1 full tick-label unit 6756 # for the lowest bin 6757 minimum = 1.0 / logbase 6758 6759 y[0], y[-1] = minimum, minimum 6760 else: 6761 minimum = 0 6762 6763 if align == 'left' or align == 'center': 6764 x -= 0.5*(bins[1]-bins[0]) 6765 elif align == 'right': 6766 x += 0.5*(bins[1]-bins[0]) 6767 6768 # If fill kwarg is set, it will be passed to the patch collection, 6769 # overriding this 6770 fill = (histtype == 'stepfilled') 6771 6772 xvals, yvals = [], [] 6773 for m in tops: 6774 if stacked: 6775 # starting point for drawing polygon 6776 y[0] = y[1] 6777 # top of the previous polygon becomes the bottom 6778 y[2*len(bins)-1:] = y[1:2*len(bins)-1][::-1] 6779 # set the top of this polygon 6780 y[1:2*len(bins)-1:2], y[2:2*len(bins):2] = (m + bottom, 6781 m + bottom) 6782 if log: 6783 y[y < minimum] = minimum 6784 if orientation == 'horizontal': 6785 xvals.append(y.copy()) 6786 yvals.append(x.copy()) 6787 else: 6788 xvals.append(x.copy()) 6789 yvals.append(y.copy()) 6790 6791 # stepfill is closed, step is not 6792 split = -1 if fill else 2 * len(bins) 6793 # add patches in reverse order so that when stacking, 6794 # items lower in the stack are plotted on top of 6795 # items higher in the stack 6796 for x, y, c in reversed(list(zip(xvals, yvals, color))): 6797 patches.append(self.fill( 6798 x[:split], y[:split], 6799 closed=True if fill else None, 6800 facecolor=c, 6801 edgecolor=None if fill else c, 6802 fill=fill if fill else None)) 6803 for patch_list in patches: 6804 for patch in patch_list: 6805 if orientation == 'vertical': 6806 patch.sticky_edges.y.append(minimum) 6807 elif orientation == 'horizontal': 6808 patch.sticky_edges.x.append(minimum) 6809 6810 # we return patches, so put it back in the expected order 6811 patches.reverse() 6812 6813 self.set_autoscalex_on(_saved_autoscalex) 6814 self.set_autoscaley_on(_saved_autoscaley) 6815 self.autoscale_view() 6816 6817 if label is None: 6818 labels = [None] 6819 elif isinstance(label, six.string_types): 6820 labels = [label] 6821 else: 6822 labels = [six.text_type(lab) for lab in label] 6823 6824 for patch, lbl in zip_longest(patches, labels, fillvalue=None): 6825 if patch: 6826 p = patch[0] 6827 p.update(kwargs) 6828 if lbl is not None: 6829 p.set_label(lbl) 6830 6831 for p in patch[1:]: 6832 p.update(kwargs) 6833 p.set_label('_nolegend_') 6834 6835 if nx == 1: 6836 return tops[0], bins, cbook.silent_list('Patch', patches[0]) 6837 else: 6838 return tops, bins, cbook.silent_list('Lists of Patches', patches) 6839 6840 @_preprocess_data(replace_names=["x", "y", "weights"], label_namer=None) 6841 def hist2d(self, x, y, bins=10, range=None, normed=False, weights=None, 6842 cmin=None, cmax=None, **kwargs): 6843 """ 6844 Make a 2D histogram plot. 6845 6846 Parameters 6847 ---------- 6848 x, y: array_like, shape (n, ) 6849 Input values 6850 6851 bins: [None | int | [int, int] | array_like | [array, array]] 6852 6853 The bin specification: 6854 6855 - If int, the number of bins for the two dimensions 6856 (nx=ny=bins). 6857 6858 - If ``[int, int]``, the number of bins in each dimension 6859 (nx, ny = bins). 6860 6861 - If array_like, the bin edges for the two dimensions 6862 (x_edges=y_edges=bins). 6863 6864 - If ``[array, array]``, the bin edges in each dimension 6865 (x_edges, y_edges = bins). 6866 6867 The default value is 10. 6868 6869 range : array_like shape(2, 2), optional, default: None 6870 The leftmost and rightmost edges of the bins along each dimension 6871 (if not specified explicitly in the bins parameters): ``[[xmin, 6872 xmax], [ymin, ymax]]``. All values outside of this range will be 6873 considered outliers and not tallied in the histogram. 6874 6875 normed : boolean, optional, default: False 6876 Normalize histogram. 6877 6878 weights : array_like, shape (n, ), optional, default: None 6879 An array of values w_i weighing each sample (x_i, y_i). 6880 6881 cmin : scalar, optional, default: None 6882 All bins that has count less than cmin will not be displayed and 6883 these count values in the return value count histogram will also 6884 be set to nan upon return 6885 6886 cmax : scalar, optional, default: None 6887 All bins that has count more than cmax will not be displayed (set 6888 to none before passing to imshow) and these count values in the 6889 return value count histogram will also be set to nan upon return 6890 6891 Returns 6892 ------- 6893 h : 2D array 6894 The bi-dimensional histogram of samples x and y. Values in x are 6895 histogrammed along the first dimension and values in y are 6896 histogrammed along the second dimension. 6897 xedges : 1D array 6898 The bin edges along the x axis. 6899 yedges : 1D array 6900 The bin edges along the y axis. 6901 image : AxesImage 6902 6903 Other Parameters 6904 ---------------- 6905 cmap : Colormap or str, optional 6906 A `.colors.Colormap` instance. If not set, use rc settings. 6907 6908 norm : Normalize, optional 6909 A `.colors.Normalize` instance is used to 6910 scale luminance data to ``[0, 1]``. If not set, defaults to 6911 `.colors.Normalize()`. 6912 6913 vmin/vmax : None or scalar, optional 6914 Arguments passed to the `~.colors.Normalize` instance. 6915 6916 alpha : ``0 <= scalar <= 1`` or ``None``, optional 6917 The alpha blending value. 6918 6919 See also 6920 -------- 6921 hist : 1D histogram plotting 6922 6923 Notes 6924 ----- 6925 - Currently ``hist2d`` calculates it's own axis limits, and any limits 6926 previously set are ignored. 6927 - Rendering the histogram with a logarithmic color scale is 6928 accomplished by passing a `.colors.LogNorm` instance to the *norm* 6929 keyword argument. Likewise, power-law normalization (similar 6930 in effect to gamma correction) can be accomplished with 6931 `.colors.PowerNorm`. 6932 """ 6933 6934 h, xedges, yedges = np.histogram2d(x, y, bins=bins, range=range, 6935 normed=normed, weights=weights) 6936 6937 if cmin is not None: 6938 h[h < cmin] = None 6939 if cmax is not None: 6940 h[h > cmax] = None 6941 6942 pc = self.pcolorfast(xedges, yedges, h.T, **kwargs) 6943 self.set_xlim(xedges[0], xedges[-1]) 6944 self.set_ylim(yedges[0], yedges[-1]) 6945 6946 return h, xedges, yedges, pc 6947 6948 @_preprocess_data(replace_names=["x"], label_namer=None) 6949 @docstring.dedent_interpd 6950 def psd(self, x, NFFT=None, Fs=None, Fc=None, detrend=None, 6951 window=None, noverlap=None, pad_to=None, 6952 sides=None, scale_by_freq=None, return_line=None, **kwargs): 6953 r""" 6954 Plot the power spectral density. 6955 6956 Call signature:: 6957 6958 psd(x, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none, 6959 window=mlab.window_hanning, noverlap=0, pad_to=None, 6960 sides='default', scale_by_freq=None, return_line=None, **kwargs) 6961 6962 The power spectral density :math:`P_{xx}` by Welch's average 6963 periodogram method. The vector *x* is divided into *NFFT* length 6964 segments. Each segment is detrended by function *detrend* and 6965 windowed by function *window*. *noverlap* gives the length of 6966 the overlap between segments. The :math:`|\mathrm{fft}(i)|^2` 6967 of each segment :math:`i` are averaged to compute :math:`P_{xx}`, 6968 with a scaling to correct for power loss due to windowing. 6969 6970 If len(*x*) < *NFFT*, it will be zero padded to *NFFT*. 6971 6972 Parameters 6973 ---------- 6974 x : 1-D array or sequence 6975 Array or sequence containing the data 6976 6977 %(Spectral)s 6978 6979 %(PSD)s 6980 6981 noverlap : integer 6982 The number of points of overlap between segments. 6983 The default value is 0 (no overlap). 6984 6985 Fc : integer 6986 The center frequency of *x* (defaults to 0), which offsets 6987 the x extents of the plot to reflect the frequency range used 6988 when a signal is acquired and then filtered and downsampled to 6989 baseband. 6990 6991 return_line : bool 6992 Whether to include the line object plotted in the returned values. 6993 Default is False. 6994 6995 Returns 6996 ------- 6997 Pxx : 1-D array 6998 The values for the power spectrum `P_{xx}` before scaling 6999 (real valued) 7000 7001 freqs : 1-D array 7002 The frequencies corresponding to the elements in *Pxx* 7003 7004 line : a :class:`~matplotlib.lines.Line2D` instance 7005 The line created by this function. 7006 Only returned if *return_line* is True. 7007 7008 Other Parameters 7009 ---------------- 7010 **kwargs : 7011 Keyword arguments control the :class:`~matplotlib.lines.Line2D` 7012 properties: 7013 7014 %(Line2D)s 7015 7016 See Also 7017 -------- 7018 :func:`specgram` 7019 :func:`specgram` differs in the default overlap; in not returning 7020 the mean of the segment periodograms; in returning the times of the 7021 segments; and in plotting a colormap instead of a line. 7022 7023 :func:`magnitude_spectrum` 7024 :func:`magnitude_spectrum` plots the magnitude spectrum. 7025 7026 :func:`csd` 7027 :func:`csd` plots the spectral density between two signals. 7028 7029 Notes 7030 ----- 7031 For plotting, the power is plotted as 7032 :math:`10\log_{10}(P_{xx})` for decibels, though *Pxx* itself 7033 is returned. 7034 7035 References 7036 ---------- 7037 Bendat & Piersol -- Random Data: Analysis and Measurement Procedures, 7038 John Wiley & Sons (1986) 7039 """ 7040 if not self._hold: 7041 self.cla() 7042 7043 if Fc is None: 7044 Fc = 0 7045 7046 pxx, freqs = mlab.psd(x=x, NFFT=NFFT, Fs=Fs, detrend=detrend, 7047 window=window, noverlap=noverlap, pad_to=pad_to, 7048 sides=sides, scale_by_freq=scale_by_freq) 7049 freqs += Fc 7050 7051 if scale_by_freq in (None, True): 7052 psd_units = 'dB/Hz' 7053 else: 7054 psd_units = 'dB' 7055 7056 line = self.plot(freqs, 10 * np.log10(pxx), **kwargs) 7057 self.set_xlabel('Frequency') 7058 self.set_ylabel('Power Spectral Density (%s)' % psd_units) 7059 self.grid(True) 7060 vmin, vmax = self.viewLim.intervaly 7061 intv = vmax - vmin 7062 logi = int(np.log10(intv)) 7063 if logi == 0: 7064 logi = .1 7065 step = 10 * logi 7066 ticks = np.arange(math.floor(vmin), math.ceil(vmax) + 1, step) 7067 self.set_yticks(ticks) 7068 7069 if return_line is None or not return_line: 7070 return pxx, freqs 7071 else: 7072 return pxx, freqs, line 7073 7074 @_preprocess_data(replace_names=["x", "y"], label_namer="y") 7075 @docstring.dedent_interpd 7076 def csd(self, x, y, NFFT=None, Fs=None, Fc=None, detrend=None, 7077 window=None, noverlap=None, pad_to=None, 7078 sides=None, scale_by_freq=None, return_line=None, **kwargs): 7079 """ 7080 Plot the cross-spectral density. 7081 7082 Call signature:: 7083 7084 csd(x, y, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none, 7085 window=mlab.window_hanning, noverlap=0, pad_to=None, 7086 sides='default', scale_by_freq=None, return_line=None, **kwargs) 7087 7088 The cross spectral density :math:`P_{xy}` by Welch's average 7089 periodogram method. The vectors *x* and *y* are divided into 7090 *NFFT* length segments. Each segment is detrended by function 7091 *detrend* and windowed by function *window*. *noverlap* gives 7092 the length of the overlap between segments. The product of 7093 the direct FFTs of *x* and *y* are averaged over each segment 7094 to compute :math:`P_{xy}`, with a scaling to correct for power 7095 loss due to windowing. 7096 7097 If len(*x*) < *NFFT* or len(*y*) < *NFFT*, they will be zero 7098 padded to *NFFT*. 7099 7100 Parameters 7101 ---------- 7102 x, y : 1-D arrays or sequences 7103 Arrays or sequences containing the data 7104 7105 %(Spectral)s 7106 7107 %(PSD)s 7108 7109 noverlap : integer 7110 The number of points of overlap between segments. 7111 The default value is 0 (no overlap). 7112 7113 Fc : integer 7114 The center frequency of *x* (defaults to 0), which offsets 7115 the x extents of the plot to reflect the frequency range used 7116 when a signal is acquired and then filtered and downsampled to 7117 baseband. 7118 7119 return_line : bool 7120 Whether to include the line object plotted in the returned values. 7121 Default is False. 7122 7123 Returns 7124 ------- 7125 Pxy : 1-D array 7126 The values for the cross spectrum `P_{xy}` before scaling 7127 (complex valued) 7128 7129 freqs : 1-D array 7130 The frequencies corresponding to the elements in *Pxy* 7131 7132 line : a :class:`~matplotlib.lines.Line2D` instance 7133 The line created by this function. 7134 Only returned if *return_line* is True. 7135 7136 Other Parameters 7137 ---------------- 7138 **kwargs : 7139 Keyword arguments control the :class:`~matplotlib.lines.Line2D` 7140 properties: 7141 7142 %(Line2D)s 7143 7144 See Also 7145 -------- 7146 :func:`psd` 7147 :func:`psd` is the equivalent to setting y=x. 7148 7149 Notes 7150 ----- 7151 For plotting, the power is plotted as 7152 :math:`10\\log_{10}(P_{xy})` for decibels, though `P_{xy}` itself 7153 is returned. 7154 7155 References 7156 ---------- 7157 Bendat & Piersol -- Random Data: Analysis and Measurement Procedures, 7158 John Wiley & Sons (1986) 7159 """ 7160 if not self._hold: 7161 self.cla() 7162 7163 if Fc is None: 7164 Fc = 0 7165 7166 pxy, freqs = mlab.csd(x=x, y=y, NFFT=NFFT, Fs=Fs, detrend=detrend, 7167 window=window, noverlap=noverlap, pad_to=pad_to, 7168 sides=sides, scale_by_freq=scale_by_freq) 7169 # pxy is complex 7170 freqs += Fc 7171 7172 line = self.plot(freqs, 10 * np.log10(np.abs(pxy)), **kwargs) 7173 self.set_xlabel('Frequency') 7174 self.set_ylabel('Cross Spectrum Magnitude (dB)') 7175 self.grid(True) 7176 vmin, vmax = self.viewLim.intervaly 7177 7178 intv = vmax - vmin 7179 step = 10 * int(np.log10(intv)) 7180 7181 ticks = np.arange(math.floor(vmin), math.ceil(vmax) + 1, step) 7182 self.set_yticks(ticks) 7183 7184 if return_line is None or not return_line: 7185 return pxy, freqs 7186 else: 7187 return pxy, freqs, line 7188 7189 @_preprocess_data(replace_names=["x"], label_namer=None) 7190 @docstring.dedent_interpd 7191 def magnitude_spectrum(self, x, Fs=None, Fc=None, window=None, 7192 pad_to=None, sides=None, scale=None, 7193 **kwargs): 7194 """ 7195 Plot the magnitude spectrum. 7196 7197 Call signature:: 7198 7199 magnitude_spectrum(x, Fs=2, Fc=0, window=mlab.window_hanning, 7200 pad_to=None, sides='default', **kwargs) 7201 7202 Compute the magnitude spectrum of *x*. Data is padded to a 7203 length of *pad_to* and the windowing function *window* is applied to 7204 the signal. 7205 7206 Parameters 7207 ---------- 7208 x : 1-D array or sequence 7209 Array or sequence containing the data 7210 7211 %(Spectral)s 7212 7213 %(Single_Spectrum)s 7214 7215 scale : [ 'default' | 'linear' | 'dB' ] 7216 The scaling of the values in the *spec*. 'linear' is no scaling. 7217 'dB' returns the values in dB scale, i.e., the dB amplitude 7218 (20 * log10). 'default' is 'linear'. 7219 7220 Fc : integer 7221 The center frequency of *x* (defaults to 0), which offsets 7222 the x extents of the plot to reflect the frequency range used 7223 when a signal is acquired and then filtered and downsampled to 7224 baseband. 7225 7226 Returns 7227 ------- 7228 spectrum : 1-D array 7229 The values for the magnitude spectrum before scaling (real valued) 7230 7231 freqs : 1-D array 7232 The frequencies corresponding to the elements in *spectrum* 7233 7234 line : a :class:`~matplotlib.lines.Line2D` instance 7235 The line created by this function 7236 7237 Other Parameters 7238 ---------------- 7239 **kwargs : 7240 Keyword arguments control the :class:`~matplotlib.lines.Line2D` 7241 properties: 7242 7243 %(Line2D)s 7244 7245 See Also 7246 -------- 7247 :func:`psd` 7248 :func:`psd` plots the power spectral density.`. 7249 7250 :func:`angle_spectrum` 7251 :func:`angle_spectrum` plots the angles of the corresponding 7252 frequencies. 7253 7254 :func:`phase_spectrum` 7255 :func:`phase_spectrum` plots the phase (unwrapped angle) of the 7256 corresponding frequencies. 7257 7258 :func:`specgram` 7259 :func:`specgram` can plot the magnitude spectrum of segments within 7260 the signal in a colormap. 7261 7262 Notes 7263 ----- 7264 .. [Notes section required for data comment. See #10189.] 7265 7266 """ 7267 if not self._hold: 7268 self.cla() 7269 7270 if Fc is None: 7271 Fc = 0 7272 7273 if scale is None or scale == 'default': 7274 scale = 'linear' 7275 7276 spec, freqs = mlab.magnitude_spectrum(x=x, Fs=Fs, window=window, 7277 pad_to=pad_to, sides=sides) 7278 freqs += Fc 7279 7280 if scale == 'linear': 7281 Z = spec 7282 yunits = 'energy' 7283 elif scale == 'dB': 7284 Z = 20. * np.log10(spec) 7285 yunits = 'dB' 7286 else: 7287 raise ValueError('Unknown scale %s', scale) 7288 7289 lines = self.plot(freqs, Z, **kwargs) 7290 self.set_xlabel('Frequency') 7291 self.set_ylabel('Magnitude (%s)' % yunits) 7292 7293 return spec, freqs, lines[0] 7294 7295 @_preprocess_data(replace_names=["x"], label_namer=None) 7296 @docstring.dedent_interpd 7297 def angle_spectrum(self, x, Fs=None, Fc=None, window=None, 7298 pad_to=None, sides=None, **kwargs): 7299 """ 7300 Plot the angle spectrum. 7301 7302 Call signature:: 7303 7304 angle_spectrum(x, Fs=2, Fc=0, window=mlab.window_hanning, 7305 pad_to=None, sides='default', **kwargs) 7306 7307 Compute the angle spectrum (wrapped phase spectrum) of *x*. 7308 Data is padded to a length of *pad_to* and the windowing function 7309 *window* is applied to the signal. 7310 7311 Parameters 7312 ---------- 7313 x : 1-D array or sequence 7314 Array or sequence containing the data 7315 7316 %(Spectral)s 7317 7318 %(Single_Spectrum)s 7319 7320 Fc : integer 7321 The center frequency of *x* (defaults to 0), which offsets 7322 the x extents of the plot to reflect the frequency range used 7323 when a signal is acquired and then filtered and downsampled to 7324 baseband. 7325 7326 Returns 7327 ------- 7328 spectrum : 1-D array 7329 The values for the angle spectrum in radians (real valued) 7330 7331 freqs : 1-D array 7332 The frequencies corresponding to the elements in *spectrum* 7333 7334 line : a :class:`~matplotlib.lines.Line2D` instance 7335 The line created by this function 7336 7337 Other Parameters 7338 ---------------- 7339 **kwargs : 7340 Keyword arguments control the :class:`~matplotlib.lines.Line2D` 7341 properties: 7342 7343 %(Line2D)s 7344 7345 See Also 7346 -------- 7347 :func:`magnitude_spectrum` 7348 :func:`angle_spectrum` plots the magnitudes of the corresponding 7349 frequencies. 7350 7351 :func:`phase_spectrum` 7352 :func:`phase_spectrum` plots the unwrapped version of this 7353 function. 7354 7355 :func:`specgram` 7356 :func:`specgram` can plot the angle spectrum of segments within the 7357 signal in a colormap. 7358 7359 Notes 7360 ----- 7361 .. [Notes section required for data comment. See #10189.] 7362 7363 """ 7364 if not self._hold: 7365 self.cla() 7366 7367 if Fc is None: 7368 Fc = 0 7369 7370 spec, freqs = mlab.angle_spectrum(x=x, Fs=Fs, window=window, 7371 pad_to=pad_to, sides=sides) 7372 freqs += Fc 7373 7374 lines = self.plot(freqs, spec, **kwargs) 7375 self.set_xlabel('Frequency') 7376 self.set_ylabel('Angle (radians)') 7377 7378 return spec, freqs, lines[0] 7379 7380 @_preprocess_data(replace_names=["x"], label_namer=None) 7381 @docstring.dedent_interpd 7382 def phase_spectrum(self, x, Fs=None, Fc=None, window=None, 7383 pad_to=None, sides=None, **kwargs): 7384 """ 7385 Plot the phase spectrum. 7386 7387 Call signature:: 7388 7389 phase_spectrum(x, Fs=2, Fc=0, window=mlab.window_hanning, 7390 pad_to=None, sides='default', **kwargs) 7391 7392 Compute the phase spectrum (unwrapped angle spectrum) of *x*. 7393 Data is padded to a length of *pad_to* and the windowing function 7394 *window* is applied to the signal. 7395 7396 Parameters 7397 ---------- 7398 x : 1-D array or sequence 7399 Array or sequence containing the data 7400 7401 %(Spectral)s 7402 7403 %(Single_Spectrum)s 7404 7405 Fc : integer 7406 The center frequency of *x* (defaults to 0), which offsets 7407 the x extents of the plot to reflect the frequency range used 7408 when a signal is acquired and then filtered and downsampled to 7409 baseband. 7410 7411 Returns 7412 ------- 7413 spectrum : 1-D array 7414 The values for the phase spectrum in radians (real valued) 7415 7416 freqs : 1-D array 7417 The frequencies corresponding to the elements in *spectrum* 7418 7419 line : a :class:`~matplotlib.lines.Line2D` instance 7420 The line created by this function 7421 7422 Other Parameters 7423 ---------------- 7424 **kwargs : 7425 Keyword arguments control the :class:`~matplotlib.lines.Line2D` 7426 properties: 7427 7428 %(Line2D)s 7429 7430 See Also 7431 -------- 7432 :func:`magnitude_spectrum` 7433 :func:`magnitude_spectrum` plots the magnitudes of the 7434 corresponding frequencies. 7435 7436 :func:`angle_spectrum` 7437 :func:`angle_spectrum` plots the wrapped version of this function. 7438 7439 :func:`specgram` 7440 :func:`specgram` can plot the phase spectrum of segments within the 7441 signal in a colormap. 7442 7443 Notes 7444 ----- 7445 .. [Notes section required for data comment. See #10189.] 7446 7447 """ 7448 if not self._hold: 7449 self.cla() 7450 7451 if Fc is None: 7452 Fc = 0 7453 7454 spec, freqs = mlab.phase_spectrum(x=x, Fs=Fs, window=window, 7455 pad_to=pad_to, sides=sides) 7456 freqs += Fc 7457 7458 lines = self.plot(freqs, spec, **kwargs) 7459 self.set_xlabel('Frequency') 7460 self.set_ylabel('Phase (radians)') 7461 7462 return spec, freqs, lines[0] 7463 7464 @_preprocess_data(replace_names=["x", "y"], label_namer=None) 7465 @docstring.dedent_interpd 7466 def cohere(self, x, y, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none, 7467 window=mlab.window_hanning, noverlap=0, pad_to=None, 7468 sides='default', scale_by_freq=None, **kwargs): 7469 """ 7470 Plot the coherence between *x* and *y*. 7471 7472 Plot the coherence between *x* and *y*. Coherence is the 7473 normalized cross spectral density: 7474 7475 .. math:: 7476 7477 C_{xy} = \\frac{|P_{xy}|^2}{P_{xx}P_{yy}} 7478 7479 Parameters 7480 ---------- 7481 %(Spectral)s 7482 7483 %(PSD)s 7484 7485 noverlap : integer 7486 The number of points of overlap between blocks. The 7487 default value is 0 (no overlap). 7488 7489 Fc : integer 7490 The center frequency of *x* (defaults to 0), which offsets 7491 the x extents of the plot to reflect the frequency range used 7492 when a signal is acquired and then filtered and downsampled to 7493 baseband. 7494 7495 7496 Returns 7497 ------- 7498 The return value is a tuple (*Cxy*, *f*), where *f* are the 7499 frequencies of the coherence vector. 7500 7501 kwargs are applied to the lines. 7502 7503 Other Parameters 7504 ---------------- 7505 **kwargs : 7506 Keyword arguments control the :class:`~matplotlib.lines.Line2D` 7507 properties: 7508 7509 %(Line2D)s 7510 7511 References 7512 ---------- 7513 Bendat & Piersol -- Random Data: Analysis and Measurement Procedures, 7514 John Wiley & Sons (1986) 7515 """ 7516 if not self._hold: 7517 self.cla() 7518 cxy, freqs = mlab.cohere(x=x, y=y, NFFT=NFFT, Fs=Fs, detrend=detrend, 7519 window=window, noverlap=noverlap, 7520 scale_by_freq=scale_by_freq) 7521 freqs += Fc 7522 7523 self.plot(freqs, cxy, **kwargs) 7524 self.set_xlabel('Frequency') 7525 self.set_ylabel('Coherence') 7526 self.grid(True) 7527 7528 return cxy, freqs 7529 7530 @_preprocess_data(replace_names=["x"], label_namer=None) 7531 @docstring.dedent_interpd 7532 def specgram(self, x, NFFT=None, Fs=None, Fc=None, detrend=None, 7533 window=None, noverlap=None, 7534 cmap=None, xextent=None, pad_to=None, sides=None, 7535 scale_by_freq=None, mode=None, scale=None, 7536 vmin=None, vmax=None, **kwargs): 7537 """ 7538 Plot a spectrogram. 7539 7540 Call signature:: 7541 7542 specgram(x, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none, 7543 window=mlab.window_hanning, noverlap=128, 7544 cmap=None, xextent=None, pad_to=None, sides='default', 7545 scale_by_freq=None, mode='default', scale='default', 7546 **kwargs) 7547 7548 Compute and plot a spectrogram of data in *x*. Data are split into 7549 *NFFT* length segments and the spectrum of each section is 7550 computed. The windowing function *window* is applied to each 7551 segment, and the amount of overlap of each segment is 7552 specified with *noverlap*. The spectrogram is plotted as a colormap 7553 (using imshow). 7554 7555 Parameters 7556 ---------- 7557 x : 1-D array or sequence 7558 Array or sequence containing the data. 7559 7560 %(Spectral)s 7561 7562 %(PSD)s 7563 7564 mode : [ 'default' | 'psd' | 'magnitude' | 'angle' | 'phase' ] 7565 What sort of spectrum to use. Default is 'psd', which takes 7566 the power spectral density. 'complex' returns the complex-valued 7567 frequency spectrum. 'magnitude' returns the magnitude spectrum. 7568 'angle' returns the phase spectrum without unwrapping. 'phase' 7569 returns the phase spectrum with unwrapping. 7570 7571 noverlap : integer 7572 The number of points of overlap between blocks. The 7573 default value is 128. 7574 7575 scale : [ 'default' | 'linear' | 'dB' ] 7576 The scaling of the values in the *spec*. 'linear' is no scaling. 7577 'dB' returns the values in dB scale. When *mode* is 'psd', 7578 this is dB power (10 * log10). Otherwise this is dB amplitude 7579 (20 * log10). 'default' is 'dB' if *mode* is 'psd' or 7580 'magnitude' and 'linear' otherwise. This must be 'linear' 7581 if *mode* is 'angle' or 'phase'. 7582 7583 Fc : integer 7584 The center frequency of *x* (defaults to 0), which offsets 7585 the x extents of the plot to reflect the frequency range used 7586 when a signal is acquired and then filtered and downsampled to 7587 baseband. 7588 7589 cmap : 7590 A :class:`matplotlib.colors.Colormap` instance; if *None*, use 7591 default determined by rc 7592 7593 xextent : [None | (xmin, xmax)] 7594 The image extent along the x-axis. The default sets *xmin* to the 7595 left border of the first bin (*spectrum* column) and *xmax* to the 7596 right border of the last bin. Note that for *noverlap>0* the width 7597 of the bins is smaller than those of the segments. 7598 7599 **kwargs : 7600 Additional kwargs are passed on to imshow which makes the 7601 specgram image 7602 7603 Returns 7604 ------- 7605 spectrum : 2-D array 7606 Columns are the periodograms of successive segments. 7607 7608 freqs : 1-D array 7609 The frequencies corresponding to the rows in *spectrum*. 7610 7611 t : 1-D array 7612 The times corresponding to midpoints of segments (i.e., the columns 7613 in *spectrum*). 7614 7615 im : instance of class :class:`~matplotlib.image.AxesImage` 7616 The image created by imshow containing the spectrogram 7617 7618 See Also 7619 -------- 7620 :func:`psd` 7621 :func:`psd` differs in the default overlap; in returning the mean 7622 of the segment periodograms; in not returning times; and in 7623 generating a line plot instead of colormap. 7624 7625 :func:`magnitude_spectrum` 7626 A single spectrum, similar to having a single segment when *mode* 7627 is 'magnitude'. Plots a line instead of a colormap. 7628 7629 :func:`angle_spectrum` 7630 A single spectrum, similar to having a single segment when *mode* 7631 is 'angle'. Plots a line instead of a colormap. 7632 7633 :func:`phase_spectrum` 7634 A single spectrum, similar to having a single segment when *mode* 7635 is 'phase'. Plots a line instead of a colormap. 7636 7637 Notes 7638 ----- 7639 The parameters *detrend* and *scale_by_freq* do only apply when *mode* 7640 is set to 'psd'. 7641 """ 7642 if not self._hold: 7643 self.cla() 7644 7645 if NFFT is None: 7646 NFFT = 256 # same default as in mlab.specgram() 7647 if Fc is None: 7648 Fc = 0 # same default as in mlab._spectral_helper() 7649 if noverlap is None: 7650 noverlap = 128 # same default as in mlab.specgram() 7651 7652 if mode == 'complex': 7653 raise ValueError('Cannot plot a complex specgram') 7654 7655 if scale is None or scale == 'default': 7656 if mode in ['angle', 'phase']: 7657 scale = 'linear' 7658 else: 7659 scale = 'dB' 7660 elif mode in ['angle', 'phase'] and scale == 'dB': 7661 raise ValueError('Cannot use dB scale with angle or phase mode') 7662 7663 spec, freqs, t = mlab.specgram(x=x, NFFT=NFFT, Fs=Fs, 7664 detrend=detrend, window=window, 7665 noverlap=noverlap, pad_to=pad_to, 7666 sides=sides, 7667 scale_by_freq=scale_by_freq, 7668 mode=mode) 7669 7670 if scale == 'linear': 7671 Z = spec 7672 elif scale == 'dB': 7673 if mode is None or mode == 'default' or mode == 'psd': 7674 Z = 10. * np.log10(spec) 7675 else: 7676 Z = 20. * np.log10(spec) 7677 else: 7678 raise ValueError('Unknown scale %s', scale) 7679 7680 Z = np.flipud(Z) 7681 7682 if xextent is None: 7683 # padding is needed for first and last segment: 7684 pad_xextent = (NFFT-noverlap) / Fs / 2 7685 xextent = np.min(t) - pad_xextent, np.max(t) + pad_xextent 7686 xmin, xmax = xextent 7687 freqs += Fc 7688 extent = xmin, xmax, freqs[0], freqs[-1] 7689 im = self.imshow(Z, cmap, extent=extent, vmin=vmin, vmax=vmax, 7690 **kwargs) 7691 self.axis('auto') 7692 7693 return spec, freqs, t, im 7694 7695 def spy(self, Z, precision=0, marker=None, markersize=None, 7696 aspect='equal', origin="upper", **kwargs): 7697 """ 7698 Plot the sparsity pattern on a 2-D array. 7699 7700 ``spy(Z)`` plots the sparsity pattern of the 2-D array *Z*. 7701 7702 Parameters 7703 ---------- 7704 7705 Z : sparse array (n, m) 7706 The array to be plotted. 7707 7708 precision : float, optional, default: 0 7709 If *precision* is 0, any non-zero value will be plotted; else, 7710 values of :math:`|Z| > precision` will be plotted. 7711 7712 For :class:`scipy.sparse.spmatrix` instances, there is a special 7713 case: if *precision* is 'present', any value present in the array 7714 will be plotted, even if it is identically zero. 7715 7716 origin : ["upper", "lower"], optional, default: "upper" 7717 Place the [0,0] index of the array in the upper left or lower left 7718 corner of the axes. 7719 7720 aspect : ['auto' | 'equal' | scalar], optional, default: "equal" 7721 7722 If 'equal', and `extent` is None, changes the axes aspect ratio to 7723 match that of the image. If `extent` is not `None`, the axes 7724 aspect ratio is changed to match that of the extent. 7725 7726 7727 If 'auto', changes the image aspect ratio to match that of the 7728 axes. 7729 7730 If None, default to rc ``image.aspect`` value. 7731 7732 Two plotting styles are available: image or marker. Both 7733 are available for full arrays, but only the marker style 7734 works for :class:`scipy.sparse.spmatrix` instances. 7735 7736 If *marker* and *markersize* are *None*, an image will be 7737 returned and any remaining kwargs are passed to 7738 :func:`~matplotlib.pyplot.imshow`; else, a 7739 :class:`~matplotlib.lines.Line2D` object will be returned with 7740 the value of marker determining the marker type, and any 7741 remaining kwargs passed to the 7742 :meth:`~matplotlib.axes.Axes.plot` method. 7743 7744 If *marker* and *markersize* are *None*, useful kwargs include: 7745 7746 * *cmap* 7747 * *alpha* 7748 7749 See also 7750 -------- 7751 imshow : for image options. 7752 plot : for plotting options 7753 """ 7754 if marker is None and markersize is None and hasattr(Z, 'tocoo'): 7755 marker = 's' 7756 if marker is None and markersize is None: 7757 Z = np.asarray(Z) 7758 mask = np.abs(Z) > precision 7759 7760 if 'cmap' not in kwargs: 7761 kwargs['cmap'] = mcolors.ListedColormap(['w', 'k'], 7762 name='binary') 7763 nr, nc = Z.shape 7764 extent = [-0.5, nc - 0.5, nr - 0.5, -0.5] 7765 ret = self.imshow(mask, interpolation='nearest', aspect=aspect, 7766 extent=extent, origin=origin, **kwargs) 7767 else: 7768 if hasattr(Z, 'tocoo'): 7769 c = Z.tocoo() 7770 if precision == 'present': 7771 y = c.row 7772 x = c.col 7773 else: 7774 nonzero = np.abs(c.data) > precision 7775 y = c.row[nonzero] 7776 x = c.col[nonzero] 7777 else: 7778 Z = np.asarray(Z) 7779 nonzero = np.abs(Z) > precision 7780 y, x = np.nonzero(nonzero) 7781 if marker is None: 7782 marker = 's' 7783 if markersize is None: 7784 markersize = 10 7785 marks = mlines.Line2D(x, y, linestyle='None', 7786 marker=marker, markersize=markersize, **kwargs) 7787 self.add_line(marks) 7788 nr, nc = Z.shape 7789 self.set_xlim(xmin=-0.5, xmax=nc - 0.5) 7790 self.set_ylim(ymin=nr - 0.5, ymax=-0.5) 7791 self.set_aspect(aspect) 7792 ret = marks 7793 self.title.set_y(1.05) 7794 self.xaxis.tick_top() 7795 self.xaxis.set_ticks_position('both') 7796 self.xaxis.set_major_locator(mticker.MaxNLocator(nbins=9, 7797 steps=[1, 2, 5, 10], 7798 integer=True)) 7799 self.yaxis.set_major_locator(mticker.MaxNLocator(nbins=9, 7800 steps=[1, 2, 5, 10], 7801 integer=True)) 7802 return ret 7803 7804 def matshow(self, Z, **kwargs): 7805 """ 7806 Plot the values of a 2D matrix or array as color-coded image. 7807 7808 The matrix will be shown the way it would be printed, with the first 7809 row at the top. Row and column numbering is zero-based. 7810 7811 Parameters 7812 ---------- 7813 Z : array-like(N, M) 7814 The matrix to be displayed. 7815 7816 Returns 7817 ------- 7818 image : `~matplotlib.image.AxesImage` 7819 7820 Other Parameters 7821 ---------------- 7822 **kwargs : `~matplotlib.axes.Axes.imshow` arguments 7823 7824 See Also 7825 -------- 7826 imshow : More general function to plot data on a 2D regular raster. 7827 7828 Notes 7829 ----- 7830 This is just a convenience function wrapping `.imshow` to set useful 7831 defaults for a displaying a matrix. In particular: 7832 7833 - Set ``origin='upper'``. 7834 - Set ``interpolation='nearest'``. 7835 - Set ``aspect='equal'``. 7836 - Ticks are placed to the left and above. 7837 - Ticks are formatted to show integer indices. 7838 7839 """ 7840 Z = np.asanyarray(Z) 7841 nr, nc = Z.shape 7842 kw = {'origin': 'upper', 7843 'interpolation': 'nearest', 7844 'aspect': 'equal'} # (already the imshow default) 7845 kw.update(kwargs) 7846 im = self.imshow(Z, **kw) 7847 self.title.set_y(1.05) 7848 self.xaxis.tick_top() 7849 self.xaxis.set_ticks_position('both') 7850 self.xaxis.set_major_locator(mticker.MaxNLocator(nbins=9, 7851 steps=[1, 2, 5, 10], 7852 integer=True)) 7853 self.yaxis.set_major_locator(mticker.MaxNLocator(nbins=9, 7854 steps=[1, 2, 5, 10], 7855 integer=True)) 7856 return im 7857 7858 @_preprocess_data(replace_names=["dataset"], label_namer=None) 7859 def violinplot(self, dataset, positions=None, vert=True, widths=0.5, 7860 showmeans=False, showextrema=True, showmedians=False, 7861 points=100, bw_method=None): 7862 """ 7863 Make a violin plot. 7864 7865 Make a violin plot for each column of *dataset* or each vector in 7866 sequence *dataset*. Each filled area extends to represent the 7867 entire data range, with optional lines at the mean, the median, 7868 the minimum, and the maximum. 7869 7870 Parameters 7871 ---------- 7872 dataset : Array or a sequence of vectors. 7873 The input data. 7874 7875 positions : array-like, default = [1, 2, ..., n] 7876 Sets the positions of the violins. The ticks and limits are 7877 automatically set to match the positions. 7878 7879 vert : bool, default = True. 7880 If true, creates a vertical violin plot. 7881 Otherwise, creates a horizontal violin plot. 7882 7883 widths : array-like, default = 0.5 7884 Either a scalar or a vector that sets the maximal width of 7885 each violin. The default is 0.5, which uses about half of the 7886 available horizontal space. 7887 7888 showmeans : bool, default = False 7889 If `True`, will toggle rendering of the means. 7890 7891 showextrema : bool, default = True 7892 If `True`, will toggle rendering of the extrema. 7893 7894 showmedians : bool, default = False 7895 If `True`, will toggle rendering of the medians. 7896 7897 points : scalar, default = 100 7898 Defines the number of points to evaluate each of the 7899 gaussian kernel density estimations at. 7900 7901 bw_method : str, scalar or callable, optional 7902 The method used to calculate the estimator bandwidth. This can be 7903 'scott', 'silverman', a scalar constant or a callable. If a 7904 scalar, this will be used directly as `kde.factor`. If a 7905 callable, it should take a `GaussianKDE` instance as its only 7906 parameter and return a scalar. If None (default), 'scott' is used. 7907 7908 Returns 7909 ------- 7910 7911 result : dict 7912 A dictionary mapping each component of the violinplot to a 7913 list of the corresponding collection instances created. The 7914 dictionary has the following keys: 7915 7916 - ``bodies``: A list of the 7917 :class:`matplotlib.collections.PolyCollection` instances 7918 containing the filled area of each violin. 7919 7920 - ``cmeans``: A 7921 :class:`matplotlib.collections.LineCollection` instance 7922 created to identify the mean values of each of the 7923 violin's distribution. 7924 7925 - ``cmins``: A 7926 :class:`matplotlib.collections.LineCollection` instance 7927 created to identify the bottom of each violin's 7928 distribution. 7929 7930 - ``cmaxes``: A 7931 :class:`matplotlib.collections.LineCollection` instance 7932 created to identify the top of each violin's 7933 distribution. 7934 7935 - ``cbars``: A 7936 :class:`matplotlib.collections.LineCollection` instance 7937 created to identify the centers of each violin's 7938 distribution. 7939 7940 - ``cmedians``: A 7941 :class:`matplotlib.collections.LineCollection` instance 7942 created to identify the median values of each of the 7943 violin's distribution. 7944 7945 Notes 7946 ----- 7947 .. [Notes section required for data comment. See #10189.] 7948 7949 """ 7950 7951 def _kde_method(X, coords): 7952 # fallback gracefully if the vector contains only one value 7953 if np.all(X[0] == X): 7954 return (X[0] == coords).astype(float) 7955 kde = mlab.GaussianKDE(X, bw_method) 7956 return kde.evaluate(coords) 7957 7958 vpstats = cbook.violin_stats(dataset, _kde_method, points=points) 7959 return self.violin(vpstats, positions=positions, vert=vert, 7960 widths=widths, showmeans=showmeans, 7961 showextrema=showextrema, showmedians=showmedians) 7962 7963 def violin(self, vpstats, positions=None, vert=True, widths=0.5, 7964 showmeans=False, showextrema=True, showmedians=False): 7965 """Drawing function for violin plots. 7966 7967 Draw a violin plot for each column of `vpstats`. Each filled area 7968 extends to represent the entire data range, with optional lines at the 7969 mean, the median, the minimum, and the maximum. 7970 7971 Parameters 7972 ---------- 7973 7974 vpstats : list of dicts 7975 A list of dictionaries containing stats for each violin plot. 7976 Required keys are: 7977 7978 - ``coords``: A list of scalars containing the coordinates that 7979 the violin's kernel density estimate were evaluated at. 7980 7981 - ``vals``: A list of scalars containing the values of the 7982 kernel density estimate at each of the coordinates given 7983 in *coords*. 7984 7985 - ``mean``: The mean value for this violin's dataset. 7986 7987 - ``median``: The median value for this violin's dataset. 7988 7989 - ``min``: The minimum value for this violin's dataset. 7990 7991 - ``max``: The maximum value for this violin's dataset. 7992 7993 positions : array-like, default = [1, 2, ..., n] 7994 Sets the positions of the violins. The ticks and limits are 7995 automatically set to match the positions. 7996 7997 vert : bool, default = True. 7998 If true, plots the violins veritcally. 7999 Otherwise, plots the violins horizontally. 8000 8001 widths : array-like, default = 0.5 8002 Either a scalar or a vector that sets the maximal width of 8003 each violin. The default is 0.5, which uses about half of the 8004 available horizontal space. 8005 8006 showmeans : bool, default = False 8007 If true, will toggle rendering of the means. 8008 8009 showextrema : bool, default = True 8010 If true, will toggle rendering of the extrema. 8011 8012 showmedians : bool, default = False 8013 If true, will toggle rendering of the medians. 8014 8015 Returns 8016 ------- 8017 result : dict 8018 A dictionary mapping each component of the violinplot to a 8019 list of the corresponding collection instances created. The 8020 dictionary has the following keys: 8021 8022 - ``bodies``: A list of the 8023 :class:`matplotlib.collections.PolyCollection` instances 8024 containing the filled area of each violin. 8025 8026 - ``cmeans``: A 8027 :class:`matplotlib.collections.LineCollection` instance 8028 created to identify the mean values of each of the 8029 violin's distribution. 8030 8031 - ``cmins``: A 8032 :class:`matplotlib.collections.LineCollection` instance 8033 created to identify the bottom of each violin's 8034 distribution. 8035 8036 - ``cmaxes``: A 8037 :class:`matplotlib.collections.LineCollection` instance 8038 created to identify the top of each violin's 8039 distribution. 8040 8041 - ``cbars``: A 8042 :class:`matplotlib.collections.LineCollection` instance 8043 created to identify the centers of each violin's 8044 distribution. 8045 8046 - ``cmedians``: A 8047 :class:`matplotlib.collections.LineCollection` instance 8048 created to identify the median values of each of the 8049 violin's distribution. 8050 8051 """ 8052 8053 # Statistical quantities to be plotted on the violins 8054 means = [] 8055 mins = [] 8056 maxes = [] 8057 medians = [] 8058 8059 # Collections to be returned 8060 artists = {} 8061 8062 N = len(vpstats) 8063 datashape_message = ("List of violinplot statistics and `{0}` " 8064 "values must have the same length") 8065 8066 # Validate positions 8067 if positions is None: 8068 positions = range(1, N + 1) 8069 elif len(positions) != N: 8070 raise ValueError(datashape_message.format("positions")) 8071 8072 # Validate widths 8073 if np.isscalar(widths): 8074 widths = [widths] * N 8075 elif len(widths) != N: 8076 raise ValueError(datashape_message.format("widths")) 8077 8078 # Calculate ranges for statistics lines 8079 pmins = -0.25 * np.array(widths) + positions 8080 pmaxes = 0.25 * np.array(widths) + positions 8081 8082 # Check whether we are rendering vertically or horizontally 8083 if vert: 8084 fill = self.fill_betweenx 8085 perp_lines = self.hlines 8086 par_lines = self.vlines 8087 else: 8088 fill = self.fill_between 8089 perp_lines = self.vlines 8090 par_lines = self.hlines 8091 8092 if rcParams['_internal.classic_mode']: 8093 fillcolor = 'y' 8094 edgecolor = 'r' 8095 else: 8096 fillcolor = edgecolor = self._get_lines.get_next_color() 8097 8098 # Render violins 8099 bodies = [] 8100 for stats, pos, width in zip(vpstats, positions, widths): 8101 # The 0.5 factor reflects the fact that we plot from v-p to 8102 # v+p 8103 vals = np.array(stats['vals']) 8104 vals = 0.5 * width * vals / vals.max() 8105 bodies += [fill(stats['coords'], 8106 -vals + pos, 8107 vals + pos, 8108 facecolor=fillcolor, 8109 alpha=0.3)] 8110 means.append(stats['mean']) 8111 mins.append(stats['min']) 8112 maxes.append(stats['max']) 8113 medians.append(stats['median']) 8114 artists['bodies'] = bodies 8115 8116 # Render means 8117 if showmeans: 8118 artists['cmeans'] = perp_lines(means, pmins, pmaxes, 8119 colors=edgecolor) 8120 8121 # Render extrema 8122 if showextrema: 8123 artists['cmaxes'] = perp_lines(maxes, pmins, pmaxes, 8124 colors=edgecolor) 8125 artists['cmins'] = perp_lines(mins, pmins, pmaxes, 8126 colors=edgecolor) 8127 artists['cbars'] = par_lines(positions, mins, maxes, 8128 colors=edgecolor) 8129 8130 # Render medians 8131 if showmedians: 8132 artists['cmedians'] = perp_lines(medians, 8133 pmins, 8134 pmaxes, 8135 colors=edgecolor) 8136 8137 return artists 8138 8139 def tricontour(self, *args, **kwargs): 8140 return mtri.tricontour(self, *args, **kwargs) 8141 tricontour.__doc__ = mtri.tricontour.__doc__ 8142 8143 def tricontourf(self, *args, **kwargs): 8144 return mtri.tricontourf(self, *args, **kwargs) 8145 tricontourf.__doc__ = mtri.tricontour.__doc__ 8146 8147 def tripcolor(self, *args, **kwargs): 8148 return mtri.tripcolor(self, *args, **kwargs) 8149 tripcolor.__doc__ = mtri.tripcolor.__doc__ 8150 8151 def triplot(self, *args, **kwargs): 8152 return mtri.triplot(self, *args, **kwargs) 8153 triplot.__doc__ = mtri.triplot.__doc__ 8154