1""" 2This is an object-oriented plotting library. 3 4A procedural interface is provided by the companion pyplot module, 5which may be imported directly, e.g.:: 6 7 import matplotlib.pyplot as plt 8 9or using ipython:: 10 11 ipython 12 13at your terminal, followed by:: 14 15 In [1]: %matplotlib 16 In [2]: import matplotlib.pyplot as plt 17 18at the ipython shell prompt. 19 20For the most part, direct use of the object-oriented library is 21encouraged when programming; pyplot is primarily for working 22interactively. The 23exceptions are the pyplot commands :func:`~matplotlib.pyplot.figure`, 24:func:`~matplotlib.pyplot.subplot`, 25:func:`~matplotlib.pyplot.subplots`, and 26:func:`~pyplot.savefig`, which can greatly simplify scripting. 27 28Modules include: 29 30 :mod:`matplotlib.axes` 31 defines the :class:`~matplotlib.axes.Axes` class. Most pylab 32 commands are wrappers for :class:`~matplotlib.axes.Axes` 33 methods. The axes module is the highest level of OO access to 34 the library. 35 36 :mod:`matplotlib.figure` 37 defines the :class:`~matplotlib.figure.Figure` class. 38 39 :mod:`matplotlib.artist` 40 defines the :class:`~matplotlib.artist.Artist` base class for 41 all classes that draw things. 42 43 :mod:`matplotlib.lines` 44 defines the :class:`~matplotlib.lines.Line2D` class for 45 drawing lines and markers 46 47 :mod:`matplotlib.patches` 48 defines classes for drawing polygons 49 50 :mod:`matplotlib.text` 51 defines the :class:`~matplotlib.text.Text`, 52 :class:`~matplotlib.text.TextWithDash`, and 53 :class:`~matplotlib.text.Annotate` classes 54 55 :mod:`matplotlib.image` 56 defines the :class:`~matplotlib.image.AxesImage` and 57 :class:`~matplotlib.image.FigureImage` classes 58 59 :mod:`matplotlib.collections` 60 classes for efficient drawing of groups of lines or polygons 61 62 :mod:`matplotlib.colors` 63 classes for interpreting color specifications and for making 64 colormaps 65 66 :mod:`matplotlib.cm` 67 colormaps and the :class:`~matplotlib.image.ScalarMappable` 68 mixin class for providing color mapping functionality to other 69 classes 70 71 :mod:`matplotlib.ticker` 72 classes for calculating tick mark locations and for formatting 73 tick labels 74 75 :mod:`matplotlib.backends` 76 a subpackage with modules for various gui libraries and output 77 formats 78 79The base matplotlib namespace includes: 80 81 :data:`~matplotlib.rcParams` 82 a global dictionary of default configuration settings. It is 83 initialized by code which may be overridden by a matplotlibrc 84 file. 85 86 :func:`~matplotlib.rc` 87 a function for setting groups of rcParams values 88 89 :func:`~matplotlib.use` 90 a function for setting the matplotlib backend. If used, this 91 function must be called immediately after importing matplotlib 92 for the first time. In particular, it must be called 93 **before** importing pylab (if pylab is imported). 94 95matplotlib was initially written by John D. Hunter (1968-2012) and is now 96developed and maintained by a host of others. 97 98Occasionally the internal documentation (python docstrings) will refer 99to MATLAB®, a registered trademark of The MathWorks, Inc. 100 101""" 102from __future__ import absolute_import, division, print_function 103 104import six 105 106import atexit 107from collections import MutableMapping 108import contextlib 109import distutils.version 110import functools 111import io 112import inspect 113import itertools 114import locale 115import logging 116import os 117import re 118import shutil 119import stat 120import sys 121import tempfile 122import warnings 123 124# cbook must import matplotlib only within function 125# definitions, so it is safe to import from it here. 126from . import cbook 127from matplotlib.cbook import ( 128 _backports, mplDeprecation, dedent, get_label, sanitize_sequence) 129from matplotlib.compat import subprocess 130from matplotlib.rcsetup import defaultParams, validate_backend, cycler 131 132import numpy 133from six.moves.urllib.request import urlopen 134from six.moves import reload_module as reload 135 136# Get the version from the _version.py versioneer file. For a git checkout, 137# this is computed based on the number of commits since the last tag. 138from ._version import get_versions 139__version__ = str(get_versions()['version']) 140del get_versions 141 142_log = logging.getLogger(__name__) 143 144__version__numpy__ = str('1.7.1') # minimum required numpy version 145 146__bibtex__ = r"""@Article{Hunter:2007, 147 Author = {Hunter, J. D.}, 148 Title = {Matplotlib: A 2D graphics environment}, 149 Journal = {Computing In Science \& Engineering}, 150 Volume = {9}, 151 Number = {3}, 152 Pages = {90--95}, 153 abstract = {Matplotlib is a 2D graphics package used for Python 154 for application development, interactive scripting, and 155 publication-quality image generation across user 156 interfaces and operating systems.}, 157 publisher = {IEEE COMPUTER SOC}, 158 year = 2007 159}""" 160 161 162_python27 = (sys.version_info.major == 2 and sys.version_info.minor >= 7) 163_python34 = (sys.version_info.major == 3 and sys.version_info.minor >= 4) 164if not (_python27 or _python34): 165 raise ImportError("Matplotlib requires Python 2.7 or 3.4 or later") 166 167if _python27: 168 _log.addHandler(logging.NullHandler()) 169 170 171def compare_versions(a, b): 172 "return True if a is greater than or equal to b" 173 if a: 174 if six.PY3: 175 if isinstance(a, bytes): 176 a = a.decode('ascii') 177 if isinstance(b, bytes): 178 b = b.decode('ascii') 179 a = distutils.version.LooseVersion(a) 180 b = distutils.version.LooseVersion(b) 181 return a >= b 182 else: 183 return False 184 185 186try: 187 import dateutil 188except ImportError: 189 raise ImportError("Matplotlib requires dateutil") 190 191 192if not compare_versions(six.__version__, '1.10'): 193 raise ImportError( 194 "Matplotlib requires six>=1.10; you have %s" % six.__version__) 195 196 197try: 198 import pyparsing 199except ImportError: 200 raise ImportError("Matplotlib requires pyparsing") 201else: 202 if not compare_versions(pyparsing.__version__, '2.0.1'): 203 raise ImportError( 204 "Matplotlib requires pyparsing>=2.0.1; you have %s" 205 % pyparsing.__version__) 206 207 208if not compare_versions(numpy.__version__, __version__numpy__): 209 raise ImportError( 210 "Matplotlib requires numpy>=%s; you have %s" % ( 211 __version__numpy__, numpy.__version__)) 212 213 214if not hasattr(sys, 'argv'): # for modpython 215 sys.argv = [str('modpython')] 216 217 218def _is_writable_dir(p): 219 """ 220 p is a string pointing to a putative writable dir -- return True p 221 is such a string, else False 222 """ 223 return os.access(p, os.W_OK) and os.path.isdir(p) 224 225_verbose_msg = """\ 226matplotlib.verbose is deprecated; 227Command line argument --verbose-LEVEL is deprecated. 228This functionality is now provided by the standard 229python logging library. To get more (or less) logging output: 230 import logging 231 logger = logging.getLogger('matplotlib') 232 logger.set_level(logging.INFO)""" 233 234 235def _set_logger_verbose_level(level_str='silent', file_str='sys.stdout'): 236 """ 237 Use a --verbose-LEVEL level to set the logging level: 238 239 """ 240 levelmap = {'silent': logging.WARNING, 'helpful': logging.INFO, 241 'debug': logging.DEBUG, 'debug-annoying': logging.DEBUG, 242 'info': logging.INFO, 'warning': logging.WARNING} 243 # Check that current state of logger isn't already more verbose 244 # than the requested level. If it is more verbose, then leave more 245 # verbose. 246 newlev = levelmap[level_str] 247 oldlev = _log.getEffectiveLevel() 248 if newlev < oldlev: 249 _log.setLevel(newlev) 250 std = { 251 'sys.stdout': sys.stdout, 252 'sys.stderr': sys.stderr, 253 } 254 if file_str in std: 255 fileo = std[file_str] 256 else: 257 fileo = sys.stdout 258 try: 259 fileo = open(file_str, 'w') 260 # if this fails, we will just write to stdout 261 except IOError: 262 warnings.warn('could not open log file "{0}"' 263 'for writing. Check your ' 264 'matplotlibrc'.format(file_str)) 265 console = logging.StreamHandler(fileo) 266 console.setLevel(newlev) 267 _log.addHandler(console) 268 269 270def _parse_commandline(): 271 """ 272 Check for --verbose-LEVEL type command line arguments and 273 set logging level appropriately. 274 """ 275 276 levels = ('silent', 'helpful', 'debug', 'debug-annoying', 277 'info', 'warning') 278 279 for arg in sys.argv[1:]: 280 if arg.startswith('--verbose-'): 281 level_str = arg[10:] 282 # If it doesn't match one of ours, then don't even 283 # bother noting it, we are just a 3rd-party library 284 # to somebody else's script. 285 if level_str in levels: 286 _set_logger_verbose_level(level_str) 287 288_parse_commandline() 289 290 291class Verbose(object): 292 """ 293 A class to handle reporting. Set the fileo attribute to any file 294 instance to handle the output. Default is sys.stdout 295 """ 296 levels = ('silent', 'helpful', 'debug', 'debug-annoying') 297 vald = {level: i for i, level in enumerate(levels)} 298 299 # parse the verbosity from the command line; flags look like 300 # --verbose-silent or --verbose-helpful 301 _commandLineVerbose = None 302 303 for arg in sys.argv[1:]: 304 if not arg.startswith('--verbose-'): 305 continue 306 level_str = arg[10:] 307 # If it doesn't match one of ours, then don't even 308 # bother noting it, we are just a 3rd-party library 309 # to somebody else's script. 310 if level_str in levels: 311 _commandLineVerbose = level_str 312 313 @cbook.deprecated("2.2", message=_verbose_msg) 314 def __init__(self): 315 self.set_level('silent') 316 self.fileo = sys.stdout 317 318 @cbook.deprecated("2.2", message=_verbose_msg) 319 def set_level(self, level): 320 'set the verbosity to one of the Verbose.levels strings' 321 322 if self._commandLineVerbose is not None: 323 level = self._commandLineVerbose 324 if level not in self.levels: 325 warnings.warn('matplotlib: unrecognized --verbose-* string "%s".' 326 ' Legal values are %s' % (level, self.levels)) 327 else: 328 self.level = level 329 330 @cbook.deprecated("2.2", message=_verbose_msg) 331 def set_fileo(self, fname): 332 std = { 333 'sys.stdout': sys.stdout, 334 'sys.stderr': sys.stderr, 335 } 336 if fname in std: 337 self.fileo = std[fname] 338 else: 339 try: 340 fileo = open(fname, 'w') 341 except IOError: 342 raise ValueError('Verbose object could not open log file "{0}"' 343 ' for writing.\nCheck your matplotlibrc ' 344 'verbose.fileo setting'.format(fname)) 345 else: 346 self.fileo = fileo 347 348 @cbook.deprecated("2.2", message=_verbose_msg) 349 def report(self, s, level='helpful'): 350 """ 351 print message s to self.fileo if self.level>=level. Return 352 value indicates whether a message was issued 353 354 """ 355 if self.ge(level): 356 print(s, file=self.fileo) 357 return True 358 return False 359 360 @cbook.deprecated("2.2", message=_verbose_msg) 361 def wrap(self, fmt, func, level='helpful', always=True): 362 """ 363 return a callable function that wraps func and reports it 364 output through the verbose handler if current verbosity level 365 is higher than level 366 367 if always is True, the report will occur on every function 368 call; otherwise only on the first time the function is called 369 """ 370 assert callable(func) 371 372 def wrapper(*args, **kwargs): 373 ret = func(*args, **kwargs) 374 375 if (always or not wrapper._spoke): 376 spoke = self.report(fmt % ret, level) 377 if not wrapper._spoke: 378 wrapper._spoke = spoke 379 return ret 380 wrapper._spoke = False 381 wrapper.__doc__ = func.__doc__ 382 return wrapper 383 384 @cbook.deprecated("2.2", message=_verbose_msg) 385 def ge(self, level): 386 'return true if self.level is >= level' 387 return self.vald[self.level] >= self.vald[level] 388 389 390with warnings.catch_warnings(): 391 warnings.simplefilter("ignore") 392 verbose = Verbose() 393 394 395def _wrap(fmt, func, level=logging.DEBUG, always=True): 396 """ 397 return a callable function that wraps func and reports its 398 output through logger 399 400 if always is True, the report will occur on every function 401 call; otherwise only on the first time the function is called 402 """ 403 assert callable(func) 404 405 def wrapper(*args, **kwargs): 406 ret = func(*args, **kwargs) 407 408 if (always or not wrapper._spoke): 409 _log.log(level, fmt % ret) 410 spoke = True 411 if not wrapper._spoke: 412 wrapper._spoke = spoke 413 return ret 414 wrapper._spoke = False 415 wrapper.__doc__ = func.__doc__ 416 return wrapper 417 418 419def checkdep_dvipng(): 420 try: 421 s = subprocess.Popen([str('dvipng'), '-version'], 422 stdout=subprocess.PIPE, 423 stderr=subprocess.PIPE) 424 stdout, stderr = s.communicate() 425 line = stdout.decode('ascii').split('\n')[1] 426 v = line.split()[-1] 427 return v 428 except (IndexError, ValueError, OSError): 429 return None 430 431 432def checkdep_ghostscript(): 433 if checkdep_ghostscript.executable is None: 434 if sys.platform == 'win32': 435 # mgs is the name in miktex 436 gs_execs = ['gswin32c', 'gswin64c', 'mgs', 'gs'] 437 else: 438 gs_execs = ['gs'] 439 for gs_exec in gs_execs: 440 try: 441 s = subprocess.Popen( 442 [str(gs_exec), '--version'], stdout=subprocess.PIPE, 443 stderr=subprocess.PIPE) 444 stdout, stderr = s.communicate() 445 if s.returncode == 0: 446 v = stdout[:-1].decode('ascii') 447 checkdep_ghostscript.executable = gs_exec 448 checkdep_ghostscript.version = v 449 except (IndexError, ValueError, OSError): 450 pass 451 return checkdep_ghostscript.executable, checkdep_ghostscript.version 452checkdep_ghostscript.executable = None 453checkdep_ghostscript.version = None 454 455 456# Deprecated, as it is unneeded and some distributions (e.g. MiKTeX 2.9.6350) 457# do not actually report the TeX version. 458@cbook.deprecated("2.1") 459def checkdep_tex(): 460 try: 461 s = subprocess.Popen([str('tex'), '-version'], stdout=subprocess.PIPE, 462 stderr=subprocess.PIPE) 463 stdout, stderr = s.communicate() 464 line = stdout.decode('ascii').split('\n')[0] 465 pattern = r'3\.1\d+' 466 match = re.search(pattern, line) 467 v = match.group(0) 468 return v 469 except (IndexError, ValueError, AttributeError, OSError): 470 return None 471 472 473def checkdep_pdftops(): 474 try: 475 s = subprocess.Popen([str('pdftops'), '-v'], stdout=subprocess.PIPE, 476 stderr=subprocess.PIPE) 477 stdout, stderr = s.communicate() 478 lines = stderr.decode('ascii').split('\n') 479 for line in lines: 480 if 'version' in line: 481 v = line.split()[-1] 482 return v 483 except (IndexError, ValueError, UnboundLocalError, OSError): 484 return None 485 486 487def checkdep_inkscape(): 488 if checkdep_inkscape.version is None: 489 try: 490 s = subprocess.Popen([str('inkscape'), '-V'], 491 stdout=subprocess.PIPE, 492 stderr=subprocess.PIPE) 493 stdout, stderr = s.communicate() 494 lines = stdout.decode('ascii').split('\n') 495 for line in lines: 496 if 'Inkscape' in line: 497 v = line.split()[1] 498 break 499 checkdep_inkscape.version = v 500 except (IndexError, ValueError, UnboundLocalError, OSError): 501 pass 502 return checkdep_inkscape.version 503checkdep_inkscape.version = None 504 505 506@cbook.deprecated("2.1") 507def checkdep_xmllint(): 508 try: 509 s = subprocess.Popen([str('xmllint'), '--version'], 510 stdout=subprocess.PIPE, 511 stderr=subprocess.PIPE) 512 stdout, stderr = s.communicate() 513 lines = stderr.decode('ascii').split('\n') 514 for line in lines: 515 if 'version' in line: 516 v = line.split()[-1] 517 break 518 return v 519 except (IndexError, ValueError, UnboundLocalError, OSError): 520 return None 521 522 523def checkdep_ps_distiller(s): 524 if not s: 525 return False 526 527 flag = True 528 gs_req = '8.60' 529 gs_exec, gs_v = checkdep_ghostscript() 530 if not compare_versions(gs_v, gs_req): 531 flag = False 532 warnings.warn(('matplotlibrc ps.usedistiller option can not be used ' 533 'unless ghostscript-%s or later is installed on your ' 534 'system') % gs_req) 535 536 if s == 'xpdf': 537 pdftops_req = '3.0' 538 pdftops_req_alt = '0.9' # poppler version numbers, ugh 539 pdftops_v = checkdep_pdftops() 540 if compare_versions(pdftops_v, pdftops_req): 541 pass 542 elif (compare_versions(pdftops_v, pdftops_req_alt) and not 543 compare_versions(pdftops_v, '1.0')): 544 pass 545 else: 546 flag = False 547 warnings.warn(('matplotlibrc ps.usedistiller can not be set to ' 548 'xpdf unless xpdf-%s or later is installed on ' 549 'your system') % pdftops_req) 550 551 if flag: 552 return s 553 else: 554 return False 555 556 557def checkdep_usetex(s): 558 if not s: 559 return False 560 561 gs_req = '8.60' 562 dvipng_req = '1.6' 563 flag = True 564 565 if _backports.which("tex") is None: 566 flag = False 567 warnings.warn('matplotlibrc text.usetex option can not be used unless ' 568 'TeX is installed on your system') 569 570 dvipng_v = checkdep_dvipng() 571 if not compare_versions(dvipng_v, dvipng_req): 572 flag = False 573 warnings.warn('matplotlibrc text.usetex can not be used with *Agg ' 574 'backend unless dvipng-%s or later is installed on ' 575 'your system' % dvipng_req) 576 577 gs_exec, gs_v = checkdep_ghostscript() 578 if not compare_versions(gs_v, gs_req): 579 flag = False 580 warnings.warn('matplotlibrc text.usetex can not be used unless ' 581 'ghostscript-%s or later is installed on your system' 582 % gs_req) 583 584 return flag 585 586 587def _get_home(): 588 """Find user's home directory if possible. 589 Otherwise, returns None. 590 591 :see: 592 http://mail.python.org/pipermail/python-list/2005-February/325395.html 593 """ 594 if six.PY2 and sys.platform == 'win32': 595 path = os.path.expanduser(b"~").decode(sys.getfilesystemencoding()) 596 else: 597 path = os.path.expanduser("~") 598 if os.path.isdir(path): 599 return path 600 for evar in ('HOME', 'USERPROFILE', 'TMP'): 601 path = os.environ.get(evar) 602 if path is not None and os.path.isdir(path): 603 return path 604 return None 605 606 607def _create_tmp_config_dir(): 608 """ 609 If the config directory can not be created, create a temporary 610 directory. 611 """ 612 configdir = os.environ['MPLCONFIGDIR'] = ( 613 tempfile.mkdtemp(prefix='matplotlib-')) 614 atexit.register(shutil.rmtree, configdir) 615 return configdir 616 617 618get_home = _wrap('$HOME=%s', _get_home, always=False) 619 620 621def _get_xdg_config_dir(): 622 """ 623 Returns the XDG configuration directory, according to the `XDG 624 base directory spec 625 <http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html>`_. 626 """ 627 path = os.environ.get('XDG_CONFIG_HOME') 628 if path is None: 629 path = get_home() 630 if path is not None: 631 path = os.path.join(path, '.config') 632 return path 633 634 635def _get_xdg_cache_dir(): 636 """ 637 Returns the XDG cache directory, according to the `XDG 638 base directory spec 639 <http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html>`_. 640 """ 641 path = os.environ.get('XDG_CACHE_HOME') 642 if path is None: 643 path = get_home() 644 if path is not None: 645 path = os.path.join(path, '.cache') 646 return path 647 648 649def _get_config_or_cache_dir(xdg_base): 650 from matplotlib.cbook import mkdirs 651 652 configdir = os.environ.get('MPLCONFIGDIR') 653 if configdir is not None: 654 configdir = os.path.abspath(configdir) 655 if not os.path.exists(configdir): 656 mkdirs(configdir) 657 658 if not _is_writable_dir(configdir): 659 return _create_tmp_config_dir() 660 return configdir 661 662 p = None 663 h = get_home() 664 if h is not None: 665 p = os.path.join(h, '.matplotlib') 666 if sys.platform.startswith(('linux', 'freebsd')): 667 p = None 668 if xdg_base is not None: 669 p = os.path.join(xdg_base, 'matplotlib') 670 671 if p is not None: 672 if os.path.exists(p): 673 if _is_writable_dir(p): 674 return p 675 else: 676 try: 677 mkdirs(p) 678 except OSError: 679 pass 680 else: 681 return p 682 683 return _create_tmp_config_dir() 684 685 686def _get_configdir(): 687 """ 688 Return the string representing the configuration directory. 689 690 The directory is chosen as follows: 691 692 1. If the MPLCONFIGDIR environment variable is supplied, choose that. 693 694 2a. On Linux, follow the XDG specification and look first in 695 `$XDG_CONFIG_HOME`, if defined, or `$HOME/.config`. 696 697 2b. On other platforms, choose `$HOME/.matplotlib`. 698 699 3. If the chosen directory exists and is writable, use that as the 700 configuration directory. 701 4. If possible, create a temporary directory, and use it as the 702 configuration directory. 703 5. A writable directory could not be found or created; return None. 704 """ 705 return _get_config_or_cache_dir(_get_xdg_config_dir()) 706 707get_configdir = _wrap('CONFIGDIR=%s', _get_configdir, always=False) 708 709 710def _get_cachedir(): 711 """ 712 Return the location of the cache directory. 713 714 The procedure used to find the directory is the same as for 715 _get_config_dir, except using `$XDG_CACHE_HOME`/`~/.cache` instead. 716 """ 717 return _get_config_or_cache_dir(_get_xdg_cache_dir()) 718 719get_cachedir = _wrap('CACHEDIR=%s', _get_cachedir, always=False) 720 721 722def _decode_filesystem_path(path): 723 if not isinstance(path, str): 724 return path.decode(sys.getfilesystemencoding()) 725 else: 726 return path 727 728 729def _get_data_path(): 730 'get the path to matplotlib data' 731 732 if 'MATPLOTLIBDATA' in os.environ: 733 path = os.environ['MATPLOTLIBDATA'] 734 if not os.path.isdir(path): 735 raise RuntimeError('Path in environment MATPLOTLIBDATA not a ' 736 'directory') 737 return path 738 739 _file = _decode_filesystem_path(__file__) 740 path = os.sep.join([os.path.dirname(_file), 'mpl-data']) 741 if os.path.isdir(path): 742 return path 743 744 # setuptools' namespace_packages may highjack this init file 745 # so need to try something known to be in matplotlib, not basemap 746 import matplotlib.afm 747 _file = _decode_filesystem_path(matplotlib.afm.__file__) 748 path = os.sep.join([os.path.dirname(_file), 'mpl-data']) 749 if os.path.isdir(path): 750 return path 751 752 # py2exe zips pure python, so still need special check 753 if getattr(sys, 'frozen', None): 754 exe_path = os.path.dirname(_decode_filesystem_path(sys.executable)) 755 path = os.path.join(exe_path, 'mpl-data') 756 if os.path.isdir(path): 757 return path 758 759 # Try again assuming we need to step up one more directory 760 path = os.path.join(os.path.split(exe_path)[0], 'mpl-data') 761 if os.path.isdir(path): 762 return path 763 764 # Try again assuming sys.path[0] is a dir not a exe 765 path = os.path.join(sys.path[0], 'mpl-data') 766 if os.path.isdir(path): 767 return path 768 769 raise RuntimeError('Could not find the matplotlib data files') 770 771 772def _get_data_path_cached(): 773 if defaultParams['datapath'][0] is None: 774 defaultParams['datapath'][0] = _get_data_path() 775 return defaultParams['datapath'][0] 776 777get_data_path = _wrap('matplotlib data path %s', _get_data_path_cached, 778 always=False) 779 780 781def get_py2exe_datafiles(): 782 datapath = get_data_path() 783 _, tail = os.path.split(datapath) 784 d = {} 785 for root, _, files in os.walk(datapath): 786 # Need to explicitly remove cocoa_agg files or py2exe complains 787 # NOTE I don't know why, but do as previous version 788 if 'Matplotlib.nib' in files: 789 files.remove('Matplotlib.nib') 790 files = [os.path.join(root, filename) for filename in files] 791 root = root.replace(tail, 'mpl-data') 792 root = root[root.index('mpl-data'):] 793 d[root] = files 794 return list(d.items()) 795 796 797def matplotlib_fname(): 798 """ 799 Get the location of the config file. 800 801 The file location is determined in the following order 802 803 - `$PWD/matplotlibrc` 804 805 - `$MATPLOTLIBRC` if it is a file (or a named pipe, which can be created 806 e.g. by process substitution) 807 808 - `$MATPLOTLIBRC/matplotlibrc` 809 810 - `$MPLCONFIGDIR/matplotlibrc` 811 812 - On Linux, 813 814 - `$XDG_CONFIG_HOME/matplotlib/matplotlibrc` (if 815 $XDG_CONFIG_HOME is defined) 816 817 - or `$HOME/.config/matplotlib/matplotlibrc` (if 818 $XDG_CONFIG_HOME is not defined) 819 820 - On other platforms, 821 822 - `$HOME/.matplotlib/matplotlibrc` if `$HOME` is defined. 823 824 - Lastly, it looks in `$MATPLOTLIBDATA/matplotlibrc` for a 825 system-defined copy. 826 """ 827 828 def gen_candidates(): 829 yield os.path.join(six.moves.getcwd(), 'matplotlibrc') 830 try: 831 matplotlibrc = os.environ['MATPLOTLIBRC'] 832 except KeyError: 833 pass 834 else: 835 yield matplotlibrc 836 yield os.path.join(matplotlibrc, 'matplotlibrc') 837 yield os.path.join(_get_configdir(), 'matplotlibrc') 838 yield os.path.join(get_data_path(), 'matplotlibrc') 839 840 for fname in gen_candidates(): 841 if os.path.exists(fname): 842 st_mode = os.stat(fname).st_mode 843 if stat.S_ISREG(st_mode) or stat.S_ISFIFO(st_mode): 844 break 845 # Return first candidate that is a file, or last candidate if none is 846 # valid (in that case, a warning is raised at startup by `rc_params`). 847 return fname 848 849 850# names of keys to deprecate 851# the values are a tuple of (new_name, f_old_2_new, f_new_2_old) 852# the inverse function may be `None` 853_deprecated_map = {} 854 855_deprecated_ignore_map = {'nbagg.transparent': 'figure.facecolor'} 856 857_obsolete_set = {'plugins.directory', 'text.dvipnghack'} 858 859# The following may use a value of None to suppress the warning. 860# do NOT include in _all_deprecated 861_deprecated_set = {'axes.hold', 862 'backend.qt4', 863 'backend.qt5'} 864 865_all_deprecated = set(itertools.chain( 866 _deprecated_ignore_map, _deprecated_map, _obsolete_set)) 867 868 869class RcParams(MutableMapping, dict): 870 871 """ 872 A dictionary object including validation 873 874 validating functions are defined and associated with rc parameters in 875 :mod:`matplotlib.rcsetup` 876 """ 877 878 validate = dict((key, converter) for key, (default, converter) in 879 six.iteritems(defaultParams) 880 if key not in _all_deprecated) 881 msg_depr = "%s is deprecated and replaced with %s; please use the latter." 882 msg_depr_set = ("%s is deprecated. Please remove it from your " 883 "matplotlibrc and/or style files.") 884 msg_depr_ignore = "%s is deprecated and ignored. Use %s instead." 885 msg_obsolete = ("%s is obsolete. Please remove it from your matplotlibrc " 886 "and/or style files.") 887 msg_backend_obsolete = ("The {} rcParam was deprecated in version 2.2. In" 888 " order to force the use of a specific Qt binding," 889 " either import that binding first, or set the " 890 "QT_API environment variable.") 891 892 # validate values on the way in 893 def __init__(self, *args, **kwargs): 894 self.update(*args, **kwargs) 895 896 def __setitem__(self, key, val): 897 try: 898 if key in _deprecated_map: 899 alt_key, alt_val, inverse_alt = _deprecated_map[key] 900 warnings.warn(self.msg_depr % (key, alt_key), 901 mplDeprecation) 902 key = alt_key 903 val = alt_val(val) 904 elif key in _deprecated_set and val is not None: 905 if key.startswith('backend'): 906 warnings.warn(self.msg_backend_obsolete.format(key), 907 mplDeprecation) 908 else: 909 warnings.warn(self.msg_depr_set % key, 910 mplDeprecation) 911 elif key in _deprecated_ignore_map: 912 alt = _deprecated_ignore_map[key] 913 warnings.warn(self.msg_depr_ignore % (key, alt), 914 mplDeprecation) 915 return 916 elif key in _obsolete_set: 917 warnings.warn(self.msg_obsolete % (key, ), 918 mplDeprecation) 919 return 920 try: 921 cval = self.validate[key](val) 922 except ValueError as ve: 923 raise ValueError("Key %s: %s" % (key, str(ve))) 924 dict.__setitem__(self, key, cval) 925 except KeyError: 926 raise KeyError( 927 '%s is not a valid rc parameter. See rcParams.keys() for a ' 928 'list of valid parameters.' % (key,)) 929 930 def __getitem__(self, key): 931 inverse_alt = None 932 if key in _deprecated_map: 933 alt_key, alt_val, inverse_alt = _deprecated_map[key] 934 warnings.warn(self.msg_depr % (key, alt_key), 935 mplDeprecation) 936 key = alt_key 937 938 elif key in _deprecated_ignore_map: 939 alt = _deprecated_ignore_map[key] 940 warnings.warn(self.msg_depr_ignore % (key, alt), 941 mplDeprecation) 942 key = alt 943 944 elif key in _obsolete_set: 945 warnings.warn(self.msg_obsolete % (key, ), 946 mplDeprecation) 947 return None 948 949 val = dict.__getitem__(self, key) 950 if inverse_alt is not None: 951 return inverse_alt(val) 952 else: 953 return val 954 955 def __repr__(self): 956 import pprint 957 class_name = self.__class__.__name__ 958 indent = len(class_name) + 1 959 repr_split = pprint.pformat(dict(self), indent=1, 960 width=80 - indent).split('\n') 961 repr_indented = ('\n' + ' ' * indent).join(repr_split) 962 return '{0}({1})'.format(class_name, repr_indented) 963 964 def __str__(self): 965 return '\n'.join('{0}: {1}'.format(k, v) 966 for k, v in sorted(self.items())) 967 968 def __iter__(self): 969 """ 970 Yield sorted list of keys. 971 """ 972 for k in sorted(dict.__iter__(self)): 973 yield k 974 975 def find_all(self, pattern): 976 """ 977 Return the subset of this RcParams dictionary whose keys match, 978 using :func:`re.search`, the given ``pattern``. 979 980 .. note:: 981 982 Changes to the returned dictionary are *not* propagated to 983 the parent RcParams dictionary. 984 985 """ 986 pattern_re = re.compile(pattern) 987 return RcParams((key, value) 988 for key, value in self.items() 989 if pattern_re.search(key)) 990 991 992def rc_params(fail_on_error=False): 993 """Return a :class:`matplotlib.RcParams` instance from the 994 default matplotlib rc file. 995 """ 996 fname = matplotlib_fname() 997 if not os.path.exists(fname): 998 # this should never happen, default in mpl-data should always be found 999 message = 'could not find rc file; returning defaults' 1000 ret = RcParams([(key, default) for key, (default, _) in 1001 six.iteritems(defaultParams) 1002 if key not in _all_deprecated]) 1003 warnings.warn(message) 1004 return ret 1005 1006 return rc_params_from_file(fname, fail_on_error) 1007 1008 1009URL_REGEX = re.compile(r'http://|https://|ftp://|file://|file:\\') 1010 1011 1012def is_url(filename): 1013 """Return True if string is an http, ftp, or file URL path.""" 1014 return URL_REGEX.match(filename) is not None 1015 1016 1017def _url_lines(f): 1018 # Compatibility for urlopen in python 3, which yields bytes. 1019 for line in f: 1020 yield line.decode('utf8') 1021 1022 1023@contextlib.contextmanager 1024def _open_file_or_url(fname): 1025 if is_url(fname): 1026 f = urlopen(fname) 1027 yield _url_lines(f) 1028 f.close() 1029 else: 1030 fname = os.path.expanduser(fname) 1031 encoding = locale.getpreferredencoding(do_setlocale=False) 1032 if encoding is None: 1033 encoding = "utf-8" 1034 with io.open(fname, encoding=encoding) as f: 1035 yield f 1036 1037 1038_error_details_fmt = 'line #%d\n\t"%s"\n\tin file "%s"' 1039 1040 1041def _rc_params_in_file(fname, fail_on_error=False): 1042 """Return :class:`matplotlib.RcParams` from the contents of the given file. 1043 1044 Unlike `rc_params_from_file`, the configuration class only contains the 1045 parameters specified in the file (i.e. default values are not filled in). 1046 """ 1047 cnt = 0 1048 rc_temp = {} 1049 with _open_file_or_url(fname) as fd: 1050 try: 1051 for line in fd: 1052 cnt += 1 1053 strippedline = line.split('#', 1)[0].strip() 1054 if not strippedline: 1055 continue 1056 tup = strippedline.split(':', 1) 1057 if len(tup) != 2: 1058 error_details = _error_details_fmt % (cnt, line, fname) 1059 warnings.warn('Illegal %s' % error_details) 1060 continue 1061 key, val = tup 1062 key = key.strip() 1063 val = val.strip() 1064 if key in rc_temp: 1065 warnings.warn('Duplicate key in file "%s", line #%d' % 1066 (fname, cnt)) 1067 rc_temp[key] = (val, line, cnt) 1068 except UnicodeDecodeError: 1069 warnings.warn( 1070 ('Cannot decode configuration file %s with ' 1071 'encoding %s, check LANG and LC_* variables') 1072 % (fname, locale.getpreferredencoding(do_setlocale=False) or 1073 'utf-8 (default)')) 1074 raise 1075 1076 config = RcParams() 1077 1078 for key in ('verbose.level', 'verbose.fileo'): 1079 if key in rc_temp: 1080 val, line, cnt = rc_temp.pop(key) 1081 if fail_on_error: 1082 config[key] = val # try to convert to proper type or raise 1083 else: 1084 try: 1085 config[key] = val # try to convert to proper type or skip 1086 except Exception as msg: 1087 error_details = _error_details_fmt % (cnt, line, fname) 1088 warnings.warn('Bad val "%s" on %s\n\t%s' % 1089 (val, error_details, msg)) 1090 1091 for key, (val, line, cnt) in six.iteritems(rc_temp): 1092 if key in defaultParams: 1093 if fail_on_error: 1094 config[key] = val # try to convert to proper type or raise 1095 else: 1096 try: 1097 config[key] = val # try to convert to proper type or skip 1098 except Exception as msg: 1099 error_details = _error_details_fmt % (cnt, line, fname) 1100 warnings.warn('Bad val "%s" on %s\n\t%s' % 1101 (val, error_details, msg)) 1102 elif key in _deprecated_ignore_map: 1103 warnings.warn('%s is deprecated. Update your matplotlibrc to use ' 1104 '%s instead.' % (key, _deprecated_ignore_map[key]), 1105 mplDeprecation) 1106 1107 else: 1108 print(""" 1109Bad key "%s" on line %d in 1110%s. 1111You probably need to get an updated matplotlibrc file from 1112http://github.com/matplotlib/matplotlib/blob/master/matplotlibrc.template 1113or from the matplotlib source distribution""" % (key, cnt, fname), 1114 file=sys.stderr) 1115 1116 return config 1117 1118 1119def rc_params_from_file(fname, fail_on_error=False, use_default_template=True): 1120 """Return :class:`matplotlib.RcParams` from the contents of the given file. 1121 1122 Parameters 1123 ---------- 1124 fname : str 1125 Name of file parsed for matplotlib settings. 1126 fail_on_error : bool 1127 If True, raise an error when the parser fails to convert a parameter. 1128 use_default_template : bool 1129 If True, initialize with default parameters before updating with those 1130 in the given file. If False, the configuration class only contains the 1131 parameters specified in the file. (Useful for updating dicts.) 1132 """ 1133 config_from_file = _rc_params_in_file(fname, fail_on_error) 1134 1135 if not use_default_template: 1136 return config_from_file 1137 1138 iter_params = six.iteritems(defaultParams) 1139 with warnings.catch_warnings(): 1140 warnings.simplefilter("ignore", mplDeprecation) 1141 config = RcParams([(key, default) for key, (default, _) in iter_params 1142 if key not in _all_deprecated]) 1143 config.update(config_from_file) 1144 1145 if config['datapath'] is None: 1146 config['datapath'] = get_data_path() 1147 1148 if "".join(config['text.latex.preamble']): 1149 _log.info(""" 1150***************************************************************** 1151You have the following UNSUPPORTED LaTeX preamble customizations: 1152%s 1153Please do not ask for support with these customizations active. 1154***************************************************************** 1155""", '\n'.join(config['text.latex.preamble'])) 1156 _log.debug('loaded rc file %s', fname) 1157 1158 return config 1159 1160 1161# this is the instance used by the matplotlib classes 1162rcParams = rc_params() 1163 1164if rcParams['examples.directory']: 1165 # paths that are intended to be relative to matplotlib_fname() 1166 # are allowed for the examples.directory parameter. 1167 # However, we will need to fully qualify the path because 1168 # Sphinx requires absolute paths. 1169 if not os.path.isabs(rcParams['examples.directory']): 1170 _basedir, _fname = os.path.split(matplotlib_fname()) 1171 # Sometimes matplotlib_fname() can return relative paths, 1172 # Also, using realpath() guarantees that Sphinx will use 1173 # the same path that matplotlib sees (in case of weird symlinks). 1174 _basedir = os.path.realpath(_basedir) 1175 _fullpath = os.path.join(_basedir, rcParams['examples.directory']) 1176 rcParams['examples.directory'] = _fullpath 1177 1178rcParamsOrig = rcParams.copy() 1179 1180with warnings.catch_warnings(): 1181 warnings.simplefilter("ignore", mplDeprecation) 1182 rcParamsDefault = RcParams([(key, default) for key, (default, converter) in 1183 six.iteritems(defaultParams) 1184 if key not in _all_deprecated]) 1185 1186rcParams['ps.usedistiller'] = checkdep_ps_distiller( 1187 rcParams['ps.usedistiller']) 1188 1189rcParams['text.usetex'] = checkdep_usetex(rcParams['text.usetex']) 1190 1191if rcParams['axes.formatter.use_locale']: 1192 locale.setlocale(locale.LC_ALL, '') 1193 1194 1195def rc(group, **kwargs): 1196 """ 1197 Set the current rc params. Group is the grouping for the rc, e.g., 1198 for ``lines.linewidth`` the group is ``lines``, for 1199 ``axes.facecolor``, the group is ``axes``, and so on. Group may 1200 also be a list or tuple of group names, e.g., (*xtick*, *ytick*). 1201 *kwargs* is a dictionary attribute name/value pairs, e.g.,:: 1202 1203 rc('lines', linewidth=2, color='r') 1204 1205 sets the current rc params and is equivalent to:: 1206 1207 rcParams['lines.linewidth'] = 2 1208 rcParams['lines.color'] = 'r' 1209 1210 The following aliases are available to save typing for interactive 1211 users: 1212 1213 ===== ================= 1214 Alias Property 1215 ===== ================= 1216 'lw' 'linewidth' 1217 'ls' 'linestyle' 1218 'c' 'color' 1219 'fc' 'facecolor' 1220 'ec' 'edgecolor' 1221 'mew' 'markeredgewidth' 1222 'aa' 'antialiased' 1223 ===== ================= 1224 1225 Thus you could abbreviate the above rc command as:: 1226 1227 rc('lines', lw=2, c='r') 1228 1229 1230 Note you can use python's kwargs dictionary facility to store 1231 dictionaries of default parameters. e.g., you can customize the 1232 font rc as follows:: 1233 1234 font = {'family' : 'monospace', 1235 'weight' : 'bold', 1236 'size' : 'larger'} 1237 1238 rc('font', **font) # pass in the font dict as kwargs 1239 1240 This enables you to easily switch between several configurations. Use 1241 ``matplotlib.style.use('default')`` or :func:`~matplotlib.rcdefaults` to 1242 restore the default rc params after changes. 1243 """ 1244 1245 aliases = { 1246 'lw': 'linewidth', 1247 'ls': 'linestyle', 1248 'c': 'color', 1249 'fc': 'facecolor', 1250 'ec': 'edgecolor', 1251 'mew': 'markeredgewidth', 1252 'aa': 'antialiased', 1253 } 1254 1255 if isinstance(group, six.string_types): 1256 group = (group,) 1257 for g in group: 1258 for k, v in six.iteritems(kwargs): 1259 name = aliases.get(k) or k 1260 key = '%s.%s' % (g, name) 1261 try: 1262 rcParams[key] = v 1263 except KeyError: 1264 raise KeyError(('Unrecognized key "%s" for group "%s" and ' 1265 'name "%s"') % (key, g, name)) 1266 1267 1268def rcdefaults(): 1269 """Restore the rc params from Matplotlib's internal defaults. 1270 1271 See Also 1272 -------- 1273 rc_file_defaults : 1274 Restore the rc params from the rc file originally loaded by Matplotlib. 1275 matplotlib.style.use : 1276 Use a specific style file. Call ``style.use('default')`` to restore 1277 the default style. 1278 """ 1279 rcParams.clear() 1280 rcParams.update(rcParamsDefault) 1281 1282 1283def rc_file_defaults(): 1284 """Restore the rc params from the original rc file loaded by Matplotlib. 1285 """ 1286 rcParams.update(rcParamsOrig) 1287 1288 1289def rc_file(fname): 1290 """ 1291 Update rc params from file. 1292 """ 1293 rcParams.update(rc_params_from_file(fname)) 1294 1295 1296class rc_context(object): 1297 """ 1298 Return a context manager for managing rc settings. 1299 1300 This allows one to do:: 1301 1302 with mpl.rc_context(fname='screen.rc'): 1303 plt.plot(x, a) 1304 with mpl.rc_context(fname='print.rc'): 1305 plt.plot(x, b) 1306 plt.plot(x, c) 1307 1308 The 'a' vs 'x' and 'c' vs 'x' plots would have settings from 1309 'screen.rc', while the 'b' vs 'x' plot would have settings from 1310 'print.rc'. 1311 1312 A dictionary can also be passed to the context manager:: 1313 1314 with mpl.rc_context(rc={'text.usetex': True}, fname='screen.rc'): 1315 plt.plot(x, a) 1316 1317 The 'rc' dictionary takes precedence over the settings loaded from 1318 'fname'. Passing a dictionary only is also valid. For example a 1319 common usage is:: 1320 1321 with mpl.rc_context(rc={'interactive': False}): 1322 fig, ax = plt.subplots() 1323 ax.plot(range(3), range(3)) 1324 fig.savefig('A.png', format='png') 1325 plt.close(fig) 1326 """ 1327 # While it may seem natural to implement rc_context using 1328 # contextlib.contextmanager, that would entail always calling the finally: 1329 # clause of the contextmanager (which restores the original rcs) including 1330 # during garbage collection; as a result, something like `plt.xkcd(); 1331 # gc.collect()` would result in the style being lost (as `xkcd()` is 1332 # implemented on top of rc_context, and nothing is holding onto context 1333 # manager except possibly circular references. 1334 1335 def __init__(self, rc=None, fname=None): 1336 self._orig = rcParams.copy() 1337 try: 1338 if fname: 1339 rc_file(fname) 1340 if rc: 1341 rcParams.update(rc) 1342 except Exception: 1343 # If anything goes wrong, revert to the original rcs. 1344 dict.update(rcParams, self._orig) 1345 raise 1346 1347 def __enter__(self): 1348 return self 1349 1350 def __exit__(self, exc_type, exc_value, exc_tb): 1351 # No need to revalidate the original values. 1352 dict.update(rcParams, self._orig) 1353 1354 1355_use_error_msg = """ 1356This call to matplotlib.use() has no effect because the backend has already 1357been chosen; matplotlib.use() must be called *before* pylab, matplotlib.pyplot, 1358or matplotlib.backends is imported for the first time. 1359 1360The backend was *originally* set to {backend!r} by the following code: 1361{tb} 1362""" 1363 1364 1365def use(arg, warn=True, force=False): 1366 """ 1367 Set the matplotlib backend to one of the known backends. 1368 1369 The argument is case-insensitive. *warn* specifies whether a 1370 warning should be issued if a backend has already been set up. 1371 *force* is an **experimental** flag that tells matplotlib to 1372 attempt to initialize a new backend by reloading the backend 1373 module. 1374 1375 .. note:: 1376 1377 This function must be called *before* importing pyplot for 1378 the first time; or, if you are not using pyplot, it must be called 1379 before importing matplotlib.backends. If warn is True, a warning 1380 is issued if you try and call this after pylab or pyplot have been 1381 loaded. In certain black magic use cases, e.g. 1382 :func:`pyplot.switch_backend`, we are doing the reloading necessary to 1383 make the backend switch work (in some cases, e.g., pure image 1384 backends) so one can set warn=False to suppress the warnings. 1385 1386 To find out which backend is currently set, see 1387 :func:`matplotlib.get_backend`. 1388 1389 """ 1390 # Lets determine the proper backend name first 1391 if arg.startswith('module://'): 1392 name = arg 1393 else: 1394 # Lowercase only non-module backend names (modules are case-sensitive) 1395 arg = arg.lower() 1396 name = validate_backend(arg) 1397 1398 # Check if we've already set up a backend 1399 if 'matplotlib.backends' in sys.modules: 1400 # Warn only if called with a different name 1401 if (rcParams['backend'] != name) and warn: 1402 import matplotlib.backends 1403 warnings.warn( 1404 _use_error_msg.format( 1405 backend=rcParams['backend'], 1406 tb=matplotlib.backends._backend_loading_tb), 1407 stacklevel=2) 1408 1409 # Unless we've been told to force it, just return 1410 if not force: 1411 return 1412 need_reload = True 1413 else: 1414 need_reload = False 1415 1416 # Store the backend name 1417 rcParams['backend'] = name 1418 1419 # If needed we reload here because a lot of setup code is triggered on 1420 # module import. See backends/__init__.py for more detail. 1421 if need_reload: 1422 reload(sys.modules['matplotlib.backends']) 1423 1424 1425try: 1426 use(os.environ['MPLBACKEND']) 1427except KeyError: 1428 pass 1429 1430 1431def get_backend(): 1432 """Return the name of the current backend.""" 1433 return rcParams['backend'] 1434 1435 1436def interactive(b): 1437 """ 1438 Set interactive mode to boolean b. 1439 1440 If b is True, then draw after every plotting command, e.g., after xlabel 1441 """ 1442 rcParams['interactive'] = b 1443 1444 1445def is_interactive(): 1446 'Return true if plot mode is interactive' 1447 return rcParams['interactive'] 1448 1449 1450def tk_window_focus(): 1451 """Return true if focus maintenance under TkAgg on win32 is on. 1452 This currently works only for python.exe and IPython.exe. 1453 Both IDLE and Pythonwin.exe fail badly when tk_window_focus is on.""" 1454 if rcParams['backend'] != 'TkAgg': 1455 return False 1456 return rcParams['tk.window_focus'] 1457 1458 1459default_test_modules = [ 1460 'matplotlib.tests', 1461 'matplotlib.sphinxext.tests', 1462 'mpl_toolkits.tests', 1463] 1464 1465 1466def _init_tests(): 1467 try: 1468 import faulthandler 1469 except ImportError: 1470 pass 1471 else: 1472 # CPython's faulthandler since v3.6 handles exceptions on Windows 1473 # https://bugs.python.org/issue23848 but until v3.6.4 it was 1474 # printing non-fatal exceptions https://bugs.python.org/issue30557 1475 import platform 1476 if not (sys.platform == 'win32' and 1477 (3, 6) < sys.version_info < (3, 6, 4) and 1478 platform.python_implementation() == 'CPython'): 1479 faulthandler.enable() 1480 1481 # The version of FreeType to install locally for running the 1482 # tests. This must match the value in `setupext.py` 1483 LOCAL_FREETYPE_VERSION = '2.6.1' 1484 1485 from matplotlib import ft2font 1486 if (ft2font.__freetype_version__ != LOCAL_FREETYPE_VERSION or 1487 ft2font.__freetype_build_type__ != 'local'): 1488 warnings.warn( 1489 "Matplotlib is not built with the correct FreeType version to run " 1490 "tests. Set local_freetype=True in setup.cfg and rebuild. " 1491 "Expect many image comparison failures below. " 1492 "Expected freetype version {0}. " 1493 "Found freetype version {1}. " 1494 "Freetype build type is {2}local".format( 1495 LOCAL_FREETYPE_VERSION, 1496 ft2font.__freetype_version__, 1497 "" if ft2font.__freetype_build_type__ == 'local' else "not " 1498 ) 1499 ) 1500 1501 try: 1502 import pytest 1503 try: 1504 from unittest import mock 1505 except ImportError: 1506 import mock 1507 except ImportError: 1508 print("matplotlib.test requires pytest and mock to run.") 1509 raise 1510 1511 1512def test(verbosity=None, coverage=False, switch_backend_warn=True, 1513 recursionlimit=0, **kwargs): 1514 """run the matplotlib test suite""" 1515 _init_tests() 1516 if not os.path.isdir(os.path.join(os.path.dirname(__file__), 'tests')): 1517 raise ImportError("Matplotlib test data is not installed") 1518 1519 old_backend = get_backend() 1520 old_recursionlimit = sys.getrecursionlimit() 1521 try: 1522 use('agg') 1523 if recursionlimit: 1524 sys.setrecursionlimit(recursionlimit) 1525 import pytest 1526 1527 args = kwargs.pop('argv', []) 1528 provide_default_modules = True 1529 use_pyargs = True 1530 for arg in args: 1531 if any(arg.startswith(module_path) 1532 for module_path in default_test_modules): 1533 provide_default_modules = False 1534 break 1535 if os.path.exists(arg): 1536 provide_default_modules = False 1537 use_pyargs = False 1538 break 1539 if use_pyargs: 1540 args += ['--pyargs'] 1541 if provide_default_modules: 1542 args += default_test_modules 1543 1544 if coverage: 1545 args += ['--cov'] 1546 1547 if verbosity: 1548 args += ['-' + 'v' * verbosity] 1549 1550 retcode = pytest.main(args, **kwargs) 1551 finally: 1552 if old_backend.lower() != 'agg': 1553 use(old_backend, warn=switch_backend_warn) 1554 if recursionlimit: 1555 sys.setrecursionlimit(old_recursionlimit) 1556 1557 return retcode 1558 1559 1560test.__test__ = False # pytest: this function is not a test 1561 1562 1563def _replacer(data, key): 1564 """Either returns data[key] or passes data back. Also 1565 converts input data to a sequence as needed. 1566 """ 1567 # if key isn't a string don't bother 1568 if not isinstance(key, six.string_types): 1569 return (key) 1570 # try to use __getitem__ 1571 try: 1572 return sanitize_sequence(data[key]) 1573 # key does not exist, silently fall back to key 1574 except KeyError: 1575 return key 1576 1577 1578_DATA_DOC_APPENDIX = """ 1579 1580.. note:: 1581 In addition to the above described arguments, this function can take a 1582 **data** keyword argument. If such a **data** argument is given, the 1583 following arguments are replaced by **data[<arg>]**: 1584 1585 {replaced} 1586""" 1587 1588 1589def _add_data_doc(docstring, replace_names, replace_all_args): 1590 """Add documentation for a *data* field to the given docstring. 1591 1592 Parameters 1593 ---------- 1594 docstring : str 1595 The input docstring. 1596 replace_names : list of strings or None 1597 The list of parameter names which arguments should be replaced by 1598 `data[name]`. If None, all arguments are replaced if they are 1599 included in `data`. 1600 replace_all_args : bool 1601 If True, all arguments in *args get replaced, even if they are not 1602 in replace_names. 1603 1604 Returns 1605 ------- 1606 The augmented docstring. 1607 """ 1608 if docstring is None: 1609 docstring = '' 1610 else: 1611 docstring = dedent(docstring) 1612 _repl = "" 1613 if replace_names is None: 1614 _repl = "* All positional and all keyword arguments." 1615 else: 1616 if len(replace_names) != 0: 1617 _repl = "* All arguments with the following names: '{names}'." 1618 if replace_all_args: 1619 _repl += "\n * All positional arguments." 1620 _repl = _repl.format(names="', '".join(sorted(replace_names))) 1621 return docstring + _DATA_DOC_APPENDIX.format(replaced=_repl) 1622 1623 1624def _preprocess_data(replace_names=None, replace_all_args=False, 1625 label_namer=None, positional_parameter_names=None): 1626 """ 1627 A decorator to add a 'data' kwarg to any a function. The signature 1628 of the input function must include the ax argument at the first position :: 1629 1630 def foo(ax, *args, **kwargs) 1631 1632 so this is suitable for use with Axes methods. 1633 1634 Parameters 1635 ---------- 1636 replace_names : list of strings, optional, default: None 1637 The list of parameter names which arguments should be replaced by 1638 `data[name]`. If None, all arguments are replaced if they are 1639 included in `data`. 1640 replace_all_args : bool, default: False 1641 If True, all arguments in *args get replaced, even if they are not 1642 in replace_names. 1643 label_namer : string, optional, default: None 1644 The name of the parameter which argument should be used as label, if 1645 label is not set. If None, the label keyword argument is not set. 1646 positional_parameter_names : list of strings or callable, optional 1647 The full list of positional parameter names (excluding an explicit 1648 `ax`/'self' argument at the first place and including all possible 1649 positional parameter in `*args`), in the right order. Can also include 1650 all other keyword parameter. Only needed if the wrapped function does 1651 contain `*args` and (replace_names is not None or replace_all_args is 1652 False). If it is a callable, it will be called with the actual 1653 tuple of *args and the data and should return a list like 1654 above. 1655 NOTE: callables should only be used when the names and order of *args 1656 can only be determined at runtime. Please use list of names 1657 when the order and names of *args is clear before runtime! 1658 1659 .. note:: decorator also converts MappingView input data to list. 1660 """ 1661 if replace_names is not None: 1662 replace_names = set(replace_names) 1663 1664 def param(func): 1665 new_sig = None 1666 # signature is since 3.3 and wrapped since 3.2, but we support 3.4+. 1667 python_has_signature = python_has_wrapped = six.PY3 1668 1669 # if in a legacy version of python and IPython is already imported 1670 # try to use their back-ported signature 1671 if not python_has_signature and 'IPython' in sys.modules: 1672 try: 1673 import IPython.utils.signatures 1674 signature = IPython.utils.signatures.signature 1675 Parameter = IPython.utils.signatures.Parameter 1676 except ImportError: 1677 pass 1678 else: 1679 python_has_signature = True 1680 else: 1681 if python_has_signature: 1682 signature = inspect.signature 1683 Parameter = inspect.Parameter 1684 1685 if not python_has_signature: 1686 arg_spec = inspect.getargspec(func) 1687 _arg_names = arg_spec.args 1688 _has_varargs = arg_spec.varargs is not None 1689 _has_varkwargs = arg_spec.keywords is not None 1690 else: 1691 sig = signature(func) 1692 _has_varargs = False 1693 _has_varkwargs = False 1694 _arg_names = [] 1695 params = list(sig.parameters.values()) 1696 for p in params: 1697 if p.kind is Parameter.VAR_POSITIONAL: 1698 _has_varargs = True 1699 elif p.kind is Parameter.VAR_KEYWORD: 1700 _has_varkwargs = True 1701 else: 1702 _arg_names.append(p.name) 1703 data_param = Parameter('data', 1704 Parameter.KEYWORD_ONLY, 1705 default=None) 1706 if _has_varkwargs: 1707 params.insert(-1, data_param) 1708 else: 1709 params.append(data_param) 1710 new_sig = sig.replace(parameters=params) 1711 # Import-time check: do we have enough information to replace *args? 1712 arg_names_at_runtime = False 1713 # there can't be any positional arguments behind *args and no 1714 # positional args can end up in **kwargs, so only *varargs make 1715 # problems. 1716 # http://stupidpythonideas.blogspot.de/2013/08/arguments-and-parameters.html 1717 if not _has_varargs: 1718 # all args are "named", so no problem 1719 # remove the first "ax" / self arg 1720 arg_names = _arg_names[1:] 1721 else: 1722 # Here we have "unnamed" variables and we need a way to determine 1723 # whether to replace a arg or not 1724 if replace_names is None: 1725 # all argnames should be replaced 1726 arg_names = None 1727 elif len(replace_names) == 0: 1728 # No argnames should be replaced 1729 arg_names = [] 1730 elif len(_arg_names) > 1 and (positional_parameter_names is None): 1731 # we got no manual parameter names but more than an 'ax' ... 1732 if len(replace_names - set(_arg_names[1:])) == 0: 1733 # all to be replaced arguments are in the list 1734 arg_names = _arg_names[1:] 1735 else: 1736 raise AssertionError( 1737 "Got unknown 'replace_names' and wrapped function " 1738 "{!r} uses '*args', need 'positional_parameter_names'" 1739 .format(func.__name__)) 1740 else: 1741 if positional_parameter_names is not None: 1742 if callable(positional_parameter_names): 1743 # determined by the function at runtime 1744 arg_names_at_runtime = True 1745 # so that we don't compute the label_pos at import time 1746 arg_names = [] 1747 else: 1748 arg_names = positional_parameter_names 1749 else: 1750 if replace_all_args: 1751 arg_names = [] 1752 else: 1753 raise AssertionError( 1754 "Got 'replace_names' and wrapped function {!r} " 1755 "uses *args, need 'positional_parameter_names' or " 1756 "'replace_all_args'".format(func.__name__)) 1757 1758 # compute the possible label_namer and label position in positional 1759 # arguments 1760 label_pos = 9999 # bigger than all "possible" argument lists 1761 label_namer_pos = 9999 # bigger than all "possible" argument lists 1762 if (label_namer and # we actually want a label here ... 1763 arg_names and # and we can determine a label in *args ... 1764 (label_namer in arg_names)): # and it is in *args 1765 label_namer_pos = arg_names.index(label_namer) 1766 if "label" in arg_names: 1767 label_pos = arg_names.index("label") 1768 1769 # Check the case we know a label_namer but we can't find it the 1770 # arg_names... Unfortunately the label_namer can be in **kwargs, 1771 # which we can't detect here and which results in a non-set label 1772 # which might surprise the user :-( 1773 if label_namer and not arg_names_at_runtime and not _has_varkwargs: 1774 if not arg_names: 1775 raise AssertionError( 1776 "label_namer {!r} can't be found as the parameter without " 1777 "'positional_parameter_names'".format(label_namer)) 1778 elif label_namer not in arg_names: 1779 raise AssertionError( 1780 "label_namer {!r} can't be found in the parameter names " 1781 "(known argnames: %s).".format(label_namer, arg_names)) 1782 else: 1783 # this is the case when the name is in arg_names 1784 pass 1785 1786 @functools.wraps(func) 1787 def inner(ax, *args, **kwargs): 1788 # this is needed because we want to change these values if 1789 # arg_names_at_runtime==True, but python does not allow assigning 1790 # to a variable in a outer scope. So use some new local ones and 1791 # set them to the already computed values. 1792 _label_pos = label_pos 1793 _label_namer_pos = label_namer_pos 1794 _arg_names = arg_names 1795 1796 label = None 1797 1798 data = kwargs.pop('data', None) 1799 1800 if data is None: # data validation 1801 args = tuple(sanitize_sequence(a) for a in args) 1802 else: 1803 if arg_names_at_runtime: 1804 # update the information about replace names and 1805 # label position 1806 _arg_names = positional_parameter_names(args, data) 1807 if (label_namer and # we actually want a label here ... 1808 _arg_names and # and we can find a label in *args 1809 (label_namer in _arg_names)): # and it is in *args 1810 _label_namer_pos = _arg_names.index(label_namer) 1811 if "label" in _arg_names: 1812 _label_pos = arg_names.index("label") 1813 1814 # save the current label_namer value so that it can be used as 1815 # a label 1816 if _label_namer_pos < len(args): 1817 label = args[_label_namer_pos] 1818 else: 1819 label = kwargs.get(label_namer, None) 1820 # ensure a string, as label can't be anything else 1821 if not isinstance(label, six.string_types): 1822 label = None 1823 1824 if (replace_names is None) or (replace_all_args is True): 1825 # all should be replaced 1826 args = tuple(_replacer(data, a) for 1827 j, a in enumerate(args)) 1828 else: 1829 # An arg is replaced if the arg_name of that position is 1830 # in replace_names ... 1831 if len(_arg_names) < len(args): 1832 raise RuntimeError( 1833 "Got more args than function expects") 1834 args = tuple(_replacer(data, a) 1835 if _arg_names[j] in replace_names else a 1836 for j, a in enumerate(args)) 1837 1838 if replace_names is None: 1839 # replace all kwargs ... 1840 kwargs = dict((k, _replacer(data, v)) 1841 for k, v in six.iteritems(kwargs)) 1842 else: 1843 # ... or only if a kwarg of that name is in replace_names 1844 kwargs = dict((k, _replacer(data, v) 1845 if k in replace_names else v) 1846 for k, v in six.iteritems(kwargs)) 1847 1848 # replace the label if this func "wants" a label arg and the user 1849 # didn't set one. Note: if the user puts in "label=None", it does 1850 # *NOT* get replaced! 1851 user_supplied_label = ( 1852 (len(args) >= _label_pos) or # label is included in args 1853 ('label' in kwargs) # ... or in kwargs 1854 ) 1855 if (label_namer and not user_supplied_label): 1856 if _label_namer_pos < len(args): 1857 kwargs['label'] = get_label(args[_label_namer_pos], label) 1858 elif label_namer in kwargs: 1859 kwargs['label'] = get_label(kwargs[label_namer], label) 1860 else: 1861 warnings.warn( 1862 "Tried to set a label via parameter %r in func %r but " 1863 "couldn't find such an argument.\n" 1864 "(This is a programming error, please report to " 1865 "the Matplotlib list!)" % (label_namer, func.__name__), 1866 RuntimeWarning, stacklevel=2) 1867 return func(ax, *args, **kwargs) 1868 1869 inner.__doc__ = _add_data_doc(inner.__doc__, 1870 replace_names, replace_all_args) 1871 if not python_has_wrapped: 1872 inner.__wrapped__ = func 1873 if new_sig is not None: 1874 inner.__signature__ = new_sig 1875 return inner 1876 1877 return param 1878 1879_log.debug('matplotlib version %s', __version__) 1880_log.debug('interactive is %s', is_interactive()) 1881_log.debug('platform is %s', sys.platform) 1882_log.debug('loaded modules: %s', list(sys.modules)) 1883