diff --git a/AttributionReport.spec b/AttributionReport.spec
deleted file mode 100644
index 8b45c02..0000000
--- a/AttributionReport.spec
+++ /dev/null
@@ -1,17 +0,0 @@
-# -*- mode: python -*-
-a = Analysis(['main.py'],
- pathex=['C:\\Users\\tsouza\\PycharmProjects\\attribution_report'],
- hiddenimports=[],
- hookspath=None,
- runtime_hooks=None)
-pyz = PYZ(a.pure)
-exe = EXE(pyz,
- a.scripts,
- a.binaries,
- a.zipfiles,
- a.datas,
- name='AttributionReport.exe',
- debug=False,
- strip=None,
- upx=True,
- console=True )
diff --git a/README.md b/README.md
deleted file mode 100644
index 5013cc8..0000000
--- a/README.md
+++ /dev/null
@@ -1,19 +0,0 @@
-# Attribution Report
-
-## Introduction
-
-Attribution report is a report that compares a data dump from Salesforce, and a dump from Addgene's Deposit data.
-
-
-## Running
-
-To run, either run dist/AttributionReport.exe, or run dist.mac/AttributionReport.app
-
-
-## Building
-
-You can build this for a Mac by running:
-``` $ python setup.py py2app --dist-dir dist.mac ```
-
-or you can build this for a PC by running:
-``` pyinstaller main.py --name=AttributionReport -F ```
diff --git a/attribution.py b/attribution.py
index 07cf239..c52f0c1 100644
--- a/attribution.py
+++ b/attribution.py
@@ -220,7 +220,7 @@ class AttributionReport(object):
if __name__ == '__main__':
- app = AttributionReport(months=6,footer_length=6)
+ app = AttributionReport(months=6, footer_length=6)
print "setup App"
app.set_dataframe_deposit("/Users/tyrelsouza/Dropbox (Addgene)/Addgene Shared/Dev/Attribution Report/deposit_data.csv")
print "set Deposit DF"
diff --git a/dist.mac/AttributionReport.app/Contents/Frameworks/Python.framework/Python b/dist.mac/AttributionReport.app/Contents/Frameworks/Python.framework/Python
deleted file mode 120000
index be75854..0000000
--- a/dist.mac/AttributionReport.app/Contents/Frameworks/Python.framework/Python
+++ /dev/null
@@ -1 +0,0 @@
-Versions/Current/Python
\ No newline at end of file
diff --git a/dist.mac/AttributionReport.app/Contents/Frameworks/Python.framework/Resources b/dist.mac/AttributionReport.app/Contents/Frameworks/Python.framework/Resources
deleted file mode 120000
index 953ee36..0000000
--- a/dist.mac/AttributionReport.app/Contents/Frameworks/Python.framework/Resources
+++ /dev/null
@@ -1 +0,0 @@
-Versions/Current/Resources
\ No newline at end of file
diff --git a/dist.mac/AttributionReport.app/Contents/Frameworks/Python.framework/Versions/2.7/Python b/dist.mac/AttributionReport.app/Contents/Frameworks/Python.framework/Versions/2.7/Python
deleted file mode 100755
index d3fa1f0..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Frameworks/Python.framework/Versions/2.7/Python and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Frameworks/Python.framework/Versions/2.7/Resources/Info.plist b/dist.mac/AttributionReport.app/Contents/Frameworks/Python.framework/Versions/2.7/Resources/Info.plist
deleted file mode 100644
index 5cf68e9..0000000
--- a/dist.mac/AttributionReport.app/Contents/Frameworks/Python.framework/Versions/2.7/Resources/Info.plist
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
- CFBundleDevelopmentRegion
- English
- CFBundleExecutable
- Python
- CFBundleGetInfoString
- Python Runtime and Library
- CFBundleIdentifier
- org.python.python
- CFBundleInfoDictionaryVersion
- 6.0
- CFBundleName
- Python
- CFBundlePackageType
- FMWK
- CFBundleShortVersionString
- 2.7.10, (c) 2001-2015 Python Software Foundation.
- CFBundleLongVersionString
- 2.7.10, (c) 2001-2015 Python Software Foundation.
- CFBundleSignature
- ????
- CFBundleVersion
- 2.7.10
-
-
diff --git a/dist.mac/AttributionReport.app/Contents/Frameworks/Python.framework/Versions/2.7/include/python2.7/pyconfig.h b/dist.mac/AttributionReport.app/Contents/Frameworks/Python.framework/Versions/2.7/include/python2.7/pyconfig.h
deleted file mode 100644
index aa93780..0000000
--- a/dist.mac/AttributionReport.app/Contents/Frameworks/Python.framework/Versions/2.7/include/python2.7/pyconfig.h
+++ /dev/null
@@ -1,1282 +0,0 @@
-/* pyconfig.h. Generated from pyconfig.h.in by configure. */
-/* pyconfig.h.in. Generated from configure.ac by autoheader. */
-
-
-#ifndef Py_PYCONFIG_H
-#define Py_PYCONFIG_H
-
-
-/* Define if building universal (internal helper macro) */
-/* #undef AC_APPLE_UNIVERSAL_BUILD */
-
-/* Define for AIX if your compiler is a genuine IBM xlC/xlC_r and you want
- support for AIX C++ shared extension modules. */
-/* #undef AIX_GENUINE_CPLUSPLUS */
-
-/* Define this if you have AtheOS threads. */
-/* #undef ATHEOS_THREADS */
-
-/* Define this if you have BeOS threads. */
-/* #undef BEOS_THREADS */
-
-/* Define if you have the Mach cthreads package */
-/* #undef C_THREADS */
-
-/* Define if C doubles are 64-bit IEEE 754 binary format, stored in ARM
- mixed-endian order (byte order 45670123) */
-/* #undef DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754 */
-
-/* Define if C doubles are 64-bit IEEE 754 binary format, stored with the most
- significant byte first */
-/* #undef DOUBLE_IS_BIG_ENDIAN_IEEE754 */
-
-/* Define if C doubles are 64-bit IEEE 754 binary format, stored with the
- least significant byte first */
-#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 1
-
-/* Define if --enable-ipv6 is specified */
-#define ENABLE_IPV6 1
-
-/* Define if flock needs to be linked with bsd library. */
-/* #undef FLOCK_NEEDS_LIBBSD */
-
-/* Define if getpgrp() must be called as getpgrp(0). */
-/* #undef GETPGRP_HAVE_ARG */
-
-/* Define if gettimeofday() does not have second (timezone) argument This is
- the case on Motorola V4 (R40V4.2) */
-/* #undef GETTIMEOFDAY_NO_TZ */
-
-/* Define to 1 if you have the `acosh' function. */
-#define HAVE_ACOSH 1
-
-/* struct addrinfo (netdb.h) */
-#define HAVE_ADDRINFO 1
-
-/* Define to 1 if you have the `alarm' function. */
-#define HAVE_ALARM 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_ALLOCA_H 1
-
-/* Define this if your time.h defines altzone. */
-/* #undef HAVE_ALTZONE */
-
-/* Define to 1 if you have the `asinh' function. */
-#define HAVE_ASINH 1
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_ASM_TYPES_H */
-
-/* Define to 1 if you have the `atanh' function. */
-#define HAVE_ATANH 1
-
-/* Define if GCC supports __attribute__((format(PyArg_ParseTuple, 2, 3))) */
-/* #undef HAVE_ATTRIBUTE_FORMAT_PARSETUPLE */
-
-/* Define to 1 if you have the `bind_textdomain_codeset' function. */
-/* #undef HAVE_BIND_TEXTDOMAIN_CODESET */
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_BLUETOOTH_BLUETOOTH_H */
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_BLUETOOTH_H */
-
-/* Define if nice() returns success/failure instead of the new priority. */
-/* #undef HAVE_BROKEN_NICE */
-
-/* Define if the system reports an invalid PIPE_BUF value. */
-/* #undef HAVE_BROKEN_PIPE_BUF */
-
-/* Define if poll() sets errno on invalid file descriptors. */
-/* #undef HAVE_BROKEN_POLL */
-
-/* Define if the Posix semaphores do not work on your system */
-/* #undef HAVE_BROKEN_POSIX_SEMAPHORES */
-
-/* Define if pthread_sigmask() does not work on your system. */
-/* #undef HAVE_BROKEN_PTHREAD_SIGMASK */
-
-/* define to 1 if your sem_getvalue is broken. */
-#define HAVE_BROKEN_SEM_GETVALUE 1
-
-/* Define if `unsetenv` does not return an int. */
-/* #undef HAVE_BROKEN_UNSETENV */
-
-/* Define this if you have the type _Bool. */
-#define HAVE_C99_BOOL 1
-
-/* Define to 1 if you have the 'chflags' function. */
-#define HAVE_CHFLAGS 1
-
-/* Define to 1 if you have the `chown' function. */
-#define HAVE_CHOWN 1
-
-/* Define if you have the 'chroot' function. */
-#define HAVE_CHROOT 1
-
-/* Define to 1 if you have the `clock' function. */
-#define HAVE_CLOCK 1
-
-/* Define to 1 if you have the `confstr' function. */
-#define HAVE_CONFSTR 1
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_CONIO_H */
-
-/* Define to 1 if you have the `copysign' function. */
-#define HAVE_COPYSIGN 1
-
-/* Define to 1 if you have the `ctermid' function. */
-#define HAVE_CTERMID 1
-
-/* Define if you have the 'ctermid_r' function. */
-#define HAVE_CTERMID_R 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_CURSES_H 1
-
-/* Define if you have the 'is_term_resized' function. */
-#define HAVE_CURSES_IS_TERM_RESIZED 1
-
-/* Define if you have the 'resizeterm' function. */
-#define HAVE_CURSES_RESIZETERM 1
-
-/* Define if you have the 'resize_term' function. */
-#define HAVE_CURSES_RESIZE_TERM 1
-
-/* Define to 1 if you have the declaration of `isfinite', and to 0 if you
- don't. */
-#define HAVE_DECL_ISFINITE 1
-
-/* Define to 1 if you have the declaration of `isinf', and to 0 if you don't.
- */
-#define HAVE_DECL_ISINF 1
-
-/* Define to 1 if you have the declaration of `isnan', and to 0 if you don't.
- */
-#define HAVE_DECL_ISNAN 1
-
-/* Define to 1 if you have the declaration of `tzname', and to 0 if you don't.
- */
-/* #undef HAVE_DECL_TZNAME */
-
-/* Define to 1 if you have the device macros. */
-#define HAVE_DEVICE_MACROS 1
-
-/* Define to 1 if you have the /dev/ptc device file. */
-/* #undef HAVE_DEV_PTC */
-
-/* Define to 1 if you have the /dev/ptmx device file. */
-#define HAVE_DEV_PTMX 1
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_DIRECT_H */
-
-/* Define to 1 if you have the header file, and it defines `DIR'.
- */
-#define HAVE_DIRENT_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_DLFCN_H 1
-
-/* Define to 1 if you have the `dlopen' function. */
-#define HAVE_DLOPEN 1
-
-/* Define to 1 if you have the `dup2' function. */
-#define HAVE_DUP2 1
-
-/* Defined when any dynamic module loading is enabled. */
-#define HAVE_DYNAMIC_LOADING 1
-
-/* Define if you have the 'epoll' functions. */
-/* #undef HAVE_EPOLL */
-
-/* Define to 1 if you have the `erf' function. */
-#define HAVE_ERF 1
-
-/* Define to 1 if you have the `erfc' function. */
-#define HAVE_ERFC 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_ERRNO_H 1
-
-/* Define to 1 if you have the `execv' function. */
-#define HAVE_EXECV 1
-
-/* Define to 1 if you have the `expm1' function. */
-#define HAVE_EXPM1 1
-
-/* Define if you have the 'fchdir' function. */
-#define HAVE_FCHDIR 1
-
-/* Define to 1 if you have the `fchmod' function. */
-#define HAVE_FCHMOD 1
-
-/* Define to 1 if you have the `fchown' function. */
-#define HAVE_FCHOWN 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_FCNTL_H 1
-
-/* Define if you have the 'fdatasync' function. */
-/* #undef HAVE_FDATASYNC */
-
-/* Define to 1 if you have the `finite' function. */
-#define HAVE_FINITE 1
-
-/* Define to 1 if you have the `flock' function. */
-#define HAVE_FLOCK 1
-
-/* Define to 1 if you have the `fork' function. */
-#define HAVE_FORK 1
-
-/* Define to 1 if you have the `forkpty' function. */
-#define HAVE_FORKPTY 1
-
-/* Define to 1 if you have the `fpathconf' function. */
-#define HAVE_FPATHCONF 1
-
-/* Define to 1 if you have the `fseek64' function. */
-/* #undef HAVE_FSEEK64 */
-
-/* Define to 1 if you have the `fseeko' function. */
-#define HAVE_FSEEKO 1
-
-/* Define to 1 if you have the `fstatvfs' function. */
-#define HAVE_FSTATVFS 1
-
-/* Define if you have the 'fsync' function. */
-#define HAVE_FSYNC 1
-
-/* Define to 1 if you have the `ftell64' function. */
-/* #undef HAVE_FTELL64 */
-
-/* Define to 1 if you have the `ftello' function. */
-#define HAVE_FTELLO 1
-
-/* Define to 1 if you have the `ftime' function. */
-#define HAVE_FTIME 1
-
-/* Define to 1 if you have the `ftruncate' function. */
-#define HAVE_FTRUNCATE 1
-
-/* Define to 1 if you have the `gai_strerror' function. */
-#define HAVE_GAI_STRERROR 1
-
-/* Define to 1 if you have the `gamma' function. */
-#define HAVE_GAMMA 1
-
-/* Define if we can use gcc inline assembler to get and set x87 control word
- */
-#define HAVE_GCC_ASM_FOR_X87 1
-
-/* Define if you have the getaddrinfo function. */
-#define HAVE_GETADDRINFO 1
-
-/* Define to 1 if you have the `getcwd' function. */
-#define HAVE_GETCWD 1
-
-/* Define this if you have flockfile(), getc_unlocked(), and funlockfile() */
-#define HAVE_GETC_UNLOCKED 1
-
-/* Define to 1 if you have the `getentropy' function. */
-/* #undef HAVE_GETENTROPY */
-
-/* Define to 1 if you have the `getgroups' function. */
-#define HAVE_GETGROUPS 1
-
-/* Define to 1 if you have the `gethostbyname' function. */
-#define HAVE_GETHOSTBYNAME 1
-
-/* Define this if you have some version of gethostbyname_r() */
-/* #undef HAVE_GETHOSTBYNAME_R */
-
-/* Define this if you have the 3-arg version of gethostbyname_r(). */
-/* #undef HAVE_GETHOSTBYNAME_R_3_ARG */
-
-/* Define this if you have the 5-arg version of gethostbyname_r(). */
-/* #undef HAVE_GETHOSTBYNAME_R_5_ARG */
-
-/* Define this if you have the 6-arg version of gethostbyname_r(). */
-/* #undef HAVE_GETHOSTBYNAME_R_6_ARG */
-
-/* Define to 1 if you have the `getitimer' function. */
-#define HAVE_GETITIMER 1
-
-/* Define to 1 if you have the `getloadavg' function. */
-#define HAVE_GETLOADAVG 1
-
-/* Define to 1 if you have the `getlogin' function. */
-#define HAVE_GETLOGIN 1
-
-/* Define to 1 if you have the `getnameinfo' function. */
-#define HAVE_GETNAMEINFO 1
-
-/* Define if you have the 'getpagesize' function. */
-#define HAVE_GETPAGESIZE 1
-
-/* Define to 1 if you have the `getpeername' function. */
-#define HAVE_GETPEERNAME 1
-
-/* Define to 1 if you have the `getpgid' function. */
-#define HAVE_GETPGID 1
-
-/* Define to 1 if you have the `getpgrp' function. */
-#define HAVE_GETPGRP 1
-
-/* Define to 1 if you have the `getpid' function. */
-#define HAVE_GETPID 1
-
-/* Define to 1 if you have the `getpriority' function. */
-#define HAVE_GETPRIORITY 1
-
-/* Define to 1 if you have the `getpwent' function. */
-#define HAVE_GETPWENT 1
-
-/* Define to 1 if you have the `getresgid' function. */
-/* #undef HAVE_GETRESGID */
-
-/* Define to 1 if you have the `getresuid' function. */
-/* #undef HAVE_GETRESUID */
-
-/* Define to 1 if you have the `getsid' function. */
-#define HAVE_GETSID 1
-
-/* Define to 1 if you have the `getspent' function. */
-/* #undef HAVE_GETSPENT */
-
-/* Define to 1 if you have the `getspnam' function. */
-/* #undef HAVE_GETSPNAM */
-
-/* Define to 1 if you have the `gettimeofday' function. */
-#define HAVE_GETTIMEOFDAY 1
-
-/* Define to 1 if you have the `getwd' function. */
-#define HAVE_GETWD 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_GRP_H 1
-
-/* Define if you have the 'hstrerror' function. */
-#define HAVE_HSTRERROR 1
-
-/* Define to 1 if you have the `hypot' function. */
-#define HAVE_HYPOT 1
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_IEEEFP_H */
-
-/* Define if you have the 'inet_aton' function. */
-#define HAVE_INET_ATON 1
-
-/* Define if you have the 'inet_pton' function. */
-#define HAVE_INET_PTON 1
-
-/* Define to 1 if you have the `initgroups' function. */
-#define HAVE_INITGROUPS 1
-
-/* Define if your compiler provides int32_t. */
-#define HAVE_INT32_T 1
-
-/* Define if your compiler provides int64_t. */
-#define HAVE_INT64_T 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_IO_H */
-
-/* Define to 1 if you have the `kill' function. */
-#define HAVE_KILL 1
-
-/* Define to 1 if you have the `killpg' function. */
-#define HAVE_KILLPG 1
-
-/* Define if you have the 'kqueue' functions. */
-#define HAVE_KQUEUE 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_LANGINFO_H 1
-
-/* Defined to enable large file support when an off_t is bigger than a long
- and long long is available and at least as big as an off_t. You may need to
- add some flags for configuration and compilation to enable this mode. (For
- Solaris and Linux, the necessary defines are already defined.) */
-/* #undef HAVE_LARGEFILE_SUPPORT */
-
-/* Define to 1 if you have the 'lchflags' function. */
-#define HAVE_LCHFLAGS 1
-
-/* Define to 1 if you have the `lchmod' function. */
-#define HAVE_LCHMOD 1
-
-/* Define to 1 if you have the `lchown' function. */
-#define HAVE_LCHOWN 1
-
-/* Define to 1 if you have the `lgamma' function. */
-#define HAVE_LGAMMA 1
-
-/* Define to 1 if you have the `dl' library (-ldl). */
-#define HAVE_LIBDL 1
-
-/* Define to 1 if you have the `dld' library (-ldld). */
-/* #undef HAVE_LIBDLD */
-
-/* Define to 1 if you have the `ieee' library (-lieee). */
-/* #undef HAVE_LIBIEEE */
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_LIBINTL_H */
-
-/* Define if you have the readline library (-lreadline). */
-#define HAVE_LIBREADLINE 1
-
-/* Define to 1 if you have the `resolv' library (-lresolv). */
-/* #undef HAVE_LIBRESOLV */
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_LIBUTIL_H */
-
-/* Define if you have the 'link' function. */
-#define HAVE_LINK 1
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_LINUX_NETLINK_H */
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_LINUX_TIPC_H */
-
-/* Define to 1 if you have the `log1p' function. */
-#define HAVE_LOG1P 1
-
-/* Define this if you have the type long double. */
-#define HAVE_LONG_DOUBLE 1
-
-/* Define this if you have the type long long. */
-#define HAVE_LONG_LONG 1
-
-/* Define to 1 if you have the `lstat' function. */
-#define HAVE_LSTAT 1
-
-/* Define this if you have the makedev macro. */
-#define HAVE_MAKEDEV 1
-
-/* Define to 1 if you have the `memmove' function. */
-#define HAVE_MEMMOVE 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have the `mkfifo' function. */
-#define HAVE_MKFIFO 1
-
-/* Define to 1 if you have the `mknod' function. */
-#define HAVE_MKNOD 1
-
-/* Define to 1 if you have the `mktime' function. */
-#define HAVE_MKTIME 1
-
-/* Define to 1 if you have the `mmap' function. */
-#define HAVE_MMAP 1
-
-/* Define to 1 if you have the `mremap' function. */
-/* #undef HAVE_MREMAP */
-
-/* Define to 1 if you have the header file. */
-#define HAVE_NCURSES_H 1
-
-/* Define to 1 if you have the header file, and it defines `DIR'. */
-/* #undef HAVE_NDIR_H */
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_NETPACKET_PACKET_H */
-
-/* Define to 1 if you have the `nice' function. */
-#define HAVE_NICE 1
-
-/* Define to 1 if you have the `openpty' function. */
-#define HAVE_OPENPTY 1
-
-/* Define if compiling using MacOS X 10.5 SDK or later. */
-#define HAVE_OSX105_SDK 1
-
-/* Define to 1 if you have the `pathconf' function. */
-#define HAVE_PATHCONF 1
-
-/* Define to 1 if you have the `pause' function. */
-#define HAVE_PAUSE 1
-
-/* Define to 1 if you have the `plock' function. */
-/* #undef HAVE_PLOCK */
-
-/* Define to 1 if you have the `poll' function. */
-#undef HAVE_POLL
-
-/* Define to 1 if you have the header file. */
-#undef HAVE_POLL_H
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_PROCESS_H */
-
-/* Define if your compiler supports function prototype */
-#define HAVE_PROTOTYPES 1
-
-/* Define if you have GNU PTH threads. */
-/* #undef HAVE_PTH */
-
-/* Define to 1 if you have the `pthread_atfork' function. */
-#define HAVE_PTHREAD_ATFORK 1
-
-/* Defined for Solaris 2.6 bug in pthread header. */
-/* #undef HAVE_PTHREAD_DESTRUCTOR */
-
-/* Define to 1 if you have the header file. */
-#define HAVE_PTHREAD_H 1
-
-/* Define to 1 if you have the `pthread_init' function. */
-/* #undef HAVE_PTHREAD_INIT */
-
-/* Define to 1 if you have the `pthread_sigmask' function. */
-#define HAVE_PTHREAD_SIGMASK 1
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_PTY_H */
-
-/* Define to 1 if you have the `putenv' function. */
-#define HAVE_PUTENV 1
-
-/* Define if the libcrypto has RAND_egd */
-#define HAVE_RAND_EGD 1
-
-/* Define to 1 if you have the `readlink' function. */
-#define HAVE_READLINK 1
-
-/* Define to 1 if you have the `realpath' function. */
-#define HAVE_REALPATH 1
-
-/* Define if you have readline 2.1 */
-#define HAVE_RL_CALLBACK 1
-
-/* Define if you can turn off readline's signal handling. */
-#define HAVE_RL_CATCH_SIGNAL 1
-
-/* Define if you have readline 2.2 */
-#define HAVE_RL_COMPLETION_APPEND_CHARACTER 1
-
-/* Define if you have readline 4.0 */
-#define HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK 1
-
-/* Define if you have readline 4.2 */
-#define HAVE_RL_COMPLETION_MATCHES 1
-
-/* Define if you have rl_completion_suppress_append */
-#define HAVE_RL_COMPLETION_SUPPRESS_APPEND 1
-
-/* Define if you have readline 4.0 */
-#define HAVE_RL_PRE_INPUT_HOOK 1
-
-/* Define to 1 if you have the `round' function. */
-#define HAVE_ROUND 1
-
-/* Define to 1 if you have the `select' function. */
-#define HAVE_SELECT 1
-
-/* Define to 1 if you have the `sem_getvalue' function. */
-#define HAVE_SEM_GETVALUE 1
-
-/* Define to 1 if you have the `sem_open' function. */
-#define HAVE_SEM_OPEN 1
-
-/* Define to 1 if you have the `sem_timedwait' function. */
-/* #undef HAVE_SEM_TIMEDWAIT */
-
-/* Define to 1 if you have the `sem_unlink' function. */
-#define HAVE_SEM_UNLINK 1
-
-/* Define to 1 if you have the `setegid' function. */
-#define HAVE_SETEGID 1
-
-/* Define to 1 if you have the `seteuid' function. */
-#define HAVE_SETEUID 1
-
-/* Define to 1 if you have the `setgid' function. */
-#define HAVE_SETGID 1
-
-/* Define if you have the 'setgroups' function. */
-#define HAVE_SETGROUPS 1
-
-/* Define to 1 if you have the `setitimer' function. */
-#define HAVE_SETITIMER 1
-
-/* Define to 1 if you have the `setlocale' function. */
-#define HAVE_SETLOCALE 1
-
-/* Define to 1 if you have the `setpgid' function. */
-#define HAVE_SETPGID 1
-
-/* Define to 1 if you have the `setpgrp' function. */
-#define HAVE_SETPGRP 1
-
-/* Define to 1 if you have the `setregid' function. */
-#define HAVE_SETREGID 1
-
-/* Define to 1 if you have the `setresgid' function. */
-/* #undef HAVE_SETRESGID */
-
-/* Define to 1 if you have the `setresuid' function. */
-/* #undef HAVE_SETRESUID */
-
-/* Define to 1 if you have the `setreuid' function. */
-#define HAVE_SETREUID 1
-
-/* Define to 1 if you have the `setsid' function. */
-#define HAVE_SETSID 1
-
-/* Define to 1 if you have the `setuid' function. */
-#define HAVE_SETUID 1
-
-/* Define to 1 if you have the `setvbuf' function. */
-#define HAVE_SETVBUF 1
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_SHADOW_H */
-
-/* Define to 1 if you have the `sigaction' function. */
-#define HAVE_SIGACTION 1
-
-/* Define to 1 if you have the `siginterrupt' function. */
-#define HAVE_SIGINTERRUPT 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SIGNAL_H 1
-
-/* Define to 1 if you have the `sigrelse' function. */
-#define HAVE_SIGRELSE 1
-
-/* Define to 1 if you have the `snprintf' function. */
-#define HAVE_SNPRINTF 1
-
-/* Define if sockaddr has sa_len member */
-#define HAVE_SOCKADDR_SA_LEN 1
-
-/* struct sockaddr_storage (sys/socket.h) */
-#define HAVE_SOCKADDR_STORAGE 1
-
-/* Define if you have the 'socketpair' function. */
-#define HAVE_SOCKETPAIR 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SPAWN_H 1
-
-/* Define if your compiler provides ssize_t */
-#define HAVE_SSIZE_T 1
-
-/* Define to 1 if you have the `statvfs' function. */
-#define HAVE_STATVFS 1
-
-/* Define if you have struct stat.st_mtim.tv_nsec */
-/* #undef HAVE_STAT_TV_NSEC */
-
-/* Define if you have struct stat.st_mtimensec */
-#define HAVE_STAT_TV_NSEC2 1
-
-/* Define if your compiler supports variable length function prototypes (e.g.
- void fprintf(FILE *, char *, ...);) *and* */
-#define HAVE_STDARG_PROTOTYPES 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the `strdup' function. */
-#define HAVE_STRDUP 1
-
-/* Define to 1 if you have the `strftime' function. */
-#define HAVE_STRFTIME 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_STROPTS_H */
-
-/* Define to 1 if `st_birthtime' is a member of `struct stat'. */
-#define HAVE_STRUCT_STAT_ST_BIRTHTIME 1
-
-/* Define to 1 if `st_blksize' is a member of `struct stat'. */
-#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
-
-/* Define to 1 if `st_blocks' is a member of `struct stat'. */
-#define HAVE_STRUCT_STAT_ST_BLOCKS 1
-
-/* Define to 1 if `st_flags' is a member of `struct stat'. */
-#define HAVE_STRUCT_STAT_ST_FLAGS 1
-
-/* Define to 1 if `st_gen' is a member of `struct stat'. */
-#define HAVE_STRUCT_STAT_ST_GEN 1
-
-/* Define to 1 if `st_rdev' is a member of `struct stat'. */
-#define HAVE_STRUCT_STAT_ST_RDEV 1
-
-/* Define to 1 if `tm_zone' is a member of `struct tm'. */
-#define HAVE_STRUCT_TM_TM_ZONE 1
-
-/* Define to 1 if your `struct stat' has `st_blocks'. Deprecated, use
- `HAVE_STRUCT_STAT_ST_BLOCKS' instead. */
-#define HAVE_ST_BLOCKS 1
-
-/* Define if you have the 'symlink' function. */
-#define HAVE_SYMLINK 1
-
-/* Define to 1 if you have the `sysconf' function. */
-#define HAVE_SYSCONF 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYSEXITS_H 1
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_SYS_AUDIOIO_H */
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_SYS_BSDTTY_H */
-
-/* Define to 1 if you have the header file, and it defines `DIR'.
- */
-/* #undef HAVE_SYS_DIR_H */
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_SYS_EPOLL_H */
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_EVENT_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_FILE_H 1
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_SYS_LOADAVG_H */
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_LOCK_H 1
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_SYS_MKDEV_H */
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_SYS_MODEM_H */
-
-/* Define to 1 if you have the header file, and it defines `DIR'.
- */
-/* #undef HAVE_SYS_NDIR_H */
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_PARAM_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_POLL_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_RESOURCE_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_SELECT_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_SOCKET_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_STATVFS_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_SYS_TERMIO_H */
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_TIMES_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_TIME_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_UN_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_UTSNAME_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_WAIT_H 1
-
-/* Define to 1 if you have the `tcgetpgrp' function. */
-#define HAVE_TCGETPGRP 1
-
-/* Define to 1 if you have the `tcsetpgrp' function. */
-#define HAVE_TCSETPGRP 1
-
-/* Define to 1 if you have the `tempnam' function. */
-#define HAVE_TEMPNAM 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_TERMIOS_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_TERM_H 1
-
-/* Define to 1 if you have the `tgamma' function. */
-#define HAVE_TGAMMA 1
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_THREAD_H */
-
-/* Define to 1 if you have the `timegm' function. */
-#define HAVE_TIMEGM 1
-
-/* Define to 1 if you have the `times' function. */
-#define HAVE_TIMES 1
-
-/* Define to 1 if you have the `tmpfile' function. */
-#define HAVE_TMPFILE 1
-
-/* Define to 1 if you have the `tmpnam' function. */
-#define HAVE_TMPNAM 1
-
-/* Define to 1 if you have the `tmpnam_r' function. */
-/* #undef HAVE_TMPNAM_R */
-
-/* Define to 1 if your `struct tm' has `tm_zone'. Deprecated, use
- `HAVE_STRUCT_TM_TM_ZONE' instead. */
-#define HAVE_TM_ZONE 1
-
-/* Define to 1 if you have the `truncate' function. */
-#define HAVE_TRUNCATE 1
-
-/* Define to 1 if you don't have `tm_zone' but do have the external array
- `tzname'. */
-/* #undef HAVE_TZNAME */
-
-/* Define this if you have tcl and TCL_UTF_MAX==6 */
-/* #undef HAVE_UCS4_TCL */
-
-/* Define if your compiler provides uint32_t. */
-#define HAVE_UINT32_T 1
-
-/* Define if your compiler provides uint64_t. */
-#define HAVE_UINT64_T 1
-
-/* Define to 1 if the system has the type `uintptr_t'. */
-#define HAVE_UINTPTR_T 1
-
-/* Define to 1 if you have the `uname' function. */
-#define HAVE_UNAME 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_UNISTD_H 1
-
-/* Define to 1 if you have the `unsetenv' function. */
-#define HAVE_UNSETENV 1
-
-/* Define if you have a useable wchar_t type defined in wchar.h; useable means
- wchar_t must be an unsigned type with at least 16 bits. (see
- Include/unicodeobject.h). */
-/* #undef HAVE_USABLE_WCHAR_T */
-
-/* Define to 1 if you have the header file. */
-#define HAVE_UTIL_H 1
-
-/* Define to 1 if you have the `utimes' function. */
-#define HAVE_UTIMES 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_UTIME_H 1
-
-/* Define to 1 if you have the `wait3' function. */
-#define HAVE_WAIT3 1
-
-/* Define to 1 if you have the `wait4' function. */
-#define HAVE_WAIT4 1
-
-/* Define to 1 if you have the `waitpid' function. */
-#define HAVE_WAITPID 1
-
-/* Define if the compiler provides a wchar.h header file. */
-#define HAVE_WCHAR_H 1
-
-/* Define to 1 if you have the `wcscoll' function. */
-#define HAVE_WCSCOLL 1
-
-/* Define if tzset() actually switches the local timezone in a meaningful way.
- */
-#define HAVE_WORKING_TZSET 1
-
-/* Define if the zlib library has inflateCopy */
-#define HAVE_ZLIB_COPY 1
-
-/* Define to 1 if you have the `_getpty' function. */
-/* #undef HAVE__GETPTY */
-
-/* Define if you are using Mach cthreads directly under /include */
-/* #undef HURD_C_THREADS */
-
-/* Define if you are using Mach cthreads under mach / */
-/* #undef MACH_C_THREADS */
-
-/* Define to 1 if `major', `minor', and `makedev' are declared in .
- */
-/* #undef MAJOR_IN_MKDEV */
-
-/* Define to 1 if `major', `minor', and `makedev' are declared in
- . */
-/* #undef MAJOR_IN_SYSMACROS */
-
-/* Define if mvwdelch in curses.h is an expression. */
-#define MVWDELCH_IS_EXPRESSION 1
-
-/* Define to the address where bug reports for this package should be sent. */
-/* #undef PACKAGE_BUGREPORT */
-
-/* Define to the full name of this package. */
-/* #undef PACKAGE_NAME */
-
-/* Define to the full name and version of this package. */
-/* #undef PACKAGE_STRING */
-
-/* Define to the one symbol short name of this package. */
-/* #undef PACKAGE_TARNAME */
-
-/* Define to the home page for this package. */
-/* #undef PACKAGE_URL */
-
-/* Define to the version of this package. */
-/* #undef PACKAGE_VERSION */
-
-/* Define if POSIX semaphores aren't enabled on your system */
-/* #undef POSIX_SEMAPHORES_NOT_ENABLED */
-
-/* Defined if PTHREAD_SCOPE_SYSTEM supported. */
-#define PTHREAD_SYSTEM_SCHED_SUPPORTED 1
-
-/* Define as the preferred size in bits of long digits */
-/* #undef PYLONG_BITS_IN_DIGIT */
-
-/* Define to printf format modifier for long long type */
-#define PY_FORMAT_LONG_LONG "ll"
-
-/* Define to printf format modifier for Py_ssize_t */
-#define PY_FORMAT_SIZE_T "z"
-
-/* Define as the integral type used for Unicode representation. */
-#define PY_UNICODE_TYPE unsigned short
-
-/* Define if you want to build an interpreter with many run-time checks. */
-/* #undef Py_DEBUG */
-
-/* Defined if Python is built as a shared library. */
-/* #undef Py_ENABLE_SHARED */
-
-/* Define as the size of the unicode type. */
-#define Py_UNICODE_SIZE 2
-
-/* Define if you want to have a Unicode type. */
-#define Py_USING_UNICODE 1
-
-/* assume C89 semantics that RETSIGTYPE is always void */
-#define RETSIGTYPE void
-
-/* Define if setpgrp() must be called as setpgrp(0, 0). */
-/* #undef SETPGRP_HAVE_ARG */
-
-/* Define this to be extension of shared libraries (including the dot!). */
-#define SHLIB_EXT ".so"
-
-/* Define if i>>j for signed int i does not extend the sign bit when i < 0 */
-/* #undef SIGNED_RIGHT_SHIFT_ZERO_FILLS */
-
-/* The size of `double', as computed by sizeof. */
-#define SIZEOF_DOUBLE 8
-
-/* The size of `float', as computed by sizeof. */
-#define SIZEOF_FLOAT 4
-
-/* The size of `fpos_t', as computed by sizeof. */
-#define SIZEOF_FPOS_T 8
-
-/* The size of `int', as computed by sizeof. */
-#define SIZEOF_INT 4
-
-/* The size of `long', as computed by sizeof. */
-#define SIZEOF_LONG 8
-
-/* The size of `long double', as computed by sizeof. */
-#define SIZEOF_LONG_DOUBLE 16
-
-/* The size of `long long', as computed by sizeof. */
-#define SIZEOF_LONG_LONG 8
-
-/* The size of `off_t', as computed by sizeof. */
-#define SIZEOF_OFF_T 8
-
-/* The size of `pid_t', as computed by sizeof. */
-#define SIZEOF_PID_T 4
-
-/* The size of `pthread_t', as computed by sizeof. */
-#define SIZEOF_PTHREAD_T 8
-
-/* The size of `short', as computed by sizeof. */
-#define SIZEOF_SHORT 2
-
-/* The size of `size_t', as computed by sizeof. */
-#define SIZEOF_SIZE_T 8
-
-/* The size of `time_t', as computed by sizeof. */
-#define SIZEOF_TIME_T 8
-
-/* The size of `uintptr_t', as computed by sizeof. */
-#define SIZEOF_UINTPTR_T 8
-
-/* The size of `void *', as computed by sizeof. */
-#define SIZEOF_VOID_P 8
-
-/* The size of `wchar_t', as computed by sizeof. */
-#define SIZEOF_WCHAR_T 4
-
-/* The size of `_Bool', as computed by sizeof. */
-#define SIZEOF__BOOL 1
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Define if you can safely include both and
- (which you can't on SCO ODT 3.0). */
-#define SYS_SELECT_WITH_SYS_TIME 1
-
-/* Define if tanh(-0.) is -0., or if platform doesn't have signed zeros */
-#define TANH_PRESERVES_ZERO_SIGN 1
-
-/* Define to 1 if you can safely include both and . */
-#define TIME_WITH_SYS_TIME 1
-
-/* Define to 1 if your declares `struct tm'. */
-/* #undef TM_IN_SYS_TIME */
-
-/* Enable extensions on AIX 3, Interix. */
-#ifndef _ALL_SOURCE
-# define _ALL_SOURCE 1
-#endif
-/* Enable GNU extensions on systems that have them. */
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE 1
-#endif
-/* Enable threading extensions on Solaris. */
-#ifndef _POSIX_PTHREAD_SEMANTICS
-# define _POSIX_PTHREAD_SEMANTICS 1
-#endif
-/* Enable extensions on HP NonStop. */
-#ifndef _TANDEM_SOURCE
-# define _TANDEM_SOURCE 1
-#endif
-/* Enable general extensions on Solaris. */
-#ifndef __EXTENSIONS__
-# define __EXTENSIONS__ 1
-#endif
-
-
-/* Define if you want to use MacPython modules on MacOSX in unix-Python. */
-#define USE_TOOLBOX_OBJECT_GLUE 1
-
-/* Define if a va_list is an array of some kind */
-#define VA_LIST_IS_ARRAY 1
-
-/* Define if you want SIGFPE handled (see Include/pyfpe.h). */
-/* #undef WANT_SIGFPE_HANDLER */
-
-/* Define if you want wctype.h functions to be used instead of the one
- supplied by Python itself. (see Include/unicodectype.h). */
-/* #undef WANT_WCTYPE_FUNCTIONS */
-
-/* Define if WINDOW in curses.h offers a field _flags. */
-/* #undef WINDOW_HAS_FLAGS */
-
-/* Define if you want documentation strings in extension modules */
-#define WITH_DOC_STRINGS 1
-
-/* Define if you want to use the new-style (Openstep, Rhapsody, MacOS) dynamic
- linker (dyld) instead of the old-style (NextStep) dynamic linker (rld).
- Dyld is necessary to support frameworks. */
-#define WITH_DYLD 1
-
-/* Define to 1 if libintl is needed for locale functions. */
-/* #undef WITH_LIBINTL */
-
-/* Define if you want to produce an OpenStep/Rhapsody framework (shared
- library plus accessory files). */
-#define WITH_NEXT_FRAMEWORK 1
-
-/* Define if you want to compile in Python-specific mallocs */
-#define WITH_PYMALLOC 1
-
-/* Define if you want to compile in rudimentary thread support */
-#define WITH_THREAD 1
-
-/* Define to profile with the Pentium timestamp counter */
-/* #undef WITH_TSC */
-
-/* Define if you want pymalloc to be disabled when running under valgrind */
-/* #undef WITH_VALGRIND */
-
-/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
- significant byte first (like Motorola and SPARC, unlike Intel). */
-#if defined AC_APPLE_UNIVERSAL_BUILD
-# if defined __BIG_ENDIAN__
-# define WORDS_BIGENDIAN 1
-# endif
-#else
-# ifndef WORDS_BIGENDIAN
-/* # undef WORDS_BIGENDIAN */
-# endif
-#endif
-
-/* Define if arithmetic is subject to x87-style double rounding issue */
-/* #undef X87_DOUBLE_ROUNDING */
-
-/* Define on OpenBSD to activate all library features */
-/* #undef _BSD_SOURCE */
-
-/* Define on Irix to enable u_int */
-#define _BSD_TYPES 1
-
-/* Define on Darwin to activate all library features */
-#define _DARWIN_C_SOURCE 1
-
-/* This must be set to 64 on some systems to enable large file support. */
-#define _FILE_OFFSET_BITS 64
-
-/* Define on Linux to activate all library features */
-#define _GNU_SOURCE 1
-
-/* This must be defined on some systems to enable large file support. */
-#define _LARGEFILE_SOURCE 1
-
-/* This must be defined on AIX systems to enable large file support. */
-/* #undef _LARGE_FILES */
-
-/* Define to 1 if on MINIX. */
-/* #undef _MINIX */
-
-/* Define on NetBSD to activate all library features */
-#define _NETBSD_SOURCE 1
-
-/* Define _OSF_SOURCE to get the makedev macro. */
-/* #undef _OSF_SOURCE */
-
-/* Define to 2 if the system does not provide POSIX.1 features except with
- this defined. */
-/* #undef _POSIX_1_SOURCE */
-
-/* Define to activate features from IEEE Stds 1003.1-2001 */
-/* #undef _POSIX_C_SOURCE */
-
-/* Define to 1 if you need to in order for `stat' and other things to work. */
-/* #undef _POSIX_SOURCE */
-
-/* Define if you have POSIX threads, and your system does not define that. */
-/* #undef _POSIX_THREADS */
-
-/* Define to force use of thread-safe errno, h_errno, and other functions */
-#define _REENTRANT 1
-
-/* Define for Solaris 2.5.1 so the uint32_t typedef from ,
- , or is not used. If the typedef were allowed, the
- #define below would cause a syntax error. */
-/* #undef _UINT32_T */
-
-/* Define for Solaris 2.5.1 so the uint64_t typedef from ,
- , or is not used. If the typedef were allowed, the
- #define below would cause a syntax error. */
-/* #undef _UINT64_T */
-
-/* Define to the level of X/Open that your system supports */
-/* #undef _XOPEN_SOURCE */
-
-/* Define to activate Unix95-and-earlier features */
-/* #undef _XOPEN_SOURCE_EXTENDED */
-
-/* Define on FreeBSD to activate all library features */
-#define __BSD_VISIBLE 1
-
-/* Define to 1 if type `char' is unsigned and you are not using gcc. */
-#ifndef __CHAR_UNSIGNED__
-/* # undef __CHAR_UNSIGNED__ */
-#endif
-
-/* Defined on Solaris to see additional function prototypes. */
-#define __EXTENSIONS__ 1
-
-/* Define to 'long' if doesn't define. */
-/* #undef clock_t */
-
-/* Define to empty if `const' does not conform to ANSI C. */
-/* #undef const */
-
-/* Define to `int' if doesn't define. */
-/* #undef gid_t */
-
-/* Define to the type of a signed integer type of width exactly 32 bits if
- such a type exists and the standard includes do not define it. */
-/* #undef int32_t */
-
-/* Define to the type of a signed integer type of width exactly 64 bits if
- such a type exists and the standard includes do not define it. */
-/* #undef int64_t */
-
-/* Define to `int' if does not define. */
-/* #undef mode_t */
-
-/* Define to `long int' if does not define. */
-/* #undef off_t */
-
-/* Define to `int' if does not define. */
-/* #undef pid_t */
-
-/* Define to empty if the keyword does not work. */
-/* #undef signed */
-
-/* Define to `unsigned int' if does not define. */
-/* #undef size_t */
-
-/* Define to `int' if does not define. */
-/* #undef socklen_t */
-
-/* Define to `int' if doesn't define. */
-/* #undef uid_t */
-
-/* Define to the type of an unsigned integer type of width exactly 32 bits if
- such a type exists and the standard includes do not define it. */
-/* #undef uint32_t */
-
-/* Define to the type of an unsigned integer type of width exactly 64 bits if
- such a type exists and the standard includes do not define it. */
-/* #undef uint64_t */
-
-/* Define to empty if the keyword does not work. */
-/* #undef volatile */
-
-
-/* Define the macros needed if on a UnixWare 7.x system. */
-#if defined(__USLC__) && defined(__SCO_VERSION__)
-#define STRICT_SYSV_CURSES /* Don't use ncurses extensions */
-#endif
-
-#endif /*Py_PYCONFIG_H*/
-
diff --git a/dist.mac/AttributionReport.app/Contents/Frameworks/Python.framework/Versions/Current b/dist.mac/AttributionReport.app/Contents/Frameworks/Python.framework/Versions/Current
deleted file mode 120000
index e6b7b62..0000000
--- a/dist.mac/AttributionReport.app/Contents/Frameworks/Python.framework/Versions/Current
+++ /dev/null
@@ -1 +0,0 @@
-2.7
\ No newline at end of file
diff --git a/dist.mac/AttributionReport.app/Contents/Frameworks/libcrypto.1.0.0.dylib b/dist.mac/AttributionReport.app/Contents/Frameworks/libcrypto.1.0.0.dylib
deleted file mode 100644
index 456ddd6..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Frameworks/libcrypto.1.0.0.dylib and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Frameworks/libfreetype.6.dylib b/dist.mac/AttributionReport.app/Contents/Frameworks/libfreetype.6.dylib
deleted file mode 100644
index 09300eb..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Frameworks/libfreetype.6.dylib and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Frameworks/libgdbm.4.dylib b/dist.mac/AttributionReport.app/Contents/Frameworks/libgdbm.4.dylib
deleted file mode 100644
index 03e4481..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Frameworks/libgdbm.4.dylib and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Frameworks/libjpeg.8.dylib b/dist.mac/AttributionReport.app/Contents/Frameworks/libjpeg.8.dylib
deleted file mode 100644
index 4aae5d2..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Frameworks/libjpeg.8.dylib and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Frameworks/libpng16.16.dylib b/dist.mac/AttributionReport.app/Contents/Frameworks/libpng16.16.dylib
deleted file mode 100644
index 765a8e7..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Frameworks/libpng16.16.dylib and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Frameworks/libsqlite3.0.dylib b/dist.mac/AttributionReport.app/Contents/Frameworks/libsqlite3.0.dylib
deleted file mode 100644
index f5df04d..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Frameworks/libsqlite3.0.dylib and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Frameworks/libssl.1.0.0.dylib b/dist.mac/AttributionReport.app/Contents/Frameworks/libssl.1.0.0.dylib
deleted file mode 100644
index f31973d..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Frameworks/libssl.1.0.0.dylib and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Frameworks/libtiff.5.dylib b/dist.mac/AttributionReport.app/Contents/Frameworks/libtiff.5.dylib
deleted file mode 100644
index f479648..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Frameworks/libtiff.5.dylib and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Info.plist b/dist.mac/AttributionReport.app/Contents/Info.plist
deleted file mode 100644
index 33c695e..0000000
--- a/dist.mac/AttributionReport.app/Contents/Info.plist
+++ /dev/null
@@ -1,89 +0,0 @@
-
-
-
-
- CFBundleDevelopmentRegion
- English
- CFBundleDisplayName
- main
- CFBundleExecutable
- main
- CFBundleIconFile
- main
- CFBundleIdentifier
- org.pythonmac.unspecified.main
- CFBundleInfoDictionaryVersion
- 6.0
- CFBundleName
- main
- CFBundlePackageType
- APPL
- CFBundleShortVersionString
- 0.0.0
- CFBundleSignature
- ????
- CFBundleVersion
- 0.0.0
- LSHasLocalizedDisplayName
-
- NSAppleScriptEnabled
-
- NSHumanReadableCopyright
- Copyright not specified
- NSMainNibFile
- MainMenu
- NSPrincipalClass
- NSApplication
- PyMainFileNames
-
- __boot__
-
- PyOptions
-
- alias
-
- argv_emulation
-
- emulate_shell_environment
-
- no_chdir
-
- prefer_ppc
-
- site_packages
-
- use_faulthandler
-
- use_pythonpath
-
- verbose
-
-
- PyResourcePackages
-
-
- PyRuntimeLocations
-
- @executable_path/../Frameworks/Python.framework/Versions/2.7/Python
-
- PythonInfoDict
-
- PythonExecutable
- /Users/tyrelsouza/.virtualenvs/julian_report/bin/python
- PythonLongVersion
- 2.7.10 (default, Jun 1 2015, 09:44:56)
-[GCC 4.2.1 Compatible Apple LLVM 6.1.0 (clang-602.0.53)]
- PythonShortVersion
- 2.7
- py2app
-
- alias
-
- template
- app
- version
- 0.9
-
-
-
-
diff --git a/dist.mac/AttributionReport.app/Contents/MacOS/main b/dist.mac/AttributionReport.app/Contents/MacOS/main
deleted file mode 100755
index 69e5dd0..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/MacOS/main and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/MacOS/python b/dist.mac/AttributionReport.app/Contents/MacOS/python
deleted file mode 100755
index 9975ab0..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/MacOS/python and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/PkgInfo b/dist.mac/AttributionReport.app/Contents/PkgInfo
deleted file mode 100644
index bd04210..0000000
--- a/dist.mac/AttributionReport.app/Contents/PkgInfo
+++ /dev/null
@@ -1 +0,0 @@
-APPL????
\ No newline at end of file
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/__boot__.py b/dist.mac/AttributionReport.app/Contents/Resources/__boot__.py
deleted file mode 100644
index c0ceae9..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/__boot__.py
+++ /dev/null
@@ -1,81 +0,0 @@
-def _reset_sys_path():
- # Clear generic sys.path[0]
- import sys, os
- resources = os.environ['RESOURCEPATH']
- while sys.path[0] == resources:
- del sys.path[0]
-_reset_sys_path()
-
-
-def _chdir_resource():
- import os
- os.chdir(os.environ['RESOURCEPATH'])
-_chdir_resource()
-
-
-def _disable_linecache():
- import linecache
- def fake_getline(*args, **kwargs):
- return ''
- linecache.orig_getline = linecache.getline
- linecache.getline = fake_getline
-_disable_linecache()
-
-
-import re, sys
-cookie_re = re.compile(b"coding[:=]\s*([-\w.]+)")
-if sys.version_info[0] == 2:
- default_encoding = 'ascii'
-else:
- default_encoding = 'utf-8'
-
-def guess_encoding(fp):
- for i in range(2):
- ln = fp.readline()
-
- m = cookie_re.search(ln)
- if m is not None:
- return m.group(1).decode('ascii')
-
- return default_encoding
-
-def _run():
- global __file__
- import os, site
- sys.frozen = 'macosx_app'
- base = os.environ['RESOURCEPATH']
-
- argv0 = os.path.basename(os.environ['ARGVZERO'])
- script = SCRIPT_MAP.get(argv0, DEFAULT_SCRIPT)
-
- path = os.path.join(base, script)
- sys.argv[0] = __file__ = path
- if sys.version_info[0] == 2:
- with open(path, 'rU') as fp:
- source = fp.read() + "\n"
- else:
- with open(path, 'rb') as fp:
- encoding = guess_encoding(fp)
-
- with open(path, 'r', encoding=encoding) as fp:
- source = fp.read() + '\n'
- exec(compile(source, path, 'exec'), globals(), globals())
-
-
-import os
-os.environ['MATPLOTLIBDATA'] = os.path.join(os.environ['RESOURCEPATH'], 'mpl-data')
-
-
-def _setup_ctypes():
- from ctypes.macholib import dyld
- import os
- frameworks = os.path.join(os.environ['RESOURCEPATH'], '..', 'Frameworks')
- dyld.DEFAULT_FRAMEWORK_FALLBACK.insert(0, frameworks)
- dyld.DEFAULT_LIBRARY_FALLBACK.insert(0, frameworks)
-
-_setup_ctypes()
-
-
-DEFAULT_SCRIPT='main.py'
-SCRIPT_MAP={}
-_run()
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/__error__.sh b/dist.mac/AttributionReport.app/Contents/Resources/__error__.sh
deleted file mode 100755
index f1122a6..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/__error__.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/sh
-#
-# This is the default apptemplate error script
-#
-if ( test -n "$2" ) ; then
- echo "$1 Error"
- echo "An unexpected error has occurred during execution of the main script"
- echo ""
- echo "$2: $3"
- echo ""
- echo "See the Console for a detailed traceback."
-else
- echo "$1 Error"
-
- # Usage: ERRORURL , this is used by the
- # bundle runner to put up a dialog.
- #echo "ERRORURL: http://www.python.org/ Visit the Python Website
-# echo "ERRORURL: http://homepages.cwi.nl/~jack/macpython/index.html Visit the MacPython Website"
-fi
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/include/python2.7/pyconfig.h b/dist.mac/AttributionReport.app/Contents/Resources/include/python2.7/pyconfig.h
deleted file mode 100644
index aa93780..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/include/python2.7/pyconfig.h
+++ /dev/null
@@ -1,1282 +0,0 @@
-/* pyconfig.h. Generated from pyconfig.h.in by configure. */
-/* pyconfig.h.in. Generated from configure.ac by autoheader. */
-
-
-#ifndef Py_PYCONFIG_H
-#define Py_PYCONFIG_H
-
-
-/* Define if building universal (internal helper macro) */
-/* #undef AC_APPLE_UNIVERSAL_BUILD */
-
-/* Define for AIX if your compiler is a genuine IBM xlC/xlC_r and you want
- support for AIX C++ shared extension modules. */
-/* #undef AIX_GENUINE_CPLUSPLUS */
-
-/* Define this if you have AtheOS threads. */
-/* #undef ATHEOS_THREADS */
-
-/* Define this if you have BeOS threads. */
-/* #undef BEOS_THREADS */
-
-/* Define if you have the Mach cthreads package */
-/* #undef C_THREADS */
-
-/* Define if C doubles are 64-bit IEEE 754 binary format, stored in ARM
- mixed-endian order (byte order 45670123) */
-/* #undef DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754 */
-
-/* Define if C doubles are 64-bit IEEE 754 binary format, stored with the most
- significant byte first */
-/* #undef DOUBLE_IS_BIG_ENDIAN_IEEE754 */
-
-/* Define if C doubles are 64-bit IEEE 754 binary format, stored with the
- least significant byte first */
-#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 1
-
-/* Define if --enable-ipv6 is specified */
-#define ENABLE_IPV6 1
-
-/* Define if flock needs to be linked with bsd library. */
-/* #undef FLOCK_NEEDS_LIBBSD */
-
-/* Define if getpgrp() must be called as getpgrp(0). */
-/* #undef GETPGRP_HAVE_ARG */
-
-/* Define if gettimeofday() does not have second (timezone) argument This is
- the case on Motorola V4 (R40V4.2) */
-/* #undef GETTIMEOFDAY_NO_TZ */
-
-/* Define to 1 if you have the `acosh' function. */
-#define HAVE_ACOSH 1
-
-/* struct addrinfo (netdb.h) */
-#define HAVE_ADDRINFO 1
-
-/* Define to 1 if you have the `alarm' function. */
-#define HAVE_ALARM 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_ALLOCA_H 1
-
-/* Define this if your time.h defines altzone. */
-/* #undef HAVE_ALTZONE */
-
-/* Define to 1 if you have the `asinh' function. */
-#define HAVE_ASINH 1
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_ASM_TYPES_H */
-
-/* Define to 1 if you have the `atanh' function. */
-#define HAVE_ATANH 1
-
-/* Define if GCC supports __attribute__((format(PyArg_ParseTuple, 2, 3))) */
-/* #undef HAVE_ATTRIBUTE_FORMAT_PARSETUPLE */
-
-/* Define to 1 if you have the `bind_textdomain_codeset' function. */
-/* #undef HAVE_BIND_TEXTDOMAIN_CODESET */
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_BLUETOOTH_BLUETOOTH_H */
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_BLUETOOTH_H */
-
-/* Define if nice() returns success/failure instead of the new priority. */
-/* #undef HAVE_BROKEN_NICE */
-
-/* Define if the system reports an invalid PIPE_BUF value. */
-/* #undef HAVE_BROKEN_PIPE_BUF */
-
-/* Define if poll() sets errno on invalid file descriptors. */
-/* #undef HAVE_BROKEN_POLL */
-
-/* Define if the Posix semaphores do not work on your system */
-/* #undef HAVE_BROKEN_POSIX_SEMAPHORES */
-
-/* Define if pthread_sigmask() does not work on your system. */
-/* #undef HAVE_BROKEN_PTHREAD_SIGMASK */
-
-/* define to 1 if your sem_getvalue is broken. */
-#define HAVE_BROKEN_SEM_GETVALUE 1
-
-/* Define if `unsetenv` does not return an int. */
-/* #undef HAVE_BROKEN_UNSETENV */
-
-/* Define this if you have the type _Bool. */
-#define HAVE_C99_BOOL 1
-
-/* Define to 1 if you have the 'chflags' function. */
-#define HAVE_CHFLAGS 1
-
-/* Define to 1 if you have the `chown' function. */
-#define HAVE_CHOWN 1
-
-/* Define if you have the 'chroot' function. */
-#define HAVE_CHROOT 1
-
-/* Define to 1 if you have the `clock' function. */
-#define HAVE_CLOCK 1
-
-/* Define to 1 if you have the `confstr' function. */
-#define HAVE_CONFSTR 1
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_CONIO_H */
-
-/* Define to 1 if you have the `copysign' function. */
-#define HAVE_COPYSIGN 1
-
-/* Define to 1 if you have the `ctermid' function. */
-#define HAVE_CTERMID 1
-
-/* Define if you have the 'ctermid_r' function. */
-#define HAVE_CTERMID_R 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_CURSES_H 1
-
-/* Define if you have the 'is_term_resized' function. */
-#define HAVE_CURSES_IS_TERM_RESIZED 1
-
-/* Define if you have the 'resizeterm' function. */
-#define HAVE_CURSES_RESIZETERM 1
-
-/* Define if you have the 'resize_term' function. */
-#define HAVE_CURSES_RESIZE_TERM 1
-
-/* Define to 1 if you have the declaration of `isfinite', and to 0 if you
- don't. */
-#define HAVE_DECL_ISFINITE 1
-
-/* Define to 1 if you have the declaration of `isinf', and to 0 if you don't.
- */
-#define HAVE_DECL_ISINF 1
-
-/* Define to 1 if you have the declaration of `isnan', and to 0 if you don't.
- */
-#define HAVE_DECL_ISNAN 1
-
-/* Define to 1 if you have the declaration of `tzname', and to 0 if you don't.
- */
-/* #undef HAVE_DECL_TZNAME */
-
-/* Define to 1 if you have the device macros. */
-#define HAVE_DEVICE_MACROS 1
-
-/* Define to 1 if you have the /dev/ptc device file. */
-/* #undef HAVE_DEV_PTC */
-
-/* Define to 1 if you have the /dev/ptmx device file. */
-#define HAVE_DEV_PTMX 1
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_DIRECT_H */
-
-/* Define to 1 if you have the header file, and it defines `DIR'.
- */
-#define HAVE_DIRENT_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_DLFCN_H 1
-
-/* Define to 1 if you have the `dlopen' function. */
-#define HAVE_DLOPEN 1
-
-/* Define to 1 if you have the `dup2' function. */
-#define HAVE_DUP2 1
-
-/* Defined when any dynamic module loading is enabled. */
-#define HAVE_DYNAMIC_LOADING 1
-
-/* Define if you have the 'epoll' functions. */
-/* #undef HAVE_EPOLL */
-
-/* Define to 1 if you have the `erf' function. */
-#define HAVE_ERF 1
-
-/* Define to 1 if you have the `erfc' function. */
-#define HAVE_ERFC 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_ERRNO_H 1
-
-/* Define to 1 if you have the `execv' function. */
-#define HAVE_EXECV 1
-
-/* Define to 1 if you have the `expm1' function. */
-#define HAVE_EXPM1 1
-
-/* Define if you have the 'fchdir' function. */
-#define HAVE_FCHDIR 1
-
-/* Define to 1 if you have the `fchmod' function. */
-#define HAVE_FCHMOD 1
-
-/* Define to 1 if you have the `fchown' function. */
-#define HAVE_FCHOWN 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_FCNTL_H 1
-
-/* Define if you have the 'fdatasync' function. */
-/* #undef HAVE_FDATASYNC */
-
-/* Define to 1 if you have the `finite' function. */
-#define HAVE_FINITE 1
-
-/* Define to 1 if you have the `flock' function. */
-#define HAVE_FLOCK 1
-
-/* Define to 1 if you have the `fork' function. */
-#define HAVE_FORK 1
-
-/* Define to 1 if you have the `forkpty' function. */
-#define HAVE_FORKPTY 1
-
-/* Define to 1 if you have the `fpathconf' function. */
-#define HAVE_FPATHCONF 1
-
-/* Define to 1 if you have the `fseek64' function. */
-/* #undef HAVE_FSEEK64 */
-
-/* Define to 1 if you have the `fseeko' function. */
-#define HAVE_FSEEKO 1
-
-/* Define to 1 if you have the `fstatvfs' function. */
-#define HAVE_FSTATVFS 1
-
-/* Define if you have the 'fsync' function. */
-#define HAVE_FSYNC 1
-
-/* Define to 1 if you have the `ftell64' function. */
-/* #undef HAVE_FTELL64 */
-
-/* Define to 1 if you have the `ftello' function. */
-#define HAVE_FTELLO 1
-
-/* Define to 1 if you have the `ftime' function. */
-#define HAVE_FTIME 1
-
-/* Define to 1 if you have the `ftruncate' function. */
-#define HAVE_FTRUNCATE 1
-
-/* Define to 1 if you have the `gai_strerror' function. */
-#define HAVE_GAI_STRERROR 1
-
-/* Define to 1 if you have the `gamma' function. */
-#define HAVE_GAMMA 1
-
-/* Define if we can use gcc inline assembler to get and set x87 control word
- */
-#define HAVE_GCC_ASM_FOR_X87 1
-
-/* Define if you have the getaddrinfo function. */
-#define HAVE_GETADDRINFO 1
-
-/* Define to 1 if you have the `getcwd' function. */
-#define HAVE_GETCWD 1
-
-/* Define this if you have flockfile(), getc_unlocked(), and funlockfile() */
-#define HAVE_GETC_UNLOCKED 1
-
-/* Define to 1 if you have the `getentropy' function. */
-/* #undef HAVE_GETENTROPY */
-
-/* Define to 1 if you have the `getgroups' function. */
-#define HAVE_GETGROUPS 1
-
-/* Define to 1 if you have the `gethostbyname' function. */
-#define HAVE_GETHOSTBYNAME 1
-
-/* Define this if you have some version of gethostbyname_r() */
-/* #undef HAVE_GETHOSTBYNAME_R */
-
-/* Define this if you have the 3-arg version of gethostbyname_r(). */
-/* #undef HAVE_GETHOSTBYNAME_R_3_ARG */
-
-/* Define this if you have the 5-arg version of gethostbyname_r(). */
-/* #undef HAVE_GETHOSTBYNAME_R_5_ARG */
-
-/* Define this if you have the 6-arg version of gethostbyname_r(). */
-/* #undef HAVE_GETHOSTBYNAME_R_6_ARG */
-
-/* Define to 1 if you have the `getitimer' function. */
-#define HAVE_GETITIMER 1
-
-/* Define to 1 if you have the `getloadavg' function. */
-#define HAVE_GETLOADAVG 1
-
-/* Define to 1 if you have the `getlogin' function. */
-#define HAVE_GETLOGIN 1
-
-/* Define to 1 if you have the `getnameinfo' function. */
-#define HAVE_GETNAMEINFO 1
-
-/* Define if you have the 'getpagesize' function. */
-#define HAVE_GETPAGESIZE 1
-
-/* Define to 1 if you have the `getpeername' function. */
-#define HAVE_GETPEERNAME 1
-
-/* Define to 1 if you have the `getpgid' function. */
-#define HAVE_GETPGID 1
-
-/* Define to 1 if you have the `getpgrp' function. */
-#define HAVE_GETPGRP 1
-
-/* Define to 1 if you have the `getpid' function. */
-#define HAVE_GETPID 1
-
-/* Define to 1 if you have the `getpriority' function. */
-#define HAVE_GETPRIORITY 1
-
-/* Define to 1 if you have the `getpwent' function. */
-#define HAVE_GETPWENT 1
-
-/* Define to 1 if you have the `getresgid' function. */
-/* #undef HAVE_GETRESGID */
-
-/* Define to 1 if you have the `getresuid' function. */
-/* #undef HAVE_GETRESUID */
-
-/* Define to 1 if you have the `getsid' function. */
-#define HAVE_GETSID 1
-
-/* Define to 1 if you have the `getspent' function. */
-/* #undef HAVE_GETSPENT */
-
-/* Define to 1 if you have the `getspnam' function. */
-/* #undef HAVE_GETSPNAM */
-
-/* Define to 1 if you have the `gettimeofday' function. */
-#define HAVE_GETTIMEOFDAY 1
-
-/* Define to 1 if you have the `getwd' function. */
-#define HAVE_GETWD 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_GRP_H 1
-
-/* Define if you have the 'hstrerror' function. */
-#define HAVE_HSTRERROR 1
-
-/* Define to 1 if you have the `hypot' function. */
-#define HAVE_HYPOT 1
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_IEEEFP_H */
-
-/* Define if you have the 'inet_aton' function. */
-#define HAVE_INET_ATON 1
-
-/* Define if you have the 'inet_pton' function. */
-#define HAVE_INET_PTON 1
-
-/* Define to 1 if you have the `initgroups' function. */
-#define HAVE_INITGROUPS 1
-
-/* Define if your compiler provides int32_t. */
-#define HAVE_INT32_T 1
-
-/* Define if your compiler provides int64_t. */
-#define HAVE_INT64_T 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_IO_H */
-
-/* Define to 1 if you have the `kill' function. */
-#define HAVE_KILL 1
-
-/* Define to 1 if you have the `killpg' function. */
-#define HAVE_KILLPG 1
-
-/* Define if you have the 'kqueue' functions. */
-#define HAVE_KQUEUE 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_LANGINFO_H 1
-
-/* Defined to enable large file support when an off_t is bigger than a long
- and long long is available and at least as big as an off_t. You may need to
- add some flags for configuration and compilation to enable this mode. (For
- Solaris and Linux, the necessary defines are already defined.) */
-/* #undef HAVE_LARGEFILE_SUPPORT */
-
-/* Define to 1 if you have the 'lchflags' function. */
-#define HAVE_LCHFLAGS 1
-
-/* Define to 1 if you have the `lchmod' function. */
-#define HAVE_LCHMOD 1
-
-/* Define to 1 if you have the `lchown' function. */
-#define HAVE_LCHOWN 1
-
-/* Define to 1 if you have the `lgamma' function. */
-#define HAVE_LGAMMA 1
-
-/* Define to 1 if you have the `dl' library (-ldl). */
-#define HAVE_LIBDL 1
-
-/* Define to 1 if you have the `dld' library (-ldld). */
-/* #undef HAVE_LIBDLD */
-
-/* Define to 1 if you have the `ieee' library (-lieee). */
-/* #undef HAVE_LIBIEEE */
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_LIBINTL_H */
-
-/* Define if you have the readline library (-lreadline). */
-#define HAVE_LIBREADLINE 1
-
-/* Define to 1 if you have the `resolv' library (-lresolv). */
-/* #undef HAVE_LIBRESOLV */
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_LIBUTIL_H */
-
-/* Define if you have the 'link' function. */
-#define HAVE_LINK 1
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_LINUX_NETLINK_H */
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_LINUX_TIPC_H */
-
-/* Define to 1 if you have the `log1p' function. */
-#define HAVE_LOG1P 1
-
-/* Define this if you have the type long double. */
-#define HAVE_LONG_DOUBLE 1
-
-/* Define this if you have the type long long. */
-#define HAVE_LONG_LONG 1
-
-/* Define to 1 if you have the `lstat' function. */
-#define HAVE_LSTAT 1
-
-/* Define this if you have the makedev macro. */
-#define HAVE_MAKEDEV 1
-
-/* Define to 1 if you have the `memmove' function. */
-#define HAVE_MEMMOVE 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have the `mkfifo' function. */
-#define HAVE_MKFIFO 1
-
-/* Define to 1 if you have the `mknod' function. */
-#define HAVE_MKNOD 1
-
-/* Define to 1 if you have the `mktime' function. */
-#define HAVE_MKTIME 1
-
-/* Define to 1 if you have the `mmap' function. */
-#define HAVE_MMAP 1
-
-/* Define to 1 if you have the `mremap' function. */
-/* #undef HAVE_MREMAP */
-
-/* Define to 1 if you have the header file. */
-#define HAVE_NCURSES_H 1
-
-/* Define to 1 if you have the header file, and it defines `DIR'. */
-/* #undef HAVE_NDIR_H */
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_NETPACKET_PACKET_H */
-
-/* Define to 1 if you have the `nice' function. */
-#define HAVE_NICE 1
-
-/* Define to 1 if you have the `openpty' function. */
-#define HAVE_OPENPTY 1
-
-/* Define if compiling using MacOS X 10.5 SDK or later. */
-#define HAVE_OSX105_SDK 1
-
-/* Define to 1 if you have the `pathconf' function. */
-#define HAVE_PATHCONF 1
-
-/* Define to 1 if you have the `pause' function. */
-#define HAVE_PAUSE 1
-
-/* Define to 1 if you have the `plock' function. */
-/* #undef HAVE_PLOCK */
-
-/* Define to 1 if you have the `poll' function. */
-#undef HAVE_POLL
-
-/* Define to 1 if you have the header file. */
-#undef HAVE_POLL_H
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_PROCESS_H */
-
-/* Define if your compiler supports function prototype */
-#define HAVE_PROTOTYPES 1
-
-/* Define if you have GNU PTH threads. */
-/* #undef HAVE_PTH */
-
-/* Define to 1 if you have the `pthread_atfork' function. */
-#define HAVE_PTHREAD_ATFORK 1
-
-/* Defined for Solaris 2.6 bug in pthread header. */
-/* #undef HAVE_PTHREAD_DESTRUCTOR */
-
-/* Define to 1 if you have the header file. */
-#define HAVE_PTHREAD_H 1
-
-/* Define to 1 if you have the `pthread_init' function. */
-/* #undef HAVE_PTHREAD_INIT */
-
-/* Define to 1 if you have the `pthread_sigmask' function. */
-#define HAVE_PTHREAD_SIGMASK 1
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_PTY_H */
-
-/* Define to 1 if you have the `putenv' function. */
-#define HAVE_PUTENV 1
-
-/* Define if the libcrypto has RAND_egd */
-#define HAVE_RAND_EGD 1
-
-/* Define to 1 if you have the `readlink' function. */
-#define HAVE_READLINK 1
-
-/* Define to 1 if you have the `realpath' function. */
-#define HAVE_REALPATH 1
-
-/* Define if you have readline 2.1 */
-#define HAVE_RL_CALLBACK 1
-
-/* Define if you can turn off readline's signal handling. */
-#define HAVE_RL_CATCH_SIGNAL 1
-
-/* Define if you have readline 2.2 */
-#define HAVE_RL_COMPLETION_APPEND_CHARACTER 1
-
-/* Define if you have readline 4.0 */
-#define HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK 1
-
-/* Define if you have readline 4.2 */
-#define HAVE_RL_COMPLETION_MATCHES 1
-
-/* Define if you have rl_completion_suppress_append */
-#define HAVE_RL_COMPLETION_SUPPRESS_APPEND 1
-
-/* Define if you have readline 4.0 */
-#define HAVE_RL_PRE_INPUT_HOOK 1
-
-/* Define to 1 if you have the `round' function. */
-#define HAVE_ROUND 1
-
-/* Define to 1 if you have the `select' function. */
-#define HAVE_SELECT 1
-
-/* Define to 1 if you have the `sem_getvalue' function. */
-#define HAVE_SEM_GETVALUE 1
-
-/* Define to 1 if you have the `sem_open' function. */
-#define HAVE_SEM_OPEN 1
-
-/* Define to 1 if you have the `sem_timedwait' function. */
-/* #undef HAVE_SEM_TIMEDWAIT */
-
-/* Define to 1 if you have the `sem_unlink' function. */
-#define HAVE_SEM_UNLINK 1
-
-/* Define to 1 if you have the `setegid' function. */
-#define HAVE_SETEGID 1
-
-/* Define to 1 if you have the `seteuid' function. */
-#define HAVE_SETEUID 1
-
-/* Define to 1 if you have the `setgid' function. */
-#define HAVE_SETGID 1
-
-/* Define if you have the 'setgroups' function. */
-#define HAVE_SETGROUPS 1
-
-/* Define to 1 if you have the `setitimer' function. */
-#define HAVE_SETITIMER 1
-
-/* Define to 1 if you have the `setlocale' function. */
-#define HAVE_SETLOCALE 1
-
-/* Define to 1 if you have the `setpgid' function. */
-#define HAVE_SETPGID 1
-
-/* Define to 1 if you have the `setpgrp' function. */
-#define HAVE_SETPGRP 1
-
-/* Define to 1 if you have the `setregid' function. */
-#define HAVE_SETREGID 1
-
-/* Define to 1 if you have the `setresgid' function. */
-/* #undef HAVE_SETRESGID */
-
-/* Define to 1 if you have the `setresuid' function. */
-/* #undef HAVE_SETRESUID */
-
-/* Define to 1 if you have the `setreuid' function. */
-#define HAVE_SETREUID 1
-
-/* Define to 1 if you have the `setsid' function. */
-#define HAVE_SETSID 1
-
-/* Define to 1 if you have the `setuid' function. */
-#define HAVE_SETUID 1
-
-/* Define to 1 if you have the `setvbuf' function. */
-#define HAVE_SETVBUF 1
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_SHADOW_H */
-
-/* Define to 1 if you have the `sigaction' function. */
-#define HAVE_SIGACTION 1
-
-/* Define to 1 if you have the `siginterrupt' function. */
-#define HAVE_SIGINTERRUPT 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SIGNAL_H 1
-
-/* Define to 1 if you have the `sigrelse' function. */
-#define HAVE_SIGRELSE 1
-
-/* Define to 1 if you have the `snprintf' function. */
-#define HAVE_SNPRINTF 1
-
-/* Define if sockaddr has sa_len member */
-#define HAVE_SOCKADDR_SA_LEN 1
-
-/* struct sockaddr_storage (sys/socket.h) */
-#define HAVE_SOCKADDR_STORAGE 1
-
-/* Define if you have the 'socketpair' function. */
-#define HAVE_SOCKETPAIR 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SPAWN_H 1
-
-/* Define if your compiler provides ssize_t */
-#define HAVE_SSIZE_T 1
-
-/* Define to 1 if you have the `statvfs' function. */
-#define HAVE_STATVFS 1
-
-/* Define if you have struct stat.st_mtim.tv_nsec */
-/* #undef HAVE_STAT_TV_NSEC */
-
-/* Define if you have struct stat.st_mtimensec */
-#define HAVE_STAT_TV_NSEC2 1
-
-/* Define if your compiler supports variable length function prototypes (e.g.
- void fprintf(FILE *, char *, ...);) *and* */
-#define HAVE_STDARG_PROTOTYPES 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the `strdup' function. */
-#define HAVE_STRDUP 1
-
-/* Define to 1 if you have the `strftime' function. */
-#define HAVE_STRFTIME 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_STROPTS_H */
-
-/* Define to 1 if `st_birthtime' is a member of `struct stat'. */
-#define HAVE_STRUCT_STAT_ST_BIRTHTIME 1
-
-/* Define to 1 if `st_blksize' is a member of `struct stat'. */
-#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
-
-/* Define to 1 if `st_blocks' is a member of `struct stat'. */
-#define HAVE_STRUCT_STAT_ST_BLOCKS 1
-
-/* Define to 1 if `st_flags' is a member of `struct stat'. */
-#define HAVE_STRUCT_STAT_ST_FLAGS 1
-
-/* Define to 1 if `st_gen' is a member of `struct stat'. */
-#define HAVE_STRUCT_STAT_ST_GEN 1
-
-/* Define to 1 if `st_rdev' is a member of `struct stat'. */
-#define HAVE_STRUCT_STAT_ST_RDEV 1
-
-/* Define to 1 if `tm_zone' is a member of `struct tm'. */
-#define HAVE_STRUCT_TM_TM_ZONE 1
-
-/* Define to 1 if your `struct stat' has `st_blocks'. Deprecated, use
- `HAVE_STRUCT_STAT_ST_BLOCKS' instead. */
-#define HAVE_ST_BLOCKS 1
-
-/* Define if you have the 'symlink' function. */
-#define HAVE_SYMLINK 1
-
-/* Define to 1 if you have the `sysconf' function. */
-#define HAVE_SYSCONF 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYSEXITS_H 1
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_SYS_AUDIOIO_H */
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_SYS_BSDTTY_H */
-
-/* Define to 1 if you have the header file, and it defines `DIR'.
- */
-/* #undef HAVE_SYS_DIR_H */
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_SYS_EPOLL_H */
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_EVENT_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_FILE_H 1
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_SYS_LOADAVG_H */
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_LOCK_H 1
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_SYS_MKDEV_H */
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_SYS_MODEM_H */
-
-/* Define to 1 if you have the header file, and it defines `DIR'.
- */
-/* #undef HAVE_SYS_NDIR_H */
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_PARAM_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_POLL_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_RESOURCE_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_SELECT_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_SOCKET_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_STATVFS_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_SYS_TERMIO_H */
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_TIMES_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_TIME_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_UN_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_UTSNAME_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_WAIT_H 1
-
-/* Define to 1 if you have the `tcgetpgrp' function. */
-#define HAVE_TCGETPGRP 1
-
-/* Define to 1 if you have the `tcsetpgrp' function. */
-#define HAVE_TCSETPGRP 1
-
-/* Define to 1 if you have the `tempnam' function. */
-#define HAVE_TEMPNAM 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_TERMIOS_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_TERM_H 1
-
-/* Define to 1 if you have the `tgamma' function. */
-#define HAVE_TGAMMA 1
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_THREAD_H */
-
-/* Define to 1 if you have the `timegm' function. */
-#define HAVE_TIMEGM 1
-
-/* Define to 1 if you have the `times' function. */
-#define HAVE_TIMES 1
-
-/* Define to 1 if you have the `tmpfile' function. */
-#define HAVE_TMPFILE 1
-
-/* Define to 1 if you have the `tmpnam' function. */
-#define HAVE_TMPNAM 1
-
-/* Define to 1 if you have the `tmpnam_r' function. */
-/* #undef HAVE_TMPNAM_R */
-
-/* Define to 1 if your `struct tm' has `tm_zone'. Deprecated, use
- `HAVE_STRUCT_TM_TM_ZONE' instead. */
-#define HAVE_TM_ZONE 1
-
-/* Define to 1 if you have the `truncate' function. */
-#define HAVE_TRUNCATE 1
-
-/* Define to 1 if you don't have `tm_zone' but do have the external array
- `tzname'. */
-/* #undef HAVE_TZNAME */
-
-/* Define this if you have tcl and TCL_UTF_MAX==6 */
-/* #undef HAVE_UCS4_TCL */
-
-/* Define if your compiler provides uint32_t. */
-#define HAVE_UINT32_T 1
-
-/* Define if your compiler provides uint64_t. */
-#define HAVE_UINT64_T 1
-
-/* Define to 1 if the system has the type `uintptr_t'. */
-#define HAVE_UINTPTR_T 1
-
-/* Define to 1 if you have the `uname' function. */
-#define HAVE_UNAME 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_UNISTD_H 1
-
-/* Define to 1 if you have the `unsetenv' function. */
-#define HAVE_UNSETENV 1
-
-/* Define if you have a useable wchar_t type defined in wchar.h; useable means
- wchar_t must be an unsigned type with at least 16 bits. (see
- Include/unicodeobject.h). */
-/* #undef HAVE_USABLE_WCHAR_T */
-
-/* Define to 1 if you have the header file. */
-#define HAVE_UTIL_H 1
-
-/* Define to 1 if you have the `utimes' function. */
-#define HAVE_UTIMES 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_UTIME_H 1
-
-/* Define to 1 if you have the `wait3' function. */
-#define HAVE_WAIT3 1
-
-/* Define to 1 if you have the `wait4' function. */
-#define HAVE_WAIT4 1
-
-/* Define to 1 if you have the `waitpid' function. */
-#define HAVE_WAITPID 1
-
-/* Define if the compiler provides a wchar.h header file. */
-#define HAVE_WCHAR_H 1
-
-/* Define to 1 if you have the `wcscoll' function. */
-#define HAVE_WCSCOLL 1
-
-/* Define if tzset() actually switches the local timezone in a meaningful way.
- */
-#define HAVE_WORKING_TZSET 1
-
-/* Define if the zlib library has inflateCopy */
-#define HAVE_ZLIB_COPY 1
-
-/* Define to 1 if you have the `_getpty' function. */
-/* #undef HAVE__GETPTY */
-
-/* Define if you are using Mach cthreads directly under /include */
-/* #undef HURD_C_THREADS */
-
-/* Define if you are using Mach cthreads under mach / */
-/* #undef MACH_C_THREADS */
-
-/* Define to 1 if `major', `minor', and `makedev' are declared in .
- */
-/* #undef MAJOR_IN_MKDEV */
-
-/* Define to 1 if `major', `minor', and `makedev' are declared in
- . */
-/* #undef MAJOR_IN_SYSMACROS */
-
-/* Define if mvwdelch in curses.h is an expression. */
-#define MVWDELCH_IS_EXPRESSION 1
-
-/* Define to the address where bug reports for this package should be sent. */
-/* #undef PACKAGE_BUGREPORT */
-
-/* Define to the full name of this package. */
-/* #undef PACKAGE_NAME */
-
-/* Define to the full name and version of this package. */
-/* #undef PACKAGE_STRING */
-
-/* Define to the one symbol short name of this package. */
-/* #undef PACKAGE_TARNAME */
-
-/* Define to the home page for this package. */
-/* #undef PACKAGE_URL */
-
-/* Define to the version of this package. */
-/* #undef PACKAGE_VERSION */
-
-/* Define if POSIX semaphores aren't enabled on your system */
-/* #undef POSIX_SEMAPHORES_NOT_ENABLED */
-
-/* Defined if PTHREAD_SCOPE_SYSTEM supported. */
-#define PTHREAD_SYSTEM_SCHED_SUPPORTED 1
-
-/* Define as the preferred size in bits of long digits */
-/* #undef PYLONG_BITS_IN_DIGIT */
-
-/* Define to printf format modifier for long long type */
-#define PY_FORMAT_LONG_LONG "ll"
-
-/* Define to printf format modifier for Py_ssize_t */
-#define PY_FORMAT_SIZE_T "z"
-
-/* Define as the integral type used for Unicode representation. */
-#define PY_UNICODE_TYPE unsigned short
-
-/* Define if you want to build an interpreter with many run-time checks. */
-/* #undef Py_DEBUG */
-
-/* Defined if Python is built as a shared library. */
-/* #undef Py_ENABLE_SHARED */
-
-/* Define as the size of the unicode type. */
-#define Py_UNICODE_SIZE 2
-
-/* Define if you want to have a Unicode type. */
-#define Py_USING_UNICODE 1
-
-/* assume C89 semantics that RETSIGTYPE is always void */
-#define RETSIGTYPE void
-
-/* Define if setpgrp() must be called as setpgrp(0, 0). */
-/* #undef SETPGRP_HAVE_ARG */
-
-/* Define this to be extension of shared libraries (including the dot!). */
-#define SHLIB_EXT ".so"
-
-/* Define if i>>j for signed int i does not extend the sign bit when i < 0 */
-/* #undef SIGNED_RIGHT_SHIFT_ZERO_FILLS */
-
-/* The size of `double', as computed by sizeof. */
-#define SIZEOF_DOUBLE 8
-
-/* The size of `float', as computed by sizeof. */
-#define SIZEOF_FLOAT 4
-
-/* The size of `fpos_t', as computed by sizeof. */
-#define SIZEOF_FPOS_T 8
-
-/* The size of `int', as computed by sizeof. */
-#define SIZEOF_INT 4
-
-/* The size of `long', as computed by sizeof. */
-#define SIZEOF_LONG 8
-
-/* The size of `long double', as computed by sizeof. */
-#define SIZEOF_LONG_DOUBLE 16
-
-/* The size of `long long', as computed by sizeof. */
-#define SIZEOF_LONG_LONG 8
-
-/* The size of `off_t', as computed by sizeof. */
-#define SIZEOF_OFF_T 8
-
-/* The size of `pid_t', as computed by sizeof. */
-#define SIZEOF_PID_T 4
-
-/* The size of `pthread_t', as computed by sizeof. */
-#define SIZEOF_PTHREAD_T 8
-
-/* The size of `short', as computed by sizeof. */
-#define SIZEOF_SHORT 2
-
-/* The size of `size_t', as computed by sizeof. */
-#define SIZEOF_SIZE_T 8
-
-/* The size of `time_t', as computed by sizeof. */
-#define SIZEOF_TIME_T 8
-
-/* The size of `uintptr_t', as computed by sizeof. */
-#define SIZEOF_UINTPTR_T 8
-
-/* The size of `void *', as computed by sizeof. */
-#define SIZEOF_VOID_P 8
-
-/* The size of `wchar_t', as computed by sizeof. */
-#define SIZEOF_WCHAR_T 4
-
-/* The size of `_Bool', as computed by sizeof. */
-#define SIZEOF__BOOL 1
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Define if you can safely include both and
- (which you can't on SCO ODT 3.0). */
-#define SYS_SELECT_WITH_SYS_TIME 1
-
-/* Define if tanh(-0.) is -0., or if platform doesn't have signed zeros */
-#define TANH_PRESERVES_ZERO_SIGN 1
-
-/* Define to 1 if you can safely include both and . */
-#define TIME_WITH_SYS_TIME 1
-
-/* Define to 1 if your declares `struct tm'. */
-/* #undef TM_IN_SYS_TIME */
-
-/* Enable extensions on AIX 3, Interix. */
-#ifndef _ALL_SOURCE
-# define _ALL_SOURCE 1
-#endif
-/* Enable GNU extensions on systems that have them. */
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE 1
-#endif
-/* Enable threading extensions on Solaris. */
-#ifndef _POSIX_PTHREAD_SEMANTICS
-# define _POSIX_PTHREAD_SEMANTICS 1
-#endif
-/* Enable extensions on HP NonStop. */
-#ifndef _TANDEM_SOURCE
-# define _TANDEM_SOURCE 1
-#endif
-/* Enable general extensions on Solaris. */
-#ifndef __EXTENSIONS__
-# define __EXTENSIONS__ 1
-#endif
-
-
-/* Define if you want to use MacPython modules on MacOSX in unix-Python. */
-#define USE_TOOLBOX_OBJECT_GLUE 1
-
-/* Define if a va_list is an array of some kind */
-#define VA_LIST_IS_ARRAY 1
-
-/* Define if you want SIGFPE handled (see Include/pyfpe.h). */
-/* #undef WANT_SIGFPE_HANDLER */
-
-/* Define if you want wctype.h functions to be used instead of the one
- supplied by Python itself. (see Include/unicodectype.h). */
-/* #undef WANT_WCTYPE_FUNCTIONS */
-
-/* Define if WINDOW in curses.h offers a field _flags. */
-/* #undef WINDOW_HAS_FLAGS */
-
-/* Define if you want documentation strings in extension modules */
-#define WITH_DOC_STRINGS 1
-
-/* Define if you want to use the new-style (Openstep, Rhapsody, MacOS) dynamic
- linker (dyld) instead of the old-style (NextStep) dynamic linker (rld).
- Dyld is necessary to support frameworks. */
-#define WITH_DYLD 1
-
-/* Define to 1 if libintl is needed for locale functions. */
-/* #undef WITH_LIBINTL */
-
-/* Define if you want to produce an OpenStep/Rhapsody framework (shared
- library plus accessory files). */
-#define WITH_NEXT_FRAMEWORK 1
-
-/* Define if you want to compile in Python-specific mallocs */
-#define WITH_PYMALLOC 1
-
-/* Define if you want to compile in rudimentary thread support */
-#define WITH_THREAD 1
-
-/* Define to profile with the Pentium timestamp counter */
-/* #undef WITH_TSC */
-
-/* Define if you want pymalloc to be disabled when running under valgrind */
-/* #undef WITH_VALGRIND */
-
-/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
- significant byte first (like Motorola and SPARC, unlike Intel). */
-#if defined AC_APPLE_UNIVERSAL_BUILD
-# if defined __BIG_ENDIAN__
-# define WORDS_BIGENDIAN 1
-# endif
-#else
-# ifndef WORDS_BIGENDIAN
-/* # undef WORDS_BIGENDIAN */
-# endif
-#endif
-
-/* Define if arithmetic is subject to x87-style double rounding issue */
-/* #undef X87_DOUBLE_ROUNDING */
-
-/* Define on OpenBSD to activate all library features */
-/* #undef _BSD_SOURCE */
-
-/* Define on Irix to enable u_int */
-#define _BSD_TYPES 1
-
-/* Define on Darwin to activate all library features */
-#define _DARWIN_C_SOURCE 1
-
-/* This must be set to 64 on some systems to enable large file support. */
-#define _FILE_OFFSET_BITS 64
-
-/* Define on Linux to activate all library features */
-#define _GNU_SOURCE 1
-
-/* This must be defined on some systems to enable large file support. */
-#define _LARGEFILE_SOURCE 1
-
-/* This must be defined on AIX systems to enable large file support. */
-/* #undef _LARGE_FILES */
-
-/* Define to 1 if on MINIX. */
-/* #undef _MINIX */
-
-/* Define on NetBSD to activate all library features */
-#define _NETBSD_SOURCE 1
-
-/* Define _OSF_SOURCE to get the makedev macro. */
-/* #undef _OSF_SOURCE */
-
-/* Define to 2 if the system does not provide POSIX.1 features except with
- this defined. */
-/* #undef _POSIX_1_SOURCE */
-
-/* Define to activate features from IEEE Stds 1003.1-2001 */
-/* #undef _POSIX_C_SOURCE */
-
-/* Define to 1 if you need to in order for `stat' and other things to work. */
-/* #undef _POSIX_SOURCE */
-
-/* Define if you have POSIX threads, and your system does not define that. */
-/* #undef _POSIX_THREADS */
-
-/* Define to force use of thread-safe errno, h_errno, and other functions */
-#define _REENTRANT 1
-
-/* Define for Solaris 2.5.1 so the uint32_t typedef from ,
- , or is not used. If the typedef were allowed, the
- #define below would cause a syntax error. */
-/* #undef _UINT32_T */
-
-/* Define for Solaris 2.5.1 so the uint64_t typedef from ,
- , or is not used. If the typedef were allowed, the
- #define below would cause a syntax error. */
-/* #undef _UINT64_T */
-
-/* Define to the level of X/Open that your system supports */
-/* #undef _XOPEN_SOURCE */
-
-/* Define to activate Unix95-and-earlier features */
-/* #undef _XOPEN_SOURCE_EXTENDED */
-
-/* Define on FreeBSD to activate all library features */
-#define __BSD_VISIBLE 1
-
-/* Define to 1 if type `char' is unsigned and you are not using gcc. */
-#ifndef __CHAR_UNSIGNED__
-/* # undef __CHAR_UNSIGNED__ */
-#endif
-
-/* Defined on Solaris to see additional function prototypes. */
-#define __EXTENSIONS__ 1
-
-/* Define to 'long' if doesn't define. */
-/* #undef clock_t */
-
-/* Define to empty if `const' does not conform to ANSI C. */
-/* #undef const */
-
-/* Define to `int' if doesn't define. */
-/* #undef gid_t */
-
-/* Define to the type of a signed integer type of width exactly 32 bits if
- such a type exists and the standard includes do not define it. */
-/* #undef int32_t */
-
-/* Define to the type of a signed integer type of width exactly 64 bits if
- such a type exists and the standard includes do not define it. */
-/* #undef int64_t */
-
-/* Define to `int' if does not define. */
-/* #undef mode_t */
-
-/* Define to `long int' if does not define. */
-/* #undef off_t */
-
-/* Define to `int' if does not define. */
-/* #undef pid_t */
-
-/* Define to empty if the keyword does not work. */
-/* #undef signed */
-
-/* Define to `unsigned int' if does not define. */
-/* #undef size_t */
-
-/* Define to `int' if does not define. */
-/* #undef socklen_t */
-
-/* Define to `int' if doesn't define. */
-/* #undef uid_t */
-
-/* Define to the type of an unsigned integer type of width exactly 32 bits if
- such a type exists and the standard includes do not define it. */
-/* #undef uint32_t */
-
-/* Define to the type of an unsigned integer type of width exactly 64 bits if
- such a type exists and the standard includes do not define it. */
-/* #undef uint64_t */
-
-/* Define to empty if the keyword does not work. */
-/* #undef volatile */
-
-
-/* Define the macros needed if on a UnixWare 7.x system. */
-#if defined(__USLC__) && defined(__SCO_VERSION__)
-#define STRICT_SYSV_CURSES /* Don't use ncurses extensions */
-#endif
-
-#endif /*Py_PYCONFIG_H*/
-
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/MacOS.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/MacOS.so
deleted file mode 100644
index 3019555..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/MacOS.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/Nav.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/Nav.so
deleted file mode 100644
index 2d16cb5..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/Nav.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/PIL/_imaging.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/PIL/_imaging.so
deleted file mode 100644
index 412b9cc..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/PIL/_imaging.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_AE.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_AE.so
deleted file mode 100644
index f6fc846..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_AE.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_Ctl.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_Ctl.so
deleted file mode 100644
index af8fe2b..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_Ctl.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_Dlg.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_Dlg.so
deleted file mode 100644
index 9259b3e..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_Dlg.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_Evt.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_Evt.so
deleted file mode 100644
index 02bdbef..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_Evt.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_File.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_File.so
deleted file mode 100644
index 769fa02..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_File.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_Menu.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_Menu.so
deleted file mode 100644
index d6a20c4..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_Menu.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_Qd.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_Qd.so
deleted file mode 100644
index eff8cb1..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_Qd.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_Res.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_Res.so
deleted file mode 100644
index 033b739..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_Res.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_Win.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_Win.so
deleted file mode 100644
index aae5e21..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_Win.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_bisect.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_bisect.so
deleted file mode 100644
index f31813e..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_bisect.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_codecs_cn.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_codecs_cn.so
deleted file mode 100644
index e9d6194..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_codecs_cn.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_codecs_hk.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_codecs_hk.so
deleted file mode 100644
index e406d73..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_codecs_hk.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_codecs_iso2022.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_codecs_iso2022.so
deleted file mode 100644
index 687a325..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_codecs_iso2022.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_codecs_jp.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_codecs_jp.so
deleted file mode 100644
index 243c9af..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_codecs_jp.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_codecs_kr.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_codecs_kr.so
deleted file mode 100644
index 8028858..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_codecs_kr.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_codecs_tw.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_codecs_tw.so
deleted file mode 100644
index 77a16a5..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_codecs_tw.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_collections.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_collections.so
deleted file mode 100644
index 7ef572d..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_collections.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_csv.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_csv.so
deleted file mode 100644
index 1f71866..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_csv.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_ctypes.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_ctypes.so
deleted file mode 100644
index f8e375b..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_ctypes.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_curses.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_curses.so
deleted file mode 100644
index 5094d8c..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_curses.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_elementtree.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_elementtree.so
deleted file mode 100644
index 81e0763..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_elementtree.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_functools.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_functools.so
deleted file mode 100644
index 4f3bc71..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_functools.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_hashlib.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_hashlib.so
deleted file mode 100644
index 9c1b9c5..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_hashlib.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_heapq.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_heapq.so
deleted file mode 100644
index 58a867a..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_heapq.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_io.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_io.so
deleted file mode 100644
index 6bbd39c..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_io.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_json.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_json.so
deleted file mode 100644
index 9272416..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_json.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_locale.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_locale.so
deleted file mode 100644
index 62cc0ff..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_locale.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_lsprof.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_lsprof.so
deleted file mode 100644
index 11dc81b..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_lsprof.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_multibytecodec.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_multibytecodec.so
deleted file mode 100644
index d1869e5..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_multibytecodec.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_multiprocessing.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_multiprocessing.so
deleted file mode 100644
index ae31e72..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_multiprocessing.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_random.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_random.so
deleted file mode 100644
index 2e0a5b3..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_random.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_scproxy.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_scproxy.so
deleted file mode 100644
index 3d5bf91..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_scproxy.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_socket.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_socket.so
deleted file mode 100644
index 3232d15..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_socket.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_sqlite3.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_sqlite3.so
deleted file mode 100644
index 8930d28..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_sqlite3.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_ssl.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_ssl.so
deleted file mode 100644
index 3d32996..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_ssl.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_struct.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_struct.so
deleted file mode 100644
index daf2e1a..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_struct.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_tkinter.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_tkinter.so
deleted file mode 100644
index 84b27ba..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/_tkinter.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/array.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/array.so
deleted file mode 100644
index 5783a47..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/array.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/binascii.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/binascii.so
deleted file mode 100644
index bb060d0..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/binascii.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/bz2.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/bz2.so
deleted file mode 100644
index 48d2c8d..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/bz2.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/cPickle.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/cPickle.so
deleted file mode 100644
index baa2744..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/cPickle.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/cStringIO.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/cStringIO.so
deleted file mode 100644
index d4172e2..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/cStringIO.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/datetime.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/datetime.so
deleted file mode 100644
index aaa5db5..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/datetime.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/dbm.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/dbm.so
deleted file mode 100644
index d9c67e3..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/dbm.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/fcntl.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/fcntl.so
deleted file mode 100644
index d8bfa36..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/fcntl.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/future_builtins.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/future_builtins.so
deleted file mode 100644
index d777f41..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/future_builtins.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/gdbm.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/gdbm.so
deleted file mode 100644
index c7b67c6..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/gdbm.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/gestalt.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/gestalt.so
deleted file mode 100644
index 57b4042..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/gestalt.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/grp.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/grp.so
deleted file mode 100644
index f51cc13..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/grp.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/itertools.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/itertools.so
deleted file mode 100644
index 451e44e..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/itertools.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/lxml/etree.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/lxml/etree.so
deleted file mode 100644
index 1e84a56..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/lxml/etree.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/math.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/math.so
deleted file mode 100644
index 3fbba8f..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/math.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/mmap.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/mmap.so
deleted file mode 100644
index 519961e..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/mmap.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/numexpr/interpreter.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/numexpr/interpreter.so
deleted file mode 100644
index 83ce242..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/numexpr/interpreter.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/operator.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/operator.so
deleted file mode 100644
index 2e89b05..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/operator.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pandas/_period.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pandas/_period.so
deleted file mode 100644
index a609aba..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pandas/_period.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pandas/_sparse.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pandas/_sparse.so
deleted file mode 100644
index b035edf..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pandas/_sparse.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pandas/_testing.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pandas/_testing.so
deleted file mode 100644
index 0781373..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pandas/_testing.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pandas/algos.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pandas/algos.so
deleted file mode 100644
index 54ef262..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pandas/algos.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pandas/hashtable.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pandas/hashtable.so
deleted file mode 100644
index c1bc2f6..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pandas/hashtable.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pandas/index.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pandas/index.so
deleted file mode 100644
index 9694d6b..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pandas/index.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pandas/json.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pandas/json.so
deleted file mode 100644
index 2809341..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pandas/json.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pandas/lib.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pandas/lib.so
deleted file mode 100644
index 2668a59..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pandas/lib.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pandas/msgpack.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pandas/msgpack.so
deleted file mode 100644
index 0e88bda..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pandas/msgpack.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pandas/parser.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pandas/parser.so
deleted file mode 100644
index ac42b16..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pandas/parser.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pandas/tslib.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pandas/tslib.so
deleted file mode 100644
index 09d7d16..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pandas/tslib.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/parser.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/parser.so
deleted file mode 100644
index dccf965..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/parser.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pyexpat.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pyexpat.so
deleted file mode 100644
index b06aa22..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/pyexpat.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/resource.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/resource.so
deleted file mode 100644
index 671f359..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/resource.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/select.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/select.so
deleted file mode 100644
index 2842d1a..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/select.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/strop.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/strop.so
deleted file mode 100644
index 9b6389a..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/strop.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/termios.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/termios.so
deleted file mode 100644
index 9bf6310..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/termios.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/time.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/time.so
deleted file mode 100644
index 22566c1..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/time.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/unicodedata.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/unicodedata.so
deleted file mode 100644
index 6ef2545..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/unicodedata.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/urwid/str_util.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/urwid/str_util.so
deleted file mode 100644
index 9dc5f26..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/urwid/str_util.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/zlib.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/zlib.so
deleted file mode 100644
index 18a1d40..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/lib-dynload/zlib.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/.dylibs/libfreetype.6.dylib b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/.dylibs/libfreetype.6.dylib
deleted file mode 100755
index abe3c2e..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/.dylibs/libfreetype.6.dylib and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/.dylibs/libpng16.16.dylib b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/.dylibs/libpng16.16.dylib
deleted file mode 100755
index ac9a187..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/.dylibs/libpng16.16.dylib and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/.dylibs/libz.1.2.8.dylib b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/.dylibs/libz.1.2.8.dylib
deleted file mode 100755
index 89a6b35..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/.dylibs/libz.1.2.8.dylib and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/__init__.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/__init__.py
deleted file mode 100644
index c172709..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/__init__.py
+++ /dev/null
@@ -1,1469 +0,0 @@
-"""
-This is an object-oriented plotting library.
-
-A procedural interface is provided by the companion pyplot module,
-which may be imported directly, e.g.::
-
- import matplotlib.pyplot as plt
-
-or using ipython::
-
- ipython
-
-at your terminal, followed by::
-
- In [1]: %matplotlib
- In [2]: import matplotlib.pyplot as plt
-
-at the ipython shell prompt.
-
-For the most part, direct use of the object-oriented library is
-encouraged when programming; pyplot is primarily for working
-interactively. The
-exceptions are the pyplot commands :func:`~matplotlib.pyplot.figure`,
-:func:`~matplotlib.pyplot.subplot`,
-:func:`~matplotlib.pyplot.subplots`, and
-:func:`~pyplot.savefig`, which can greatly simplify scripting.
-
-Modules include:
-
- :mod:`matplotlib.axes`
- defines the :class:`~matplotlib.axes.Axes` class. Most pylab
- commands are wrappers for :class:`~matplotlib.axes.Axes`
- methods. The axes module is the highest level of OO access to
- the library.
-
- :mod:`matplotlib.figure`
- defines the :class:`~matplotlib.figure.Figure` class.
-
- :mod:`matplotlib.artist`
- defines the :class:`~matplotlib.artist.Artist` base class for
- all classes that draw things.
-
- :mod:`matplotlib.lines`
- defines the :class:`~matplotlib.lines.Line2D` class for
- drawing lines and markers
-
- :mod:`matplotlib.patches`
- defines classes for drawing polygons
-
- :mod:`matplotlib.text`
- defines the :class:`~matplotlib.text.Text`,
- :class:`~matplotlib.text.TextWithDash`, and
- :class:`~matplotlib.text.Annotate` classes
-
- :mod:`matplotlib.image`
- defines the :class:`~matplotlib.image.AxesImage` and
- :class:`~matplotlib.image.FigureImage` classes
-
- :mod:`matplotlib.collections`
- classes for efficient drawing of groups of lines or polygons
-
- :mod:`matplotlib.colors`
- classes for interpreting color specifications and for making
- colormaps
-
- :mod:`matplotlib.cm`
- colormaps and the :class:`~matplotlib.image.ScalarMappable`
- mixin class for providing color mapping functionality to other
- classes
-
- :mod:`matplotlib.ticker`
- classes for calculating tick mark locations and for formatting
- tick labels
-
- :mod:`matplotlib.backends`
- a subpackage with modules for various gui libraries and output
- formats
-
-The base matplotlib namespace includes:
-
- :data:`~matplotlib.rcParams`
- a global dictionary of default configuration settings. It is
- initialized by code which may be overridded by a matplotlibrc
- file.
-
- :func:`~matplotlib.rc`
- a function for setting groups of rcParams values
-
- :func:`~matplotlib.use`
- a function for setting the matplotlib backend. If used, this
- function must be called immediately after importing matplotlib
- for the first time. In particular, it must be called
- **before** importing pylab (if pylab is imported).
-
-matplotlib was initially written by John D. Hunter (1968-2012) and is now
-developed and maintained by a host of others.
-
-Occasionally the internal documentation (python docstrings) will refer
-to MATLAB®, a registered trademark of The MathWorks, Inc.
-
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-import sys
-import distutils.version
-from itertools import chain
-
-__version__ = str('1.4.3')
-__version__numpy__ = str('1.6') # minimum required numpy version
-
-try:
- import dateutil
-except ImportError:
- raise ImportError("matplotlib requires dateutil")
-
-def compare_versions(a, b):
- "return True if a is greater than or equal to b"
- if a:
- if six.PY3:
- if isinstance(a, bytes):
- a = a.decode('ascii')
- if isinstance(b, bytes):
- b = b.decode('ascii')
- a = distutils.version.LooseVersion(a)
- b = distutils.version.LooseVersion(b)
- return a >= b
- else:
- return False
-
-if not compare_versions(six.__version__, '1.3'):
- raise ImportError(
- 'six 1.3 or later is required; you have %s' % (
- six.__version__))
-
-try:
- import pyparsing
-except ImportError:
- raise ImportError("matplotlib requires pyparsing")
-else:
- if not compare_versions(pyparsing.__version__, '1.5.6'):
- raise ImportError(
- "matplotlib requires pyparsing >= 1.5.6")
-
- # pyparsing 2.0.0 bug, but it may be patched in distributions
- try:
- f = pyparsing.Forward()
- f <<= pyparsing.Literal('a')
- bad_pyparsing = f is None
- except TypeError:
- bad_pyparsing = True
-
- # pyparsing 1.5.6 does not have <<= on the Forward class, but
- # pyparsing 2.0.0 and later will spew deprecation warnings if
- # using << instead. Additionally, the <<= in pyparsing 1.5.7 is
- # broken, since it doesn't return self. In order to support
- # pyparsing 1.5.6 and above with a common code base, this small
- # monkey patch is applied.
- if bad_pyparsing:
- def _forward_ilshift(self, other):
- self.__lshift__(other)
- return self
- pyparsing.Forward.__ilshift__ = _forward_ilshift
-
-try:
- from urllib.request import urlopen
-except ImportError:
- from urllib2 import urlopen
-
-import os
-import re
-import tempfile
-import warnings
-import contextlib
-import distutils.sysconfig
-
-# cbook must import matplotlib only within function
-# definitions, so it is safe to import from it here.
-from matplotlib.cbook import is_string_like
-from matplotlib.compat import subprocess
-
-try:
- reload
-except NameError:
- # Python 3
- from imp import reload
-
-
-if not hasattr(sys, 'argv'): # for modpython
- sys.argv = [str('modpython')]
-
-
-from matplotlib.rcsetup import (defaultParams,
- validate_backend)
-
-major, minor1, minor2, s, tmp = sys.version_info
-_python24 = (major == 2 and minor1 >= 4) or major >= 3
-
-# the havedate check was a legacy from old matplotlib which preceeded
-# datetime support
-_havedate = True
-
-#try:
-# import pkg_resources # pkg_resources is part of setuptools
-#except ImportError: _have_pkg_resources = False
-#else: _have_pkg_resources = True
-
-if not _python24:
- raise ImportError('matplotlib requires Python 2.4 or later')
-
-
-import numpy
-if not compare_versions(numpy.__version__, __version__numpy__):
- raise ImportError(
- 'numpy %s or later is required; you have %s' % (
- __version__numpy__, numpy.__version__))
-
-
-def _is_writable_dir(p):
- """
- p is a string pointing to a putative writable dir -- return True p
- is such a string, else False
- """
- try:
- p + '' # test is string like
- except TypeError:
- return False
-
- # Test whether the operating system thinks it's a writable directory.
- # Note that this check is necessary on Google App Engine, because the
- # subsequent check will succeed even though p may not be writable.
- if not os.access(p, os.W_OK) or not os.path.isdir(p):
- return False
-
- # Also test that it is actually possible to write to a file here.
- try:
- t = tempfile.TemporaryFile(dir=p)
- try:
- t.write(b'1')
- finally:
- t.close()
- except OSError:
- return False
-
- return True
-
-
-class Verbose:
- """
- A class to handle reporting. Set the fileo attribute to any file
- instance to handle the output. Default is sys.stdout
- """
- levels = ('silent', 'helpful', 'debug', 'debug-annoying')
- vald = dict( [(level, i) for i,level in enumerate(levels)])
-
- # parse the verbosity from the command line; flags look like
- # --verbose-silent or --verbose-helpful
- _commandLineVerbose = None
-
- for arg in sys.argv[1:]:
- # cast to str because we are using unicode_literals,
- # and argv is always str
- if not arg.startswith(str('--verbose-')):
- continue
- level_str = arg[10:]
- # If it doesn't match one of ours, then don't even
- # bother noting it, we are just a 3rd-party library
- # to somebody else's script.
- if level_str in levels:
- _commandLineVerbose = level_str
-
- def __init__(self):
- self.set_level('silent')
- self.fileo = sys.stdout
-
- def set_level(self, level):
- 'set the verbosity to one of the Verbose.levels strings'
-
- if self._commandLineVerbose is not None:
- level = self._commandLineVerbose
- if level not in self.levels:
- warnings.warn('matplotlib: unrecognized --verbose-* string "%s".'
- ' Legal values are %s' % (level, self.levels))
- else:
- self.level = level
-
- def set_fileo(self, fname):
- std = {
- 'sys.stdout': sys.stdout,
- 'sys.stderr': sys.stderr,
- }
- if fname in std:
- self.fileo = std[fname]
- else:
- try:
- fileo = open(fname, 'w')
- except IOError:
- raise ValueError('Verbose object could not open log file "%s" for writing.\nCheck your matplotlibrc verbose.fileo setting'%fname)
- else:
- self.fileo = fileo
-
- def report(self, s, level='helpful'):
- """
- print message s to self.fileo if self.level>=level. Return
- value indicates whether a message was issued
-
- """
- if self.ge(level):
- print(s, file=self.fileo)
- return True
- return False
-
- def wrap(self, fmt, func, level='helpful', always=True):
- """
- return a callable function that wraps func and reports it
- output through the verbose handler if current verbosity level
- is higher than level
-
- if always is True, the report will occur on every function
- call; otherwise only on the first time the function is called
- """
- assert six.callable(func)
- def wrapper(*args, **kwargs):
- ret = func(*args, **kwargs)
-
- if (always or not wrapper._spoke):
- spoke = self.report(fmt%ret, level)
- if not wrapper._spoke: wrapper._spoke = spoke
- return ret
- wrapper._spoke = False
- wrapper.__doc__ = func.__doc__
- return wrapper
-
- def ge(self, level):
- 'return true if self.level is >= level'
- return self.vald[self.level]>=self.vald[level]
-
-
-verbose=Verbose()
-
-
-
-def checkdep_dvipng():
- try:
- s = subprocess.Popen(['dvipng','-version'], stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- stdout, stderr = s.communicate()
- line = stdout.decode('ascii').split('\n')[1]
- v = line.split()[-1]
- return v
- except (IndexError, ValueError, OSError):
- return None
-
-def checkdep_ghostscript():
- if sys.platform == 'win32':
- gs_execs = ['gswin32c', 'gswin64c', 'gs']
- else:
- gs_execs = ['gs']
- for gs_exec in gs_execs:
- try:
- s = subprocess.Popen(
- [gs_exec, '--version'], stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- stdout, stderr = s.communicate()
- if s.returncode == 0:
- v = stdout[:-1].decode('ascii')
- return gs_exec, v
- except (IndexError, ValueError, OSError):
- pass
- return None, None
-
-def checkdep_tex():
- try:
- s = subprocess.Popen(['tex','-version'], stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- stdout, stderr = s.communicate()
- line = stdout.decode('ascii').split('\n')[0]
- pattern = '3\.1\d+'
- match = re.search(pattern, line)
- v = match.group(0)
- return v
- except (IndexError, ValueError, AttributeError, OSError):
- return None
-
-def checkdep_pdftops():
- try:
- s = subprocess.Popen(['pdftops','-v'], stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- stdout, stderr = s.communicate()
- lines = stderr.decode('ascii').split('\n')
- for line in lines:
- if 'version' in line:
- v = line.split()[-1]
- return v
- except (IndexError, ValueError, UnboundLocalError, OSError):
- return None
-
-def checkdep_inkscape():
- try:
- s = subprocess.Popen(['inkscape','-V'], stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- stdout, stderr = s.communicate()
- lines = stdout.decode('ascii').split('\n')
- for line in lines:
- if 'Inkscape' in line:
- v = line.split()[1]
- break
- return v
- except (IndexError, ValueError, UnboundLocalError, OSError):
- return None
-
-def checkdep_xmllint():
- try:
- s = subprocess.Popen(['xmllint','--version'], stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- stdout, stderr = s.communicate()
- lines = stderr.decode('ascii').split('\n')
- for line in lines:
- if 'version' in line:
- v = line.split()[-1]
- break
- return v
- except (IndexError, ValueError, UnboundLocalError, OSError):
- return None
-
-def checkdep_ps_distiller(s):
- if not s:
- return False
-
- flag = True
- gs_req = '7.07'
- gs_sugg = '7.07'
- gs_exec, gs_v = checkdep_ghostscript()
- if compare_versions(gs_v, gs_sugg): pass
- elif compare_versions(gs_v, gs_req):
- verbose.report(('ghostscript-%s found. ghostscript-%s or later '
- 'is recommended to use the ps.usedistiller option.') % (gs_v, gs_sugg))
- else:
- flag = False
- warnings.warn(('matplotlibrc ps.usedistiller option can not be used '
- 'unless ghostscript-%s or later is installed on your system') % gs_req)
-
- if s == 'xpdf':
- pdftops_req = '3.0'
- pdftops_req_alt = '0.9' # poppler version numbers, ugh
- pdftops_v = checkdep_pdftops()
- if compare_versions(pdftops_v, pdftops_req):
- pass
- elif compare_versions(pdftops_v, pdftops_req_alt) and not \
- compare_versions(pdftops_v, '1.0'):
- pass
- else:
- flag = False
- warnings.warn(('matplotlibrc ps.usedistiller can not be set to '
- 'xpdf unless xpdf-%s or later is installed on your system') % pdftops_req)
-
- if flag:
- return s
- else:
- return False
-
-def checkdep_usetex(s):
- if not s:
- return False
-
- tex_req = '3.1415'
- gs_req = '7.07'
- gs_sugg = '7.07'
- dvipng_req = '1.5'
- flag = True
-
- tex_v = checkdep_tex()
- if compare_versions(tex_v, tex_req): pass
- else:
- flag = False
- warnings.warn(('matplotlibrc text.usetex option can not be used '
- 'unless TeX-%s or later is '
- 'installed on your system') % tex_req)
-
- dvipng_v = checkdep_dvipng()
- if compare_versions(dvipng_v, dvipng_req): pass
- else:
- flag = False
- warnings.warn( 'matplotlibrc text.usetex can not be used with *Agg '
- 'backend unless dvipng-1.5 or later is '
- 'installed on your system')
-
- gs_exec, gs_v = checkdep_ghostscript()
- if compare_versions(gs_v, gs_sugg): pass
- elif compare_versions(gs_v, gs_req):
- verbose.report(('ghostscript-%s found. ghostscript-%s or later is '
- 'recommended for use with the text.usetex '
- 'option.') % (gs_v, gs_sugg))
- else:
- flag = False
- warnings.warn(('matplotlibrc text.usetex can not be used '
- 'unless ghostscript-%s or later is '
- 'installed on your system') % gs_req)
-
- return flag
-
-
-def _get_home():
- """Find user's home directory if possible.
- Otherwise, returns None.
-
- :see: http://mail.python.org/pipermail/python-list/2005-February/325395.html
- """
- try:
- if six.PY2 and sys.platform == 'win32':
- path = os.path.expanduser(b"~").decode(sys.getfilesystemencoding())
- else:
- path = os.path.expanduser("~")
- except ImportError:
- # This happens on Google App Engine (pwd module is not present).
- pass
- else:
- if os.path.isdir(path):
- return path
- for evar in ('HOME', 'USERPROFILE', 'TMP'):
- path = os.environ.get(evar)
- if path is not None and os.path.isdir(path):
- return path
- return None
-
-
-def _create_tmp_config_dir():
- """
- If the config directory can not be created, create a temporary
- directory.
-
- Returns None if a writable temporary directory could not be created.
- """
- import getpass
- import tempfile
-
- try:
- tempdir = tempfile.gettempdir()
- except NotImplementedError:
- # Some restricted platforms (such as Google App Engine) do not provide
- # gettempdir.
- return None
- tempdir = os.path.join(tempdir, 'matplotlib-%s' % getpass.getuser())
- os.environ['MPLCONFIGDIR'] = tempdir
-
- return tempdir
-
-
-get_home = verbose.wrap('$HOME=%s', _get_home, always=False)
-
-def _get_xdg_config_dir():
- """
- Returns the XDG configuration directory, according to the `XDG
- base directory spec
- `_.
- """
- path = os.environ.get('XDG_CONFIG_HOME')
- if path is None:
- path = get_home()
- if path is not None:
- path = os.path.join(path, '.config')
- return path
-
-
-def _get_xdg_cache_dir():
- """
- Returns the XDG cache directory, according to the `XDG
- base directory spec
- `_.
- """
- path = os.environ.get('XDG_CACHE_HOME')
- if path is None:
- path = get_home()
- if path is not None:
- path = os.path.join(path, '.cache')
- return path
-
-
-def _get_config_or_cache_dir(xdg_base):
- from matplotlib.cbook import mkdirs
-
- configdir = os.environ.get('MPLCONFIGDIR')
- if configdir is not None:
- configdir = os.path.abspath(configdir)
- if not os.path.exists(configdir):
- mkdirs(configdir)
-
- if not _is_writable_dir(configdir):
- return _create_tmp_config_dir()
- return configdir
-
- p = None
- h = get_home()
- if h is not None:
- p = os.path.join(h, '.matplotlib')
- if (sys.platform.startswith('linux') and xdg_base):
- p = os.path.join(xdg_base, 'matplotlib')
-
- if p is not None:
- if os.path.exists(p):
- if _is_writable_dir(p):
- return p
- else:
- try:
- mkdirs(p)
- except OSError:
- pass
- else:
- return p
-
- return _create_tmp_config_dir()
-
-
-def _get_configdir():
- """
- Return the string representing the configuration directory.
-
- The directory is chosen as follows:
-
- 1. If the MPLCONFIGDIR environment variable is supplied, choose that.
-
- 2a. On Linux, if `$HOME/.matplotlib` exists, choose that, but warn that
- that is the old location. Barring that, follow the XDG specification
- and look first in `$XDG_CONFIG_HOME`, if defined, or `$HOME/.config`.
-
- 2b. On other platforms, choose `$HOME/.matplotlib`.
-
- 3. If the chosen directory exists and is writable, use that as the
- configuration directory.
- 4. If possible, create a temporary directory, and use it as the
- configuration directory.
- 5. A writable directory could not be found or created; return None.
- """
- return _get_config_or_cache_dir(_get_xdg_config_dir())
-
-get_configdir = verbose.wrap('CONFIGDIR=%s', _get_configdir, always=False)
-
-
-def _get_cachedir():
- """
- Return the location of the cache directory.
-
- The procedure used to find the directory is the same as for
- _get_config_dir, except using `$XDG_CACHE_HOME`/`~/.cache` instead.
- """
- return _get_config_or_cache_dir(_get_xdg_cache_dir())
-
-get_cachedir = verbose.wrap('CACHEDIR=%s', _get_cachedir, always=False)
-
-
-def _get_data_path():
- 'get the path to matplotlib data'
-
- if 'MATPLOTLIBDATA' in os.environ:
- path = os.environ['MATPLOTLIBDATA']
- if not os.path.isdir(path):
- raise RuntimeError('Path in environment MATPLOTLIBDATA not a directory')
- return path
-
- path = os.sep.join([os.path.dirname(__file__), 'mpl-data'])
- if os.path.isdir(path):
- return path
-
- # setuptools' namespace_packages may highjack this init file
- # so need to try something known to be in matplotlib, not basemap
- import matplotlib.afm
- path = os.sep.join([os.path.dirname(matplotlib.afm.__file__), 'mpl-data'])
- if os.path.isdir(path):
- return path
-
- # py2exe zips pure python, so still need special check
- if getattr(sys,'frozen',None):
- exe_path = os.path.dirname(sys.executable)
- path = os.path.join(exe_path, 'mpl-data')
- if os.path.isdir(path):
- return path
-
- # Try again assuming we need to step up one more directory
- path = os.path.join(os.path.split(exe_path)[0], 'mpl-data')
- if os.path.isdir(path):
- return path
-
- # Try again assuming sys.path[0] is a dir not a exe
- path = os.path.join(sys.path[0], 'mpl-data')
- if os.path.isdir(path):
- return path
-
- raise RuntimeError('Could not find the matplotlib data files')
-
-def _get_data_path_cached():
- if defaultParams['datapath'][0] is None:
- defaultParams['datapath'][0] = _get_data_path()
- return defaultParams['datapath'][0]
-
-get_data_path = verbose.wrap('matplotlib data path %s', _get_data_path_cached,
- always=False)
-
-
-
-def get_example_data(fname):
- """
- get_example_data is deprecated -- use matplotlib.cbook.get_sample_data instead
- """
- raise NotImplementedError('get_example_data is deprecated -- use matplotlib.cbook.get_sample_data instead')
-
-
-def get_py2exe_datafiles():
- datapath = get_data_path()
- _, tail = os.path.split(datapath)
- d = {}
- for root, _, files in os.walk(datapath):
- # Need to explicitly remove cocoa_agg files or py2exe complains
- # NOTE I dont know why, but do as previous version
- if 'Matplotlib.nib' in files:
- files.remove('Matplotlib.nib')
- files = [os.path.join(root, filename) for filename in files]
- root = root.replace(tail, 'mpl-data')
- root = root[root.index('mpl-data'):]
- d[root] = files
- return list(d.items())
-
-
-def matplotlib_fname():
- """
- Get the location of the config file.
-
- The file location is determined in the following order
-
- - `$PWD/matplotlibrc`
-
- - environment variable `MATPLOTLIBRC`
-
- - `$MPLCONFIGDIR/matplotlib`
-
- - On Linux,
-
- - `$HOME/.matplotlib/matplotlibrc`, if it exists
-
- - or `$XDG_CONFIG_HOME/matplotlib/matplotlibrc` (if
- $XDG_CONFIG_HOME is defined)
-
- - or `$HOME/.config/matplotlib/matplotlibrc` (if
- $XDG_CONFIG_HOME is not defined)
-
- - On other platforms,
-
- - `$HOME/.matplotlib/matplotlibrc` if `$HOME` is defined.
-
- - Lastly, it looks in `$MATPLOTLIBDATA/matplotlibrc` for a
- system-defined copy.
- """
- if six.PY2:
- cwd = os.getcwdu()
- else:
- cwd = os.getcwd()
- fname = os.path.join(cwd, 'matplotlibrc')
- if os.path.exists(fname):
- return fname
-
- if 'MATPLOTLIBRC' in os.environ:
- path = os.environ['MATPLOTLIBRC']
- if os.path.exists(path):
- fname = os.path.join(path, 'matplotlibrc')
- if os.path.exists(fname):
- return fname
-
- configdir = _get_configdir()
- if configdir is not None:
- fname = os.path.join(configdir, 'matplotlibrc')
- if os.path.exists(fname):
- home = get_home()
- if (sys.platform.startswith('linux') and
- home is not None and
- os.path.exists(os.path.join(
- home, '.matplotlib', 'matplotlibrc'))):
- warnings.warn(
- "Found matplotlib configuration in ~/.matplotlib/. "
- "To conform with the XDG base directory standard, "
- "this configuration location has been deprecated "
- "on Linux, and the new location is now %s/matplotlib/. "
- "Please move your configuration there to ensure that "
- "matplotlib will continue to find it in the future." %
- _get_xdg_config_dir())
- return os.path.join(
- home, '.matplotlib', 'matplotlibrc')
- return fname
-
- path = get_data_path() # guaranteed to exist or raise
- fname = os.path.join(path, 'matplotlibrc')
- if not os.path.exists(fname):
- warnings.warn('Could not find matplotlibrc; using defaults')
-
- return fname
-
-
-_deprecated_map = {
- 'text.fontstyle': ('font.style',lambda x: x),
- 'text.fontangle': ('font.style',lambda x: x),
- 'text.fontvariant': ('font.variant',lambda x: x),
- 'text.fontweight': ('font.weight',lambda x: x),
- 'text.fontsize': ('font.size',lambda x: x),
- 'tick.size' : ('tick.major.size',lambda x: x),
- 'svg.embed_char_paths' : ('svg.fonttype',lambda x: "path" if x else "none"),
- 'savefig.extension' : ('savefig.format',lambda x: x),
- }
-
-_deprecated_ignore_map = {
- }
-
-_obsolete_set = set(['tk.pythoninspect', ])
-_all_deprecated = set(chain(_deprecated_ignore_map,
- _deprecated_map, _obsolete_set))
-
-_rcparam_warn_str = ("Trying to set {key} to {value} via the {func} "
- "method of RcParams which does not validate cleanly. "
- "This warning will turn into an Exception in 1.5. "
- "If you think {value} should validate correctly for "
- "rcParams[{key}] "
- "please create an issue on github."
- )
-
-
-class RcParams(dict):
-
- """
- A dictionary object including validation
-
- validating functions are defined and associated with rc parameters in
- :mod:`matplotlib.rcsetup`
- """
-
- validate = dict((key, converter) for key, (default, converter) in
- six.iteritems(defaultParams)
- if key not in _all_deprecated)
- msg_depr = "%s is deprecated and replaced with %s; please use the latter."
- msg_depr_ignore = "%s is deprecated and ignored. Use %s"
-
- # validate values on the way in
- def __init__(self, *args, **kwargs):
- for k, v in six.iteritems(dict(*args, **kwargs)):
- try:
- self[k] = v
- except (ValueError, RuntimeError):
- # force the issue
- warnings.warn(_rcparam_warn_str.format(key=repr(k),
- value=repr(v),
- func='__init__'))
- dict.__setitem__(self, k, v)
-
- def __setitem__(self, key, val):
- try:
- if key in _deprecated_map:
- alt_key, alt_val = _deprecated_map[key]
- warnings.warn(self.msg_depr % (key, alt_key))
- key = alt_key
- val = alt_val(val)
- elif key in _deprecated_ignore_map:
- alt = _deprecated_ignore_map[key]
- warnings.warn(self.msg_depr_ignore % (key, alt))
- return
- try:
- cval = self.validate[key](val)
- except ValueError as ve:
- raise ValueError("Key %s: %s" % (key, str(ve)))
- dict.__setitem__(self, key, cval)
- except KeyError:
- raise KeyError('%s is not a valid rc parameter.\
-See rcParams.keys() for a list of valid parameters.' % (key,))
-
- def __getitem__(self, key):
- if key in _deprecated_map:
- alt_key, alt_val = _deprecated_map[key]
- warnings.warn(self.msg_depr % (key, alt_key))
- key = alt_key
- elif key in _deprecated_ignore_map:
- alt = _deprecated_ignore_map[key]
- warnings.warn(self.msg_depr_ignore % (key, alt))
- key = alt
- return dict.__getitem__(self, key)
-
- # http://stackoverflow.com/questions/2390827/how-to-properly-subclass-dict-and-override-get-set
- # the default dict `update` does not use __setitem__
- # so rcParams.update(...) (such as in seaborn) side-steps
- # all of the validation over-ride update to force
- # through __setitem__
- def update(self, *args, **kwargs):
- for k, v in six.iteritems(dict(*args, **kwargs)):
- try:
- self[k] = v
- except (ValueError, RuntimeError):
- # force the issue
- warnings.warn(_rcparam_warn_str.format(key=repr(k),
- value=repr(v),
- func='update'))
- dict.__setitem__(self, k, v)
-
- def __repr__(self):
- import pprint
- class_name = self.__class__.__name__
- indent = len(class_name) + 1
- repr_split = pprint.pformat(dict(self), indent=1,
- width=80 - indent).split('\n')
- repr_indented = ('\n' + ' ' * indent).join(repr_split)
- return '{0}({1})'.format(class_name, repr_indented)
-
- def __str__(self):
- return '\n'.join('{0}: {1}'.format(k, v)
- for k, v in sorted(self.items()))
-
- def keys(self):
- """
- Return sorted list of keys.
- """
- k = list(dict.keys(self))
- k.sort()
- return k
-
- def values(self):
- """
- Return values in order of sorted keys.
- """
- return [self[k] for k in self.keys()]
-
- def find_all(self, pattern):
- """
- Return the subset of this RcParams dictionary whose keys match,
- using :func:`re.search`, the given ``pattern``.
-
- .. note::
-
- Changes to the returned dictionary are *not* propagated to
- the parent RcParams dictionary.
-
- """
- import re
- pattern_re = re.compile(pattern)
- return RcParams((key, value)
- for key, value in self.items()
- if pattern_re.search(key))
-
-
-def rc_params(fail_on_error=False):
- """Return a :class:`matplotlib.RcParams` instance from the
- default matplotlib rc file.
- """
- fname = matplotlib_fname()
- if not os.path.exists(fname):
- # this should never happen, default in mpl-data should always be found
- message = 'could not find rc file; returning defaults'
- ret = RcParams([(key, default) for key, (default, _) in
- six.iteritems(defaultParams)
- if key not in _all_deprecated])
- warnings.warn(message)
- return ret
-
- return rc_params_from_file(fname, fail_on_error)
-
-
-URL_REGEX = re.compile(r'http://|https://|ftp://|file://|file:\\')
-
-
-def is_url(filename):
- """Return True if string is an http, ftp, or file URL path."""
- return URL_REGEX.match(filename) is not None
-
-
-def _url_lines(f):
- # Compatibility for urlopen in python 3, which yields bytes.
- for line in f:
- yield line.decode('utf8')
-
-
-@contextlib.contextmanager
-def _open_file_or_url(fname):
- if is_url(fname):
- f = urlopen(fname)
- yield _url_lines(f)
- f.close()
- else:
- with open(fname) as f:
- yield f
-
-
-_error_details_fmt = 'line #%d\n\t"%s"\n\tin file "%s"'
-
-
-def _rc_params_in_file(fname, fail_on_error=False):
- """Return :class:`matplotlib.RcParams` from the contents of the given file.
-
- Unlike `rc_params_from_file`, the configuration class only contains the
- parameters specified in the file (i.e. default values are not filled in).
- """
- cnt = 0
- rc_temp = {}
- with _open_file_or_url(fname) as fd:
- for line in fd:
- cnt += 1
- strippedline = line.split('#', 1)[0].strip()
- if not strippedline: continue
- tup = strippedline.split(':', 1)
- if len(tup) != 2:
- error_details = _error_details_fmt % (cnt, line, fname)
- warnings.warn('Illegal %s' % error_details)
- continue
- key, val = tup
- key = key.strip()
- val = val.strip()
- if key in rc_temp:
- warnings.warn('Duplicate key in file "%s", line #%d' % \
- (fname, cnt))
- rc_temp[key] = (val, line, cnt)
-
- config = RcParams()
-
- for key in ('verbose.level', 'verbose.fileo'):
- if key in rc_temp:
- val, line, cnt = rc_temp.pop(key)
- if fail_on_error:
- config[key] = val # try to convert to proper type or raise
- else:
- try:
- config[key] = val # try to convert to proper type or skip
- except Exception as msg:
- error_details = _error_details_fmt % (cnt, line, fname)
- warnings.warn('Bad val "%s" on %s\n\t%s' %
- (val, error_details, msg))
-
- for key, (val, line, cnt) in six.iteritems(rc_temp):
- if key in defaultParams:
- if fail_on_error:
- config[key] = val # try to convert to proper type or raise
- else:
- try:
- config[key] = val # try to convert to proper type or skip
- except Exception as msg:
- error_details = _error_details_fmt % (cnt, line, fname)
- warnings.warn('Bad val "%s" on %s\n\t%s' %
- (val, error_details, msg))
- elif key in _deprecated_ignore_map:
- warnings.warn('%s is deprecated. Update your matplotlibrc to use '
- '%s instead.'% (key, _deprecated_ignore_map[key]))
-
- else:
- print("""
-Bad key "%s" on line %d in
-%s.
-You probably need to get an updated matplotlibrc file from
-http://matplotlib.sf.net/_static/matplotlibrc or from the matplotlib source
-distribution""" % (key, cnt, fname), file=sys.stderr)
-
- return config
-
-
-def rc_params_from_file(fname, fail_on_error=False, use_default_template=True):
- """Return :class:`matplotlib.RcParams` from the contents of the given file.
-
- Parameters
- ----------
- fname : str
- Name of file parsed for matplotlib settings.
- fail_on_error : bool
- If True, raise an error when the parser fails to convert a parameter.
- use_default_template : bool
- If True, initialize with default parameters before updating with those
- in the given file. If False, the configuration class only contains the
- parameters specified in the file. (Useful for updating dicts.)
- """
- config_from_file = _rc_params_in_file(fname, fail_on_error)
-
- if not use_default_template:
- return config_from_file
-
- iter_params = six.iteritems(defaultParams)
- config = RcParams([(key, default) for key, (default, _) in iter_params
- if key not in _all_deprecated])
- config.update(config_from_file)
-
- verbose.set_level(config['verbose.level'])
- verbose.set_fileo(config['verbose.fileo'])
-
- if config['datapath'] is None:
- config['datapath'] = get_data_path()
-
- if not config['text.latex.preamble'] == ['']:
- verbose.report("""
-*****************************************************************
-You have the following UNSUPPORTED LaTeX preamble customizations:
-%s
-Please do not ask for support with these customizations active.
-*****************************************************************
-"""% '\n'.join(config['text.latex.preamble']), 'helpful')
-
- verbose.report('loaded rc file %s'%fname)
-
- return config
-
-
-# this is the instance used by the matplotlib classes
-rcParams = rc_params()
-
-if rcParams['examples.directory']:
- # paths that are intended to be relative to matplotlib_fname()
- # are allowed for the examples.directory parameter.
- # However, we will need to fully qualify the path because
- # Sphinx requires absolute paths.
- if not os.path.isabs(rcParams['examples.directory']):
- _basedir, _fname = os.path.split(matplotlib_fname())
- # Sometimes matplotlib_fname() can return relative paths,
- # Also, using realpath() guarentees that Sphinx will use
- # the same path that matplotlib sees (in case of weird symlinks).
- _basedir = os.path.realpath(_basedir)
- _fullpath = os.path.join(_basedir, rcParams['examples.directory'])
- rcParams['examples.directory'] = _fullpath
-
-rcParamsOrig = rcParams.copy()
-
-rcParamsDefault = RcParams([(key, default) for key, (default, converter) in
- six.iteritems(defaultParams)
- if key not in _all_deprecated])
-
-
-rcParams['ps.usedistiller'] = checkdep_ps_distiller(
- rcParams['ps.usedistiller'])
-rcParams['text.usetex'] = checkdep_usetex(rcParams['text.usetex'])
-
-if rcParams['axes.formatter.use_locale']:
- import locale
- locale.setlocale(locale.LC_ALL, '')
-
-
-def rc(group, **kwargs):
- """
- Set the current rc params. Group is the grouping for the rc, e.g.,
- for ``lines.linewidth`` the group is ``lines``, for
- ``axes.facecolor``, the group is ``axes``, and so on. Group may
- also be a list or tuple of group names, e.g., (*xtick*, *ytick*).
- *kwargs* is a dictionary attribute name/value pairs, e.g.,::
-
- rc('lines', linewidth=2, color='r')
-
- sets the current rc params and is equivalent to::
-
- rcParams['lines.linewidth'] = 2
- rcParams['lines.color'] = 'r'
-
- The following aliases are available to save typing for interactive
- users:
-
- ===== =================
- Alias Property
- ===== =================
- 'lw' 'linewidth'
- 'ls' 'linestyle'
- 'c' 'color'
- 'fc' 'facecolor'
- 'ec' 'edgecolor'
- 'mew' 'markeredgewidth'
- 'aa' 'antialiased'
- ===== =================
-
- Thus you could abbreviate the above rc command as::
-
- rc('lines', lw=2, c='r')
-
-
- Note you can use python's kwargs dictionary facility to store
- dictionaries of default parameters. e.g., you can customize the
- font rc as follows::
-
- font = {'family' : 'monospace',
- 'weight' : 'bold',
- 'size' : 'larger'}
-
- rc('font', **font) # pass in the font dict as kwargs
-
- This enables you to easily switch between several configurations.
- Use :func:`~matplotlib.pyplot.rcdefaults` to restore the default
- rc params after changes.
- """
-
- aliases = {
- 'lw' : 'linewidth',
- 'ls' : 'linestyle',
- 'c' : 'color',
- 'fc' : 'facecolor',
- 'ec' : 'edgecolor',
- 'mew' : 'markeredgewidth',
- 'aa' : 'antialiased',
- }
-
- if is_string_like(group):
- group = (group,)
- for g in group:
- for k, v in six.iteritems(kwargs):
- name = aliases.get(k) or k
- key = '%s.%s' % (g, name)
- try:
- rcParams[key] = v
- except KeyError:
- raise KeyError('Unrecognized key "%s" for group "%s" and name "%s"' %
- (key, g, name))
-
-def rcdefaults():
- """
- Restore the default rc params. These are not the params loaded by
- the rc file, but mpl's internal params. See rc_file_defaults for
- reloading the default params from the rc file
- """
- rcParams.clear()
- rcParams.update(rcParamsDefault)
-
-
-def rc_file(fname):
- """
- Update rc params from file.
- """
- rcParams.update(rc_params_from_file(fname))
-
-
-class rc_context(object):
- """
- Return a context manager for managing rc settings.
-
- This allows one to do::
-
- with mpl.rc_context(fname='screen.rc'):
- plt.plot(x, a)
- with mpl.rc_context(fname='print.rc'):
- plt.plot(x, b)
- plt.plot(x, c)
-
- The 'a' vs 'x' and 'c' vs 'x' plots would have settings from
- 'screen.rc', while the 'b' vs 'x' plot would have settings from
- 'print.rc'.
-
- A dictionary can also be passed to the context manager::
-
- with mpl.rc_context(rc={'text.usetex': True}, fname='screen.rc'):
- plt.plot(x, a)
-
- The 'rc' dictionary takes precedence over the settings loaded from
- 'fname'. Passing a dictionary only is also valid.
- """
-
- def __init__(self, rc=None, fname=None):
- self.rcdict = rc
- self.fname = fname
- self._rcparams = rcParams.copy()
- try:
- if self.fname:
- rc_file(self.fname)
- if self.rcdict:
- rcParams.update(self.rcdict)
- except:
- # if anything goes wrong, revert rc parameters and re-raise
- rcParams.clear()
- rcParams.update(self._rcparams)
- raise
-
- def __enter__(self):
- return self
-
- def __exit__(self, type, value, tb):
- rcParams.update(self._rcparams)
-
-
-def rc_file_defaults():
- """
- Restore the default rc params from the original matplotlib rc that
- was loaded
- """
- rcParams.update(rcParamsOrig)
-
-_use_error_msg = """ This call to matplotlib.use() has no effect
-because the backend has already been chosen;
-matplotlib.use() must be called *before* pylab, matplotlib.pyplot,
-or matplotlib.backends is imported for the first time.
-"""
-
-def use(arg, warn=True, force=False):
- """
- Set the matplotlib backend to one of the known backends.
-
- The argument is case-insensitive. *warn* specifies whether a
- warning should be issued if a backend has already been set up.
- *force* is an **experimental** flag that tells matplotlib to
- attempt to initialize a new backend by reloading the backend
- module.
-
- .. note::
-
- This function must be called *before* importing pyplot for
- the first time; or, if you are not using pyplot, it must be called
- before importing matplotlib.backends. If warn is True, a warning
- is issued if you try and call this after pylab or pyplot have been
- loaded. In certain black magic use cases, e.g.
- :func:`pyplot.switch_backend`, we are doing the reloading necessary to
- make the backend switch work (in some cases, e.g., pure image
- backends) so one can set warn=False to suppress the warnings.
-
- To find out which backend is currently set, see
- :func:`matplotlib.get_backend`.
-
- """
- # Lets determine the proper backend name first
- if arg.startswith('module://'):
- name = arg
- else:
- # Lowercase only non-module backend names (modules are case-sensitive)
- arg = arg.lower()
- name = validate_backend(arg)
-
- # Check if we've already set up a backend
- if 'matplotlib.backends' in sys.modules:
- # Warn only if called with a different name
- if (rcParams['backend'] != name) and warn:
- warnings.warn(_use_error_msg)
-
- # Unless we've been told to force it, just return
- if not force:
- return
- need_reload = True
- else:
- need_reload = False
-
- # Store the backend name
- rcParams['backend'] = name
-
- # If needed we reload here because a lot of setup code is triggered on
- # module import. See backends/__init__.py for more detail.
- if need_reload:
- reload(sys.modules['matplotlib.backends'])
-
-def get_backend():
- """Return the name of the current backend."""
- return rcParams['backend']
-
-def interactive(b):
- """
- Set interactive mode to boolean b.
-
- If b is True, then draw after every plotting command, e.g., after xlabel
- """
- rcParams['interactive'] = b
-
-def is_interactive():
- 'Return true if plot mode is interactive'
- return rcParams['interactive']
-
-def tk_window_focus():
- """Return true if focus maintenance under TkAgg on win32 is on.
- This currently works only for python.exe and IPython.exe.
- Both IDLE and Pythonwin.exe fail badly when tk_window_focus is on."""
- if rcParams['backend'] != 'TkAgg':
- return False
- return rcParams['tk.window_focus']
-
-# Now allow command line to override
-
-# Allow command line access to the backend with -d (MATLAB compatible
-# flag)
-
-for s in sys.argv[1:]:
- # cast to str because we are using unicode_literals,
- # and argv is always str
- if s.startswith(str('-d')) and len(s) > 2: # look for a -d flag
- try:
- use(s[2:])
- except (KeyError, ValueError):
- pass
- # we don't want to assume all -d flags are backends, e.g., -debug
-
-default_test_modules = [
- 'matplotlib.tests.test_agg',
- 'matplotlib.tests.test_animation',
- 'matplotlib.tests.test_arrow_patches',
- 'matplotlib.tests.test_artist',
- 'matplotlib.tests.test_axes',
- 'matplotlib.tests.test_backend_bases',
- 'matplotlib.tests.test_backend_pdf',
- 'matplotlib.tests.test_backend_pgf',
- 'matplotlib.tests.test_backend_ps',
- 'matplotlib.tests.test_backend_qt4',
- 'matplotlib.tests.test_backend_svg',
- 'matplotlib.tests.test_basic',
- 'matplotlib.tests.test_bbox_tight',
- 'matplotlib.tests.test_cbook',
- 'matplotlib.tests.test_coding_standards',
- 'matplotlib.tests.test_collections',
- 'matplotlib.tests.test_colorbar',
- 'matplotlib.tests.test_colors',
- 'matplotlib.tests.test_compare_images',
- 'matplotlib.tests.test_contour',
- 'matplotlib.tests.test_dates',
- 'matplotlib.tests.test_delaunay',
- 'matplotlib.tests.test_figure',
- 'matplotlib.tests.test_font_manager',
- 'matplotlib.tests.test_gridspec',
- 'matplotlib.tests.test_image',
- 'matplotlib.tests.test_legend',
- 'matplotlib.tests.test_lines',
- 'matplotlib.tests.test_mathtext',
- 'matplotlib.tests.test_mlab',
- 'matplotlib.tests.test_patches',
- 'matplotlib.tests.test_path',
- 'matplotlib.tests.test_patheffects',
- 'matplotlib.tests.test_pickle',
- 'matplotlib.tests.test_png',
- 'matplotlib.tests.test_quiver',
- 'matplotlib.tests.test_rcparams',
- 'matplotlib.tests.test_scale',
- 'matplotlib.tests.test_simplification',
- 'matplotlib.tests.test_spines',
- 'matplotlib.tests.test_streamplot',
- 'matplotlib.tests.test_style',
- 'matplotlib.tests.test_subplots',
- 'matplotlib.tests.test_table',
- 'matplotlib.tests.test_text',
- 'matplotlib.tests.test_ticker',
- 'matplotlib.tests.test_tightlayout',
- 'matplotlib.tests.test_transforms',
- 'matplotlib.tests.test_triangulation',
- 'mpl_toolkits.tests.test_mplot3d',
- 'mpl_toolkits.tests.test_axes_grid1',
- ]
-
-
-def test(verbosity=1):
- """run the matplotlib test suite"""
- old_backend = rcParams['backend']
- try:
- use('agg')
- import nose
- import nose.plugins.builtin
- from .testing.noseclasses import KnownFailure
- from nose.plugins.manager import PluginManager
- from nose.plugins import multiprocess
-
- # store the old values before overriding
- plugins = []
- plugins.append( KnownFailure() )
- plugins.extend( [plugin() for plugin in nose.plugins.builtin.plugins] )
-
- manager = PluginManager(plugins=plugins)
- config = nose.config.Config(verbosity=verbosity, plugins=manager)
-
- # Nose doesn't automatically instantiate all of the plugins in the
- # child processes, so we have to provide the multiprocess plugin with
- # a list.
- multiprocess._instantiate_plugins = [KnownFailure]
-
- success = nose.run(
- defaultTest=default_test_modules,
- config=config,
- )
- finally:
- if old_backend.lower() != 'agg':
- use(old_backend)
-
- return success
-
-test.__test__ = False # nose: this function is not a test
-
-verbose.report('matplotlib version %s'%__version__)
-verbose.report('verbose.level %s'%verbose.level)
-verbose.report('interactive is %s'%is_interactive())
-verbose.report('platform is %s'%sys.platform)
-verbose.report('loaded modules: %s'%six.iterkeys(sys.modules), 'debug')
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/_cm.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/_cm.py
deleted file mode 100644
index 7624b8a..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/_cm.py
+++ /dev/null
@@ -1,1997 +0,0 @@
-"""
-Nothing here but dictionaries for generating LinearSegmentedColormaps,
-and a dictionary of these dictionaries.
-
-Documentation for each is in pyplot.colormaps()
-"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import numpy as np
-
-_binary_data = {
- 'red': ((0., 1., 1.), (1., 0., 0.)),
- 'green': ((0., 1., 1.), (1., 0., 0.)),
- 'blue': ((0., 1., 1.), (1., 0., 0.))
- }
-
-_autumn_data = {'red': ((0., 1.0, 1.0), (1.0, 1.0, 1.0)),
- 'green': ((0., 0., 0.), (1.0, 1.0, 1.0)),
- 'blue': ((0., 0., 0.), (1.0, 0., 0.))}
-
-_bone_data = {'red': ((0., 0., 0.),
- (0.746032, 0.652778, 0.652778),
- (1.0, 1.0, 1.0)),
- 'green': ((0., 0., 0.),
- (0.365079, 0.319444, 0.319444),
- (0.746032, 0.777778, 0.777778),
- (1.0, 1.0, 1.0)),
- 'blue': ((0., 0., 0.),
- (0.365079, 0.444444, 0.444444),
- (1.0, 1.0, 1.0))}
-
-_cool_data = {'red': ((0., 0., 0.), (1.0, 1.0, 1.0)),
- 'green': ((0., 1., 1.), (1.0, 0., 0.)),
- 'blue': ((0., 1., 1.), (1.0, 1., 1.))}
-
-_copper_data = {'red': ((0., 0., 0.),
- (0.809524, 1.000000, 1.000000),
- (1.0, 1.0, 1.0)),
- 'green': ((0., 0., 0.),
- (1.0, 0.7812, 0.7812)),
- 'blue': ((0., 0., 0.),
- (1.0, 0.4975, 0.4975))}
-
-_flag_data = {
- 'red': lambda x: 0.75 * np.sin((x * 31.5 + 0.25) * np.pi) + 0.5,
- 'green': lambda x: np.sin(x * 31.5 * np.pi),
- 'blue': lambda x: 0.75 * np.sin((x * 31.5 - 0.25) * np.pi) + 0.5,
-}
-
-_prism_data = {
- 'red': lambda x: 0.75 * np.sin((x * 20.9 + 0.25) * np.pi) + 0.67,
- 'green': lambda x: 0.75 * np.sin((x * 20.9 - 0.25) * np.pi) + 0.33,
- 'blue': lambda x: -1.1 * np.sin((x * 20.9) * np.pi),
-}
-
-
-def cubehelix(gamma=1.0, s=0.5, r=-1.5, h=1.0):
- """Return custom data dictionary of (r,g,b) conversion functions, which
- can be used with :func:`register_cmap`, for the cubehelix color scheme.
-
- Unlike most other color schemes cubehelix was designed by D.A. Green to
- be monotonically increasing in terms of perceived brightness.
- Also, when printed on a black and white postscript printer, the scheme
- results in a greyscale with monotonically increasing brightness.
- This color scheme is named cubehelix because the r,g,b values produced
- can be visualised as a squashed helix around the diagonal in the
- r,g,b color cube.
-
- For a unit color cube (i.e. 3-D coordinates for r,g,b each in the
- range 0 to 1) the color scheme starts at (r,g,b) = (0,0,0), i.e. black,
- and finishes at (r,g,b) = (1,1,1), i.e. white. For some fraction *x*,
- between 0 and 1, the color is the corresponding grey value at that
- fraction along the black to white diagonal (x,x,x) plus a color
- element. This color element is calculated in a plane of constant
- perceived intensity and controlled by the following parameters.
-
- Optional keyword arguments:
-
- ========= =======================================================
- Keyword Description
- ========= =======================================================
- gamma gamma factor to emphasise either low intensity values
- (gamma < 1), or high intensity values (gamma > 1);
- defaults to 1.0.
- s the start color; defaults to 0.5 (i.e. purple).
- r the number of r,g,b rotations in color that are made
- from the start to the end of the color scheme; defaults
- to -1.5 (i.e. -> B -> G -> R -> B).
- h the hue parameter which controls how saturated the
- colors are. If this parameter is zero then the color
- scheme is purely a greyscale; defaults to 1.0.
- ========= =======================================================
-
- """
-
- def get_color_function(p0, p1):
-
- def color(x):
- # Apply gamma factor to emphasise low or high intensity values
- xg = x ** gamma
-
- # Calculate amplitude and angle of deviation from the black
- # to white diagonal in the plane of constant
- # perceived intensity.
- a = h * xg * (1 - xg) / 2
-
- phi = 2 * np.pi * (s / 3 + r * x)
-
- return xg + a * (p0 * np.cos(phi) + p1 * np.sin(phi))
- return color
-
- return {
- 'red': get_color_function(-0.14861, 1.78277),
- 'green': get_color_function(-0.29227, -0.90649),
- 'blue': get_color_function(1.97294, 0.0),
- }
-
-_cubehelix_data = cubehelix()
-
-_bwr_data = ((0.0, 0.0, 1.0), (1.0, 1.0, 1.0), (1.0, 0.0, 0.0))
-_brg_data = ((0.0, 0.0, 1.0), (1.0, 0.0, 0.0), (0.0, 1.0, 0.0))
-
-# Gnuplot palette functions
-gfunc = {
- 0: lambda x: 0,
- 1: lambda x: 0.5,
- 2: lambda x: 1,
- 3: lambda x: x,
- 4: lambda x: x ** 2,
- 5: lambda x: x ** 3,
- 6: lambda x: x ** 4,
- 7: lambda x: np.sqrt(x),
- 8: lambda x: np.sqrt(np.sqrt(x)),
- 9: lambda x: np.sin(x * np.pi / 2),
- 10: lambda x: np.cos(x * np.pi / 2),
- 11: lambda x: np.abs(x - 0.5),
- 12: lambda x: (2 * x - 1) ** 2,
- 13: lambda x: np.sin(x * np.pi),
- 14: lambda x: np.abs(np.cos(x * np.pi)),
- 15: lambda x: np.sin(x * 2 * np.pi),
- 16: lambda x: np.cos(x * 2 * np.pi),
- 17: lambda x: np.abs(np.sin(x * 2 * np.pi)),
- 18: lambda x: np.abs(np.cos(x * 2 * np.pi)),
- 19: lambda x: np.abs(np.sin(x * 4 * np.pi)),
- 20: lambda x: np.abs(np.cos(x * 4 * np.pi)),
- 21: lambda x: 3 * x,
- 22: lambda x: 3 * x - 1,
- 23: lambda x: 3 * x - 2,
- 24: lambda x: np.abs(3 * x - 1),
- 25: lambda x: np.abs(3 * x - 2),
- 26: lambda x: (3 * x - 1) / 2,
- 27: lambda x: (3 * x - 2) / 2,
- 28: lambda x: np.abs((3 * x - 1) / 2),
- 29: lambda x: np.abs((3 * x - 2) / 2),
- 30: lambda x: x / 0.32 - 0.78125,
- 31: lambda x: 2 * x - 0.84,
- 32: lambda x: gfunc32(x),
- 33: lambda x: np.abs(2 * x - 0.5),
- 34: lambda x: 2 * x,
- 35: lambda x: 2 * x - 0.5,
- 36: lambda x: 2 * x - 1.
-}
-
-
-def gfunc32(x):
- ret = np.zeros(len(x))
- m = (x < 0.25)
- ret[m] = 4 * x[m]
- m = (x >= 0.25) & (x < 0.92)
- ret[m] = -2 * x[m] + 1.84
- m = (x >= 0.92)
- ret[m] = x[m] / 0.08 - 11.5
- return ret
-
-_gnuplot_data = {
- 'red': gfunc[7],
- 'green': gfunc[5],
- 'blue': gfunc[15],
-}
-
-_gnuplot2_data = {
- 'red': gfunc[30],
- 'green': gfunc[31],
- 'blue': gfunc[32],
-}
-
-_ocean_data = {
- 'red': gfunc[23],
- 'green': gfunc[28],
- 'blue': gfunc[3],
-}
-
-_afmhot_data = {
- 'red': gfunc[34],
- 'green': gfunc[35],
- 'blue': gfunc[36],
-}
-
-_rainbow_data = {
- 'red': gfunc[33],
- 'green': gfunc[13],
- 'blue': gfunc[10],
-}
-
-_seismic_data = (
- (0.0, 0.0, 0.3), (0.0, 0.0, 1.0),
- (1.0, 1.0, 1.0), (1.0, 0.0, 0.0),
- (0.5, 0.0, 0.0))
-
-_terrain_data = (
- (0.00, (0.2, 0.2, 0.6)),
- (0.15, (0.0, 0.6, 1.0)),
- (0.25, (0.0, 0.8, 0.4)),
- (0.50, (1.0, 1.0, 0.6)),
- (0.75, (0.5, 0.36, 0.33)),
- (1.00, (1.0, 1.0, 1.0)))
-
-_gray_data = {'red': ((0., 0, 0), (1., 1, 1)),
- 'green': ((0., 0, 0), (1., 1, 1)),
- 'blue': ((0., 0, 0), (1., 1, 1))}
-
-_hot_data = {'red': ((0., 0.0416, 0.0416),
- (0.365079, 1.000000, 1.000000),
- (1.0, 1.0, 1.0)),
- 'green': ((0., 0., 0.),
- (0.365079, 0.000000, 0.000000),
- (0.746032, 1.000000, 1.000000),
- (1.0, 1.0, 1.0)),
- 'blue': ((0., 0., 0.),
- (0.746032, 0.000000, 0.000000),
- (1.0, 1.0, 1.0))}
-
-_hsv_data = {'red': ((0., 1., 1.),
- (0.158730, 1.000000, 1.000000),
- (0.174603, 0.968750, 0.968750),
- (0.333333, 0.031250, 0.031250),
- (0.349206, 0.000000, 0.000000),
- (0.666667, 0.000000, 0.000000),
- (0.682540, 0.031250, 0.031250),
- (0.841270, 0.968750, 0.968750),
- (0.857143, 1.000000, 1.000000),
- (1.0, 1.0, 1.0)),
- 'green': ((0., 0., 0.),
- (0.158730, 0.937500, 0.937500),
- (0.174603, 1.000000, 1.000000),
- (0.507937, 1.000000, 1.000000),
- (0.666667, 0.062500, 0.062500),
- (0.682540, 0.000000, 0.000000),
- (1.0, 0., 0.)),
- 'blue': ((0., 0., 0.),
- (0.333333, 0.000000, 0.000000),
- (0.349206, 0.062500, 0.062500),
- (0.507937, 1.000000, 1.000000),
- (0.841270, 1.000000, 1.000000),
- (0.857143, 0.937500, 0.937500),
- (1.0, 0.09375, 0.09375))}
-
-_jet_data = {'red': ((0., 0, 0), (0.35, 0, 0), (0.66, 1, 1), (0.89, 1, 1),
- (1, 0.5, 0.5)),
- 'green': ((0., 0, 0), (0.125, 0, 0), (0.375, 1, 1), (0.64, 1, 1),
- (0.91, 0, 0), (1, 0, 0)),
- 'blue': ((0., 0.5, 0.5), (0.11, 1, 1), (0.34, 1, 1),
- (0.65, 0, 0), (1, 0, 0))}
-
-_pink_data = {'red': ((0., 0.1178, 0.1178), (0.015873, 0.195857, 0.195857),
- (0.031746, 0.250661, 0.250661),
- (0.047619, 0.295468, 0.295468),
- (0.063492, 0.334324, 0.334324),
- (0.079365, 0.369112, 0.369112),
- (0.095238, 0.400892, 0.400892),
- (0.111111, 0.430331, 0.430331),
- (0.126984, 0.457882, 0.457882),
- (0.142857, 0.483867, 0.483867),
- (0.158730, 0.508525, 0.508525),
- (0.174603, 0.532042, 0.532042),
- (0.190476, 0.554563, 0.554563),
- (0.206349, 0.576204, 0.576204),
- (0.222222, 0.597061, 0.597061),
- (0.238095, 0.617213, 0.617213),
- (0.253968, 0.636729, 0.636729),
- (0.269841, 0.655663, 0.655663),
- (0.285714, 0.674066, 0.674066),
- (0.301587, 0.691980, 0.691980),
- (0.317460, 0.709441, 0.709441),
- (0.333333, 0.726483, 0.726483),
- (0.349206, 0.743134, 0.743134),
- (0.365079, 0.759421, 0.759421),
- (0.380952, 0.766356, 0.766356),
- (0.396825, 0.773229, 0.773229),
- (0.412698, 0.780042, 0.780042),
- (0.428571, 0.786796, 0.786796),
- (0.444444, 0.793492, 0.793492),
- (0.460317, 0.800132, 0.800132),
- (0.476190, 0.806718, 0.806718),
- (0.492063, 0.813250, 0.813250),
- (0.507937, 0.819730, 0.819730),
- (0.523810, 0.826160, 0.826160),
- (0.539683, 0.832539, 0.832539),
- (0.555556, 0.838870, 0.838870),
- (0.571429, 0.845154, 0.845154),
- (0.587302, 0.851392, 0.851392),
- (0.603175, 0.857584, 0.857584),
- (0.619048, 0.863731, 0.863731),
- (0.634921, 0.869835, 0.869835),
- (0.650794, 0.875897, 0.875897),
- (0.666667, 0.881917, 0.881917),
- (0.682540, 0.887896, 0.887896),
- (0.698413, 0.893835, 0.893835),
- (0.714286, 0.899735, 0.899735),
- (0.730159, 0.905597, 0.905597),
- (0.746032, 0.911421, 0.911421),
- (0.761905, 0.917208, 0.917208),
- (0.777778, 0.922958, 0.922958),
- (0.793651, 0.928673, 0.928673),
- (0.809524, 0.934353, 0.934353),
- (0.825397, 0.939999, 0.939999),
- (0.841270, 0.945611, 0.945611),
- (0.857143, 0.951190, 0.951190),
- (0.873016, 0.956736, 0.956736),
- (0.888889, 0.962250, 0.962250),
- (0.904762, 0.967733, 0.967733),
- (0.920635, 0.973185, 0.973185),
- (0.936508, 0.978607, 0.978607),
- (0.952381, 0.983999, 0.983999),
- (0.968254, 0.989361, 0.989361),
- (0.984127, 0.994695, 0.994695), (1.0, 1.0, 1.0)),
- 'green': ((0., 0., 0.), (0.015873, 0.102869, 0.102869),
- (0.031746, 0.145479, 0.145479),
- (0.047619, 0.178174, 0.178174),
- (0.063492, 0.205738, 0.205738),
- (0.079365, 0.230022, 0.230022),
- (0.095238, 0.251976, 0.251976),
- (0.111111, 0.272166, 0.272166),
- (0.126984, 0.290957, 0.290957),
- (0.142857, 0.308607, 0.308607),
- (0.158730, 0.325300, 0.325300),
- (0.174603, 0.341178, 0.341178),
- (0.190476, 0.356348, 0.356348),
- (0.206349, 0.370899, 0.370899),
- (0.222222, 0.384900, 0.384900),
- (0.238095, 0.398410, 0.398410),
- (0.253968, 0.411476, 0.411476),
- (0.269841, 0.424139, 0.424139),
- (0.285714, 0.436436, 0.436436),
- (0.301587, 0.448395, 0.448395),
- (0.317460, 0.460044, 0.460044),
- (0.333333, 0.471405, 0.471405),
- (0.349206, 0.482498, 0.482498),
- (0.365079, 0.493342, 0.493342),
- (0.380952, 0.517549, 0.517549),
- (0.396825, 0.540674, 0.540674),
- (0.412698, 0.562849, 0.562849),
- (0.428571, 0.584183, 0.584183),
- (0.444444, 0.604765, 0.604765),
- (0.460317, 0.624669, 0.624669),
- (0.476190, 0.643958, 0.643958),
- (0.492063, 0.662687, 0.662687),
- (0.507937, 0.680900, 0.680900),
- (0.523810, 0.698638, 0.698638),
- (0.539683, 0.715937, 0.715937),
- (0.555556, 0.732828, 0.732828),
- (0.571429, 0.749338, 0.749338),
- (0.587302, 0.765493, 0.765493),
- (0.603175, 0.781313, 0.781313),
- (0.619048, 0.796819, 0.796819),
- (0.634921, 0.812029, 0.812029),
- (0.650794, 0.826960, 0.826960),
- (0.666667, 0.841625, 0.841625),
- (0.682540, 0.856040, 0.856040),
- (0.698413, 0.870216, 0.870216),
- (0.714286, 0.884164, 0.884164),
- (0.730159, 0.897896, 0.897896),
- (0.746032, 0.911421, 0.911421),
- (0.761905, 0.917208, 0.917208),
- (0.777778, 0.922958, 0.922958),
- (0.793651, 0.928673, 0.928673),
- (0.809524, 0.934353, 0.934353),
- (0.825397, 0.939999, 0.939999),
- (0.841270, 0.945611, 0.945611),
- (0.857143, 0.951190, 0.951190),
- (0.873016, 0.956736, 0.956736),
- (0.888889, 0.962250, 0.962250),
- (0.904762, 0.967733, 0.967733),
- (0.920635, 0.973185, 0.973185),
- (0.936508, 0.978607, 0.978607),
- (0.952381, 0.983999, 0.983999),
- (0.968254, 0.989361, 0.989361),
- (0.984127, 0.994695, 0.994695), (1.0, 1.0, 1.0)),
- 'blue': ((0., 0., 0.), (0.015873, 0.102869, 0.102869),
- (0.031746, 0.145479, 0.145479),
- (0.047619, 0.178174, 0.178174),
- (0.063492, 0.205738, 0.205738),
- (0.079365, 0.230022, 0.230022),
- (0.095238, 0.251976, 0.251976),
- (0.111111, 0.272166, 0.272166),
- (0.126984, 0.290957, 0.290957),
- (0.142857, 0.308607, 0.308607),
- (0.158730, 0.325300, 0.325300),
- (0.174603, 0.341178, 0.341178),
- (0.190476, 0.356348, 0.356348),
- (0.206349, 0.370899, 0.370899),
- (0.222222, 0.384900, 0.384900),
- (0.238095, 0.398410, 0.398410),
- (0.253968, 0.411476, 0.411476),
- (0.269841, 0.424139, 0.424139),
- (0.285714, 0.436436, 0.436436),
- (0.301587, 0.448395, 0.448395),
- (0.317460, 0.460044, 0.460044),
- (0.333333, 0.471405, 0.471405),
- (0.349206, 0.482498, 0.482498),
- (0.365079, 0.493342, 0.493342),
- (0.380952, 0.503953, 0.503953),
- (0.396825, 0.514344, 0.514344),
- (0.412698, 0.524531, 0.524531),
- (0.428571, 0.534522, 0.534522),
- (0.444444, 0.544331, 0.544331),
- (0.460317, 0.553966, 0.553966),
- (0.476190, 0.563436, 0.563436),
- (0.492063, 0.572750, 0.572750),
- (0.507937, 0.581914, 0.581914),
- (0.523810, 0.590937, 0.590937),
- (0.539683, 0.599824, 0.599824),
- (0.555556, 0.608581, 0.608581),
- (0.571429, 0.617213, 0.617213),
- (0.587302, 0.625727, 0.625727),
- (0.603175, 0.634126, 0.634126),
- (0.619048, 0.642416, 0.642416),
- (0.634921, 0.650600, 0.650600),
- (0.650794, 0.658682, 0.658682),
- (0.666667, 0.666667, 0.666667),
- (0.682540, 0.674556, 0.674556),
- (0.698413, 0.682355, 0.682355),
- (0.714286, 0.690066, 0.690066),
- (0.730159, 0.697691, 0.697691),
- (0.746032, 0.705234, 0.705234),
- (0.761905, 0.727166, 0.727166),
- (0.777778, 0.748455, 0.748455),
- (0.793651, 0.769156, 0.769156),
- (0.809524, 0.789314, 0.789314),
- (0.825397, 0.808969, 0.808969),
- (0.841270, 0.828159, 0.828159),
- (0.857143, 0.846913, 0.846913),
- (0.873016, 0.865261, 0.865261),
- (0.888889, 0.883229, 0.883229),
- (0.904762, 0.900837, 0.900837),
- (0.920635, 0.918109, 0.918109),
- (0.936508, 0.935061, 0.935061),
- (0.952381, 0.951711, 0.951711),
- (0.968254, 0.968075, 0.968075),
- (0.984127, 0.984167, 0.984167), (1.0, 1.0, 1.0))}
-
-_spring_data = {'red': ((0., 1., 1.), (1.0, 1.0, 1.0)),
- 'green': ((0., 0., 0.), (1.0, 1.0, 1.0)),
- 'blue': ((0., 1., 1.), (1.0, 0.0, 0.0))}
-
-
-_summer_data = {'red': ((0., 0., 0.), (1.0, 1.0, 1.0)),
- 'green': ((0., 0.5, 0.5), (1.0, 1.0, 1.0)),
- 'blue': ((0., 0.4, 0.4), (1.0, 0.4, 0.4))}
-
-
-_winter_data = {'red': ((0., 0., 0.), (1.0, 0.0, 0.0)),
- 'green': ((0., 0., 0.), (1.0, 1.0, 1.0)),
- 'blue': ((0., 1., 1.), (1.0, 0.5, 0.5))}
-
-_nipy_spectral_data = {
- 'red': [(0.0, 0.0, 0.0), (0.05, 0.4667, 0.4667),
- (0.10, 0.5333, 0.5333), (0.15, 0.0, 0.0),
- (0.20, 0.0, 0.0), (0.25, 0.0, 0.0),
- (0.30, 0.0, 0.0), (0.35, 0.0, 0.0),
- (0.40, 0.0, 0.0), (0.45, 0.0, 0.0),
- (0.50, 0.0, 0.0), (0.55, 0.0, 0.0),
- (0.60, 0.0, 0.0), (0.65, 0.7333, 0.7333),
- (0.70, 0.9333, 0.9333), (0.75, 1.0, 1.0),
- (0.80, 1.0, 1.0), (0.85, 1.0, 1.0),
- (0.90, 0.8667, 0.8667), (0.95, 0.80, 0.80),
- (1.0, 0.80, 0.80)],
- 'green': [(0.0, 0.0, 0.0), (0.05, 0.0, 0.0),
- (0.10, 0.0, 0.0), (0.15, 0.0, 0.0),
- (0.20, 0.0, 0.0), (0.25, 0.4667, 0.4667),
- (0.30, 0.6000, 0.6000), (0.35, 0.6667, 0.6667),
- (0.40, 0.6667, 0.6667), (0.45, 0.6000, 0.6000),
- (0.50, 0.7333, 0.7333), (0.55, 0.8667, 0.8667),
- (0.60, 1.0, 1.0), (0.65, 1.0, 1.0),
- (0.70, 0.9333, 0.9333), (0.75, 0.8000, 0.8000),
- (0.80, 0.6000, 0.6000), (0.85, 0.0, 0.0),
- (0.90, 0.0, 0.0), (0.95, 0.0, 0.0),
- (1.0, 0.80, 0.80)],
- 'blue': [(0.0, 0.0, 0.0), (0.05, 0.5333, 0.5333),
- (0.10, 0.6000, 0.6000), (0.15, 0.6667, 0.6667),
- (0.20, 0.8667, 0.8667), (0.25, 0.8667, 0.8667),
- (0.30, 0.8667, 0.8667), (0.35, 0.6667, 0.6667),
- (0.40, 0.5333, 0.5333), (0.45, 0.0, 0.0),
- (0.5, 0.0, 0.0), (0.55, 0.0, 0.0),
- (0.60, 0.0, 0.0), (0.65, 0.0, 0.0),
- (0.70, 0.0, 0.0), (0.75, 0.0, 0.0),
- (0.80, 0.0, 0.0), (0.85, 0.0, 0.0),
- (0.90, 0.0, 0.0), (0.95, 0.0, 0.0),
- (1.0, 0.80, 0.80)],
-}
-
-
-# 34 colormaps based on color specifications and designs
-# developed by Cynthia Brewer (http://colorbrewer.org).
-# The ColorBrewer palettes have been included under the terms
-# of an Apache-stype license (for details, see the file
-# LICENSE_COLORBREWER in the license directory of the matplotlib
-# source distribution).
-
-_Accent_data = {'blue': [(0.0, 0.49803921580314636,
-0.49803921580314636), (0.14285714285714285, 0.83137255907058716,
-0.83137255907058716), (0.2857142857142857, 0.52549022436141968,
-0.52549022436141968), (0.42857142857142855, 0.60000002384185791,
-0.60000002384185791), (0.5714285714285714, 0.69019609689712524,
-0.69019609689712524), (0.7142857142857143, 0.49803921580314636,
-0.49803921580314636), (0.8571428571428571, 0.090196080505847931,
-0.090196080505847931), (1.0, 0.40000000596046448,
-0.40000000596046448)],
-
- 'green': [(0.0, 0.78823530673980713, 0.78823530673980713),
- (0.14285714285714285, 0.68235296010971069, 0.68235296010971069),
- (0.2857142857142857, 0.75294119119644165, 0.75294119119644165),
- (0.42857142857142855, 1.0, 1.0), (0.5714285714285714,
- 0.42352941632270813, 0.42352941632270813), (0.7142857142857143,
- 0.0078431377187371254, 0.0078431377187371254),
- (0.8571428571428571, 0.35686275362968445, 0.35686275362968445),
- (1.0, 0.40000000596046448, 0.40000000596046448)],
-
- 'red': [(0.0, 0.49803921580314636, 0.49803921580314636),
- (0.14285714285714285, 0.7450980544090271, 0.7450980544090271),
- (0.2857142857142857, 0.99215686321258545, 0.99215686321258545),
- (0.42857142857142855, 1.0, 1.0), (0.5714285714285714,
- 0.21960784494876862, 0.21960784494876862), (0.7142857142857143,
- 0.94117647409439087, 0.94117647409439087), (0.8571428571428571,
- 0.74901962280273438, 0.74901962280273438), (1.0,
- 0.40000000596046448, 0.40000000596046448)]}
-
-_Blues_data = {'blue': [(0.0, 1.0, 1.0), (0.125, 0.9686274528503418,
-0.9686274528503418), (0.25, 0.93725490570068359, 0.93725490570068359),
-(0.375, 0.88235294818878174, 0.88235294818878174), (0.5,
-0.83921569585800171, 0.83921569585800171), (0.625, 0.7764706015586853,
-0.7764706015586853), (0.75, 0.70980393886566162, 0.70980393886566162),
-(0.875, 0.61176472902297974, 0.61176472902297974), (1.0,
-0.41960784792900085, 0.41960784792900085)],
-
- 'green': [(0.0, 0.9843137264251709, 0.9843137264251709), (0.125,
- 0.92156863212585449, 0.92156863212585449), (0.25,
- 0.85882353782653809, 0.85882353782653809), (0.375,
- 0.7921568751335144, 0.7921568751335144), (0.5,
- 0.68235296010971069, 0.68235296010971069), (0.625,
- 0.57254904508590698, 0.57254904508590698), (0.75,
- 0.44313725829124451, 0.44313725829124451), (0.875,
- 0.31764706969261169, 0.31764706969261169), (1.0,
- 0.18823529779911041, 0.18823529779911041)],
-
- 'red': [(0.0, 0.9686274528503418, 0.9686274528503418), (0.125,
- 0.87058824300765991, 0.87058824300765991), (0.25,
- 0.7764706015586853, 0.7764706015586853), (0.375,
- 0.61960786581039429, 0.61960786581039429), (0.5,
- 0.41960784792900085, 0.41960784792900085), (0.625,
- 0.25882354378700256, 0.25882354378700256), (0.75,
- 0.12941177189350128, 0.12941177189350128), (0.875,
- 0.031372550874948502, 0.031372550874948502), (1.0,
- 0.031372550874948502, 0.031372550874948502)]}
-
-_BrBG_data = {'blue': [(0.0, 0.019607843831181526,
-0.019607843831181526), (0.10000000000000001, 0.039215687662363052,
-0.039215687662363052), (0.20000000000000001, 0.17647059261798859,
-0.17647059261798859), (0.29999999999999999, 0.49019607901573181,
-0.49019607901573181), (0.40000000000000002, 0.76470589637756348,
-0.76470589637756348), (0.5, 0.96078431606292725, 0.96078431606292725),
-(0.59999999999999998, 0.89803922176361084, 0.89803922176361084),
-(0.69999999999999996, 0.75686275959014893, 0.75686275959014893),
-(0.80000000000000004, 0.56078433990478516, 0.56078433990478516),
-(0.90000000000000002, 0.36862745881080627, 0.36862745881080627), (1.0,
-0.18823529779911041, 0.18823529779911041)],
-
- 'green': [(0.0, 0.18823529779911041, 0.18823529779911041),
- (0.10000000000000001, 0.31764706969261169, 0.31764706969261169),
- (0.20000000000000001, 0.5058823823928833, 0.5058823823928833),
- (0.29999999999999999, 0.7607843279838562, 0.7607843279838562),
- (0.40000000000000002, 0.90980392694473267, 0.90980392694473267),
- (0.5, 0.96078431606292725, 0.96078431606292725),
- (0.59999999999999998, 0.91764706373214722, 0.91764706373214722),
- (0.69999999999999996, 0.80392158031463623, 0.80392158031463623),
- (0.80000000000000004, 0.59215688705444336, 0.59215688705444336),
- (0.90000000000000002, 0.40000000596046448, 0.40000000596046448),
- (1.0, 0.23529411852359772, 0.23529411852359772)],
-
- 'red': [(0.0, 0.32941177487373352, 0.32941177487373352),
- (0.10000000000000001, 0.54901963472366333, 0.54901963472366333),
- (0.20000000000000001, 0.74901962280273438, 0.74901962280273438),
- (0.29999999999999999, 0.87450981140136719, 0.87450981140136719),
- (0.40000000000000002, 0.96470588445663452, 0.96470588445663452),
- (0.5, 0.96078431606292725, 0.96078431606292725),
- (0.59999999999999998, 0.78039216995239258, 0.78039216995239258),
- (0.69999999999999996, 0.50196081399917603, 0.50196081399917603),
- (0.80000000000000004, 0.20784313976764679, 0.20784313976764679),
- (0.90000000000000002, 0.0039215688593685627,
- 0.0039215688593685627), (1.0, 0.0, 0.0)]}
-
-_BuGn_data = {'blue': [(0.0, 0.99215686321258545,
-0.99215686321258545), (0.125, 0.97647058963775635,
-0.97647058963775635), (0.25, 0.90196079015731812,
-0.90196079015731812), (0.375, 0.78823530673980713,
-0.78823530673980713), (0.5, 0.64313727617263794, 0.64313727617263794),
-(0.625, 0.46274510025978088, 0.46274510025978088), (0.75,
-0.27058824896812439, 0.27058824896812439), (0.875,
-0.17254902422428131, 0.17254902422428131), (1.0, 0.10588235408067703,
-0.10588235408067703)],
-
- 'green': [(0.0, 0.98823529481887817, 0.98823529481887817), (0.125,
- 0.96078431606292725, 0.96078431606292725), (0.25,
- 0.92549020051956177, 0.92549020051956177), (0.375,
- 0.84705883264541626, 0.84705883264541626), (0.5,
- 0.7607843279838562, 0.7607843279838562), (0.625,
- 0.68235296010971069, 0.68235296010971069), (0.75,
- 0.54509806632995605, 0.54509806632995605), (0.875,
- 0.42745098471641541, 0.42745098471641541), (1.0,
- 0.26666668057441711, 0.26666668057441711)], 'red': [(0.0,
- 0.9686274528503418, 0.9686274528503418), (0.125,
- 0.89803922176361084, 0.89803922176361084), (0.25,
- 0.80000001192092896, 0.80000001192092896), (0.375,
- 0.60000002384185791, 0.60000002384185791), (0.5,
- 0.40000000596046448, 0.40000000596046448), (0.625,
- 0.25490197539329529, 0.25490197539329529), (0.75,
- 0.13725490868091583, 0.13725490868091583), (0.875, 0.0, 0.0),
- (1.0, 0.0, 0.0)]}
-
-_BuPu_data = {'blue': [(0.0, 0.99215686321258545,
-0.99215686321258545), (0.125, 0.95686274766921997,
-0.95686274766921997), (0.25, 0.90196079015731812,
-0.90196079015731812), (0.375, 0.85490196943283081,
-0.85490196943283081), (0.5, 0.7764706015586853, 0.7764706015586853),
-(0.625, 0.69411766529083252, 0.69411766529083252), (0.75,
-0.61568629741668701, 0.61568629741668701), (0.875,
-0.48627451062202454, 0.48627451062202454), (1.0, 0.29411765933036804,
-0.29411765933036804)],
-
- 'green': [(0.0, 0.98823529481887817, 0.98823529481887817), (0.125,
- 0.92549020051956177, 0.92549020051956177), (0.25,
- 0.82745099067687988, 0.82745099067687988), (0.375,
- 0.73725491762161255, 0.73725491762161255), (0.5,
- 0.58823531866073608, 0.58823531866073608), (0.625,
- 0.41960784792900085, 0.41960784792900085), (0.75,
- 0.25490197539329529, 0.25490197539329529), (0.875,
- 0.058823529630899429, 0.058823529630899429), (1.0, 0.0, 0.0)],
-
- 'red': [(0.0, 0.9686274528503418, 0.9686274528503418), (0.125,
- 0.87843137979507446, 0.87843137979507446), (0.25,
- 0.74901962280273438, 0.74901962280273438), (0.375,
- 0.61960786581039429, 0.61960786581039429), (0.5,
- 0.54901963472366333, 0.54901963472366333), (0.625,
- 0.54901963472366333, 0.54901963472366333), (0.75,
- 0.53333336114883423, 0.53333336114883423), (0.875,
- 0.5058823823928833, 0.5058823823928833), (1.0,
- 0.30196079611778259, 0.30196079611778259)]}
-
-_Dark2_data = {'blue': [(0.0, 0.46666666865348816,
-0.46666666865348816), (0.14285714285714285, 0.0078431377187371254,
-0.0078431377187371254), (0.2857142857142857, 0.70196080207824707,
-0.70196080207824707), (0.42857142857142855, 0.54117649793624878,
-0.54117649793624878), (0.5714285714285714, 0.11764705926179886,
-0.11764705926179886), (0.7142857142857143, 0.0078431377187371254,
-0.0078431377187371254), (0.8571428571428571, 0.11372549086809158,
-0.11372549086809158), (1.0, 0.40000000596046448,
-0.40000000596046448)],
-
- 'green': [(0.0, 0.61960786581039429, 0.61960786581039429),
- (0.14285714285714285, 0.37254902720451355, 0.37254902720451355),
- (0.2857142857142857, 0.43921568989753723, 0.43921568989753723),
- (0.42857142857142855, 0.16078431904315948, 0.16078431904315948),
- (0.5714285714285714, 0.65098041296005249, 0.65098041296005249),
- (0.7142857142857143, 0.67058825492858887, 0.67058825492858887),
- (0.8571428571428571, 0.46274510025978088, 0.46274510025978088),
- (1.0, 0.40000000596046448, 0.40000000596046448)],
-
- 'red': [(0.0, 0.10588235408067703, 0.10588235408067703),
- (0.14285714285714285, 0.85098040103912354, 0.85098040103912354),
- (0.2857142857142857, 0.45882353186607361, 0.45882353186607361),
- (0.42857142857142855, 0.90588235855102539, 0.90588235855102539),
- (0.5714285714285714, 0.40000000596046448, 0.40000000596046448),
- (0.7142857142857143, 0.90196079015731812, 0.90196079015731812),
- (0.8571428571428571, 0.65098041296005249, 0.65098041296005249),
- (1.0, 0.40000000596046448, 0.40000000596046448)]}
-
-_GnBu_data = {'blue': [(0.0, 0.94117647409439087,
-0.94117647409439087), (0.125, 0.85882353782653809,
-0.85882353782653809), (0.25, 0.77254903316497803,
-0.77254903316497803), (0.375, 0.70980393886566162,
-0.70980393886566162), (0.5, 0.76862746477127075, 0.76862746477127075),
-(0.625, 0.82745099067687988, 0.82745099067687988), (0.75,
-0.7450980544090271, 0.7450980544090271), (0.875, 0.67450982332229614,
-0.67450982332229614), (1.0, 0.5058823823928833, 0.5058823823928833)],
-
- 'green': [(0.0, 0.98823529481887817, 0.98823529481887817), (0.125,
- 0.9529411792755127, 0.9529411792755127), (0.25,
- 0.92156863212585449, 0.92156863212585449), (0.375,
- 0.86666667461395264, 0.86666667461395264), (0.5,
- 0.80000001192092896, 0.80000001192092896), (0.625,
- 0.70196080207824707, 0.70196080207824707), (0.75,
- 0.54901963472366333, 0.54901963472366333), (0.875,
- 0.40784314274787903, 0.40784314274787903), (1.0,
- 0.25098040699958801, 0.25098040699958801)],
-
- 'red': [(0.0, 0.9686274528503418, 0.9686274528503418), (0.125,
- 0.87843137979507446, 0.87843137979507446), (0.25,
- 0.80000001192092896, 0.80000001192092896), (0.375,
- 0.65882354974746704, 0.65882354974746704), (0.5,
- 0.48235294222831726, 0.48235294222831726), (0.625,
- 0.30588236451148987, 0.30588236451148987), (0.75,
- 0.16862745583057404, 0.16862745583057404), (0.875,
- 0.031372550874948502, 0.031372550874948502), (1.0,
- 0.031372550874948502, 0.031372550874948502)]}
-
-_Greens_data = {'blue': [(0.0, 0.96078431606292725,
-0.96078431606292725), (0.125, 0.87843137979507446,
-0.87843137979507446), (0.25, 0.75294119119644165,
-0.75294119119644165), (0.375, 0.60784316062927246,
-0.60784316062927246), (0.5, 0.46274510025978088, 0.46274510025978088),
-(0.625, 0.364705890417099, 0.364705890417099), (0.75,
-0.27058824896812439, 0.27058824896812439), (0.875,
-0.17254902422428131, 0.17254902422428131), (1.0, 0.10588235408067703,
-0.10588235408067703)],
-
- 'green': [(0.0, 0.98823529481887817, 0.98823529481887817), (0.125,
- 0.96078431606292725, 0.96078431606292725), (0.25,
- 0.91372549533843994, 0.91372549533843994), (0.375,
- 0.85098040103912354, 0.85098040103912354), (0.5,
- 0.76862746477127075, 0.76862746477127075), (0.625,
- 0.67058825492858887, 0.67058825492858887), (0.75,
- 0.54509806632995605, 0.54509806632995605), (0.875,
- 0.42745098471641541, 0.42745098471641541), (1.0,
- 0.26666668057441711, 0.26666668057441711)],
-
- 'red': [(0.0, 0.9686274528503418, 0.9686274528503418), (0.125,
- 0.89803922176361084, 0.89803922176361084), (0.25,
- 0.78039216995239258, 0.78039216995239258), (0.375,
- 0.63137257099151611, 0.63137257099151611), (0.5,
- 0.45490196347236633, 0.45490196347236633), (0.625,
- 0.25490197539329529, 0.25490197539329529), (0.75,
- 0.13725490868091583, 0.13725490868091583), (0.875, 0.0, 0.0),
- (1.0, 0.0, 0.0)]}
-
-_Greys_data = {'blue': [(0.0, 1.0, 1.0), (0.125, 0.94117647409439087,
-0.94117647409439087), (0.25, 0.85098040103912354,
-0.85098040103912354), (0.375, 0.74117648601531982,
-0.74117648601531982), (0.5, 0.58823531866073608, 0.58823531866073608),
-(0.625, 0.45098039507865906, 0.45098039507865906), (0.75,
-0.32156863808631897, 0.32156863808631897), (0.875,
-0.14509804546833038, 0.14509804546833038), (1.0, 0.0, 0.0)],
-
- 'green': [(0.0, 1.0, 1.0), (0.125, 0.94117647409439087,
- 0.94117647409439087), (0.25, 0.85098040103912354,
- 0.85098040103912354), (0.375, 0.74117648601531982,
- 0.74117648601531982), (0.5, 0.58823531866073608,
- 0.58823531866073608), (0.625, 0.45098039507865906,
- 0.45098039507865906), (0.75, 0.32156863808631897,
- 0.32156863808631897), (0.875, 0.14509804546833038,
- 0.14509804546833038), (1.0, 0.0, 0.0)],
-
- 'red': [(0.0, 1.0, 1.0), (0.125, 0.94117647409439087,
- 0.94117647409439087), (0.25, 0.85098040103912354,
- 0.85098040103912354), (0.375, 0.74117648601531982,
- 0.74117648601531982), (0.5, 0.58823531866073608,
- 0.58823531866073608), (0.625, 0.45098039507865906,
- 0.45098039507865906), (0.75, 0.32156863808631897,
- 0.32156863808631897), (0.875, 0.14509804546833038,
- 0.14509804546833038), (1.0, 0.0, 0.0)]}
-
-_Oranges_data = {'blue': [(0.0, 0.92156863212585449,
-0.92156863212585449), (0.125, 0.80784314870834351,
-0.80784314870834351), (0.25, 0.63529413938522339,
-0.63529413938522339), (0.375, 0.41960784792900085,
-0.41960784792900085), (0.5, 0.23529411852359772, 0.23529411852359772),
-(0.625, 0.074509806931018829, 0.074509806931018829), (0.75,
-0.0039215688593685627, 0.0039215688593685627), (0.875,
-0.011764706112444401, 0.011764706112444401), (1.0,
-0.015686275437474251, 0.015686275437474251)],
-
- 'green': [(0.0, 0.96078431606292725, 0.96078431606292725), (0.125,
- 0.90196079015731812, 0.90196079015731812), (0.25,
- 0.81568628549575806, 0.81568628549575806), (0.375,
- 0.68235296010971069, 0.68235296010971069), (0.5,
- 0.55294120311737061, 0.55294120311737061), (0.625,
- 0.4117647111415863, 0.4117647111415863), (0.75,
- 0.28235295414924622, 0.28235295414924622), (0.875,
- 0.21176470816135406, 0.21176470816135406), (1.0,
- 0.15294118225574493, 0.15294118225574493)],
-
- 'red': [(0.0, 1.0, 1.0), (0.125, 0.99607843160629272,
- 0.99607843160629272), (0.25, 0.99215686321258545,
- 0.99215686321258545), (0.375, 0.99215686321258545,
- 0.99215686321258545), (0.5, 0.99215686321258545,
- 0.99215686321258545), (0.625, 0.94509804248809814,
- 0.94509804248809814), (0.75, 0.85098040103912354,
- 0.85098040103912354), (0.875, 0.65098041296005249,
- 0.65098041296005249), (1.0, 0.49803921580314636,
- 0.49803921580314636)]}
-
-_OrRd_data = {'blue': [(0.0, 0.92549020051956177,
-0.92549020051956177), (0.125, 0.78431373834609985,
-0.78431373834609985), (0.25, 0.61960786581039429,
-0.61960786581039429), (0.375, 0.51764708757400513,
-0.51764708757400513), (0.5, 0.3490196168422699, 0.3490196168422699),
-(0.625, 0.28235295414924622, 0.28235295414924622), (0.75,
-0.12156862765550613, 0.12156862765550613), (0.875, 0.0, 0.0), (1.0,
-0.0, 0.0)],
-
- 'green': [(0.0, 0.9686274528503418, 0.9686274528503418), (0.125,
- 0.90980392694473267, 0.90980392694473267), (0.25,
- 0.83137255907058716, 0.83137255907058716), (0.375,
- 0.73333334922790527, 0.73333334922790527), (0.5,
- 0.55294120311737061, 0.55294120311737061), (0.625,
- 0.3960784375667572, 0.3960784375667572), (0.75,
- 0.18823529779911041, 0.18823529779911041), (0.875, 0.0, 0.0),
- (1.0, 0.0, 0.0)],
-
- 'red': [(0.0, 1.0, 1.0), (0.125, 0.99607843160629272,
- 0.99607843160629272), (0.25, 0.99215686321258545,
- 0.99215686321258545), (0.375, 0.99215686321258545,
- 0.99215686321258545), (0.5, 0.98823529481887817,
- 0.98823529481887817), (0.625, 0.93725490570068359,
- 0.93725490570068359), (0.75, 0.84313726425170898,
- 0.84313726425170898), (0.875, 0.70196080207824707,
- 0.70196080207824707), (1.0, 0.49803921580314636,
- 0.49803921580314636)]}
-
-_Paired_data = {'blue': [(0.0, 0.89019608497619629,
-0.89019608497619629), (0.090909090909090912, 0.70588237047195435,
-0.70588237047195435), (0.18181818181818182, 0.54117649793624878,
-0.54117649793624878), (0.27272727272727271, 0.17254902422428131,
-0.17254902422428131), (0.36363636363636365, 0.60000002384185791,
-0.60000002384185791), (0.45454545454545453, 0.10980392247438431,
-0.10980392247438431), (0.54545454545454541, 0.43529412150382996,
-0.43529412150382996), (0.63636363636363635, 0.0, 0.0),
-(0.72727272727272729, 0.83921569585800171, 0.83921569585800171),
-(0.81818181818181823, 0.60392159223556519, 0.60392159223556519),
-(0.90909090909090906, 0.60000002384185791, 0.60000002384185791), (1.0,
-0.15686275064945221, 0.15686275064945221)],
-
- 'green': [(0.0, 0.80784314870834351, 0.80784314870834351),
- (0.090909090909090912, 0.47058823704719543, 0.47058823704719543),
- (0.18181818181818182, 0.87450981140136719, 0.87450981140136719),
- (0.27272727272727271, 0.62745100259780884, 0.62745100259780884),
- (0.36363636363636365, 0.60392159223556519, 0.60392159223556519),
- (0.45454545454545453, 0.10196078568696976, 0.10196078568696976),
- (0.54545454545454541, 0.74901962280273438, 0.74901962280273438),
- (0.63636363636363635, 0.49803921580314636, 0.49803921580314636),
- (0.72727272727272729, 0.69803923368453979, 0.69803923368453979),
- (0.81818181818181823, 0.23921568691730499, 0.23921568691730499),
- (0.90909090909090906, 1.0, 1.0), (1.0, 0.3490196168422699,
- 0.3490196168422699)],
-
- 'red': [(0.0, 0.65098041296005249, 0.65098041296005249),
- (0.090909090909090912, 0.12156862765550613, 0.12156862765550613),
- (0.18181818181818182, 0.69803923368453979, 0.69803923368453979),
- (0.27272727272727271, 0.20000000298023224, 0.20000000298023224),
- (0.36363636363636365, 0.9843137264251709, 0.9843137264251709),
- (0.45454545454545453, 0.89019608497619629, 0.89019608497619629),
- (0.54545454545454541, 0.99215686321258545, 0.99215686321258545),
- (0.63636363636363635, 1.0, 1.0), (0.72727272727272729,
- 0.7921568751335144, 0.7921568751335144), (0.81818181818181823,
- 0.41568627953529358, 0.41568627953529358), (0.90909090909090906,
- 1.0, 1.0), (1.0, 0.69411766529083252, 0.69411766529083252)]}
-
-_Pastel1_data = {'blue': [(0.0, 0.68235296010971069,
-0.68235296010971069), (0.125, 0.89019608497619629,
-0.89019608497619629), (0.25, 0.77254903316497803,
-0.77254903316497803), (0.375, 0.89411765336990356,
-0.89411765336990356), (0.5, 0.65098041296005249, 0.65098041296005249),
-(0.625, 0.80000001192092896, 0.80000001192092896), (0.75,
-0.74117648601531982, 0.74117648601531982), (0.875,
-0.92549020051956177, 0.92549020051956177), (1.0, 0.94901961088180542,
-0.94901961088180542)],
-
- 'green': [(0.0, 0.70588237047195435, 0.70588237047195435), (0.125,
- 0.80392158031463623, 0.80392158031463623), (0.25,
- 0.92156863212585449, 0.92156863212585449), (0.375,
- 0.79607844352722168, 0.79607844352722168), (0.5,
- 0.85098040103912354, 0.85098040103912354), (0.625, 1.0, 1.0),
- (0.75, 0.84705883264541626, 0.84705883264541626), (0.875,
- 0.85490196943283081, 0.85490196943283081), (1.0,
- 0.94901961088180542, 0.94901961088180542)],
-
- 'red': [(0.0, 0.9843137264251709, 0.9843137264251709), (0.125,
- 0.70196080207824707, 0.70196080207824707), (0.25,
- 0.80000001192092896, 0.80000001192092896), (0.375,
- 0.87058824300765991, 0.87058824300765991), (0.5,
- 0.99607843160629272, 0.99607843160629272), (0.625, 1.0, 1.0),
- (0.75, 0.89803922176361084, 0.89803922176361084), (0.875,
- 0.99215686321258545, 0.99215686321258545), (1.0,
- 0.94901961088180542, 0.94901961088180542)]}
-
-_Pastel2_data = {'blue': [(0.0, 0.80392158031463623,
-0.80392158031463623), (0.14285714285714285, 0.67450982332229614,
-0.67450982332229614), (0.2857142857142857, 0.90980392694473267,
-0.90980392694473267), (0.42857142857142855, 0.89411765336990356,
-0.89411765336990356), (0.5714285714285714, 0.78823530673980713,
-0.78823530673980713), (0.7142857142857143, 0.68235296010971069,
-0.68235296010971069), (0.8571428571428571, 0.80000001192092896,
-0.80000001192092896), (1.0, 0.80000001192092896,
-0.80000001192092896)],
-
- 'green': [(0.0, 0.88627451658248901, 0.88627451658248901),
- (0.14285714285714285, 0.80392158031463623, 0.80392158031463623),
- (0.2857142857142857, 0.83529412746429443, 0.83529412746429443),
- (0.42857142857142855, 0.7921568751335144, 0.7921568751335144),
- (0.5714285714285714, 0.96078431606292725, 0.96078431606292725),
- (0.7142857142857143, 0.94901961088180542, 0.94901961088180542),
- (0.8571428571428571, 0.88627451658248901, 0.88627451658248901),
- (1.0, 0.80000001192092896, 0.80000001192092896)],
-
- 'red': [(0.0, 0.70196080207824707, 0.70196080207824707),
- (0.14285714285714285, 0.99215686321258545, 0.99215686321258545),
- (0.2857142857142857, 0.79607844352722168, 0.79607844352722168),
- (0.42857142857142855, 0.95686274766921997, 0.95686274766921997),
- (0.5714285714285714, 0.90196079015731812, 0.90196079015731812),
- (0.7142857142857143, 1.0, 1.0), (0.8571428571428571,
- 0.94509804248809814, 0.94509804248809814), (1.0,
- 0.80000001192092896, 0.80000001192092896)]}
-
-_PiYG_data = {'blue': [(0.0, 0.32156863808631897,
-0.32156863808631897), (0.10000000000000001, 0.49019607901573181,
-0.49019607901573181), (0.20000000000000001, 0.68235296010971069,
-0.68235296010971069), (0.29999999999999999, 0.85490196943283081,
-0.85490196943283081), (0.40000000000000002, 0.93725490570068359,
-0.93725490570068359), (0.5, 0.9686274528503418, 0.9686274528503418),
-(0.59999999999999998, 0.81568628549575806, 0.81568628549575806),
-(0.69999999999999996, 0.52549022436141968, 0.52549022436141968),
-(0.80000000000000004, 0.25490197539329529, 0.25490197539329529),
-(0.90000000000000002, 0.12941177189350128, 0.12941177189350128), (1.0,
-0.098039217293262482, 0.098039217293262482)],
-
- 'green': [(0.0, 0.0039215688593685627, 0.0039215688593685627),
- (0.10000000000000001, 0.10588235408067703, 0.10588235408067703),
- (0.20000000000000001, 0.46666666865348816, 0.46666666865348816),
- (0.29999999999999999, 0.7137255072593689, 0.7137255072593689),
- (0.40000000000000002, 0.87843137979507446, 0.87843137979507446),
- (0.5, 0.9686274528503418, 0.9686274528503418),
- (0.59999999999999998, 0.96078431606292725, 0.96078431606292725),
- (0.69999999999999996, 0.88235294818878174, 0.88235294818878174),
- (0.80000000000000004, 0.73725491762161255, 0.73725491762161255),
- (0.90000000000000002, 0.57254904508590698, 0.57254904508590698),
- (1.0, 0.39215686917304993, 0.39215686917304993)],
-
- 'red': [(0.0, 0.55686277151107788, 0.55686277151107788),
- (0.10000000000000001, 0.77254903316497803, 0.77254903316497803),
- (0.20000000000000001, 0.87058824300765991, 0.87058824300765991),
- (0.29999999999999999, 0.94509804248809814, 0.94509804248809814),
- (0.40000000000000002, 0.99215686321258545, 0.99215686321258545),
- (0.5, 0.9686274528503418, 0.9686274528503418),
- (0.59999999999999998, 0.90196079015731812, 0.90196079015731812),
- (0.69999999999999996, 0.72156864404678345, 0.72156864404678345),
- (0.80000000000000004, 0.49803921580314636, 0.49803921580314636),
- (0.90000000000000002, 0.30196079611778259, 0.30196079611778259),
- (1.0, 0.15294118225574493, 0.15294118225574493)]}
-
-_PRGn_data = {'blue': [(0.0, 0.29411765933036804,
-0.29411765933036804), (0.10000000000000001, 0.51372551918029785,
-0.51372551918029785), (0.20000000000000001, 0.67058825492858887,
-0.67058825492858887), (0.29999999999999999, 0.81176471710205078,
-0.81176471710205078), (0.40000000000000002, 0.90980392694473267,
-0.90980392694473267), (0.5, 0.9686274528503418, 0.9686274528503418),
-(0.59999999999999998, 0.82745099067687988, 0.82745099067687988),
-(0.69999999999999996, 0.62745100259780884, 0.62745100259780884),
-(0.80000000000000004, 0.3803921639919281, 0.3803921639919281),
-(0.90000000000000002, 0.21568627655506134, 0.21568627655506134), (1.0,
-0.10588235408067703, 0.10588235408067703)],
-
- 'green': [(0.0, 0.0, 0.0), (0.10000000000000001,
- 0.16470588743686676, 0.16470588743686676), (0.20000000000000001,
- 0.43921568989753723, 0.43921568989753723), (0.29999999999999999,
- 0.64705884456634521, 0.64705884456634521), (0.40000000000000002,
- 0.83137255907058716, 0.83137255907058716), (0.5,
- 0.9686274528503418, 0.9686274528503418), (0.59999999999999998,
- 0.94117647409439087, 0.94117647409439087), (0.69999999999999996,
- 0.85882353782653809, 0.85882353782653809), (0.80000000000000004,
- 0.68235296010971069, 0.68235296010971069), (0.90000000000000002,
- 0.47058823704719543, 0.47058823704719543), (1.0,
- 0.26666668057441711, 0.26666668057441711)],
-
- 'red': [(0.0, 0.25098040699958801, 0.25098040699958801),
- (0.10000000000000001, 0.46274510025978088, 0.46274510025978088),
- (0.20000000000000001, 0.60000002384185791, 0.60000002384185791),
- (0.29999999999999999, 0.7607843279838562, 0.7607843279838562),
- (0.40000000000000002, 0.90588235855102539, 0.90588235855102539),
- (0.5, 0.9686274528503418, 0.9686274528503418),
- (0.59999999999999998, 0.85098040103912354, 0.85098040103912354),
- (0.69999999999999996, 0.65098041296005249, 0.65098041296005249),
- (0.80000000000000004, 0.35294118523597717, 0.35294118523597717),
- (0.90000000000000002, 0.10588235408067703, 0.10588235408067703),
- (1.0, 0.0, 0.0)]}
-
-_PuBu_data = {'blue': [(0.0, 0.9843137264251709, 0.9843137264251709),
-(0.125, 0.94901961088180542, 0.94901961088180542), (0.25,
-0.90196079015731812, 0.90196079015731812), (0.375,
-0.85882353782653809, 0.85882353782653809), (0.5, 0.81176471710205078,
-0.81176471710205078), (0.625, 0.75294119119644165,
-0.75294119119644165), (0.75, 0.69019609689712524,
-0.69019609689712524), (0.875, 0.55294120311737061,
-0.55294120311737061), (1.0, 0.34509804844856262,
-0.34509804844856262)],
-
- 'green': [(0.0, 0.9686274528503418, 0.9686274528503418), (0.125,
- 0.90588235855102539, 0.90588235855102539), (0.25,
- 0.81960785388946533, 0.81960785388946533), (0.375,
- 0.74117648601531982, 0.74117648601531982), (0.5,
- 0.66274511814117432, 0.66274511814117432), (0.625,
- 0.56470590829849243, 0.56470590829849243), (0.75,
- 0.43921568989753723, 0.43921568989753723), (0.875,
- 0.35294118523597717, 0.35294118523597717), (1.0,
- 0.21960784494876862, 0.21960784494876862)],
-
- 'red': [(0.0, 1.0, 1.0), (0.125, 0.92549020051956177,
- 0.92549020051956177), (0.25, 0.81568628549575806,
- 0.81568628549575806), (0.375, 0.65098041296005249,
- 0.65098041296005249), (0.5, 0.45490196347236633,
- 0.45490196347236633), (0.625, 0.21176470816135406,
- 0.21176470816135406), (0.75, 0.019607843831181526,
- 0.019607843831181526), (0.875, 0.015686275437474251,
- 0.015686275437474251), (1.0, 0.0078431377187371254,
- 0.0078431377187371254)]}
-
-_PuBuGn_data = {'blue': [(0.0, 0.9843137264251709,
-0.9843137264251709), (0.125, 0.94117647409439087,
-0.94117647409439087), (0.25, 0.90196079015731812,
-0.90196079015731812), (0.375, 0.85882353782653809,
-0.85882353782653809), (0.5, 0.81176471710205078, 0.81176471710205078),
-(0.625, 0.75294119119644165, 0.75294119119644165), (0.75,
-0.54117649793624878, 0.54117649793624878), (0.875, 0.3490196168422699,
-0.3490196168422699), (1.0, 0.21176470816135406, 0.21176470816135406)],
-
- 'green': [(0.0, 0.9686274528503418, 0.9686274528503418), (0.125,
- 0.88627451658248901, 0.88627451658248901), (0.25,
- 0.81960785388946533, 0.81960785388946533), (0.375,
- 0.74117648601531982, 0.74117648601531982), (0.5,
- 0.66274511814117432, 0.66274511814117432), (0.625,
- 0.56470590829849243, 0.56470590829849243), (0.75,
- 0.5058823823928833, 0.5058823823928833), (0.875,
- 0.42352941632270813, 0.42352941632270813), (1.0,
- 0.27450981736183167, 0.27450981736183167)],
-
- 'red': [(0.0, 1.0, 1.0), (0.125, 0.92549020051956177,
- 0.92549020051956177), (0.25, 0.81568628549575806,
- 0.81568628549575806), (0.375, 0.65098041296005249,
- 0.65098041296005249), (0.5, 0.40392157435417175,
- 0.40392157435417175), (0.625, 0.21176470816135406,
- 0.21176470816135406), (0.75, 0.0078431377187371254,
- 0.0078431377187371254), (0.875, 0.0039215688593685627,
- 0.0039215688593685627), (1.0, 0.0039215688593685627,
- 0.0039215688593685627)]}
-
-_PuOr_data = {'blue': [(0.0, 0.031372550874948502,
-0.031372550874948502), (0.10000000000000001, 0.023529412224888802,
-0.023529412224888802), (0.20000000000000001, 0.078431375324726105,
-0.078431375324726105), (0.29999999999999999, 0.38823530077934265,
-0.38823530077934265), (0.40000000000000002, 0.7137255072593689,
-0.7137255072593689), (0.5, 0.9686274528503418, 0.9686274528503418),
-(0.59999999999999998, 0.92156863212585449, 0.92156863212585449),
-(0.69999999999999996, 0.82352942228317261, 0.82352942228317261),
-(0.80000000000000004, 0.67450982332229614, 0.67450982332229614),
-(0.90000000000000002, 0.53333336114883423, 0.53333336114883423), (1.0,
-0.29411765933036804, 0.29411765933036804)],
-
- 'green': [(0.0, 0.23137255012989044, 0.23137255012989044),
- (0.10000000000000001, 0.34509804844856262, 0.34509804844856262),
- (0.20000000000000001, 0.50980395078659058, 0.50980395078659058),
- (0.29999999999999999, 0.72156864404678345, 0.72156864404678345),
- (0.40000000000000002, 0.87843137979507446, 0.87843137979507446),
- (0.5, 0.9686274528503418, 0.9686274528503418),
- (0.59999999999999998, 0.85490196943283081, 0.85490196943283081),
- (0.69999999999999996, 0.67058825492858887, 0.67058825492858887),
- (0.80000000000000004, 0.45098039507865906, 0.45098039507865906),
- (0.90000000000000002, 0.15294118225574493, 0.15294118225574493),
- (1.0, 0.0, 0.0)],
-
- 'red': [(0.0, 0.49803921580314636, 0.49803921580314636),
- (0.10000000000000001, 0.70196080207824707, 0.70196080207824707),
- (0.20000000000000001, 0.87843137979507446, 0.87843137979507446),
- (0.29999999999999999, 0.99215686321258545, 0.99215686321258545),
- (0.40000000000000002, 0.99607843160629272, 0.99607843160629272),
- (0.5, 0.9686274528503418, 0.9686274528503418),
- (0.59999999999999998, 0.84705883264541626, 0.84705883264541626),
- (0.69999999999999996, 0.69803923368453979, 0.69803923368453979),
- (0.80000000000000004, 0.50196081399917603, 0.50196081399917603),
- (0.90000000000000002, 0.32941177487373352, 0.32941177487373352),
- (1.0, 0.17647059261798859, 0.17647059261798859)]}
-
-_PuRd_data = {'blue': [(0.0, 0.97647058963775635,
-0.97647058963775635), (0.125, 0.93725490570068359,
-0.93725490570068359), (0.25, 0.85490196943283081,
-0.85490196943283081), (0.375, 0.78039216995239258,
-0.78039216995239258), (0.5, 0.69019609689712524, 0.69019609689712524),
-(0.625, 0.54117649793624878, 0.54117649793624878), (0.75,
-0.33725491166114807, 0.33725491166114807), (0.875,
-0.26274511218070984, 0.26274511218070984), (1.0, 0.12156862765550613,
-0.12156862765550613)],
-
- 'green': [(0.0, 0.95686274766921997, 0.95686274766921997), (0.125,
- 0.88235294818878174, 0.88235294818878174), (0.25,
- 0.72549021244049072, 0.72549021244049072), (0.375,
- 0.58039218187332153, 0.58039218187332153), (0.5,
- 0.3960784375667572, 0.3960784375667572), (0.625,
- 0.16078431904315948, 0.16078431904315948), (0.75,
- 0.070588238537311554, 0.070588238537311554), (0.875, 0.0, 0.0),
- (1.0, 0.0, 0.0)],
-
- 'red': [(0.0, 0.9686274528503418, 0.9686274528503418), (0.125,
- 0.90588235855102539, 0.90588235855102539), (0.25,
- 0.83137255907058716, 0.83137255907058716), (0.375,
- 0.78823530673980713, 0.78823530673980713), (0.5,
- 0.87450981140136719, 0.87450981140136719), (0.625,
- 0.90588235855102539, 0.90588235855102539), (0.75,
- 0.80784314870834351, 0.80784314870834351), (0.875,
- 0.59607845544815063, 0.59607845544815063), (1.0,
- 0.40392157435417175, 0.40392157435417175)]}
-
-_Purples_data = {'blue': [(0.0, 0.99215686321258545,
-0.99215686321258545), (0.125, 0.96078431606292725,
-0.96078431606292725), (0.25, 0.92156863212585449,
-0.92156863212585449), (0.375, 0.86274510622024536,
-0.86274510622024536), (0.5, 0.78431373834609985, 0.78431373834609985),
-(0.625, 0.729411780834198, 0.729411780834198), (0.75,
-0.63921570777893066, 0.63921570777893066), (0.875,
-0.56078433990478516, 0.56078433990478516), (1.0, 0.49019607901573181,
-0.49019607901573181)],
-
- 'green': [(0.0, 0.9843137264251709, 0.9843137264251709), (0.125,
- 0.92941176891326904, 0.92941176891326904), (0.25,
- 0.85490196943283081, 0.85490196943283081), (0.375,
- 0.74117648601531982, 0.74117648601531982), (0.5,
- 0.60392159223556519, 0.60392159223556519), (0.625,
- 0.49019607901573181, 0.49019607901573181), (0.75,
- 0.31764706969261169, 0.31764706969261169), (0.875,
- 0.15294118225574493, 0.15294118225574493), (1.0, 0.0, 0.0)],
-
- 'red': [(0.0, 0.98823529481887817, 0.98823529481887817), (0.125,
- 0.93725490570068359, 0.93725490570068359), (0.25,
- 0.85490196943283081, 0.85490196943283081), (0.375,
- 0.73725491762161255, 0.73725491762161255), (0.5,
- 0.61960786581039429, 0.61960786581039429), (0.625,
- 0.50196081399917603, 0.50196081399917603), (0.75,
- 0.41568627953529358, 0.41568627953529358), (0.875,
- 0.32941177487373352, 0.32941177487373352), (1.0,
- 0.24705882370471954, 0.24705882370471954)]}
-
-_RdBu_data = {'blue': [(0.0, 0.12156862765550613,
-0.12156862765550613), (0.10000000000000001, 0.16862745583057404,
-0.16862745583057404), (0.20000000000000001, 0.30196079611778259,
-0.30196079611778259), (0.29999999999999999, 0.50980395078659058,
-0.50980395078659058), (0.40000000000000002, 0.78039216995239258,
-0.78039216995239258), (0.5, 0.9686274528503418, 0.9686274528503418),
-(0.59999999999999998, 0.94117647409439087, 0.94117647409439087),
-(0.69999999999999996, 0.87058824300765991, 0.87058824300765991),
-(0.80000000000000004, 0.76470589637756348, 0.76470589637756348),
-(0.90000000000000002, 0.67450982332229614, 0.67450982332229614), (1.0,
-0.3803921639919281, 0.3803921639919281)],
-
- 'green': [(0.0, 0.0, 0.0), (0.10000000000000001,
- 0.094117648899555206, 0.094117648899555206), (0.20000000000000001,
- 0.37647059559822083, 0.37647059559822083), (0.29999999999999999,
- 0.64705884456634521, 0.64705884456634521), (0.40000000000000002,
- 0.85882353782653809, 0.85882353782653809), (0.5,
- 0.9686274528503418, 0.9686274528503418), (0.59999999999999998,
- 0.89803922176361084, 0.89803922176361084), (0.69999999999999996,
- 0.77254903316497803, 0.77254903316497803), (0.80000000000000004,
- 0.57647061347961426, 0.57647061347961426), (0.90000000000000002,
- 0.40000000596046448, 0.40000000596046448), (1.0,
- 0.18823529779911041, 0.18823529779911041)],
-
- 'red': [(0.0, 0.40392157435417175, 0.40392157435417175),
- (0.10000000000000001, 0.69803923368453979, 0.69803923368453979),
- (0.20000000000000001, 0.83921569585800171, 0.83921569585800171),
- (0.29999999999999999, 0.95686274766921997, 0.95686274766921997),
- (0.40000000000000002, 0.99215686321258545, 0.99215686321258545),
- (0.5, 0.9686274528503418, 0.9686274528503418),
- (0.59999999999999998, 0.81960785388946533, 0.81960785388946533),
- (0.69999999999999996, 0.57254904508590698, 0.57254904508590698),
- (0.80000000000000004, 0.26274511218070984, 0.26274511218070984),
- (0.90000000000000002, 0.12941177189350128, 0.12941177189350128),
- (1.0, 0.019607843831181526, 0.019607843831181526)]}
-
-_RdGy_data = {'blue': [(0.0, 0.12156862765550613,
-0.12156862765550613), (0.10000000000000001, 0.16862745583057404,
-0.16862745583057404), (0.20000000000000001, 0.30196079611778259,
-0.30196079611778259), (0.29999999999999999, 0.50980395078659058,
-0.50980395078659058), (0.40000000000000002, 0.78039216995239258,
-0.78039216995239258), (0.5, 1.0, 1.0), (0.59999999999999998,
-0.87843137979507446, 0.87843137979507446), (0.69999999999999996,
-0.729411780834198, 0.729411780834198), (0.80000000000000004,
-0.52941179275512695, 0.52941179275512695), (0.90000000000000002,
-0.30196079611778259, 0.30196079611778259), (1.0, 0.10196078568696976,
-0.10196078568696976)],
-
- 'green': [(0.0, 0.0, 0.0), (0.10000000000000001,
- 0.094117648899555206, 0.094117648899555206), (0.20000000000000001,
- 0.37647059559822083, 0.37647059559822083), (0.29999999999999999,
- 0.64705884456634521, 0.64705884456634521), (0.40000000000000002,
- 0.85882353782653809, 0.85882353782653809), (0.5, 1.0, 1.0),
- (0.59999999999999998, 0.87843137979507446, 0.87843137979507446),
- (0.69999999999999996, 0.729411780834198, 0.729411780834198),
- (0.80000000000000004, 0.52941179275512695, 0.52941179275512695),
- (0.90000000000000002, 0.30196079611778259, 0.30196079611778259),
- (1.0, 0.10196078568696976, 0.10196078568696976)],
-
- 'red': [(0.0, 0.40392157435417175, 0.40392157435417175),
- (0.10000000000000001, 0.69803923368453979, 0.69803923368453979),
- (0.20000000000000001, 0.83921569585800171, 0.83921569585800171),
- (0.29999999999999999, 0.95686274766921997, 0.95686274766921997),
- (0.40000000000000002, 0.99215686321258545, 0.99215686321258545),
- (0.5, 1.0, 1.0), (0.59999999999999998, 0.87843137979507446,
- 0.87843137979507446), (0.69999999999999996, 0.729411780834198,
- 0.729411780834198), (0.80000000000000004, 0.52941179275512695,
- 0.52941179275512695), (0.90000000000000002, 0.30196079611778259,
- 0.30196079611778259), (1.0, 0.10196078568696976,
- 0.10196078568696976)]}
-
-_RdPu_data = {'blue': [(0.0, 0.9529411792755127, 0.9529411792755127),
-(0.125, 0.86666667461395264, 0.86666667461395264), (0.25,
-0.75294119119644165, 0.75294119119644165), (0.375,
-0.70980393886566162, 0.70980393886566162), (0.5, 0.63137257099151611,
-0.63137257099151611), (0.625, 0.59215688705444336,
-0.59215688705444336), (0.75, 0.49411764740943909,
-0.49411764740943909), (0.875, 0.46666666865348816,
-0.46666666865348816), (1.0, 0.41568627953529358,
-0.41568627953529358)],
-
- 'green': [(0.0, 0.9686274528503418, 0.9686274528503418), (0.125,
- 0.87843137979507446, 0.87843137979507446), (0.25,
- 0.77254903316497803, 0.77254903316497803), (0.375,
- 0.62352943420410156, 0.62352943420410156), (0.5,
- 0.40784314274787903, 0.40784314274787903), (0.625,
- 0.20392157137393951, 0.20392157137393951), (0.75,
- 0.0039215688593685627, 0.0039215688593685627), (0.875,
- 0.0039215688593685627, 0.0039215688593685627), (1.0, 0.0, 0.0)],
-
- 'red': [(0.0, 1.0, 1.0), (0.125, 0.99215686321258545,
- 0.99215686321258545), (0.25, 0.98823529481887817,
- 0.98823529481887817), (0.375, 0.98039215803146362,
- 0.98039215803146362), (0.5, 0.9686274528503418,
- 0.9686274528503418), (0.625, 0.86666667461395264,
- 0.86666667461395264), (0.75, 0.68235296010971069,
- 0.68235296010971069), (0.875, 0.47843137383460999,
- 0.47843137383460999), (1.0, 0.28627452254295349,
- 0.28627452254295349)]}
-
-_RdYlBu_data = {'blue': [(0.0, 0.14901961386203766,
- 0.14901961386203766), (0.10000000149011612,
- 0.15294118225574493, 0.15294118225574493),
- (0.20000000298023224, 0.26274511218070984,
- 0.26274511218070984), (0.30000001192092896,
- 0.3803921639919281, 0.3803921639919281),
- (0.40000000596046448, 0.56470590829849243,
- 0.56470590829849243), (0.5, 0.74901962280273438,
- 0.74901962280273438), (0.60000002384185791,
- 0.97254902124404907, 0.97254902124404907),
- (0.69999998807907104, 0.91372549533843994,
- 0.91372549533843994), (0.80000001192092896,
- 0.81960785388946533, 0.81960785388946533),
- (0.89999997615814209, 0.70588237047195435,
- 0.70588237047195435), (1.0, 0.58431375026702881,
- 0.58431375026702881)], 'green': [(0.0, 0.0, 0.0),
- (0.10000000149011612, 0.18823529779911041,
- 0.18823529779911041), (0.20000000298023224,
- 0.42745098471641541, 0.42745098471641541),
- (0.30000001192092896, 0.68235296010971069,
- 0.68235296010971069), (0.40000000596046448,
- 0.87843137979507446, 0.87843137979507446), (0.5, 1.0,
- 1.0), (0.60000002384185791, 0.9529411792755127,
- 0.9529411792755127), (0.69999998807907104,
- 0.85098040103912354, 0.85098040103912354),
- (0.80000001192092896, 0.67843139171600342,
- 0.67843139171600342), (0.89999997615814209,
- 0.45882353186607361, 0.45882353186607361), (1.0,
- 0.21176470816135406, 0.21176470816135406)], 'red':
- [(0.0, 0.64705884456634521, 0.64705884456634521),
- (0.10000000149011612, 0.84313726425170898,
- 0.84313726425170898), (0.20000000298023224,
- 0.95686274766921997, 0.95686274766921997),
- (0.30000001192092896, 0.99215686321258545,
- 0.99215686321258545), (0.40000000596046448,
- 0.99607843160629272, 0.99607843160629272), (0.5, 1.0,
- 1.0), (0.60000002384185791, 0.87843137979507446,
- 0.87843137979507446), (0.69999998807907104,
- 0.67058825492858887, 0.67058825492858887),
- (0.80000001192092896, 0.45490196347236633,
- 0.45490196347236633), (0.89999997615814209,
- 0.27058824896812439, 0.27058824896812439), (1.0,
- 0.19215686619281769, 0.19215686619281769)]}
-
-_RdYlGn_data = {'blue': [(0.0, 0.14901961386203766,
-0.14901961386203766), (0.10000000000000001, 0.15294118225574493,
-0.15294118225574493), (0.20000000000000001, 0.26274511218070984,
-0.26274511218070984), (0.29999999999999999, 0.3803921639919281,
-0.3803921639919281), (0.40000000000000002, 0.54509806632995605,
-0.54509806632995605), (0.5, 0.74901962280273438, 0.74901962280273438),
-(0.59999999999999998, 0.54509806632995605, 0.54509806632995605),
-(0.69999999999999996, 0.41568627953529358, 0.41568627953529358),
-(0.80000000000000004, 0.38823530077934265, 0.38823530077934265),
-(0.90000000000000002, 0.31372550129890442, 0.31372550129890442), (1.0,
-0.21568627655506134, 0.21568627655506134)],
-
- 'green': [(0.0, 0.0, 0.0), (0.10000000000000001,
- 0.18823529779911041, 0.18823529779911041), (0.20000000000000001,
- 0.42745098471641541, 0.42745098471641541), (0.29999999999999999,
- 0.68235296010971069, 0.68235296010971069), (0.40000000000000002,
- 0.87843137979507446, 0.87843137979507446), (0.5, 1.0, 1.0),
- (0.59999999999999998, 0.93725490570068359, 0.93725490570068359),
- (0.69999999999999996, 0.85098040103912354, 0.85098040103912354),
- (0.80000000000000004, 0.74117648601531982, 0.74117648601531982),
- (0.90000000000000002, 0.59607845544815063, 0.59607845544815063),
- (1.0, 0.40784314274787903, 0.40784314274787903)],
-
- 'red': [(0.0, 0.64705884456634521, 0.64705884456634521),
- (0.10000000000000001, 0.84313726425170898, 0.84313726425170898),
- (0.20000000000000001, 0.95686274766921997, 0.95686274766921997),
- (0.29999999999999999, 0.99215686321258545, 0.99215686321258545),
- (0.40000000000000002, 0.99607843160629272, 0.99607843160629272),
- (0.5, 1.0, 1.0), (0.59999999999999998, 0.85098040103912354,
- 0.85098040103912354), (0.69999999999999996, 0.65098041296005249,
- 0.65098041296005249), (0.80000000000000004, 0.40000000596046448,
- 0.40000000596046448), (0.90000000000000002, 0.10196078568696976,
- 0.10196078568696976), (1.0, 0.0, 0.0)]}
-
-_Reds_data = {'blue': [(0.0, 0.94117647409439087,
-0.94117647409439087), (0.125, 0.82352942228317261,
-0.82352942228317261), (0.25, 0.63137257099151611,
-0.63137257099151611), (0.375, 0.44705882668495178,
-0.44705882668495178), (0.5, 0.29019609093666077, 0.29019609093666077),
-(0.625, 0.17254902422428131, 0.17254902422428131), (0.75,
-0.11372549086809158, 0.11372549086809158), (0.875,
-0.08235294371843338, 0.08235294371843338), (1.0, 0.050980392843484879,
-0.050980392843484879)],
-
- 'green': [(0.0, 0.96078431606292725, 0.96078431606292725), (0.125,
- 0.87843137979507446, 0.87843137979507446), (0.25,
- 0.73333334922790527, 0.73333334922790527), (0.375,
- 0.57254904508590698, 0.57254904508590698), (0.5,
- 0.41568627953529358, 0.41568627953529358), (0.625,
- 0.23137255012989044, 0.23137255012989044), (0.75,
- 0.094117648899555206, 0.094117648899555206), (0.875,
- 0.058823529630899429, 0.058823529630899429), (1.0, 0.0, 0.0)],
-
- 'red': [(0.0, 1.0, 1.0), (0.125, 0.99607843160629272,
- 0.99607843160629272), (0.25, 0.98823529481887817,
- 0.98823529481887817), (0.375, 0.98823529481887817,
- 0.98823529481887817), (0.5, 0.9843137264251709,
- 0.9843137264251709), (0.625, 0.93725490570068359,
- 0.93725490570068359), (0.75, 0.79607844352722168,
- 0.79607844352722168), (0.875, 0.64705884456634521,
- 0.64705884456634521), (1.0, 0.40392157435417175,
- 0.40392157435417175)]}
-
-_Set1_data = {'blue': [(0.0, 0.10980392247438431,
-0.10980392247438431), (0.125, 0.72156864404678345,
-0.72156864404678345), (0.25, 0.29019609093666077,
-0.29019609093666077), (0.375, 0.63921570777893066,
-0.63921570777893066), (0.5, 0.0, 0.0), (0.625, 0.20000000298023224,
-0.20000000298023224), (0.75, 0.15686275064945221,
-0.15686275064945221), (0.875, 0.74901962280273438,
-0.74901962280273438), (1.0, 0.60000002384185791,
-0.60000002384185791)],
-
- 'green': [(0.0, 0.10196078568696976, 0.10196078568696976), (0.125,
- 0.49411764740943909, 0.49411764740943909), (0.25,
- 0.68627452850341797, 0.68627452850341797), (0.375,
- 0.30588236451148987, 0.30588236451148987), (0.5,
- 0.49803921580314636, 0.49803921580314636), (0.625, 1.0, 1.0),
- (0.75, 0.33725491166114807, 0.33725491166114807), (0.875,
- 0.5058823823928833, 0.5058823823928833), (1.0,
- 0.60000002384185791, 0.60000002384185791)],
-
- 'red': [(0.0, 0.89411765336990356, 0.89411765336990356), (0.125,
- 0.21568627655506134, 0.21568627655506134), (0.25,
- 0.30196079611778259, 0.30196079611778259), (0.375,
- 0.59607845544815063, 0.59607845544815063), (0.5, 1.0, 1.0),
- (0.625, 1.0, 1.0), (0.75, 0.65098041296005249,
- 0.65098041296005249), (0.875, 0.9686274528503418,
- 0.9686274528503418), (1.0, 0.60000002384185791,
- 0.60000002384185791)]}
-
-_Set2_data = {'blue': [(0.0, 0.64705884456634521,
-0.64705884456634521), (0.14285714285714285, 0.38431373238563538,
-0.38431373238563538), (0.2857142857142857, 0.79607844352722168,
-0.79607844352722168), (0.42857142857142855, 0.76470589637756348,
-0.76470589637756348), (0.5714285714285714, 0.32941177487373352,
-0.32941177487373352), (0.7142857142857143, 0.18431372940540314,
-0.18431372940540314), (0.8571428571428571, 0.58039218187332153,
-0.58039218187332153), (1.0, 0.70196080207824707,
-0.70196080207824707)],
-
- 'green': [(0.0, 0.7607843279838562, 0.7607843279838562),
- (0.14285714285714285, 0.55294120311737061, 0.55294120311737061),
- (0.2857142857142857, 0.62745100259780884, 0.62745100259780884),
- (0.42857142857142855, 0.54117649793624878, 0.54117649793624878),
- (0.5714285714285714, 0.84705883264541626, 0.84705883264541626),
- (0.7142857142857143, 0.85098040103912354, 0.85098040103912354),
- (0.8571428571428571, 0.76862746477127075, 0.76862746477127075),
- (1.0, 0.70196080207824707, 0.70196080207824707)],
-
- 'red': [(0.0, 0.40000000596046448, 0.40000000596046448),
- (0.14285714285714285, 0.98823529481887817, 0.98823529481887817),
- (0.2857142857142857, 0.55294120311737061, 0.55294120311737061),
- (0.42857142857142855, 0.90588235855102539, 0.90588235855102539),
- (0.5714285714285714, 0.65098041296005249, 0.65098041296005249),
- (0.7142857142857143, 1.0, 1.0), (0.8571428571428571,
- 0.89803922176361084, 0.89803922176361084), (1.0,
- 0.70196080207824707, 0.70196080207824707)]}
-
-_Set3_data = {'blue': [(0.0, 0.78039216995239258,
-0.78039216995239258), (0.090909090909090912, 0.70196080207824707,
-0.70196080207824707), (0.18181818181818182, 0.85490196943283081,
-0.85490196943283081), (0.27272727272727271, 0.44705882668495178,
-0.44705882668495178), (0.36363636363636365, 0.82745099067687988,
-0.82745099067687988), (0.45454545454545453, 0.38431373238563538,
-0.38431373238563538), (0.54545454545454541, 0.4117647111415863,
-0.4117647111415863), (0.63636363636363635, 0.89803922176361084,
-0.89803922176361084), (0.72727272727272729, 0.85098040103912354,
-0.85098040103912354), (0.81818181818181823, 0.74117648601531982,
-0.74117648601531982), (0.90909090909090906, 0.77254903316497803,
-0.77254903316497803), (1.0, 0.43529412150382996,
-0.43529412150382996)],
-
- 'green': [(0.0, 0.82745099067687988, 0.82745099067687988),
- (0.090909090909090912, 1.0, 1.0), (0.18181818181818182,
- 0.729411780834198, 0.729411780834198), (0.27272727272727271,
- 0.50196081399917603, 0.50196081399917603), (0.36363636363636365,
- 0.69411766529083252, 0.69411766529083252), (0.45454545454545453,
- 0.70588237047195435, 0.70588237047195435), (0.54545454545454541,
- 0.87058824300765991, 0.87058824300765991), (0.63636363636363635,
- 0.80392158031463623, 0.80392158031463623), (0.72727272727272729,
- 0.85098040103912354, 0.85098040103912354), (0.81818181818181823,
- 0.50196081399917603, 0.50196081399917603), (0.90909090909090906,
- 0.92156863212585449, 0.92156863212585449), (1.0,
- 0.92941176891326904, 0.92941176891326904)],
-
- 'red': [(0.0, 0.55294120311737061, 0.55294120311737061),
- (0.090909090909090912, 1.0, 1.0), (0.18181818181818182,
- 0.7450980544090271, 0.7450980544090271), (0.27272727272727271,
- 0.9843137264251709, 0.9843137264251709), (0.36363636363636365,
- 0.50196081399917603, 0.50196081399917603), (0.45454545454545453,
- 0.99215686321258545, 0.99215686321258545), (0.54545454545454541,
- 0.70196080207824707, 0.70196080207824707), (0.63636363636363635,
- 0.98823529481887817, 0.98823529481887817), (0.72727272727272729,
- 0.85098040103912354, 0.85098040103912354), (0.81818181818181823,
- 0.73725491762161255, 0.73725491762161255), (0.90909090909090906,
- 0.80000001192092896, 0.80000001192092896), (1.0, 1.0, 1.0)]}
-
-_Spectral_data = {'blue': [(0.0, 0.25882354378700256,
-0.25882354378700256), (0.10000000000000001, 0.30980393290519714,
-0.30980393290519714), (0.20000000000000001, 0.26274511218070984,
-0.26274511218070984), (0.29999999999999999, 0.3803921639919281,
-0.3803921639919281), (0.40000000000000002, 0.54509806632995605,
-0.54509806632995605), (0.5, 0.74901962280273438, 0.74901962280273438),
-(0.59999999999999998, 0.59607845544815063, 0.59607845544815063),
-(0.69999999999999996, 0.64313727617263794, 0.64313727617263794),
-(0.80000000000000004, 0.64705884456634521, 0.64705884456634521),
-(0.90000000000000002, 0.74117648601531982, 0.74117648601531982), (1.0,
-0.63529413938522339, 0.63529413938522339)],
-
- 'green': [(0.0, 0.0039215688593685627, 0.0039215688593685627),
- (0.10000000000000001, 0.24313725531101227, 0.24313725531101227),
- (0.20000000000000001, 0.42745098471641541, 0.42745098471641541),
- (0.29999999999999999, 0.68235296010971069, 0.68235296010971069),
- (0.40000000000000002, 0.87843137979507446, 0.87843137979507446),
- (0.5, 1.0, 1.0), (0.59999999999999998, 0.96078431606292725,
- 0.96078431606292725), (0.69999999999999996, 0.86666667461395264,
- 0.86666667461395264), (0.80000000000000004, 0.7607843279838562,
- 0.7607843279838562), (0.90000000000000002, 0.53333336114883423,
- 0.53333336114883423), (1.0, 0.30980393290519714,
- 0.30980393290519714)],
-
- 'red': [(0.0, 0.61960786581039429, 0.61960786581039429),
- (0.10000000000000001, 0.83529412746429443, 0.83529412746429443),
- (0.20000000000000001, 0.95686274766921997, 0.95686274766921997),
- (0.29999999999999999, 0.99215686321258545, 0.99215686321258545),
- (0.40000000000000002, 0.99607843160629272, 0.99607843160629272),
- (0.5, 1.0, 1.0), (0.59999999999999998, 0.90196079015731812,
- 0.90196079015731812), (0.69999999999999996, 0.67058825492858887,
- 0.67058825492858887), (0.80000000000000004, 0.40000000596046448,
- 0.40000000596046448), (0.90000000000000002, 0.19607843458652496,
- 0.19607843458652496), (1.0, 0.36862745881080627,
- 0.36862745881080627)]}
-
-_YlGn_data = {'blue': [(0.0, 0.89803922176361084,
-0.89803922176361084), (0.125, 0.72549021244049072,
-0.72549021244049072), (0.25, 0.63921570777893066,
-0.63921570777893066), (0.375, 0.55686277151107788,
-0.55686277151107788), (0.5, 0.47450980544090271, 0.47450980544090271),
-(0.625, 0.364705890417099, 0.364705890417099), (0.75,
-0.26274511218070984, 0.26274511218070984), (0.875,
-0.21568627655506134, 0.21568627655506134), (1.0, 0.16078431904315948,
-0.16078431904315948)],
-
- 'green': [(0.0, 1.0, 1.0), (0.125, 0.98823529481887817,
- 0.98823529481887817), (0.25, 0.94117647409439087,
- 0.94117647409439087), (0.375, 0.86666667461395264,
- 0.86666667461395264), (0.5, 0.7764706015586853,
- 0.7764706015586853), (0.625, 0.67058825492858887,
- 0.67058825492858887), (0.75, 0.51764708757400513,
- 0.51764708757400513), (0.875, 0.40784314274787903,
- 0.40784314274787903), (1.0, 0.27058824896812439,
- 0.27058824896812439)],
-
- 'red': [(0.0, 1.0, 1.0), (0.125, 0.9686274528503418,
- 0.9686274528503418), (0.25, 0.85098040103912354,
- 0.85098040103912354), (0.375, 0.67843139171600342,
- 0.67843139171600342), (0.5, 0.47058823704719543,
- 0.47058823704719543), (0.625, 0.25490197539329529,
- 0.25490197539329529), (0.75, 0.13725490868091583,
- 0.13725490868091583), (0.875, 0.0, 0.0), (1.0, 0.0, 0.0)]}
-
-_YlGnBu_data = {'blue': [(0.0, 0.85098040103912354,
-0.85098040103912354), (0.125, 0.69411766529083252,
-0.69411766529083252), (0.25, 0.70588237047195435,
-0.70588237047195435), (0.375, 0.73333334922790527,
-0.73333334922790527), (0.5, 0.76862746477127075, 0.76862746477127075),
-(0.625, 0.75294119119644165, 0.75294119119644165), (0.75,
-0.65882354974746704, 0.65882354974746704), (0.875,
-0.58039218187332153, 0.58039218187332153), (1.0, 0.34509804844856262,
-0.34509804844856262)],
-
- 'green': [(0.0, 1.0, 1.0), (0.125, 0.97254902124404907,
- 0.97254902124404907), (0.25, 0.91372549533843994,
- 0.91372549533843994), (0.375, 0.80392158031463623,
- 0.80392158031463623), (0.5, 0.7137255072593689,
- 0.7137255072593689), (0.625, 0.56862747669219971,
- 0.56862747669219971), (0.75, 0.36862745881080627,
- 0.36862745881080627), (0.875, 0.20392157137393951,
- 0.20392157137393951), (1.0, 0.11372549086809158,
- 0.11372549086809158)],
-
- 'red': [(0.0, 1.0, 1.0), (0.125, 0.92941176891326904,
- 0.92941176891326904), (0.25, 0.78039216995239258,
- 0.78039216995239258), (0.375, 0.49803921580314636,
- 0.49803921580314636), (0.5, 0.25490197539329529,
- 0.25490197539329529), (0.625, 0.11372549086809158,
- 0.11372549086809158), (0.75, 0.13333334028720856,
- 0.13333334028720856), (0.875, 0.14509804546833038,
- 0.14509804546833038), (1.0, 0.031372550874948502,
- 0.031372550874948502)]}
-
-_YlOrBr_data = {'blue': [(0.0, 0.89803922176361084,
-0.89803922176361084), (0.125, 0.73725491762161255,
-0.73725491762161255), (0.25, 0.56862747669219971,
-0.56862747669219971), (0.375, 0.30980393290519714,
-0.30980393290519714), (0.5, 0.16078431904315948, 0.16078431904315948),
-(0.625, 0.078431375324726105, 0.078431375324726105), (0.75,
-0.0078431377187371254, 0.0078431377187371254), (0.875,
-0.015686275437474251, 0.015686275437474251), (1.0,
-0.023529412224888802, 0.023529412224888802)],
-
- 'green': [(0.0, 1.0, 1.0), (0.125, 0.9686274528503418,
- 0.9686274528503418), (0.25, 0.89019608497619629,
- 0.89019608497619629), (0.375, 0.76862746477127075,
- 0.76862746477127075), (0.5, 0.60000002384185791,
- 0.60000002384185791), (0.625, 0.43921568989753723,
- 0.43921568989753723), (0.75, 0.29803922772407532,
- 0.29803922772407532), (0.875, 0.20392157137393951,
- 0.20392157137393951), (1.0, 0.14509804546833038,
- 0.14509804546833038)],
-
- 'red': [(0.0, 1.0, 1.0), (0.125, 1.0, 1.0), (0.25,
- 0.99607843160629272, 0.99607843160629272), (0.375,
- 0.99607843160629272, 0.99607843160629272), (0.5,
- 0.99607843160629272, 0.99607843160629272), (0.625,
- 0.92549020051956177, 0.92549020051956177), (0.75,
- 0.80000001192092896, 0.80000001192092896), (0.875,
- 0.60000002384185791, 0.60000002384185791), (1.0,
- 0.40000000596046448, 0.40000000596046448)]}
-
-_YlOrRd_data = {'blue': [(0.0, 0.80000001192092896,
-0.80000001192092896), (0.125, 0.62745100259780884,
-0.62745100259780884), (0.25, 0.46274510025978088,
-0.46274510025978088), (0.375, 0.29803922772407532,
-0.29803922772407532), (0.5, 0.23529411852359772, 0.23529411852359772),
-(0.625, 0.16470588743686676, 0.16470588743686676), (0.75,
-0.10980392247438431, 0.10980392247438431), (0.875,
-0.14901961386203766, 0.14901961386203766), (1.0, 0.14901961386203766,
-0.14901961386203766)],
-
- 'green': [(0.0, 1.0, 1.0), (0.125, 0.92941176891326904,
- 0.92941176891326904), (0.25, 0.85098040103912354,
- 0.85098040103912354), (0.375, 0.69803923368453979,
- 0.69803923368453979), (0.5, 0.55294120311737061,
- 0.55294120311737061), (0.625, 0.30588236451148987,
- 0.30588236451148987), (0.75, 0.10196078568696976,
- 0.10196078568696976), (0.875, 0.0, 0.0), (1.0, 0.0, 0.0)],
-
- 'red': [(0.0, 1.0, 1.0), (0.125, 1.0, 1.0), (0.25,
- 0.99607843160629272, 0.99607843160629272), (0.375,
- 0.99607843160629272, 0.99607843160629272), (0.5,
- 0.99215686321258545, 0.99215686321258545), (0.625,
- 0.98823529481887817, 0.98823529481887817), (0.75,
- 0.89019608497619629, 0.89019608497619629), (0.875,
- 0.74117648601531982, 0.74117648601531982), (1.0,
- 0.50196081399917603, 0.50196081399917603)]}
-
-# The next 7 palettes are from the Yorick scientific visalisation package,
-# an evolution of the GIST package, both by David H. Munro.
-# They are released under a BSD-like license (see LICENSE_YORICK in
-# the license directory of the matplotlib source distribution).
-#
-# Most palette functions have been reduced to simple function descriptions
-# by Reinier Heeres, since the rgb components were mostly straight lines.
-# gist_earth_data and gist_ncar_data were simplified by a script and some
-# manual effort.
-
-_gist_earth_data = \
-{'red': (
-(0.0, 0.0, 0.0000),
-(0.2824, 0.1882, 0.1882),
-(0.4588, 0.2714, 0.2714),
-(0.5490, 0.4719, 0.4719),
-(0.6980, 0.7176, 0.7176),
-(0.7882, 0.7553, 0.7553),
-(1.0000, 0.9922, 0.9922),
-), 'green': (
-(0.0, 0.0, 0.0000),
-(0.0275, 0.0000, 0.0000),
-(0.1098, 0.1893, 0.1893),
-(0.1647, 0.3035, 0.3035),
-(0.2078, 0.3841, 0.3841),
-(0.2824, 0.5020, 0.5020),
-(0.5216, 0.6397, 0.6397),
-(0.6980, 0.7171, 0.7171),
-(0.7882, 0.6392, 0.6392),
-(0.7922, 0.6413, 0.6413),
-(0.8000, 0.6447, 0.6447),
-(0.8078, 0.6481, 0.6481),
-(0.8157, 0.6549, 0.6549),
-(0.8667, 0.6991, 0.6991),
-(0.8745, 0.7103, 0.7103),
-(0.8824, 0.7216, 0.7216),
-(0.8902, 0.7323, 0.7323),
-(0.8980, 0.7430, 0.7430),
-(0.9412, 0.8275, 0.8275),
-(0.9569, 0.8635, 0.8635),
-(0.9647, 0.8816, 0.8816),
-(0.9961, 0.9733, 0.9733),
-(1.0000, 0.9843, 0.9843),
-), 'blue': (
-(0.0, 0.0, 0.0000),
-(0.0039, 0.1684, 0.1684),
-(0.0078, 0.2212, 0.2212),
-(0.0275, 0.4329, 0.4329),
-(0.0314, 0.4549, 0.4549),
-(0.2824, 0.5004, 0.5004),
-(0.4667, 0.2748, 0.2748),
-(0.5451, 0.3205, 0.3205),
-(0.7843, 0.3961, 0.3961),
-(0.8941, 0.6651, 0.6651),
-(1.0000, 0.9843, 0.9843),
-)}
-
-_gist_gray_data = {
- 'red': gfunc[3],
- 'green': gfunc[3],
- 'blue': gfunc[3],
-}
-
-_gist_heat_data = {
- 'red': lambda x: 1.5 * x,
- 'green': lambda x: 2 * x - 1,
- 'blue': lambda x: 4 * x - 3,
-}
-
-_gist_ncar_data = \
-{'red': (
-(0.0, 0.0, 0.0000),
-(0.3098, 0.0000, 0.0000),
-(0.3725, 0.3993, 0.3993),
-(0.4235, 0.5003, 0.5003),
-(0.5333, 1.0000, 1.0000),
-(0.7922, 1.0000, 1.0000),
-(0.8471, 0.6218, 0.6218),
-(0.8980, 0.9235, 0.9235),
-(1.0000, 0.9961, 0.9961),
-), 'green': (
-(0.0, 0.0, 0.0000),
-(0.0510, 0.3722, 0.3722),
-(0.1059, 0.0000, 0.0000),
-(0.1569, 0.7202, 0.7202),
-(0.1608, 0.7537, 0.7537),
-(0.1647, 0.7752, 0.7752),
-(0.2157, 1.0000, 1.0000),
-(0.2588, 0.9804, 0.9804),
-(0.2706, 0.9804, 0.9804),
-(0.3176, 1.0000, 1.0000),
-(0.3686, 0.8081, 0.8081),
-(0.4275, 1.0000, 1.0000),
-(0.5216, 1.0000, 1.0000),
-(0.6314, 0.7292, 0.7292),
-(0.6863, 0.2796, 0.2796),
-(0.7451, 0.0000, 0.0000),
-(0.7922, 0.0000, 0.0000),
-(0.8431, 0.1753, 0.1753),
-(0.8980, 0.5000, 0.5000),
-(1.0000, 0.9725, 0.9725),
-), 'blue': (
-(0.0, 0.5020, 0.5020),
-(0.0510, 0.0222, 0.0222),
-(0.1098, 1.0000, 1.0000),
-(0.2039, 1.0000, 1.0000),
-(0.2627, 0.6145, 0.6145),
-(0.3216, 0.0000, 0.0000),
-(0.4157, 0.0000, 0.0000),
-(0.4745, 0.2342, 0.2342),
-(0.5333, 0.0000, 0.0000),
-(0.5804, 0.0000, 0.0000),
-(0.6314, 0.0549, 0.0549),
-(0.6902, 0.0000, 0.0000),
-(0.7373, 0.0000, 0.0000),
-(0.7922, 0.9738, 0.9738),
-(0.8000, 1.0000, 1.0000),
-(0.8431, 1.0000, 1.0000),
-(0.8980, 0.9341, 0.9341),
-(1.0000, 0.9961, 0.9961),
-)}
-
-_gist_rainbow_data = (
- (0.000, (1.00, 0.00, 0.16)),
- (0.030, (1.00, 0.00, 0.00)),
- (0.215, (1.00, 1.00, 0.00)),
- (0.400, (0.00, 1.00, 0.00)),
- (0.586, (0.00, 1.00, 1.00)),
- (0.770, (0.00, 0.00, 1.00)),
- (0.954, (1.00, 0.00, 1.00)),
- (1.000, (1.00, 0.00, 0.75))
-)
-
-_gist_stern_data = {
- 'red': (
- (0.000, 0.000, 0.000), (0.0547, 1.000, 1.000),
- (0.250, 0.027, 0.250), # (0.2500, 0.250, 0.250),
- (1.000, 1.000, 1.000)),
- 'green': ((0, 0, 0), (1, 1, 1)),
- 'blue': (
- (0.000, 0.000, 0.000), (0.500, 1.000, 1.000),
- (0.735, 0.000, 0.000), (1.000, 1.000, 1.000))
-}
-
-_gist_yarg_data = {
- 'red': lambda x: 1 - x,
- 'green': lambda x: 1 - x,
- 'blue': lambda x: 1 - x,
-}
-
-# This bipolar color map was generated from CoolWarmFloat33.csv of
-# "Diverging Color Maps for Scientific Visualization" by Kenneth Moreland.
-#
-_coolwarm_data = {
- 'red': [
- (0.0, 0.2298057, 0.2298057),
- (0.03125, 0.26623388, 0.26623388),
- (0.0625, 0.30386891, 0.30386891),
- (0.09375, 0.342804478, 0.342804478),
- (0.125, 0.38301334, 0.38301334),
- (0.15625, 0.424369608, 0.424369608),
- (0.1875, 0.46666708, 0.46666708),
- (0.21875, 0.509635204, 0.509635204),
- (0.25, 0.552953156, 0.552953156),
- (0.28125, 0.596262162, 0.596262162),
- (0.3125, 0.639176211, 0.639176211),
- (0.34375, 0.681291281, 0.681291281),
- (0.375, 0.722193294, 0.722193294),
- (0.40625, 0.761464949, 0.761464949),
- (0.4375, 0.798691636, 0.798691636),
- (0.46875, 0.833466556, 0.833466556),
- (0.5, 0.865395197, 0.865395197),
- (0.53125, 0.897787179, 0.897787179),
- (0.5625, 0.924127593, 0.924127593),
- (0.59375, 0.944468518, 0.944468518),
- (0.625, 0.958852946, 0.958852946),
- (0.65625, 0.96732803, 0.96732803),
- (0.6875, 0.969954137, 0.969954137),
- (0.71875, 0.966811177, 0.966811177),
- (0.75, 0.958003065, 0.958003065),
- (0.78125, 0.943660866, 0.943660866),
- (0.8125, 0.923944917, 0.923944917),
- (0.84375, 0.89904617, 0.89904617),
- (0.875, 0.869186849, 0.869186849),
- (0.90625, 0.834620542, 0.834620542),
- (0.9375, 0.795631745, 0.795631745),
- (0.96875, 0.752534934, 0.752534934),
- (1.0, 0.705673158, 0.705673158)],
- 'green': [
- (0.0, 0.298717966, 0.298717966),
- (0.03125, 0.353094838, 0.353094838),
- (0.0625, 0.406535296, 0.406535296),
- (0.09375, 0.458757618, 0.458757618),
- (0.125, 0.50941904, 0.50941904),
- (0.15625, 0.558148092, 0.558148092),
- (0.1875, 0.604562568, 0.604562568),
- (0.21875, 0.648280772, 0.648280772),
- (0.25, 0.688929332, 0.688929332),
- (0.28125, 0.726149107, 0.726149107),
- (0.3125, 0.759599947, 0.759599947),
- (0.34375, 0.788964712, 0.788964712),
- (0.375, 0.813952739, 0.813952739),
- (0.40625, 0.834302879, 0.834302879),
- (0.4375, 0.849786142, 0.849786142),
- (0.46875, 0.860207984, 0.860207984),
- (0.5, 0.86541021, 0.86541021),
- (0.53125, 0.848937047, 0.848937047),
- (0.5625, 0.827384882, 0.827384882),
- (0.59375, 0.800927443, 0.800927443),
- (0.625, 0.769767752, 0.769767752),
- (0.65625, 0.734132809, 0.734132809),
- (0.6875, 0.694266682, 0.694266682),
- (0.71875, 0.650421156, 0.650421156),
- (0.75, 0.602842431, 0.602842431),
- (0.78125, 0.551750968, 0.551750968),
- (0.8125, 0.49730856, 0.49730856),
- (0.84375, 0.439559467, 0.439559467),
- (0.875, 0.378313092, 0.378313092),
- (0.90625, 0.312874446, 0.312874446),
- (0.9375, 0.24128379, 0.24128379),
- (0.96875, 0.157246067, 0.157246067),
- (1.0, 0.01555616, 0.01555616)],
- 'blue': [
- (0.0, 0.753683153, 0.753683153),
- (0.03125, 0.801466763, 0.801466763),
- (0.0625, 0.84495867, 0.84495867),
- (0.09375, 0.883725899, 0.883725899),
- (0.125, 0.917387822, 0.917387822),
- (0.15625, 0.945619588, 0.945619588),
- (0.1875, 0.968154911, 0.968154911),
- (0.21875, 0.98478814, 0.98478814),
- (0.25, 0.995375608, 0.995375608),
- (0.28125, 0.999836203, 0.999836203),
- (0.3125, 0.998151185, 0.998151185),
- (0.34375, 0.990363227, 0.990363227),
- (0.375, 0.976574709, 0.976574709),
- (0.40625, 0.956945269, 0.956945269),
- (0.4375, 0.931688648, 0.931688648),
- (0.46875, 0.901068838, 0.901068838),
- (0.5, 0.865395561, 0.865395561),
- (0.53125, 0.820880546, 0.820880546),
- (0.5625, 0.774508472, 0.774508472),
- (0.59375, 0.726736146, 0.726736146),
- (0.625, 0.678007945, 0.678007945),
- (0.65625, 0.628751763, 0.628751763),
- (0.6875, 0.579375448, 0.579375448),
- (0.71875, 0.530263762, 0.530263762),
- (0.75, 0.481775914, 0.481775914),
- (0.78125, 0.434243684, 0.434243684),
- (0.8125, 0.387970225, 0.387970225),
- (0.84375, 0.343229596, 0.343229596),
- (0.875, 0.300267182, 0.300267182),
- (0.90625, 0.259301199, 0.259301199),
- (0.9375, 0.220525627, 0.220525627),
- (0.96875, 0.184115123, 0.184115123),
- (1.0, 0.150232812, 0.150232812)]
- }
-
-# Implementation of Carey Rappaport's CMRmap.
-# See `A Color Map for Effective Black-and-White Rendering of Color-Scale
-# Images' by Carey Rappaport
-# http://www.mathworks.com/matlabcentral/fileexchange/2662-cmrmap-m
-_CMRmap_data = {'red': ((0.000, 0.00, 0.00),
- (0.125, 0.15, 0.15),
- (0.250, 0.30, 0.30),
- (0.375, 0.60, 0.60),
- (0.500, 1.00, 1.00),
- (0.625, 0.90, 0.90),
- (0.750, 0.90, 0.90),
- (0.875, 0.90, 0.90),
- (1.000, 1.00, 1.00)),
- 'green': ((0.000, 0.00, 0.00),
- (0.125, 0.15, 0.15),
- (0.250, 0.15, 0.15),
- (0.375, 0.20, 0.20),
- (0.500, 0.25, 0.25),
- (0.625, 0.50, 0.50),
- (0.750, 0.75, 0.75),
- (0.875, 0.90, 0.90),
- (1.000, 1.00, 1.00)),
- 'blue': ((0.000, 0.00, 0.00),
- (0.125, 0.50, 0.50),
- (0.250, 0.75, 0.75),
- (0.375, 0.50, 0.50),
- (0.500, 0.15, 0.15),
- (0.625, 0.00, 0.00),
- (0.750, 0.10, 0.10),
- (0.875, 0.50, 0.50),
- (1.000, 1.00, 1.00))}
-
-
-# An MIT licensed, colorblind-friendly heatmap from Wistia:
-# https://github.com/wistia/heatmap-palette
-# http://wistia.com/blog/heatmaps-for-colorblindness
-#
-# >>> import matplotlib.colors as c
-# >>> colors = ["#e4ff7a", "#ffe81a", "#ffbd00", "#ffa000", "#fc7f00"]
-# >>> cm = c.LinearSegmentedColormap.from_list('wistia', colors)
-# >>> _wistia_data = cm._segmentdata
-# >>> del _wistia_data['alpha']
-#
-_wistia_data = {
- 'red': [(0.0, 0.8941176470588236, 0.8941176470588236),
- (0.25, 1.0, 1.0),
- (0.5, 1.0, 1.0),
- (0.75, 1.0, 1.0),
- (1.0, 0.9882352941176471, 0.9882352941176471)],
- 'green': [(0.0, 1.0, 1.0),
- (0.25, 0.9098039215686274, 0.9098039215686274),
- (0.5, 0.7411764705882353, 0.7411764705882353),
- (0.75, 0.6274509803921569, 0.6274509803921569),
- (1.0, 0.4980392156862745, 0.4980392156862745)],
- 'blue': [(0.0, 0.47843137254901963, 0.47843137254901963),
- (0.25, 0.10196078431372549, 0.10196078431372549),
- (0.5, 0.0, 0.0),
- (0.75, 0.0, 0.0),
- (1.0, 0.0, 0.0)],
-}
-
-
-datad = {
- 'afmhot': _afmhot_data,
- 'autumn': _autumn_data,
- 'bone': _bone_data,
- 'binary': _binary_data,
- 'bwr': _bwr_data,
- 'brg': _brg_data,
- 'CMRmap': _CMRmap_data,
- 'cool': _cool_data,
- 'copper': _copper_data,
- 'cubehelix': _cubehelix_data,
- 'flag': _flag_data,
- 'gnuplot': _gnuplot_data,
- 'gnuplot2': _gnuplot2_data,
- 'gray': _gray_data,
- 'hot': _hot_data,
- 'hsv': _hsv_data,
- 'jet': _jet_data,
- 'ocean': _ocean_data,
- 'pink': _pink_data,
- 'prism': _prism_data,
- 'rainbow': _rainbow_data,
- 'seismic': _seismic_data,
- 'spring': _spring_data,
- 'summer': _summer_data,
- 'terrain': _terrain_data,
- 'winter': _winter_data,
- 'nipy_spectral': _nipy_spectral_data,
- 'spectral': _nipy_spectral_data, # alias for backward compatibility
- }
-
-
-datad['Accent'] = _Accent_data
-datad['Blues'] = _Blues_data
-datad['BrBG'] = _BrBG_data
-datad['BuGn'] = _BuGn_data
-datad['BuPu'] = _BuPu_data
-datad['Dark2'] = _Dark2_data
-datad['GnBu'] = _GnBu_data
-datad['Greens'] = _Greens_data
-datad['Greys'] = _Greys_data
-datad['Oranges'] = _Oranges_data
-datad['OrRd'] = _OrRd_data
-datad['Paired'] = _Paired_data
-datad['Pastel1'] = _Pastel1_data
-datad['Pastel2'] = _Pastel2_data
-datad['PiYG'] = _PiYG_data
-datad['PRGn'] = _PRGn_data
-datad['PuBu'] = _PuBu_data
-datad['PuBuGn'] = _PuBuGn_data
-datad['PuOr'] = _PuOr_data
-datad['PuRd'] = _PuRd_data
-datad['Purples'] = _Purples_data
-datad['RdBu'] = _RdBu_data
-datad['RdGy'] = _RdGy_data
-datad['RdPu'] = _RdPu_data
-datad['RdYlBu'] = _RdYlBu_data
-datad['RdYlGn'] = _RdYlGn_data
-datad['Reds'] = _Reds_data
-datad['Set1'] = _Set1_data
-datad['Set2'] = _Set2_data
-datad['Set3'] = _Set3_data
-datad['Spectral'] = _Spectral_data
-datad['YlGn'] = _YlGn_data
-datad['YlGnBu'] = _YlGnBu_data
-datad['YlOrBr'] = _YlOrBr_data
-datad['YlOrRd'] = _YlOrRd_data
-datad['gist_earth'] = _gist_earth_data
-datad['gist_gray'] = _gist_gray_data
-datad['gist_heat'] = _gist_heat_data
-datad['gist_ncar'] = _gist_ncar_data
-datad['gist_rainbow'] = _gist_rainbow_data
-datad['gist_stern'] = _gist_stern_data
-datad['gist_yarg'] = _gist_yarg_data
-datad['coolwarm'] = _coolwarm_data
-datad['Wistia'] = _wistia_data
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/_cntr.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/_cntr.so
deleted file mode 100755
index b792d93..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/_cntr.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/_delaunay.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/_delaunay.so
deleted file mode 100755
index 3b5b14e..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/_delaunay.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/_image.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/_image.so
deleted file mode 100755
index 4ac52e4..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/_image.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/_mathtext_data.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/_mathtext_data.py
deleted file mode 100644
index 9354c71..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/_mathtext_data.py
+++ /dev/null
@@ -1,2567 +0,0 @@
-"""
-font data tables for truetype and afm computer modern fonts
-"""
-# this dict maps symbol names to fontnames, glyphindex. To get the
-# glyph index from the character code, you have to use get_charmap
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-"""
-from matplotlib.ft2font import FT2Font
-font = FT2Font('/usr/local/share/matplotlib/cmr10.ttf')
-items = font.get_charmap().items()
-items.sort()
-
-for charcode, glyphind in items:
- print charcode, glyphind
-"""
-
-latex_to_bakoma = {
- r'\oint' : ('cmex10', 45),
- r'\bigodot' : ('cmex10', 50),
- r'\bigoplus' : ('cmex10', 55),
- r'\bigotimes' : ('cmex10', 59),
- r'\sum' : ('cmex10', 51),
- r'\prod' : ('cmex10', 24),
- r'\int' : ('cmex10', 56),
- r'\bigcup' : ('cmex10', 28),
- r'\bigcap' : ('cmex10', 60),
- r'\biguplus' : ('cmex10', 32),
- r'\bigwedge' : ('cmex10', 4),
- r'\bigvee' : ('cmex10', 37),
- r'\coprod' : ('cmex10', 42),
- r'\__sqrt__' : ('cmex10', 48),
- r'\leftbrace' : ('cmex10', 92),
- r'{' : ('cmex10', 92),
- r'\{' : ('cmex10', 92),
- r'\rightbrace' : ('cmex10', 130),
- r'}' : ('cmex10', 130),
- r'\}' : ('cmex10', 130),
- r'\leftangle' : ('cmex10', 97),
- r'\rightangle' : ('cmex10', 64),
- r'\langle' : ('cmex10', 97),
- r'\rangle' : ('cmex10', 64),
- r'\widehat' : ('cmex10', 15),
- r'\widetilde' : ('cmex10', 52),
- r'\widebar' : ('cmr10', 131),
-
- r'\omega' : ('cmmi10', 29),
- r'\varepsilon' : ('cmmi10', 20),
- r'\vartheta' : ('cmmi10', 22),
- r'\varrho' : ('cmmi10', 61),
- r'\varsigma' : ('cmmi10', 41),
- r'\varphi' : ('cmmi10', 6),
- r'\leftharpoonup' : ('cmmi10', 108),
- r'\leftharpoondown' : ('cmmi10', 68),
- r'\rightharpoonup' : ('cmmi10', 117),
- r'\rightharpoondown' : ('cmmi10', 77),
- r'\triangleright' : ('cmmi10', 130),
- r'\triangleleft' : ('cmmi10', 89),
- r'.' : ('cmmi10', 51),
- r',' : ('cmmi10', 44),
- r'<' : ('cmmi10', 99),
- r'/' : ('cmmi10', 98),
- r'>' : ('cmmi10', 107),
- r'\flat' : ('cmmi10', 131),
- r'\natural' : ('cmmi10', 90),
- r'\sharp' : ('cmmi10', 50),
- r'\smile' : ('cmmi10', 97),
- r'\frown' : ('cmmi10', 58),
- r'\ell' : ('cmmi10', 102),
- r'\imath' : ('cmmi10', 8),
- r'\jmath' : ('cmmi10', 65),
- r'\wp' : ('cmmi10', 14),
- r'\alpha' : ('cmmi10', 13),
- r'\beta' : ('cmmi10', 35),
- r'\gamma' : ('cmmi10', 24),
- r'\delta' : ('cmmi10', 38),
- r'\epsilon' : ('cmmi10', 54),
- r'\zeta' : ('cmmi10', 10),
- r'\eta' : ('cmmi10', 5),
- r'\theta' : ('cmmi10', 18),
- r'\iota' : ('cmmi10', 28),
- r'\lambda' : ('cmmi10', 9),
- r'\mu' : ('cmmi10', 32),
- r'\nu' : ('cmmi10', 34),
- r'\xi' : ('cmmi10', 7),
- r'\pi' : ('cmmi10', 36),
- r'\kappa' : ('cmmi10', 30),
- r'\rho' : ('cmmi10', 39),
- r'\sigma' : ('cmmi10', 21),
- r'\tau' : ('cmmi10', 43),
- '\\upsilon' : ('cmmi10', 25),
- r'\phi' : ('cmmi10', 42),
- r'\chi' : ('cmmi10', 17),
- r'\psi' : ('cmmi10', 31),
- r'|' : ('cmsy10', 47),
- r'\|' : ('cmsy10', 47),
- r'(' : ('cmr10', 119),
- r'\leftparen' : ('cmr10', 119),
- r'\rightparen' : ('cmr10', 68),
- r')' : ('cmr10', 68),
- r'+' : ('cmr10', 76),
- r'0' : ('cmr10', 40),
- r'1' : ('cmr10', 100),
- r'2' : ('cmr10', 49),
- r'3' : ('cmr10', 110),
- r'4' : ('cmr10', 59),
- r'5' : ('cmr10', 120),
- r'6' : ('cmr10', 69),
- r'7' : ('cmr10', 127),
- r'8' : ('cmr10', 77),
- r'9' : ('cmr10', 22),
- r':' : ('cmr10', 85),
- r';' : ('cmr10', 31),
- r'=' : ('cmr10', 41),
- r'\leftbracket' : ('cmr10', 62),
- r'[' : ('cmr10', 62),
- r'\rightbracket' : ('cmr10', 72),
- r']' : ('cmr10', 72),
- r'\%' : ('cmr10', 48),
- r'%' : ('cmr10', 48),
- r'\$' : ('cmr10', 99),
- r'@' : ('cmr10', 111),
- r'\#' : ('cmr10', 39),
- r'\_' : ('cmtt10', 79),
- r'\Gamma' : ('cmr10', 19),
- r'\Delta' : ('cmr10', 6),
- r'\Theta' : ('cmr10', 7),
- r'\Lambda' : ('cmr10', 14),
- r'\Xi' : ('cmr10', 3),
- r'\Pi' : ('cmr10', 17),
- r'\Sigma' : ('cmr10', 10),
- '\\Upsilon' : ('cmr10', 11),
- r'\Phi' : ('cmr10', 9),
- r'\Psi' : ('cmr10', 15),
- r'\Omega' : ('cmr10', 12),
-
- r'\prime' : ('cmsy10', 73),
-
- # these are mathml names, I think. I'm just using them for the
- # tex methods noted
- r'\circumflexaccent' : ('cmr10', 124), # for \hat
- r'\combiningbreve' : ('cmr10', 81), # for \breve
- r'\combiningoverline' : ('cmr10', 131), # for \bar
- r'\combininggraveaccent' : ('cmr10', 114), # for \grave
- r'\combiningacuteaccent' : ('cmr10', 63), # for \accute
- r'\combiningdiaeresis' : ('cmr10', 91), # for \ddot
- r'\combiningtilde' : ('cmr10', 75), # for \tilde
- r'\combiningrightarrowabove' : ('cmmi10', 110), # for \vec
- r'\combiningdotabove' : ('cmr10', 26), # for \dot
-
- r'\leftarrow' : ('cmsy10', 10),
- '\\uparrow' : ('cmsy10', 25),
- r'\downarrow' : ('cmsy10', 28),
- r'\leftrightarrow' : ('cmsy10', 24),
- r'\nearrow' : ('cmsy10', 99),
- r'\searrow' : ('cmsy10', 57),
- r'\simeq' : ('cmsy10', 108),
- r'\Leftarrow' : ('cmsy10', 104),
- r'\Rightarrow' : ('cmsy10', 112),
- '\\Uparrow' : ('cmsy10', 60),
- r'\Downarrow' : ('cmsy10', 68),
- r'\Leftrightarrow' : ('cmsy10', 51),
- r'\nwarrow' : ('cmsy10', 65),
- r'\swarrow' : ('cmsy10', 116),
- r'\propto' : ('cmsy10', 15),
- r'\infty' : ('cmsy10', 32),
- r'\in' : ('cmsy10', 59),
- r'\ni' : ('cmsy10', 122),
- r'\bigtriangleup' : ('cmsy10', 80),
- r'\bigtriangledown' : ('cmsy10', 132),
- r'\slash' : ('cmsy10', 87),
- r'\forall' : ('cmsy10', 21),
- r'\exists' : ('cmsy10', 5),
- r'\neg' : ('cmsy10', 20),
- r'\emptyset' : ('cmsy10', 33),
- r'\Re' : ('cmsy10', 95),
- r'\Im' : ('cmsy10', 52),
- r'\top' : ('cmsy10', 100),
- r'\bot' : ('cmsy10', 11),
- r'\aleph' : ('cmsy10', 26),
- r'\cup' : ('cmsy10', 6),
- r'\cap' : ('cmsy10', 19),
- '\\uplus' : ('cmsy10', 58),
- r'\wedge' : ('cmsy10', 43),
- r'\vee' : ('cmsy10', 96),
- r'\vdash' : ('cmsy10', 109),
- r'\dashv' : ('cmsy10', 66),
- r'\lfloor' : ('cmsy10', 117),
- r'\rfloor' : ('cmsy10', 74),
- r'\lceil' : ('cmsy10', 123),
- r'\rceil' : ('cmsy10', 81),
- r'\lbrace' : ('cmsy10', 92),
- r'\rbrace' : ('cmsy10', 105),
- r'\mid' : ('cmsy10', 47),
- r'\vert' : ('cmsy10', 47),
- r'\Vert' : ('cmsy10', 44),
- '\\updownarrow' : ('cmsy10', 94),
- '\\Updownarrow' : ('cmsy10', 53),
- r'\backslash' : ('cmsy10', 126),
- r'\wr' : ('cmsy10', 101),
- r'\nabla' : ('cmsy10', 110),
- r'\sqcup' : ('cmsy10', 67),
- r'\sqcap' : ('cmsy10', 118),
- r'\sqsubseteq' : ('cmsy10', 75),
- r'\sqsupseteq' : ('cmsy10', 124),
- r'\S' : ('cmsy10', 129),
- r'\dag' : ('cmsy10', 71),
- r'\ddag' : ('cmsy10', 127),
- r'\P' : ('cmsy10', 130),
- r'\clubsuit' : ('cmsy10', 18),
- r'\diamondsuit' : ('cmsy10', 34),
- r'\heartsuit' : ('cmsy10', 22),
- r'-' : ('cmsy10', 17),
- r'\cdot' : ('cmsy10', 78),
- r'\times' : ('cmsy10', 13),
- r'*' : ('cmsy10', 9),
- r'\ast' : ('cmsy10', 9),
- r'\div' : ('cmsy10', 31),
- r'\diamond' : ('cmsy10', 48),
- r'\pm' : ('cmsy10', 8),
- r'\mp' : ('cmsy10', 98),
- r'\oplus' : ('cmsy10', 16),
- r'\ominus' : ('cmsy10', 56),
- r'\otimes' : ('cmsy10', 30),
- r'\oslash' : ('cmsy10', 107),
- r'\odot' : ('cmsy10', 64),
- r'\bigcirc' : ('cmsy10', 115),
- r'\circ' : ('cmsy10', 72),
- r'\bullet' : ('cmsy10', 84),
- r'\asymp' : ('cmsy10', 121),
- r'\equiv' : ('cmsy10', 35),
- r'\subseteq' : ('cmsy10', 103),
- r'\supseteq' : ('cmsy10', 42),
- r'\leq' : ('cmsy10', 14),
- r'\geq' : ('cmsy10', 29),
- r'\preceq' : ('cmsy10', 79),
- r'\succeq' : ('cmsy10', 131),
- r'\sim' : ('cmsy10', 27),
- r'\approx' : ('cmsy10', 23),
- r'\subset' : ('cmsy10', 50),
- r'\supset' : ('cmsy10', 86),
- r'\ll' : ('cmsy10', 85),
- r'\gg' : ('cmsy10', 40),
- r'\prec' : ('cmsy10', 93),
- r'\succ' : ('cmsy10', 49),
- r'\rightarrow' : ('cmsy10', 12),
- r'\to' : ('cmsy10', 12),
- r'\spadesuit' : ('cmsy10', 7),
- r'?' : ('cmr10', 50),
- r'!' : ('cmr10', 29),
- r'&' : ('cmr10', 109)
-}
-
-latex_to_cmex = {
- r'\__sqrt__' : 112,
- r'\bigcap' : 92,
- r'\bigcup' : 91,
- r'\bigodot' : 75,
- r'\bigoplus' : 77,
- r'\bigotimes' : 79,
- r'\biguplus' : 93,
- r'\bigvee' : 95,
- r'\bigwedge' : 94,
- r'\coprod' : 97,
- r'\int' : 90,
- r'\leftangle' : 173,
- r'\leftbrace' : 169,
- r'\oint' : 73,
- r'\prod' : 89,
- r'\rightangle' : 174,
- r'\rightbrace' : 170,
- r'\sum' : 88,
- r'\widehat' : 98,
- r'\widetilde' : 101,
-}
-
-latex_to_standard = {
- r'\cong' : ('psyr', 64),
- r'\Delta' : ('psyr', 68),
- r'\Phi' : ('psyr', 70),
- r'\Gamma' : ('psyr', 89),
- r'\alpha' : ('psyr', 97),
- r'\beta' : ('psyr', 98),
- r'\chi' : ('psyr', 99),
- r'\delta' : ('psyr', 100),
- r'\varepsilon' : ('psyr', 101),
- r'\phi' : ('psyr', 102),
- r'\gamma' : ('psyr', 103),
- r'\eta' : ('psyr', 104),
- r'\iota' : ('psyr', 105),
- r'\varpsi' : ('psyr', 106),
- r'\kappa' : ('psyr', 108),
- r'\nu' : ('psyr', 110),
- r'\pi' : ('psyr', 112),
- r'\theta' : ('psyr', 113),
- r'\rho' : ('psyr', 114),
- r'\sigma' : ('psyr', 115),
- r'\tau' : ('psyr', 116),
- '\\upsilon' : ('psyr', 117),
- r'\varpi' : ('psyr', 118),
- r'\omega' : ('psyr', 119),
- r'\xi' : ('psyr', 120),
- r'\psi' : ('psyr', 121),
- r'\zeta' : ('psyr', 122),
- r'\sim' : ('psyr', 126),
- r'\leq' : ('psyr', 163),
- r'\infty' : ('psyr', 165),
- r'\clubsuit' : ('psyr', 167),
- r'\diamondsuit' : ('psyr', 168),
- r'\heartsuit' : ('psyr', 169),
- r'\spadesuit' : ('psyr', 170),
- r'\leftrightarrow' : ('psyr', 171),
- r'\leftarrow' : ('psyr', 172),
- '\\uparrow' : ('psyr', 173),
- r'\rightarrow' : ('psyr', 174),
- r'\downarrow' : ('psyr', 175),
- r'\pm' : ('psyr', 176),
- r'\geq' : ('psyr', 179),
- r'\times' : ('psyr', 180),
- r'\propto' : ('psyr', 181),
- r'\partial' : ('psyr', 182),
- r'\bullet' : ('psyr', 183),
- r'\div' : ('psyr', 184),
- r'\neq' : ('psyr', 185),
- r'\equiv' : ('psyr', 186),
- r'\approx' : ('psyr', 187),
- r'\ldots' : ('psyr', 188),
- r'\aleph' : ('psyr', 192),
- r'\Im' : ('psyr', 193),
- r'\Re' : ('psyr', 194),
- r'\wp' : ('psyr', 195),
- r'\otimes' : ('psyr', 196),
- r'\oplus' : ('psyr', 197),
- r'\oslash' : ('psyr', 198),
- r'\cap' : ('psyr', 199),
- r'\cup' : ('psyr', 200),
- r'\supset' : ('psyr', 201),
- r'\supseteq' : ('psyr', 202),
- r'\subset' : ('psyr', 204),
- r'\subseteq' : ('psyr', 205),
- r'\in' : ('psyr', 206),
- r'\notin' : ('psyr', 207),
- r'\angle' : ('psyr', 208),
- r'\nabla' : ('psyr', 209),
- r'\textregistered' : ('psyr', 210),
- r'\copyright' : ('psyr', 211),
- r'\texttrademark' : ('psyr', 212),
- r'\Pi' : ('psyr', 213),
- r'\prod' : ('psyr', 213),
- r'\surd' : ('psyr', 214),
- r'\__sqrt__' : ('psyr', 214),
- r'\cdot' : ('psyr', 215),
- '\\urcorner' : ('psyr', 216),
- r'\vee' : ('psyr', 217),
- r'\wedge' : ('psyr', 218),
- r'\Leftrightarrow' : ('psyr', 219),
- r'\Leftarrow' : ('psyr', 220),
- '\\Uparrow' : ('psyr', 221),
- r'\Rightarrow' : ('psyr', 222),
- r'\Downarrow' : ('psyr', 223),
- r'\Diamond' : ('psyr', 224),
- r'\langle' : ('psyr', 225),
- r'\Sigma' : ('psyr', 229),
- r'\sum' : ('psyr', 229),
- r'\forall' : ('psyr', 34),
- r'\exists' : ('psyr', 36),
- r'\lceil' : ('psyr', 233),
- r'\lbrace' : ('psyr', 123),
- r'\Psi' : ('psyr', 89),
- r'\bot' : ('psyr', 0o136),
- r'\Omega' : ('psyr', 0o127),
- r'\leftbracket' : ('psyr', 0o133),
- r'\rightbracket' : ('psyr', 0o135),
- r'\leftbrace' : ('psyr', 123),
- r'\leftparen' : ('psyr', 0o50),
- r'\prime' : ('psyr', 0o242),
- r'\sharp' : ('psyr', 0o43),
- r'\slash' : ('psyr', 0o57),
- r'\Lamda' : ('psyr', 0o114),
- r'\neg' : ('psyr', 0o330),
- '\\Upsilon' : ('psyr', 0o241),
- r'\rightbrace' : ('psyr', 0o175),
- r'\rfloor' : ('psyr', 0o373),
- r'\lambda' : ('psyr', 0o154),
- r'\to' : ('psyr', 0o256),
- r'\Xi' : ('psyr', 0o130),
- r'\emptyset' : ('psyr', 0o306),
- r'\lfloor' : ('psyr', 0o353),
- r'\rightparen' : ('psyr', 0o51),
- r'\rceil' : ('psyr', 0o371),
- r'\ni' : ('psyr', 0o47),
- r'\epsilon' : ('psyr', 0o145),
- r'\Theta' : ('psyr', 0o121),
- r'\langle' : ('psyr', 0o341),
- r'\leftangle' : ('psyr', 0o341),
- r'\rangle' : ('psyr', 0o361),
- r'\rightangle' : ('psyr', 0o361),
- r'\rbrace' : ('psyr', 0o175),
- r'\circ' : ('psyr', 0o260),
- r'\diamond' : ('psyr', 0o340),
- r'\mu' : ('psyr', 0o155),
- r'\mid' : ('psyr', 0o352),
- r'\imath' : ('pncri8a', 105),
- r'\%' : ('pncr8a', 37),
- r'\$' : ('pncr8a', 36),
- r'\{' : ('pncr8a', 123),
- r'\}' : ('pncr8a', 125),
- r'\backslash' : ('pncr8a', 92),
- r'\ast' : ('pncr8a', 42),
- r'\#' : ('pncr8a', 35),
-
- r'\circumflexaccent' : ('pncri8a', 124), # for \hat
- r'\combiningbreve' : ('pncri8a', 81), # for \breve
- r'\combininggraveaccent' : ('pncri8a', 114), # for \grave
- r'\combiningacuteaccent' : ('pncri8a', 63), # for \accute
- r'\combiningdiaeresis' : ('pncri8a', 91), # for \ddot
- r'\combiningtilde' : ('pncri8a', 75), # for \tilde
- r'\combiningrightarrowabove' : ('pncri8a', 110), # for \vec
- r'\combiningdotabove' : ('pncri8a', 26), # for \dot
-}
-
-# Automatically generated.
-
-type12uni = {
- 'uni24C8' : 9416,
- 'aring' : 229,
- 'uni22A0' : 8864,
- 'uni2292' : 8850,
- 'quotedblright' : 8221,
- 'uni03D2' : 978,
- 'uni2215' : 8725,
- 'uni03D0' : 976,
- 'V' : 86,
- 'dollar' : 36,
- 'uni301E' : 12318,
- 'uni03D5' : 981,
- 'four' : 52,
- 'uni25A0' : 9632,
- 'uni013C' : 316,
- 'uni013B' : 315,
- 'uni013E' : 318,
- 'Yacute' : 221,
- 'uni25DE' : 9694,
- 'uni013F' : 319,
- 'uni255A' : 9562,
- 'uni2606' : 9734,
- 'uni0180' : 384,
- 'uni22B7' : 8887,
- 'uni044F' : 1103,
- 'uni22B5' : 8885,
- 'uni22B4' : 8884,
- 'uni22AE' : 8878,
- 'uni22B2' : 8882,
- 'uni22B1' : 8881,
- 'uni22B0' : 8880,
- 'uni25CD' : 9677,
- 'uni03CE' : 974,
- 'uni03CD' : 973,
- 'uni03CC' : 972,
- 'uni03CB' : 971,
- 'uni03CA' : 970,
- 'uni22B8' : 8888,
- 'uni22C9' : 8905,
- 'uni0449' : 1097,
- 'uni20DD' : 8413,
- 'uni20DC' : 8412,
- 'uni20DB' : 8411,
- 'uni2231' : 8753,
- 'uni25CF' : 9679,
- 'uni306E' : 12398,
- 'uni03D1' : 977,
- 'uni01A1' : 417,
- 'uni20D7' : 8407,
- 'uni03D6' : 982,
- 'uni2233' : 8755,
- 'uni20D2' : 8402,
- 'uni20D1' : 8401,
- 'uni20D0' : 8400,
- 'P' : 80,
- 'uni22BE' : 8894,
- 'uni22BD' : 8893,
- 'uni22BC' : 8892,
- 'uni22BB' : 8891,
- 'underscore' : 95,
- 'uni03C8' : 968,
- 'uni03C7' : 967,
- 'uni0328' : 808,
- 'uni03C5' : 965,
- 'uni03C4' : 964,
- 'uni03C3' : 963,
- 'uni03C2' : 962,
- 'uni03C1' : 961,
- 'uni03C0' : 960,
- 'uni2010' : 8208,
- 'uni0130' : 304,
- 'uni0133' : 307,
- 'uni0132' : 306,
- 'uni0135' : 309,
- 'uni0134' : 308,
- 'uni0137' : 311,
- 'uni0136' : 310,
- 'uni0139' : 313,
- 'uni0138' : 312,
- 'uni2244' : 8772,
- 'uni229A' : 8858,
- 'uni2571' : 9585,
- 'uni0278' : 632,
- 'uni2239' : 8761,
- 'p' : 112,
- 'uni3019' : 12313,
- 'uni25CB' : 9675,
- 'uni03DB' : 987,
- 'uni03DC' : 988,
- 'uni03DA' : 986,
- 'uni03DF' : 991,
- 'uni03DD' : 989,
- 'uni013D' : 317,
- 'uni220A' : 8714,
- 'uni220C' : 8716,
- 'uni220B' : 8715,
- 'uni220E' : 8718,
- 'uni220D' : 8717,
- 'uni220F' : 8719,
- 'uni22CC' : 8908,
- 'Otilde' : 213,
- 'uni25E5' : 9701,
- 'uni2736' : 10038,
- 'perthousand' : 8240,
- 'zero' : 48,
- 'uni279B' : 10139,
- 'dotlessi' : 305,
- 'uni2279' : 8825,
- 'Scaron' : 352,
- 'zcaron' : 382,
- 'uni21D8' : 8664,
- 'egrave' : 232,
- 'uni0271' : 625,
- 'uni01AA' : 426,
- 'uni2332' : 9010,
- 'section' : 167,
- 'uni25E4' : 9700,
- 'Icircumflex' : 206,
- 'ntilde' : 241,
- 'uni041E' : 1054,
- 'ampersand' : 38,
- 'uni041C' : 1052,
- 'uni041A' : 1050,
- 'uni22AB' : 8875,
- 'uni21DB' : 8667,
- 'dotaccent' : 729,
- 'uni0416' : 1046,
- 'uni0417' : 1047,
- 'uni0414' : 1044,
- 'uni0415' : 1045,
- 'uni0412' : 1042,
- 'uni0413' : 1043,
- 'degree' : 176,
- 'uni0411' : 1041,
- 'K' : 75,
- 'uni25EB' : 9707,
- 'uni25EF' : 9711,
- 'uni0418' : 1048,
- 'uni0419' : 1049,
- 'uni2263' : 8803,
- 'uni226E' : 8814,
- 'uni2251' : 8785,
- 'uni02C8' : 712,
- 'uni2262' : 8802,
- 'acircumflex' : 226,
- 'uni22B3' : 8883,
- 'uni2261' : 8801,
- 'uni2394' : 9108,
- 'Aring' : 197,
- 'uni2260' : 8800,
- 'uni2254' : 8788,
- 'uni0436' : 1078,
- 'uni2267' : 8807,
- 'k' : 107,
- 'uni22C8' : 8904,
- 'uni226A' : 8810,
- 'uni231F' : 8991,
- 'smalltilde' : 732,
- 'uni2201' : 8705,
- 'uni2200' : 8704,
- 'uni2203' : 8707,
- 'uni02BD' : 701,
- 'uni2205' : 8709,
- 'uni2204' : 8708,
- 'Agrave' : 192,
- 'uni2206' : 8710,
- 'uni2209' : 8713,
- 'uni2208' : 8712,
- 'uni226D' : 8813,
- 'uni2264' : 8804,
- 'uni263D' : 9789,
- 'uni2258' : 8792,
- 'uni02D3' : 723,
- 'uni02D2' : 722,
- 'uni02D1' : 721,
- 'uni02D0' : 720,
- 'uni25E1' : 9697,
- 'divide' : 247,
- 'uni02D5' : 725,
- 'uni02D4' : 724,
- 'ocircumflex' : 244,
- 'uni2524' : 9508,
- 'uni043A' : 1082,
- 'uni24CC' : 9420,
- 'asciitilde' : 126,
- 'uni22B9' : 8889,
- 'uni24D2' : 9426,
- 'uni211E' : 8478,
- 'uni211D' : 8477,
- 'uni24DD' : 9437,
- 'uni211A' : 8474,
- 'uni211C' : 8476,
- 'uni211B' : 8475,
- 'uni25C6' : 9670,
- 'uni017F' : 383,
- 'uni017A' : 378,
- 'uni017C' : 380,
- 'uni017B' : 379,
- 'uni0346' : 838,
- 'uni22F1' : 8945,
- 'uni22F0' : 8944,
- 'two' : 50,
- 'uni2298' : 8856,
- 'uni24D1' : 9425,
- 'E' : 69,
- 'uni025D' : 605,
- 'scaron' : 353,
- 'uni2322' : 8994,
- 'uni25E3' : 9699,
- 'uni22BF' : 8895,
- 'F' : 70,
- 'uni0440' : 1088,
- 'uni255E' : 9566,
- 'uni22BA' : 8890,
- 'uni0175' : 373,
- 'uni0174' : 372,
- 'uni0177' : 375,
- 'uni0176' : 374,
- 'bracketleft' : 91,
- 'uni0170' : 368,
- 'uni0173' : 371,
- 'uni0172' : 370,
- 'asciicircum' : 94,
- 'uni0179' : 377,
- 'uni2590' : 9616,
- 'uni25E2' : 9698,
- 'uni2119' : 8473,
- 'uni2118' : 8472,
- 'uni25CC' : 9676,
- 'f' : 102,
- 'ordmasculine' : 186,
- 'uni229B' : 8859,
- 'uni22A1' : 8865,
- 'uni2111' : 8465,
- 'uni2110' : 8464,
- 'uni2113' : 8467,
- 'uni2112' : 8466,
- 'mu' : 181,
- 'uni2281' : 8833,
- 'paragraph' : 182,
- 'nine' : 57,
- 'uni25EC' : 9708,
- 'v' : 118,
- 'uni040C' : 1036,
- 'uni0113' : 275,
- 'uni22D0' : 8912,
- 'uni21CC' : 8652,
- 'uni21CB' : 8651,
- 'uni21CA' : 8650,
- 'uni22A5' : 8869,
- 'uni21CF' : 8655,
- 'uni21CE' : 8654,
- 'uni21CD' : 8653,
- 'guilsinglleft' : 8249,
- 'backslash' : 92,
- 'uni2284' : 8836,
- 'uni224E' : 8782,
- 'uni224D' : 8781,
- 'uni224F' : 8783,
- 'uni224A' : 8778,
- 'uni2287' : 8839,
- 'uni224C' : 8780,
- 'uni224B' : 8779,
- 'uni21BD' : 8637,
- 'uni2286' : 8838,
- 'uni030F' : 783,
- 'uni030D' : 781,
- 'uni030E' : 782,
- 'uni030B' : 779,
- 'uni030C' : 780,
- 'uni030A' : 778,
- 'uni026E' : 622,
- 'uni026D' : 621,
- 'six' : 54,
- 'uni026A' : 618,
- 'uni026C' : 620,
- 'uni25C1' : 9665,
- 'uni20D6' : 8406,
- 'uni045B' : 1115,
- 'uni045C' : 1116,
- 'uni256B' : 9579,
- 'uni045A' : 1114,
- 'uni045F' : 1119,
- 'uni045E' : 1118,
- 'A' : 65,
- 'uni2569' : 9577,
- 'uni0458' : 1112,
- 'uni0459' : 1113,
- 'uni0452' : 1106,
- 'uni0453' : 1107,
- 'uni2562' : 9570,
- 'uni0451' : 1105,
- 'uni0456' : 1110,
- 'uni0457' : 1111,
- 'uni0454' : 1108,
- 'uni0455' : 1109,
- 'icircumflex' : 238,
- 'uni0307' : 775,
- 'uni0304' : 772,
- 'uni0305' : 773,
- 'uni0269' : 617,
- 'uni0268' : 616,
- 'uni0300' : 768,
- 'uni0301' : 769,
- 'uni0265' : 613,
- 'uni0264' : 612,
- 'uni0267' : 615,
- 'uni0266' : 614,
- 'uni0261' : 609,
- 'uni0260' : 608,
- 'uni0263' : 611,
- 'uni0262' : 610,
- 'a' : 97,
- 'uni2207' : 8711,
- 'uni2247' : 8775,
- 'uni2246' : 8774,
- 'uni2241' : 8769,
- 'uni2240' : 8768,
- 'uni2243' : 8771,
- 'uni2242' : 8770,
- 'uni2312' : 8978,
- 'ogonek' : 731,
- 'uni2249' : 8777,
- 'uni2248' : 8776,
- 'uni3030' : 12336,
- 'q' : 113,
- 'uni21C2' : 8642,
- 'uni21C1' : 8641,
- 'uni21C0' : 8640,
- 'uni21C7' : 8647,
- 'uni21C6' : 8646,
- 'uni21C5' : 8645,
- 'uni21C4' : 8644,
- 'uni225F' : 8799,
- 'uni212C' : 8492,
- 'uni21C8' : 8648,
- 'uni2467' : 9319,
- 'oacute' : 243,
- 'uni028F' : 655,
- 'uni028E' : 654,
- 'uni026F' : 623,
- 'uni028C' : 652,
- 'uni028B' : 651,
- 'uni028A' : 650,
- 'uni2510' : 9488,
- 'ograve' : 242,
- 'edieresis' : 235,
- 'uni22CE' : 8910,
- 'uni22CF' : 8911,
- 'uni219F' : 8607,
- 'comma' : 44,
- 'uni22CA' : 8906,
- 'uni0429' : 1065,
- 'uni03C6' : 966,
- 'uni0427' : 1063,
- 'uni0426' : 1062,
- 'uni0425' : 1061,
- 'uni0424' : 1060,
- 'uni0423' : 1059,
- 'uni0422' : 1058,
- 'uni0421' : 1057,
- 'uni0420' : 1056,
- 'uni2465' : 9317,
- 'uni24D0' : 9424,
- 'uni2464' : 9316,
- 'uni0430' : 1072,
- 'otilde' : 245,
- 'uni2661' : 9825,
- 'uni24D6' : 9430,
- 'uni2466' : 9318,
- 'uni24D5' : 9429,
- 'uni219A' : 8602,
- 'uni2518' : 9496,
- 'uni22B6' : 8886,
- 'uni2461' : 9313,
- 'uni24D4' : 9428,
- 'uni2460' : 9312,
- 'uni24EA' : 9450,
- 'guillemotright' : 187,
- 'ecircumflex' : 234,
- 'greater' : 62,
- 'uni2011' : 8209,
- 'uacute' : 250,
- 'uni2462' : 9314,
- 'L' : 76,
- 'bullet' : 8226,
- 'uni02A4' : 676,
- 'uni02A7' : 679,
- 'cedilla' : 184,
- 'uni02A2' : 674,
- 'uni2015' : 8213,
- 'uni22C4' : 8900,
- 'uni22C5' : 8901,
- 'uni22AD' : 8877,
- 'uni22C7' : 8903,
- 'uni22C0' : 8896,
- 'uni2016' : 8214,
- 'uni22C2' : 8898,
- 'uni22C3' : 8899,
- 'uni24CF' : 9423,
- 'uni042F' : 1071,
- 'uni042E' : 1070,
- 'uni042D' : 1069,
- 'ydieresis' : 255,
- 'l' : 108,
- 'logicalnot' : 172,
- 'uni24CA' : 9418,
- 'uni0287' : 647,
- 'uni0286' : 646,
- 'uni0285' : 645,
- 'uni0284' : 644,
- 'uni0283' : 643,
- 'uni0282' : 642,
- 'uni0281' : 641,
- 'uni027C' : 636,
- 'uni2664' : 9828,
- 'exclamdown' : 161,
- 'uni25C4' : 9668,
- 'uni0289' : 649,
- 'uni0288' : 648,
- 'uni039A' : 922,
- 'endash' : 8211,
- 'uni2640' : 9792,
- 'uni20E4' : 8420,
- 'uni0473' : 1139,
- 'uni20E1' : 8417,
- 'uni2642' : 9794,
- 'uni03B8' : 952,
- 'uni03B9' : 953,
- 'agrave' : 224,
- 'uni03B4' : 948,
- 'uni03B5' : 949,
- 'uni03B6' : 950,
- 'uni03B7' : 951,
- 'uni03B0' : 944,
- 'uni03B1' : 945,
- 'uni03B2' : 946,
- 'uni03B3' : 947,
- 'uni2555' : 9557,
- 'Adieresis' : 196,
- 'germandbls' : 223,
- 'Odieresis' : 214,
- 'space' : 32,
- 'uni0126' : 294,
- 'uni0127' : 295,
- 'uni0124' : 292,
- 'uni0125' : 293,
- 'uni0122' : 290,
- 'uni0123' : 291,
- 'uni0120' : 288,
- 'uni0121' : 289,
- 'quoteright' : 8217,
- 'uni2560' : 9568,
- 'uni2556' : 9558,
- 'ucircumflex' : 251,
- 'uni2561' : 9569,
- 'uni2551' : 9553,
- 'uni25B2' : 9650,
- 'uni2550' : 9552,
- 'uni2563' : 9571,
- 'uni2553' : 9555,
- 'G' : 71,
- 'uni2564' : 9572,
- 'uni2552' : 9554,
- 'quoteleft' : 8216,
- 'uni2565' : 9573,
- 'uni2572' : 9586,
- 'uni2568' : 9576,
- 'uni2566' : 9574,
- 'W' : 87,
- 'uni214A' : 8522,
- 'uni012F' : 303,
- 'uni012D' : 301,
- 'uni012E' : 302,
- 'uni012B' : 299,
- 'uni012C' : 300,
- 'uni255C' : 9564,
- 'uni012A' : 298,
- 'uni2289' : 8841,
- 'Q' : 81,
- 'uni2320' : 8992,
- 'uni2321' : 8993,
- 'g' : 103,
- 'uni03BD' : 957,
- 'uni03BE' : 958,
- 'uni03BF' : 959,
- 'uni2282' : 8834,
- 'uni2285' : 8837,
- 'uni03BA' : 954,
- 'uni03BB' : 955,
- 'uni03BC' : 956,
- 'uni2128' : 8488,
- 'uni25B7' : 9655,
- 'w' : 119,
- 'uni0302' : 770,
- 'uni03DE' : 990,
- 'uni25DA' : 9690,
- 'uni0303' : 771,
- 'uni0463' : 1123,
- 'uni0462' : 1122,
- 'uni3018' : 12312,
- 'uni2514' : 9492,
- 'question' : 63,
- 'uni25B3' : 9651,
- 'uni24E1' : 9441,
- 'one' : 49,
- 'uni200A' : 8202,
- 'uni2278' : 8824,
- 'ring' : 730,
- 'uni0195' : 405,
- 'figuredash' : 8210,
- 'uni22EC' : 8940,
- 'uni0339' : 825,
- 'uni0338' : 824,
- 'uni0337' : 823,
- 'uni0336' : 822,
- 'uni0335' : 821,
- 'uni0333' : 819,
- 'uni0332' : 818,
- 'uni0331' : 817,
- 'uni0330' : 816,
- 'uni01C1' : 449,
- 'uni01C0' : 448,
- 'uni01C3' : 451,
- 'uni01C2' : 450,
- 'uni2353' : 9043,
- 'uni0308' : 776,
- 'uni2218' : 8728,
- 'uni2219' : 8729,
- 'uni2216' : 8726,
- 'uni2217' : 8727,
- 'uni2214' : 8724,
- 'uni0309' : 777,
- 'uni2609' : 9737,
- 'uni2213' : 8723,
- 'uni2210' : 8720,
- 'uni2211' : 8721,
- 'uni2245' : 8773,
- 'B' : 66,
- 'uni25D6' : 9686,
- 'iacute' : 237,
- 'uni02E6' : 742,
- 'uni02E7' : 743,
- 'uni02E8' : 744,
- 'uni02E9' : 745,
- 'uni221D' : 8733,
- 'uni221E' : 8734,
- 'Ydieresis' : 376,
- 'uni221C' : 8732,
- 'uni22D7' : 8919,
- 'uni221A' : 8730,
- 'R' : 82,
- 'uni24DC' : 9436,
- 'uni033F' : 831,
- 'uni033E' : 830,
- 'uni033C' : 828,
- 'uni033B' : 827,
- 'uni033A' : 826,
- 'b' : 98,
- 'uni228A' : 8842,
- 'uni22DB' : 8923,
- 'uni2554' : 9556,
- 'uni046B' : 1131,
- 'uni046A' : 1130,
- 'r' : 114,
- 'uni24DB' : 9435,
- 'Ccedilla' : 199,
- 'minus' : 8722,
- 'uni24DA' : 9434,
- 'uni03F0' : 1008,
- 'uni03F1' : 1009,
- 'uni20AC' : 8364,
- 'uni2276' : 8822,
- 'uni24C0' : 9408,
- 'uni0162' : 354,
- 'uni0163' : 355,
- 'uni011E' : 286,
- 'uni011D' : 285,
- 'uni011C' : 284,
- 'uni011B' : 283,
- 'uni0164' : 356,
- 'uni0165' : 357,
- 'Lslash' : 321,
- 'uni0168' : 360,
- 'uni0169' : 361,
- 'uni25C9' : 9673,
- 'uni02E5' : 741,
- 'uni21C3' : 8643,
- 'uni24C4' : 9412,
- 'uni24E2' : 9442,
- 'uni2277' : 8823,
- 'uni013A' : 314,
- 'uni2102' : 8450,
- 'Uacute' : 218,
- 'uni2317' : 8983,
- 'uni2107' : 8455,
- 'uni221F' : 8735,
- 'yacute' : 253,
- 'uni3012' : 12306,
- 'Ucircumflex' : 219,
- 'uni015D' : 349,
- 'quotedbl' : 34,
- 'uni25D9' : 9689,
- 'uni2280' : 8832,
- 'uni22AF' : 8879,
- 'onehalf' : 189,
- 'uni221B' : 8731,
- 'Thorn' : 222,
- 'uni2226' : 8742,
- 'M' : 77,
- 'uni25BA' : 9658,
- 'uni2463' : 9315,
- 'uni2336' : 9014,
- 'eight' : 56,
- 'uni2236' : 8758,
- 'multiply' : 215,
- 'uni210C' : 8460,
- 'uni210A' : 8458,
- 'uni21C9' : 8649,
- 'grave' : 96,
- 'uni210E' : 8462,
- 'uni0117' : 279,
- 'uni016C' : 364,
- 'uni0115' : 277,
- 'uni016A' : 362,
- 'uni016F' : 367,
- 'uni0112' : 274,
- 'uni016D' : 365,
- 'uni016E' : 366,
- 'Ocircumflex' : 212,
- 'uni2305' : 8965,
- 'm' : 109,
- 'uni24DF' : 9439,
- 'uni0119' : 281,
- 'uni0118' : 280,
- 'uni20A3' : 8355,
- 'uni20A4' : 8356,
- 'uni20A7' : 8359,
- 'uni2288' : 8840,
- 'uni24C3' : 9411,
- 'uni251C' : 9500,
- 'uni228D' : 8845,
- 'uni222F' : 8751,
- 'uni222E' : 8750,
- 'uni222D' : 8749,
- 'uni222C' : 8748,
- 'uni222B' : 8747,
- 'uni222A' : 8746,
- 'uni255B' : 9563,
- 'Ugrave' : 217,
- 'uni24DE' : 9438,
- 'guilsinglright' : 8250,
- 'uni250A' : 9482,
- 'Ntilde' : 209,
- 'uni0279' : 633,
- 'questiondown' : 191,
- 'uni256C' : 9580,
- 'Atilde' : 195,
- 'uni0272' : 626,
- 'uni0273' : 627,
- 'uni0270' : 624,
- 'ccedilla' : 231,
- 'uni0276' : 630,
- 'uni0277' : 631,
- 'uni0274' : 628,
- 'uni0275' : 629,
- 'uni2252' : 8786,
- 'uni041F' : 1055,
- 'uni2250' : 8784,
- 'Z' : 90,
- 'uni2256' : 8790,
- 'uni2257' : 8791,
- 'copyright' : 169,
- 'uni2255' : 8789,
- 'uni043D' : 1085,
- 'uni043E' : 1086,
- 'uni043F' : 1087,
- 'yen' : 165,
- 'uni041D' : 1053,
- 'uni043B' : 1083,
- 'uni043C' : 1084,
- 'uni21B0' : 8624,
- 'uni21B1' : 8625,
- 'uni21B2' : 8626,
- 'uni21B3' : 8627,
- 'uni21B4' : 8628,
- 'uni21B5' : 8629,
- 'uni21B6' : 8630,
- 'uni21B7' : 8631,
- 'uni21B8' : 8632,
- 'Eacute' : 201,
- 'uni2311' : 8977,
- 'uni2310' : 8976,
- 'uni228F' : 8847,
- 'uni25DB' : 9691,
- 'uni21BA' : 8634,
- 'uni21BB' : 8635,
- 'uni21BC' : 8636,
- 'uni2017' : 8215,
- 'uni21BE' : 8638,
- 'uni21BF' : 8639,
- 'uni231C' : 8988,
- 'H' : 72,
- 'uni0293' : 659,
- 'uni2202' : 8706,
- 'uni22A4' : 8868,
- 'uni231E' : 8990,
- 'uni2232' : 8754,
- 'uni225B' : 8795,
- 'uni225C' : 8796,
- 'uni24D9' : 9433,
- 'uni225A' : 8794,
- 'uni0438' : 1080,
- 'uni0439' : 1081,
- 'uni225D' : 8797,
- 'uni225E' : 8798,
- 'uni0434' : 1076,
- 'X' : 88,
- 'uni007F' : 127,
- 'uni0437' : 1079,
- 'Idieresis' : 207,
- 'uni0431' : 1073,
- 'uni0432' : 1074,
- 'uni0433' : 1075,
- 'uni22AC' : 8876,
- 'uni22CD' : 8909,
- 'uni25A3' : 9635,
- 'bar' : 124,
- 'uni24BB' : 9403,
- 'uni037E' : 894,
- 'uni027B' : 635,
- 'h' : 104,
- 'uni027A' : 634,
- 'uni027F' : 639,
- 'uni027D' : 637,
- 'uni027E' : 638,
- 'uni2227' : 8743,
- 'uni2004' : 8196,
- 'uni2225' : 8741,
- 'uni2224' : 8740,
- 'uni2223' : 8739,
- 'uni2222' : 8738,
- 'uni2221' : 8737,
- 'uni2220' : 8736,
- 'x' : 120,
- 'uni2323' : 8995,
- 'uni2559' : 9561,
- 'uni2558' : 9560,
- 'uni2229' : 8745,
- 'uni2228' : 8744,
- 'udieresis' : 252,
- 'uni029D' : 669,
- 'ordfeminine' : 170,
- 'uni22CB' : 8907,
- 'uni233D' : 9021,
- 'uni0428' : 1064,
- 'uni24C6' : 9414,
- 'uni22DD' : 8925,
- 'uni24C7' : 9415,
- 'uni015C' : 348,
- 'uni015B' : 347,
- 'uni015A' : 346,
- 'uni22AA' : 8874,
- 'uni015F' : 351,
- 'uni015E' : 350,
- 'braceleft' : 123,
- 'uni24C5' : 9413,
- 'uni0410' : 1040,
- 'uni03AA' : 938,
- 'uni24C2' : 9410,
- 'uni03AC' : 940,
- 'uni03AB' : 939,
- 'macron' : 175,
- 'uni03AD' : 941,
- 'uni03AF' : 943,
- 'uni0294' : 660,
- 'uni0295' : 661,
- 'uni0296' : 662,
- 'uni0297' : 663,
- 'uni0290' : 656,
- 'uni0291' : 657,
- 'uni0292' : 658,
- 'atilde' : 227,
- 'Acircumflex' : 194,
- 'uni2370' : 9072,
- 'uni24C1' : 9409,
- 'uni0298' : 664,
- 'uni0299' : 665,
- 'Oslash' : 216,
- 'uni029E' : 670,
- 'C' : 67,
- 'quotedblleft' : 8220,
- 'uni029B' : 667,
- 'uni029C' : 668,
- 'uni03A9' : 937,
- 'uni03A8' : 936,
- 'S' : 83,
- 'uni24C9' : 9417,
- 'uni03A1' : 929,
- 'uni03A0' : 928,
- 'exclam' : 33,
- 'uni03A5' : 933,
- 'uni03A4' : 932,
- 'uni03A7' : 935,
- 'Zcaron' : 381,
- 'uni2133' : 8499,
- 'uni2132' : 8498,
- 'uni0159' : 345,
- 'uni0158' : 344,
- 'uni2137' : 8503,
- 'uni2005' : 8197,
- 'uni2135' : 8501,
- 'uni2134' : 8500,
- 'uni02BA' : 698,
- 'uni2033' : 8243,
- 'uni0151' : 337,
- 'uni0150' : 336,
- 'uni0157' : 343,
- 'equal' : 61,
- 'uni0155' : 341,
- 'uni0154' : 340,
- 's' : 115,
- 'uni233F' : 9023,
- 'eth' : 240,
- 'uni24BE' : 9406,
- 'uni21E9' : 8681,
- 'uni2060' : 8288,
- 'Egrave' : 200,
- 'uni255D' : 9565,
- 'uni24CD' : 9421,
- 'uni21E1' : 8673,
- 'uni21B9' : 8633,
- 'hyphen' : 45,
- 'uni01BE' : 446,
- 'uni01BB' : 443,
- 'period' : 46,
- 'igrave' : 236,
- 'uni01BA' : 442,
- 'uni2296' : 8854,
- 'uni2297' : 8855,
- 'uni2294' : 8852,
- 'uni2295' : 8853,
- 'colon' : 58,
- 'uni2293' : 8851,
- 'uni2290' : 8848,
- 'uni2291' : 8849,
- 'uni032D' : 813,
- 'uni032E' : 814,
- 'uni032F' : 815,
- 'uni032A' : 810,
- 'uni032B' : 811,
- 'uni032C' : 812,
- 'uni231D' : 8989,
- 'Ecircumflex' : 202,
- 'uni24D7' : 9431,
- 'uni25DD' : 9693,
- 'trademark' : 8482,
- 'Aacute' : 193,
- 'cent' : 162,
- 'uni0445' : 1093,
- 'uni266E' : 9838,
- 'uni266D' : 9837,
- 'uni266B' : 9835,
- 'uni03C9' : 969,
- 'uni2003' : 8195,
- 'uni2047' : 8263,
- 'lslash' : 322,
- 'uni03A6' : 934,
- 'uni2043' : 8259,
- 'uni250C' : 9484,
- 'uni2040' : 8256,
- 'uni255F' : 9567,
- 'uni24CB' : 9419,
- 'uni0472' : 1138,
- 'uni0446' : 1094,
- 'uni0474' : 1140,
- 'uni0475' : 1141,
- 'uni2508' : 9480,
- 'uni2660' : 9824,
- 'uni2506' : 9478,
- 'uni2502' : 9474,
- 'c' : 99,
- 'uni2500' : 9472,
- 'N' : 78,
- 'uni22A6' : 8870,
- 'uni21E7' : 8679,
- 'uni2130' : 8496,
- 'uni2002' : 8194,
- 'breve' : 728,
- 'uni0442' : 1090,
- 'Oacute' : 211,
- 'uni229F' : 8863,
- 'uni25C7' : 9671,
- 'uni229D' : 8861,
- 'uni229E' : 8862,
- 'guillemotleft' : 171,
- 'uni0329' : 809,
- 'uni24E5' : 9445,
- 'uni011F' : 287,
- 'uni0324' : 804,
- 'uni0325' : 805,
- 'uni0326' : 806,
- 'uni0327' : 807,
- 'uni0321' : 801,
- 'uni0322' : 802,
- 'n' : 110,
- 'uni2032' : 8242,
- 'uni2269' : 8809,
- 'uni2268' : 8808,
- 'uni0306' : 774,
- 'uni226B' : 8811,
- 'uni21EA' : 8682,
- 'uni0166' : 358,
- 'uni203B' : 8251,
- 'uni01B5' : 437,
- 'idieresis' : 239,
- 'uni02BC' : 700,
- 'uni01B0' : 432,
- 'braceright' : 125,
- 'seven' : 55,
- 'uni02BB' : 699,
- 'uni011A' : 282,
- 'uni29FB' : 10747,
- 'brokenbar' : 166,
- 'uni2036' : 8246,
- 'uni25C0' : 9664,
- 'uni0156' : 342,
- 'uni22D5' : 8917,
- 'uni0258' : 600,
- 'ugrave' : 249,
- 'uni22D6' : 8918,
- 'uni22D1' : 8913,
- 'uni2034' : 8244,
- 'uni22D3' : 8915,
- 'uni22D2' : 8914,
- 'uni203C' : 8252,
- 'uni223E' : 8766,
- 'uni02BF' : 703,
- 'uni22D9' : 8921,
- 'uni22D8' : 8920,
- 'uni25BD' : 9661,
- 'uni25BE' : 9662,
- 'uni25BF' : 9663,
- 'uni041B' : 1051,
- 'periodcentered' : 183,
- 'uni25BC' : 9660,
- 'uni019E' : 414,
- 'uni019B' : 411,
- 'uni019A' : 410,
- 'uni2007' : 8199,
- 'uni0391' : 913,
- 'uni0390' : 912,
- 'uni0393' : 915,
- 'uni0392' : 914,
- 'uni0395' : 917,
- 'uni0394' : 916,
- 'uni0397' : 919,
- 'uni0396' : 918,
- 'uni0399' : 921,
- 'uni0398' : 920,
- 'uni25C8' : 9672,
- 'uni2468' : 9320,
- 'sterling' : 163,
- 'uni22EB' : 8939,
- 'uni039C' : 924,
- 'uni039B' : 923,
- 'uni039E' : 926,
- 'uni039D' : 925,
- 'uni039F' : 927,
- 'I' : 73,
- 'uni03E1' : 993,
- 'uni03E0' : 992,
- 'uni2319' : 8985,
- 'uni228B' : 8843,
- 'uni25B5' : 9653,
- 'uni25B6' : 9654,
- 'uni22EA' : 8938,
- 'uni24B9' : 9401,
- 'uni044E' : 1102,
- 'uni0199' : 409,
- 'uni2266' : 8806,
- 'Y' : 89,
- 'uni22A2' : 8866,
- 'Eth' : 208,
- 'uni266F' : 9839,
- 'emdash' : 8212,
- 'uni263B' : 9787,
- 'uni24BD' : 9405,
- 'uni22DE' : 8926,
- 'uni0360' : 864,
- 'uni2557' : 9559,
- 'uni22DF' : 8927,
- 'uni22DA' : 8922,
- 'uni22DC' : 8924,
- 'uni0361' : 865,
- 'i' : 105,
- 'uni24BF' : 9407,
- 'uni0362' : 866,
- 'uni263E' : 9790,
- 'uni028D' : 653,
- 'uni2259' : 8793,
- 'uni0323' : 803,
- 'uni2265' : 8805,
- 'daggerdbl' : 8225,
- 'y' : 121,
- 'uni010A' : 266,
- 'plusminus' : 177,
- 'less' : 60,
- 'uni21AE' : 8622,
- 'uni0315' : 789,
- 'uni230B' : 8971,
- 'uni21AF' : 8623,
- 'uni21AA' : 8618,
- 'uni21AC' : 8620,
- 'uni21AB' : 8619,
- 'uni01FB' : 507,
- 'uni01FC' : 508,
- 'uni223A' : 8762,
- 'uni01FA' : 506,
- 'uni01FF' : 511,
- 'uni01FD' : 509,
- 'uni01FE' : 510,
- 'uni2567' : 9575,
- 'uni25E0' : 9696,
- 'uni0104' : 260,
- 'uni0105' : 261,
- 'uni0106' : 262,
- 'uni0107' : 263,
- 'uni0100' : 256,
- 'uni0101' : 257,
- 'uni0102' : 258,
- 'uni0103' : 259,
- 'uni2038' : 8248,
- 'uni2009' : 8201,
- 'uni2008' : 8200,
- 'uni0108' : 264,
- 'uni0109' : 265,
- 'uni02A1' : 673,
- 'uni223B' : 8763,
- 'uni226C' : 8812,
- 'uni25AC' : 9644,
- 'uni24D3' : 9427,
- 'uni21E0' : 8672,
- 'uni21E3' : 8675,
- 'Udieresis' : 220,
- 'uni21E2' : 8674,
- 'D' : 68,
- 'uni21E5' : 8677,
- 'uni2621' : 9761,
- 'uni21D1' : 8657,
- 'uni203E' : 8254,
- 'uni22C6' : 8902,
- 'uni21E4' : 8676,
- 'uni010D' : 269,
- 'uni010E' : 270,
- 'uni010F' : 271,
- 'five' : 53,
- 'T' : 84,
- 'uni010B' : 267,
- 'uni010C' : 268,
- 'uni2605' : 9733,
- 'uni2663' : 9827,
- 'uni21E6' : 8678,
- 'uni24B6' : 9398,
- 'uni22C1' : 8897,
- 'oslash' : 248,
- 'acute' : 180,
- 'uni01F0' : 496,
- 'd' : 100,
- 'OE' : 338,
- 'uni22E3' : 8931,
- 'Igrave' : 204,
- 'uni2308' : 8968,
- 'uni2309' : 8969,
- 'uni21A9' : 8617,
- 't' : 116,
- 'uni2313' : 8979,
- 'uni03A3' : 931,
- 'uni21A4' : 8612,
- 'uni21A7' : 8615,
- 'uni21A6' : 8614,
- 'uni21A1' : 8609,
- 'uni21A0' : 8608,
- 'uni21A3' : 8611,
- 'uni21A2' : 8610,
- 'parenright' : 41,
- 'uni256A' : 9578,
- 'uni25DC' : 9692,
- 'uni24CE' : 9422,
- 'uni042C' : 1068,
- 'uni24E0' : 9440,
- 'uni042B' : 1067,
- 'uni0409' : 1033,
- 'uni0408' : 1032,
- 'uni24E7' : 9447,
- 'uni25B4' : 9652,
- 'uni042A' : 1066,
- 'uni228E' : 8846,
- 'uni0401' : 1025,
- 'adieresis' : 228,
- 'uni0403' : 1027,
- 'quotesingle' : 39,
- 'uni0405' : 1029,
- 'uni0404' : 1028,
- 'uni0407' : 1031,
- 'uni0406' : 1030,
- 'uni229C' : 8860,
- 'uni2306' : 8966,
- 'uni2253' : 8787,
- 'twodotenleader' : 8229,
- 'uni2131' : 8497,
- 'uni21DA' : 8666,
- 'uni2234' : 8756,
- 'uni2235' : 8757,
- 'uni01A5' : 421,
- 'uni2237' : 8759,
- 'uni2230' : 8752,
- 'uni02CC' : 716,
- 'slash' : 47,
- 'uni01A0' : 416,
- 'ellipsis' : 8230,
- 'uni2299' : 8857,
- 'uni2238' : 8760,
- 'numbersign' : 35,
- 'uni21A8' : 8616,
- 'uni223D' : 8765,
- 'uni01AF' : 431,
- 'uni223F' : 8767,
- 'uni01AD' : 429,
- 'uni01AB' : 427,
- 'odieresis' : 246,
- 'uni223C' : 8764,
- 'uni227D' : 8829,
- 'uni0280' : 640,
- 'O' : 79,
- 'uni227E' : 8830,
- 'uni21A5' : 8613,
- 'uni22D4' : 8916,
- 'uni25D4' : 9684,
- 'uni227F' : 8831,
- 'uni0435' : 1077,
- 'uni2302' : 8962,
- 'uni2669' : 9833,
- 'uni24E3' : 9443,
- 'uni2720' : 10016,
- 'uni22A8' : 8872,
- 'uni22A9' : 8873,
- 'uni040A' : 1034,
- 'uni22A7' : 8871,
- 'oe' : 339,
- 'uni040B' : 1035,
- 'uni040E' : 1038,
- 'uni22A3' : 8867,
- 'o' : 111,
- 'uni040F' : 1039,
- 'Edieresis' : 203,
- 'uni25D5' : 9685,
- 'plus' : 43,
- 'uni044D' : 1101,
- 'uni263C' : 9788,
- 'uni22E6' : 8934,
- 'uni2283' : 8835,
- 'uni258C' : 9612,
- 'uni219E' : 8606,
- 'uni24E4' : 9444,
- 'uni2136' : 8502,
- 'dagger' : 8224,
- 'uni24B7' : 9399,
- 'uni219B' : 8603,
- 'uni22E5' : 8933,
- 'three' : 51,
- 'uni210B' : 8459,
- 'uni2534' : 9524,
- 'uni24B8' : 9400,
- 'uni230A' : 8970,
- 'hungarumlaut' : 733,
- 'parenleft' : 40,
- 'uni0148' : 328,
- 'uni0149' : 329,
- 'uni2124' : 8484,
- 'uni2125' : 8485,
- 'uni2126' : 8486,
- 'uni2127' : 8487,
- 'uni0140' : 320,
- 'uni2129' : 8489,
- 'uni25C5' : 9669,
- 'uni0143' : 323,
- 'uni0144' : 324,
- 'uni0145' : 325,
- 'uni0146' : 326,
- 'uni0147' : 327,
- 'uni210D' : 8461,
- 'fraction' : 8260,
- 'uni2031' : 8241,
- 'uni2196' : 8598,
- 'uni2035' : 8245,
- 'uni24E6' : 9446,
- 'uni016B' : 363,
- 'uni24BA' : 9402,
- 'uni266A' : 9834,
- 'uni0116' : 278,
- 'uni2115' : 8469,
- 'registered' : 174,
- 'J' : 74,
- 'uni25DF' : 9695,
- 'uni25CE' : 9678,
- 'uni273D' : 10045,
- 'dieresis' : 168,
- 'uni212B' : 8491,
- 'uni0114' : 276,
- 'uni212D' : 8493,
- 'uni212E' : 8494,
- 'uni212F' : 8495,
- 'uni014A' : 330,
- 'uni014B' : 331,
- 'uni014C' : 332,
- 'uni014D' : 333,
- 'uni014E' : 334,
- 'uni014F' : 335,
- 'uni025E' : 606,
- 'uni24E8' : 9448,
- 'uni0111' : 273,
- 'uni24E9' : 9449,
- 'Ograve' : 210,
- 'j' : 106,
- 'uni2195' : 8597,
- 'uni2194' : 8596,
- 'uni2197' : 8599,
- 'uni2037' : 8247,
- 'uni2191' : 8593,
- 'uni2190' : 8592,
- 'uni2193' : 8595,
- 'uni2192' : 8594,
- 'uni29FA' : 10746,
- 'uni2713' : 10003,
- 'z' : 122,
- 'uni2199' : 8601,
- 'uni2198' : 8600,
- 'uni2667' : 9831,
- 'ae' : 230,
- 'uni0448' : 1096,
- 'semicolon' : 59,
- 'uni2666' : 9830,
- 'uni038F' : 911,
- 'uni0444' : 1092,
- 'uni0447' : 1095,
- 'uni038E' : 910,
- 'uni0441' : 1089,
- 'uni038C' : 908,
- 'uni0443' : 1091,
- 'uni038A' : 906,
- 'uni0250' : 592,
- 'uni0251' : 593,
- 'uni0252' : 594,
- 'uni0253' : 595,
- 'uni0254' : 596,
- 'at' : 64,
- 'uni0256' : 598,
- 'uni0257' : 599,
- 'uni0167' : 359,
- 'uni0259' : 601,
- 'uni228C' : 8844,
- 'uni2662' : 9826,
- 'uni0319' : 793,
- 'uni0318' : 792,
- 'uni24BC' : 9404,
- 'uni0402' : 1026,
- 'uni22EF' : 8943,
- 'Iacute' : 205,
- 'uni22ED' : 8941,
- 'uni22EE' : 8942,
- 'uni0311' : 785,
- 'uni0310' : 784,
- 'uni21E8' : 8680,
- 'uni0312' : 786,
- 'percent' : 37,
- 'uni0317' : 791,
- 'uni0316' : 790,
- 'uni21D6' : 8662,
- 'uni21D7' : 8663,
- 'uni21D4' : 8660,
- 'uni21D5' : 8661,
- 'uni21D2' : 8658,
- 'uni21D3' : 8659,
- 'uni21D0' : 8656,
- 'uni2138' : 8504,
- 'uni2270' : 8816,
- 'uni2271' : 8817,
- 'uni2272' : 8818,
- 'uni2273' : 8819,
- 'uni2274' : 8820,
- 'uni2275' : 8821,
- 'bracketright' : 93,
- 'uni21D9' : 8665,
- 'uni21DF' : 8671,
- 'uni21DD' : 8669,
- 'uni21DE' : 8670,
- 'AE' : 198,
- 'uni03AE' : 942,
- 'uni227A' : 8826,
- 'uni227B' : 8827,
- 'uni227C' : 8828,
- 'asterisk' : 42,
- 'aacute' : 225,
- 'uni226F' : 8815,
- 'uni22E2' : 8930,
- 'uni0386' : 902,
- 'uni22E0' : 8928,
- 'uni22E1' : 8929,
- 'U' : 85,
- 'uni22E7' : 8935,
- 'uni22E4' : 8932,
- 'uni0387' : 903,
- 'uni031A' : 794,
- 'eacute' : 233,
- 'uni22E8' : 8936,
- 'uni22E9' : 8937,
- 'uni24D8' : 9432,
- 'uni025A' : 602,
- 'uni025B' : 603,
- 'uni025C' : 604,
- 'e' : 101,
- 'uni0128' : 296,
- 'uni025F' : 607,
- 'uni2665' : 9829,
- 'thorn' : 254,
- 'uni0129' : 297,
- 'uni253C' : 9532,
- 'uni25D7' : 9687,
- 'u' : 117,
- 'uni0388' : 904,
- 'uni0389' : 905,
- 'uni0255' : 597,
- 'uni0171' : 369,
- 'uni0384' : 900,
- 'uni0385' : 901,
- 'uni044A' : 1098,
- 'uni252C' : 9516,
- 'uni044C' : 1100,
- 'uni044B' : 1099
-}
-
-uni2type1 = dict(((v,k) for k,v in six.iteritems(type12uni)))
-
-tex2uni = {
- 'widehat' : 0x0302,
- 'widetilde' : 0x0303,
- 'widebar' : 0x0305,
- 'langle' : 0x27e8,
- 'rangle' : 0x27e9,
- 'perp' : 0x27c2,
- 'neq' : 0x2260,
- 'Join' : 0x2a1d,
- 'leqslant' : 0x2a7d,
- 'geqslant' : 0x2a7e,
- 'lessapprox' : 0x2a85,
- 'gtrapprox' : 0x2a86,
- 'lesseqqgtr' : 0x2a8b,
- 'gtreqqless' : 0x2a8c,
- 'triangleeq' : 0x225c,
- 'eqslantless' : 0x2a95,
- 'eqslantgtr' : 0x2a96,
- 'backepsilon' : 0x03f6,
- 'precapprox' : 0x2ab7,
- 'succapprox' : 0x2ab8,
- 'fallingdotseq' : 0x2252,
- 'subseteqq' : 0x2ac5,
- 'supseteqq' : 0x2ac6,
- 'varpropto' : 0x221d,
- 'precnapprox' : 0x2ab9,
- 'succnapprox' : 0x2aba,
- 'subsetneqq' : 0x2acb,
- 'supsetneqq' : 0x2acc,
- 'lnapprox' : 0x2ab9,
- 'gnapprox' : 0x2aba,
- 'longleftarrow' : 0x27f5,
- 'longrightarrow' : 0x27f6,
- 'longleftrightarrow' : 0x27f7,
- 'Longleftarrow' : 0x27f8,
- 'Longrightarrow' : 0x27f9,
- 'Longleftrightarrow' : 0x27fa,
- 'longmapsto' : 0x27fc,
- 'leadsto' : 0x21dd,
- 'dashleftarrow' : 0x290e,
- 'dashrightarrow' : 0x290f,
- 'circlearrowleft' : 0x21ba,
- 'circlearrowright' : 0x21bb,
- 'leftrightsquigarrow' : 0x21ad,
- 'leftsquigarrow' : 0x219c,
- 'rightsquigarrow' : 0x219d,
- 'Game' : 0x2141,
- 'hbar' : 0x0127,
- 'hslash' : 0x210f,
- 'ldots' : 0x2026,
- 'vdots' : 0x22ee,
- 'doteqdot' : 0x2251,
- 'doteq' : 8784,
- 'partial' : 8706,
- 'gg' : 8811,
- 'asymp' : 8781,
- 'blacktriangledown' : 9662,
- 'otimes' : 8855,
- 'nearrow' : 8599,
- 'varpi' : 982,
- 'vee' : 8744,
- 'vec' : 8407,
- 'smile' : 8995,
- 'succnsim' : 8937,
- 'gimel' : 8503,
- 'vert' : 124,
- '|' : 124,
- 'varrho' : 1009,
- 'P' : 182,
- 'approxident' : 8779,
- 'Swarrow' : 8665,
- 'textasciicircum' : 94,
- 'imageof' : 8887,
- 'ntriangleleft' : 8938,
- 'nleq' : 8816,
- 'div' : 247,
- 'nparallel' : 8742,
- 'Leftarrow' : 8656,
- 'lll' : 8920,
- 'oiint' : 8751,
- 'ngeq' : 8817,
- 'Theta' : 920,
- 'origof' : 8886,
- 'blacksquare' : 9632,
- 'solbar' : 9023,
- 'neg' : 172,
- 'sum' : 8721,
- 'Vdash' : 8873,
- 'coloneq' : 8788,
- 'degree' : 176,
- 'bowtie' : 8904,
- 'blacktriangleright' : 9654,
- 'varsigma' : 962,
- 'leq' : 8804,
- 'ggg' : 8921,
- 'lneqq' : 8808,
- 'scurel' : 8881,
- 'stareq' : 8795,
- 'BbbN' : 8469,
- 'nLeftarrow' : 8653,
- 'nLeftrightarrow' : 8654,
- 'k' : 808,
- 'bot' : 8869,
- 'BbbC' : 8450,
- 'Lsh' : 8624,
- 'leftleftarrows' : 8647,
- 'BbbZ' : 8484,
- 'digamma' : 989,
- 'BbbR' : 8477,
- 'BbbP' : 8473,
- 'BbbQ' : 8474,
- 'vartriangleright' : 8883,
- 'succsim' : 8831,
- 'wedge' : 8743,
- 'lessgtr' : 8822,
- 'veebar' : 8891,
- 'mapsdown' : 8615,
- 'Rsh' : 8625,
- 'chi' : 967,
- 'prec' : 8826,
- 'nsubseteq' : 8840,
- 'therefore' : 8756,
- 'eqcirc' : 8790,
- 'textexclamdown' : 161,
- 'nRightarrow' : 8655,
- 'flat' : 9837,
- 'notin' : 8713,
- 'llcorner' : 8990,
- 'varepsilon' : 949,
- 'bigtriangleup' : 9651,
- 'aleph' : 8501,
- 'dotminus' : 8760,
- 'upsilon' : 965,
- 'Lambda' : 923,
- 'cap' : 8745,
- 'barleftarrow' : 8676,
- 'mu' : 956,
- 'boxplus' : 8862,
- 'mp' : 8723,
- 'circledast' : 8859,
- 'tau' : 964,
- 'in' : 8712,
- 'backslash' : 92,
- 'varnothing' : 8709,
- 'sharp' : 9839,
- 'eqsim' : 8770,
- 'gnsim' : 8935,
- 'Searrow' : 8664,
- 'updownarrows' : 8645,
- 'heartsuit' : 9825,
- 'trianglelefteq' : 8884,
- 'ddag' : 8225,
- 'sqsubseteq' : 8849,
- 'mapsfrom' : 8612,
- 'boxbar' : 9707,
- 'sim' : 8764,
- 'Nwarrow' : 8662,
- 'nequiv' : 8802,
- 'succ' : 8827,
- 'vdash' : 8866,
- 'Leftrightarrow' : 8660,
- 'parallel' : 8741,
- 'invnot' : 8976,
- 'natural' : 9838,
- 'ss' : 223,
- 'uparrow' : 8593,
- 'nsim' : 8769,
- 'hookrightarrow' : 8618,
- 'Equiv' : 8803,
- 'approx' : 8776,
- 'Vvdash' : 8874,
- 'nsucc' : 8833,
- 'leftrightharpoons' : 8651,
- 'Re' : 8476,
- 'boxminus' : 8863,
- 'equiv' : 8801,
- 'Lleftarrow' : 8666,
- 'thinspace' : 8201,
- 'll' : 8810,
- 'Cup' : 8915,
- 'measeq' : 8798,
- 'upharpoonleft' : 8639,
- 'lq' : 8216,
- 'Upsilon' : 933,
- 'subsetneq' : 8842,
- 'greater' : 62,
- 'supsetneq' : 8843,
- 'Cap' : 8914,
- 'L' : 321,
- 'spadesuit' : 9824,
- 'lrcorner' : 8991,
- 'not' : 824,
- 'bar' : 772,
- 'rightharpoonaccent' : 8401,
- 'boxdot' : 8865,
- 'l' : 322,
- 'leftharpoondown' : 8637,
- 'bigcup' : 8899,
- 'iint' : 8748,
- 'bigwedge' : 8896,
- 'downharpoonleft' : 8643,
- 'textasciitilde' : 126,
- 'subset' : 8834,
- 'leqq' : 8806,
- 'mapsup' : 8613,
- 'nvDash' : 8877,
- 'looparrowleft' : 8619,
- 'nless' : 8814,
- 'rightarrowbar' : 8677,
- 'Vert' : 8214,
- 'downdownarrows' : 8650,
- 'uplus' : 8846,
- 'simeq' : 8771,
- 'napprox' : 8777,
- 'ast' : 8727,
- 'twoheaduparrow' : 8607,
- 'doublebarwedge' : 8966,
- 'Sigma' : 931,
- 'leftharpoonaccent' : 8400,
- 'ntrianglelefteq' : 8940,
- 'nexists' : 8708,
- 'times' : 215,
- 'measuredangle' : 8737,
- 'bumpeq' : 8783,
- 'carriagereturn' : 8629,
- 'adots' : 8944,
- 'checkmark' : 10003,
- 'lambda' : 955,
- 'xi' : 958,
- 'rbrace' : 125,
- 'rbrack' : 93,
- 'Nearrow' : 8663,
- 'maltese' : 10016,
- 'clubsuit' : 9827,
- 'top' : 8868,
- 'overarc' : 785,
- 'varphi' : 966,
- 'Delta' : 916,
- 'iota' : 953,
- 'nleftarrow' : 8602,
- 'candra' : 784,
- 'supset' : 8835,
- 'triangleleft' : 9665,
- 'gtreqless' : 8923,
- 'ntrianglerighteq' : 8941,
- 'quad' : 8195,
- 'Xi' : 926,
- 'gtrdot' : 8919,
- 'leftthreetimes' : 8907,
- 'minus' : 8722,
- 'preccurlyeq' : 8828,
- 'nleftrightarrow' : 8622,
- 'lambdabar' : 411,
- 'blacktriangle' : 9652,
- 'kernelcontraction' : 8763,
- 'Phi' : 934,
- 'angle' : 8736,
- 'spadesuitopen' : 9828,
- 'eqless' : 8924,
- 'mid' : 8739,
- 'varkappa' : 1008,
- 'Ldsh' : 8626,
- 'updownarrow' : 8597,
- 'beta' : 946,
- 'textquotedblleft' : 8220,
- 'rho' : 961,
- 'alpha' : 945,
- 'intercal' : 8890,
- 'beth' : 8502,
- 'grave' : 768,
- 'acwopencirclearrow' : 8634,
- 'nmid' : 8740,
- 'nsupset' : 8837,
- 'sigma' : 963,
- 'dot' : 775,
- 'Rightarrow' : 8658,
- 'turnednot' : 8985,
- 'backsimeq' : 8909,
- 'leftarrowtail' : 8610,
- 'approxeq' : 8778,
- 'curlyeqsucc' : 8927,
- 'rightarrowtail' : 8611,
- 'Psi' : 936,
- 'copyright' : 169,
- 'yen' : 165,
- 'vartriangleleft' : 8882,
- 'rasp' : 700,
- 'triangleright' : 9655,
- 'precsim' : 8830,
- 'infty' : 8734,
- 'geq' : 8805,
- 'updownarrowbar' : 8616,
- 'precnsim' : 8936,
- 'H' : 779,
- 'ulcorner' : 8988,
- 'looparrowright' : 8620,
- 'ncong' : 8775,
- 'downarrow' : 8595,
- 'circeq' : 8791,
- 'subseteq' : 8838,
- 'bigstar' : 9733,
- 'prime' : 8242,
- 'lceil' : 8968,
- 'Rrightarrow' : 8667,
- 'oiiint' : 8752,
- 'curlywedge' : 8911,
- 'vDash' : 8872,
- 'lfloor' : 8970,
- 'ddots' : 8945,
- 'exists' : 8707,
- 'underbar' : 817,
- 'Pi' : 928,
- 'leftrightarrows' : 8646,
- 'sphericalangle' : 8738,
- 'coprod' : 8720,
- 'circledcirc' : 8858,
- 'gtrsim' : 8819,
- 'gneqq' : 8809,
- 'between' : 8812,
- 'theta' : 952,
- 'complement' : 8705,
- 'arceq' : 8792,
- 'nVdash' : 8878,
- 'S' : 167,
- 'wr' : 8768,
- 'wp' : 8472,
- 'backcong' : 8780,
- 'lasp' : 701,
- 'c' : 807,
- 'nabla' : 8711,
- 'dotplus' : 8724,
- 'eta' : 951,
- 'forall' : 8704,
- 'eth' : 240,
- 'colon' : 58,
- 'sqcup' : 8852,
- 'rightrightarrows' : 8649,
- 'sqsupset' : 8848,
- 'mapsto' : 8614,
- 'bigtriangledown' : 9661,
- 'sqsupseteq' : 8850,
- 'propto' : 8733,
- 'pi' : 960,
- 'pm' : 177,
- 'dots' : 0x2026,
- 'nrightarrow' : 8603,
- 'textasciiacute' : 180,
- 'Doteq' : 8785,
- 'breve' : 774,
- 'sqcap' : 8851,
- 'twoheadrightarrow' : 8608,
- 'kappa' : 954,
- 'vartriangle' : 9653,
- 'diamondsuit' : 9826,
- 'pitchfork' : 8916,
- 'blacktriangleleft' : 9664,
- 'nprec' : 8832,
- 'vdots' : 8942,
- 'curvearrowright' : 8631,
- 'barwedge' : 8892,
- 'multimap' : 8888,
- 'textquestiondown' : 191,
- 'cong' : 8773,
- 'rtimes' : 8906,
- 'rightzigzagarrow' : 8669,
- 'rightarrow' : 8594,
- 'leftarrow' : 8592,
- '__sqrt__' : 8730,
- 'twoheaddownarrow' : 8609,
- 'oint' : 8750,
- 'bigvee' : 8897,
- 'eqdef' : 8797,
- 'sterling' : 163,
- 'phi' : 981,
- 'Updownarrow' : 8661,
- 'backprime' : 8245,
- 'emdash' : 8212,
- 'Gamma' : 915,
- 'i' : 305,
- 'rceil' : 8969,
- 'leftharpoonup' : 8636,
- 'Im' : 8465,
- 'curvearrowleft' : 8630,
- 'wedgeq' : 8793,
- 'fallingdotseq' : 8786,
- 'curlyeqprec' : 8926,
- 'questeq' : 8799,
- 'less' : 60,
- 'upuparrows' : 8648,
- 'tilde' : 771,
- 'textasciigrave' : 96,
- 'smallsetminus' : 8726,
- 'ell' : 8467,
- 'cup' : 8746,
- 'danger' : 9761,
- 'nVDash' : 8879,
- 'cdotp' : 183,
- 'cdots' : 8943,
- 'hat' : 770,
- 'eqgtr' : 8925,
- 'enspace' : 8194,
- 'psi' : 968,
- 'frown' : 8994,
- 'acute' : 769,
- 'downzigzagarrow' : 8623,
- 'ntriangleright' : 8939,
- 'cupdot' : 8845,
- 'circleddash' : 8861,
- 'oslash' : 8856,
- 'mho' : 8487,
- 'd' : 803,
- 'sqsubset' : 8847,
- 'cdot' : 8901,
- 'Omega' : 937,
- 'OE' : 338,
- 'veeeq' : 8794,
- 'Finv' : 8498,
- 't' : 865,
- 'leftrightarrow' : 8596,
- 'swarrow' : 8601,
- 'rightthreetimes' : 8908,
- 'rightleftharpoons' : 8652,
- 'lesssim' : 8818,
- 'searrow' : 8600,
- 'because' : 8757,
- 'gtrless' : 8823,
- 'star' : 8902,
- 'nsubset' : 8836,
- 'zeta' : 950,
- 'dddot' : 8411,
- 'bigcirc' : 9675,
- 'Supset' : 8913,
- 'circ' : 8728,
- 'slash' : 8725,
- 'ocirc' : 778,
- 'prod' : 8719,
- 'twoheadleftarrow' : 8606,
- 'daleth' : 8504,
- 'upharpoonright' : 8638,
- 'odot' : 8857,
- 'Uparrow' : 8657,
- 'O' : 216,
- 'hookleftarrow' : 8617,
- 'trianglerighteq' : 8885,
- 'nsime' : 8772,
- 'oe' : 339,
- 'nwarrow' : 8598,
- 'o' : 248,
- 'ddddot' : 8412,
- 'downharpoonright' : 8642,
- 'succcurlyeq' : 8829,
- 'gamma' : 947,
- 'scrR' : 8475,
- 'dag' : 8224,
- 'thickspace' : 8197,
- 'frakZ' : 8488,
- 'lessdot' : 8918,
- 'triangledown' : 9663,
- 'ltimes' : 8905,
- 'scrB' : 8492,
- 'endash' : 8211,
- 'scrE' : 8496,
- 'scrF' : 8497,
- 'scrH' : 8459,
- 'scrI' : 8464,
- 'rightharpoondown' : 8641,
- 'scrL' : 8466,
- 'scrM' : 8499,
- 'frakC' : 8493,
- 'nsupseteq' : 8841,
- 'circledR' : 174,
- 'circledS' : 9416,
- 'ngtr' : 8815,
- 'bigcap' : 8898,
- 'scre' : 8495,
- 'Downarrow' : 8659,
- 'scrg' : 8458,
- 'overleftrightarrow' : 8417,
- 'scro' : 8500,
- 'lnsim' : 8934,
- 'eqcolon' : 8789,
- 'curlyvee' : 8910,
- 'urcorner' : 8989,
- 'lbrace' : 123,
- 'Bumpeq' : 8782,
- 'delta' : 948,
- 'boxtimes' : 8864,
- 'overleftarrow' : 8406,
- 'prurel' : 8880,
- 'clubsuitopen' : 9831,
- 'cwopencirclearrow' : 8635,
- 'geqq' : 8807,
- 'rightleftarrows' : 8644,
- 'ac' : 8766,
- 'ae' : 230,
- 'int' : 8747,
- 'rfloor' : 8971,
- 'risingdotseq' : 8787,
- 'nvdash' : 8876,
- 'diamond' : 8900,
- 'ddot' : 776,
- 'backsim' : 8765,
- 'oplus' : 8853,
- 'triangleq' : 8796,
- 'check' : 780,
- 'ni' : 8715,
- 'iiint' : 8749,
- 'ne' : 8800,
- 'lesseqgtr' : 8922,
- 'obar' : 9021,
- 'supseteq' : 8839,
- 'nu' : 957,
- 'AA' : 8491,
- 'AE' : 198,
- 'models' : 8871,
- 'ominus' : 8854,
- 'dashv' : 8867,
- 'omega' : 969,
- 'rq' : 8217,
- 'Subset' : 8912,
- 'rightharpoonup' : 8640,
- 'Rdsh' : 8627,
- 'bullet' : 8729,
- 'divideontimes' : 8903,
- 'lbrack' : 91,
- 'textquotedblright' : 8221,
- 'Colon' : 8759,
- '%' : 37,
- '$' : 36,
- '{' : 123,
- '}' : 125,
- '_' : 95,
- '#' : 35,
- 'imath' : 0x131,
- 'circumflexaccent' : 770,
- 'combiningbreve' : 774,
- 'combiningoverline' : 772,
- 'combininggraveaccent' : 768,
- 'combiningacuteaccent' : 769,
- 'combiningdiaeresis' : 776,
- 'combiningtilde' : 771,
- 'combiningrightarrowabove' : 8407,
- 'combiningdotabove' : 775,
- 'to' : 8594,
- 'succeq' : 8829,
- 'emptyset' : 8709,
- 'leftparen' : 40,
- 'rightparen' : 41,
- 'bigoplus' : 10753,
- 'leftangle' : 10216,
- 'rightangle' : 10217,
- 'leftbrace' : 124,
- 'rightbrace' : 125,
- 'jmath' : 567,
- 'bigodot' : 10752,
- 'preceq' : 8828,
- 'biguplus' : 10756,
- 'epsilon' : 949,
- 'vartheta' : 977,
- 'bigotimes' : 10754,
- 'guillemotleft' : 171,
- 'ring' : 730,
- 'Thorn' : 222,
- 'guilsinglright' : 8250,
- 'perthousand' : 8240,
- 'macron' : 175,
- 'cent' : 162,
- 'guillemotright' : 187,
- 'equal' : 61,
- 'asterisk' : 42,
- 'guilsinglleft' : 8249,
- 'plus' : 43,
- 'thorn' : 254,
- 'dagger' : 8224
-}
-
-# Each element is a 4-tuple of the form:
-# src_start, src_end, dst_font, dst_start
-#
-stix_virtual_fonts = {
- 'bb':
- {
- 'rm':
- [
- (0x0030, 0x0039, 'rm', 0x1d7d8), # 0-9
- (0x0041, 0x0042, 'rm', 0x1d538), # A-B
- (0x0043, 0x0043, 'rm', 0x2102), # C
- (0x0044, 0x0047, 'rm', 0x1d53b), # D-G
- (0x0048, 0x0048, 'rm', 0x210d), # H
- (0x0049, 0x004d, 'rm', 0x1d540), # I-M
- (0x004e, 0x004e, 'rm', 0x2115), # N
- (0x004f, 0x004f, 'rm', 0x1d546), # O
- (0x0050, 0x0051, 'rm', 0x2119), # P-Q
- (0x0052, 0x0052, 'rm', 0x211d), # R
- (0x0053, 0x0059, 'rm', 0x1d54a), # S-Y
- (0x005a, 0x005a, 'rm', 0x2124), # Z
- (0x0061, 0x007a, 'rm', 0x1d552), # a-z
- (0x0393, 0x0393, 'rm', 0x213e), # \Gamma
- (0x03a0, 0x03a0, 'rm', 0x213f), # \Pi
- (0x03a3, 0x03a3, 'rm', 0x2140), # \Sigma
- (0x03b3, 0x03b3, 'rm', 0x213d), # \gamma
- (0x03c0, 0x03c0, 'rm', 0x213c), # \pi
- ],
- 'it':
- [
- (0x0030, 0x0039, 'rm', 0x1d7d8), # 0-9
- (0x0041, 0x0042, 'it', 0xe154), # A-B
- (0x0043, 0x0043, 'it', 0x2102), # C
- (0x0044, 0x0044, 'it', 0x2145), # D
- (0x0045, 0x0047, 'it', 0xe156), # E-G
- (0x0048, 0x0048, 'it', 0x210d), # H
- (0x0049, 0x004d, 'it', 0xe159), # I-M
- (0x004e, 0x004e, 'it', 0x2115), # N
- (0x004f, 0x004f, 'it', 0xe15e), # O
- (0x0050, 0x0051, 'it', 0x2119), # P-Q
- (0x0052, 0x0052, 'it', 0x211d), # R
- (0x0053, 0x0059, 'it', 0xe15f), # S-Y
- (0x005a, 0x005a, 'it', 0x2124), # Z
- (0x0061, 0x0063, 'it', 0xe166), # a-c
- (0x0064, 0x0065, 'it', 0x2146), # d-e
- (0x0066, 0x0068, 'it', 0xe169), # f-h
- (0x0069, 0x006a, 'it', 0x2148), # i-j
- (0x006b, 0x007a, 'it', 0xe16c), # k-z
- (0x0393, 0x0393, 'it', 0x213e), # \Gamma (missing in beta STIX fonts)
- (0x03a0, 0x03a0, 'it', 0x213f), # \Pi
- (0x03a3, 0x03a3, 'it', 0x2140), # \Sigma (missing in beta STIX fonts)
- (0x03b3, 0x03b3, 'it', 0x213d), # \gamma (missing in beta STIX fonts)
- (0x03c0, 0x03c0, 'it', 0x213c), # \pi
- ],
- 'bf':
- [
- (0x0030, 0x0039, 'rm', 0x1d7d8), # 0-9
- (0x0041, 0x0042, 'bf', 0xe38a), # A-B
- (0x0043, 0x0043, 'bf', 0x2102), # C
- (0x0044, 0x0044, 'bf', 0x2145), # D
- (0x0045, 0x0047, 'bf', 0xe38d), # E-G
- (0x0048, 0x0048, 'bf', 0x210d), # H
- (0x0049, 0x004d, 'bf', 0xe390), # I-M
- (0x004e, 0x004e, 'bf', 0x2115), # N
- (0x004f, 0x004f, 'bf', 0xe395), # O
- (0x0050, 0x0051, 'bf', 0x2119), # P-Q
- (0x0052, 0x0052, 'bf', 0x211d), # R
- (0x0053, 0x0059, 'bf', 0xe396), # S-Y
- (0x005a, 0x005a, 'bf', 0x2124), # Z
- (0x0061, 0x0063, 'bf', 0xe39d), # a-c
- (0x0064, 0x0065, 'bf', 0x2146), # d-e
- (0x0066, 0x0068, 'bf', 0xe3a2), # f-h
- (0x0069, 0x006a, 'bf', 0x2148), # i-j
- (0x006b, 0x007a, 'bf', 0xe3a7), # k-z
- (0x0393, 0x0393, 'bf', 0x213e), # \Gamma
- (0x03a0, 0x03a0, 'bf', 0x213f), # \Pi
- (0x03a3, 0x03a3, 'bf', 0x2140), # \Sigma
- (0x03b3, 0x03b3, 'bf', 0x213d), # \gamma
- (0x03c0, 0x03c0, 'bf', 0x213c), # \pi
- ],
- },
- 'cal':
- [
- (0x0041, 0x005a, 'it', 0xe22d), # A-Z
- ],
- 'circled':
- {
- 'rm':
- [
- (0x0030, 0x0030, 'rm', 0x24ea), # 0
- (0x0031, 0x0039, 'rm', 0x2460), # 1-9
- (0x0041, 0x005a, 'rm', 0x24b6), # A-Z
- (0x0061, 0x007a, 'rm', 0x24d0) # a-z
- ],
- 'it':
- [
- (0x0030, 0x0030, 'rm', 0x24ea), # 0
- (0x0031, 0x0039, 'rm', 0x2460), # 1-9
- (0x0041, 0x005a, 'it', 0x24b6), # A-Z
- (0x0061, 0x007a, 'it', 0x24d0) # a-z
- ],
- 'bf':
- [
- (0x0030, 0x0030, 'bf', 0x24ea), # 0
- (0x0031, 0x0039, 'bf', 0x2460), # 1-9
- (0x0041, 0x005a, 'bf', 0x24b6), # A-Z
- (0x0061, 0x007a, 'bf', 0x24d0) # a-z
- ],
- },
- 'frak':
- {
- 'rm':
- [
- (0x0041, 0x0042, 'rm', 0x1d504), # A-B
- (0x0043, 0x0043, 'rm', 0x212d), # C
- (0x0044, 0x0047, 'rm', 0x1d507), # D-G
- (0x0048, 0x0048, 'rm', 0x210c), # H
- (0x0049, 0x0049, 'rm', 0x2111), # I
- (0x004a, 0x0051, 'rm', 0x1d50d), # J-Q
- (0x0052, 0x0052, 'rm', 0x211c), # R
- (0x0053, 0x0059, 'rm', 0x1d516), # S-Y
- (0x005a, 0x005a, 'rm', 0x2128), # Z
- (0x0061, 0x007a, 'rm', 0x1d51e), # a-z
- ],
- 'it':
- [
- (0x0041, 0x0042, 'rm', 0x1d504), # A-B
- (0x0043, 0x0043, 'rm', 0x212d), # C
- (0x0044, 0x0047, 'rm', 0x1d507), # D-G
- (0x0048, 0x0048, 'rm', 0x210c), # H
- (0x0049, 0x0049, 'rm', 0x2111), # I
- (0x004a, 0x0051, 'rm', 0x1d50d), # J-Q
- (0x0052, 0x0052, 'rm', 0x211c), # R
- (0x0053, 0x0059, 'rm', 0x1d516), # S-Y
- (0x005a, 0x005a, 'rm', 0x2128), # Z
- (0x0061, 0x007a, 'rm', 0x1d51e), # a-z
- ],
- 'bf':
- [
- (0x0041, 0x005a, 'bf', 0x1d56c), # A-Z
- (0x0061, 0x007a, 'bf', 0x1d586), # a-z
- ],
- },
- 'scr':
- [
- (0x0041, 0x0041, 'it', 0x1d49c), # A
- (0x0042, 0x0042, 'it', 0x212c), # B
- (0x0043, 0x0044, 'it', 0x1d49e), # C-D
- (0x0045, 0x0046, 'it', 0x2130), # E-F
- (0x0047, 0x0047, 'it', 0x1d4a2), # G
- (0x0048, 0x0048, 'it', 0x210b), # H
- (0x0049, 0x0049, 'it', 0x2110), # I
- (0x004a, 0x004b, 'it', 0x1d4a5), # J-K
- (0x004c, 0x004c, 'it', 0x2112), # L
- (0x004d, 0x003d, 'it', 0x2133), # M
- (0x004e, 0x0051, 'it', 0x1d4a9), # N-Q
- (0x0052, 0x0052, 'it', 0x211b), # R
- (0x0053, 0x005a, 'it', 0x1d4ae), # S-Z
- (0x0061, 0x0064, 'it', 0x1d4b6), # a-d
- (0x0065, 0x0065, 'it', 0x212f), # e
- (0x0066, 0x0066, 'it', 0x1d4bb), # f
- (0x0067, 0x0067, 'it', 0x210a), # g
- (0x0068, 0x006e, 'it', 0x1d4bd), # h-n
- (0x006f, 0x006f, 'it', 0x2134), # o
- (0x0070, 0x007a, 'it', 0x1d4c5), # p-z
- ],
- 'sf':
- {
- 'rm':
- [
- (0x0030, 0x0039, 'rm', 0x1d7e2), # 0-9
- (0x0041, 0x005a, 'rm', 0x1d5a0), # A-Z
- (0x0061, 0x007a, 'rm', 0x1d5ba), # a-z
- (0x0391, 0x03a9, 'rm', 0xe17d), # \Alpha-\Omega
- (0x03b1, 0x03c9, 'rm', 0xe196), # \alpha-\omega
- (0x03d1, 0x03d1, 'rm', 0xe1b0), # theta variant
- (0x03d5, 0x03d5, 'rm', 0xe1b1), # phi variant
- (0x03d6, 0x03d6, 'rm', 0xe1b3), # pi variant
- (0x03f1, 0x03f1, 'rm', 0xe1b2), # rho variant
- (0x03f5, 0x03f5, 'rm', 0xe1af), # lunate epsilon
- (0x2202, 0x2202, 'rm', 0xe17c), # partial differential
- ],
- 'it':
- [
- # These numerals are actually upright. We don't actually
- # want italic numerals ever.
- (0x0030, 0x0039, 'rm', 0x1d7e2), # 0-9
- (0x0041, 0x005a, 'it', 0x1d608), # A-Z
- (0x0061, 0x007a, 'it', 0x1d622), # a-z
- (0x0391, 0x03a9, 'rm', 0xe17d), # \Alpha-\Omega
- (0x03b1, 0x03c9, 'it', 0xe1d8), # \alpha-\omega
- (0x03d1, 0x03d1, 'it', 0xe1f2), # theta variant
- (0x03d5, 0x03d5, 'it', 0xe1f3), # phi variant
- (0x03d6, 0x03d6, 'it', 0xe1f5), # pi variant
- (0x03f1, 0x03f1, 'it', 0xe1f4), # rho variant
- (0x03f5, 0x03f5, 'it', 0xe1f1), # lunate epsilon
- ],
- 'bf':
- [
- (0x0030, 0x0039, 'bf', 0x1d7ec), # 0-9
- (0x0041, 0x005a, 'bf', 0x1d5d4), # A-Z
- (0x0061, 0x007a, 'bf', 0x1d5ee), # a-z
- (0x0391, 0x03a9, 'bf', 0x1d756), # \Alpha-\Omega
- (0x03b1, 0x03c9, 'bf', 0x1d770), # \alpha-\omega
- (0x03d1, 0x03d1, 'bf', 0x1d78b), # theta variant
- (0x03d5, 0x03d5, 'bf', 0x1d78d), # phi variant
- (0x03d6, 0x03d6, 'bf', 0x1d78f), # pi variant
- (0x03f0, 0x03f0, 'bf', 0x1d78c), # kappa variant
- (0x03f1, 0x03f1, 'bf', 0x1d78e), # rho variant
- (0x03f5, 0x03f5, 'bf', 0x1d78a), # lunate epsilon
- (0x2202, 0x2202, 'bf', 0x1d789), # partial differential
- (0x2207, 0x2207, 'bf', 0x1d76f), # \Nabla
- ],
- },
- 'tt':
- [
- (0x0030, 0x0039, 'rm', 0x1d7f6), # 0-9
- (0x0041, 0x005a, 'rm', 0x1d670), # A-Z
- (0x0061, 0x007a, 'rm', 0x1d68a) # a-z
- ],
- }
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/_path.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/_path.so
deleted file mode 100755
index e2d183c..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/_path.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/_png.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/_png.so
deleted file mode 100755
index abc3937..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/_png.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/_pylab_helpers.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/_pylab_helpers.py
deleted file mode 100644
index f521920..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/_pylab_helpers.py
+++ /dev/null
@@ -1,138 +0,0 @@
-"""
-Manage figures for pyplot interface.
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import sys, gc
-
-import atexit
-
-
-def error_msg(msg):
- print(msg, file=sys.stderr)
-
-class Gcf(object):
- """
- Singleton to manage a set of integer-numbered figures.
-
- This class is never instantiated; it consists of two class
- attributes (a list and a dictionary), and a set of static
- methods that operate on those attributes, accessing them
- directly as class attributes.
-
- Attributes:
-
- *figs*:
- dictionary of the form {*num*: *manager*, ...}
-
- *_activeQue*:
- list of *managers*, with active one at the end
-
- """
- _activeQue = []
- figs = {}
-
- @staticmethod
- def get_fig_manager(num):
- """
- If figure manager *num* exists, make it the active
- figure and return the manager; otherwise return *None*.
- """
- manager = Gcf.figs.get(num, None)
- if manager is not None:
- Gcf.set_active(manager)
- return manager
-
- @staticmethod
- def destroy(num):
- """
- Try to remove all traces of figure *num*.
-
- In the interactive backends, this is bound to the
- window "destroy" and "delete" events.
- """
- if not Gcf.has_fignum(num): return
- manager = Gcf.figs[num]
- manager.canvas.mpl_disconnect(manager._cidgcf)
-
- # There must be a good reason for the following careful
- # rebuilding of the activeQue; what is it?
- oldQue = Gcf._activeQue[:]
- Gcf._activeQue = []
- for f in oldQue:
- if f != manager:
- Gcf._activeQue.append(f)
-
- del Gcf.figs[num]
- #print len(Gcf.figs.keys()), len(Gcf._activeQue)
- manager.destroy()
- gc.collect(1)
-
- @staticmethod
- def destroy_fig(fig):
- "*fig* is a Figure instance"
- num = None
- for manager in six.itervalues(Gcf.figs):
- if manager.canvas.figure == fig:
- num = manager.num
- break
- if num is not None:
- Gcf.destroy(num)
-
- @staticmethod
- def destroy_all():
- for manager in list(Gcf.figs.values()):
- manager.canvas.mpl_disconnect(manager._cidgcf)
- manager.destroy()
-
- Gcf._activeQue = []
- Gcf.figs.clear()
- gc.collect(1)
-
- @staticmethod
- def has_fignum(num):
- """
- Return *True* if figure *num* exists.
- """
- return num in Gcf.figs
-
- @staticmethod
- def get_all_fig_managers():
- """
- Return a list of figure managers.
- """
- return list(Gcf.figs.values())
-
- @staticmethod
- def get_num_fig_managers():
- """
- Return the number of figures being managed.
- """
- return len(Gcf.figs.values())
-
- @staticmethod
- def get_active():
- """
- Return the manager of the active figure, or *None*.
- """
- if len(Gcf._activeQue)==0:
- return None
- else: return Gcf._activeQue[-1]
-
- @staticmethod
- def set_active(manager):
- """
- Make the figure corresponding to *manager* the active one.
- """
- oldQue = Gcf._activeQue[:]
- Gcf._activeQue = []
- for m in oldQue:
- if m != manager: Gcf._activeQue.append(m)
- Gcf._activeQue.append(manager)
- Gcf.figs[manager.num] = manager
-
-
-atexit.register(Gcf.destroy_all)
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/_qhull.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/_qhull.so
deleted file mode 100755
index b75fbbb..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/_qhull.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/_tri.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/_tri.so
deleted file mode 100755
index e45e549..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/_tri.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/afm.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/afm.py
deleted file mode 100644
index 754e369..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/afm.py
+++ /dev/null
@@ -1,555 +0,0 @@
-"""
-This is a python interface to Adobe Font Metrics Files. Although a
-number of other python implementations exist, and may be more complete
-than this, it was decided not to go with them because they were
-either:
-
- 1) copyrighted or used a non-BSD compatible license
-
- 2) had too many dependencies and a free standing lib was needed
-
- 3) Did more than needed and it was easier to write afresh rather than
- figure out how to get just what was needed.
-
-It is pretty easy to use, and requires only built-in python libs:
-
- >>> from matplotlib import rcParams
- >>> import os.path
- >>> afm_fname = os.path.join(rcParams['datapath'],
- ... 'fonts', 'afm', 'ptmr8a.afm')
- >>>
- >>> from matplotlib.afm import AFM
- >>> afm = AFM(open(afm_fname))
- >>> afm.string_width_height('What the heck?')
- (6220.0, 694)
- >>> afm.get_fontname()
- 'Times-Roman'
- >>> afm.get_kern_dist('A', 'f')
- 0
- >>> afm.get_kern_dist('A', 'y')
- -92.0
- >>> afm.get_bbox_char('!')
- [130, -9, 238, 676]
-
-"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import map
-
-import sys
-import os
-import re
-from ._mathtext_data import uni2type1
-
-#Convert string the a python type
-
-# some afm files have floats where we are expecting ints -- there is
-# probably a better way to handle this (support floats, round rather
-# than truncate). But I don't know what the best approach is now and
-# this change to _to_int should at least prevent mpl from crashing on
-# these JDH (2009-11-06)
-
-
-def _to_int(x):
- return int(float(x))
-
-_to_float = float
-if six.PY3:
- def _to_str(x):
- return x.decode('utf8')
-else:
- _to_str = str
-
-
-def _to_list_of_ints(s):
- s = s.replace(b',', b' ')
- return [_to_int(val) for val in s.split()]
-
-
-def _to_list_of_floats(s):
- return [_to_float(val) for val in s.split()]
-
-
-def _to_bool(s):
- if s.lower().strip() in (b'false', b'0', b'no'):
- return False
- else:
- return True
-
-
-def _sanity_check(fh):
- """
- Check if the file at least looks like AFM.
- If not, raise :exc:`RuntimeError`.
- """
-
- # Remember the file position in case the caller wants to
- # do something else with the file.
- pos = fh.tell()
- try:
- line = fh.readline()
- finally:
- fh.seek(pos, 0)
-
- # AFM spec, Section 4: The StartFontMetrics keyword [followed by a
- # version number] must be the first line in the file, and the
- # EndFontMetrics keyword must be the last non-empty line in the
- # file. We just check the first line.
- if not line.startswith(b'StartFontMetrics'):
- raise RuntimeError('Not an AFM file')
-
-
-def _parse_header(fh):
- """
- Reads the font metrics header (up to the char metrics) and returns
- a dictionary mapping *key* to *val*. *val* will be converted to the
- appropriate python type as necessary; e.g.:
-
- * 'False'->False
- * '0'->0
- * '-168 -218 1000 898'-> [-168, -218, 1000, 898]
-
- Dictionary keys are
-
- StartFontMetrics, FontName, FullName, FamilyName, Weight,
- ItalicAngle, IsFixedPitch, FontBBox, UnderlinePosition,
- UnderlineThickness, Version, Notice, EncodingScheme, CapHeight,
- XHeight, Ascender, Descender, StartCharMetrics
-
- """
- headerConverters = {
- b'StartFontMetrics': _to_float,
- b'FontName': _to_str,
- b'FullName': _to_str,
- b'FamilyName': _to_str,
- b'Weight': _to_str,
- b'ItalicAngle': _to_float,
- b'IsFixedPitch': _to_bool,
- b'FontBBox': _to_list_of_ints,
- b'UnderlinePosition': _to_int,
- b'UnderlineThickness': _to_int,
- b'Version': _to_str,
- b'Notice': _to_str,
- b'EncodingScheme': _to_str,
- b'CapHeight': _to_float, # Is the second version a mistake, or
- b'Capheight': _to_float, # do some AFM files contain 'Capheight'? -JKS
- b'XHeight': _to_float,
- b'Ascender': _to_float,
- b'Descender': _to_float,
- b'StdHW': _to_float,
- b'StdVW': _to_float,
- b'StartCharMetrics': _to_int,
- b'CharacterSet': _to_str,
- b'Characters': _to_int,
- }
-
- d = {}
- while 1:
- line = fh.readline()
- if not line:
- break
- line = line.rstrip()
- if line.startswith(b'Comment'):
- continue
- lst = line.split(b' ', 1)
- #print '%-s\t%-d line :: %-s' % ( fh.name, len(lst), line )
- key = lst[0]
- if len(lst) == 2:
- val = lst[1]
- else:
- val = b''
- #key, val = line.split(' ', 1)
- try:
- d[key] = headerConverters[key](val)
- except ValueError:
- print('Value error parsing header in AFM:',
- key, val, file=sys.stderr)
- continue
- except KeyError:
- print('Found an unknown keyword in AFM header (was %s)' % key,
- file=sys.stderr)
- continue
- if key == b'StartCharMetrics':
- return d
- raise RuntimeError('Bad parse')
-
-
-def _parse_char_metrics(fh):
- """
- Return a character metric dictionary. Keys are the ASCII num of
- the character, values are a (*wx*, *name*, *bbox*) tuple, where
- *wx* is the character width, *name* is the postscript language
- name, and *bbox* is a (*llx*, *lly*, *urx*, *ury*) tuple.
-
- This function is incomplete per the standard, but thus far parses
- all the sample afm files tried.
- """
-
- ascii_d = {}
- name_d = {}
- while 1:
- line = fh.readline()
- if not line:
- break
- line = line.rstrip()
- if line.startswith(b'EndCharMetrics'):
- return ascii_d, name_d
- vals = line.split(b';')[:4]
- if len(vals) != 4:
- raise RuntimeError('Bad char metrics line: %s' % line)
- num = _to_int(vals[0].split()[1])
- wx = _to_float(vals[1].split()[1])
- name = vals[2].split()[1]
- name = name.decode('ascii')
- bbox = _to_list_of_floats(vals[3][2:])
- bbox = list(map(int, bbox))
- # Workaround: If the character name is 'Euro', give it the
- # corresponding character code, according to WinAnsiEncoding (see PDF
- # Reference).
- if name == 'Euro':
- num = 128
- if num != -1:
- ascii_d[num] = (wx, name, bbox)
- name_d[name] = (wx, bbox)
- raise RuntimeError('Bad parse')
-
-
-def _parse_kern_pairs(fh):
- """
- Return a kern pairs dictionary; keys are (*char1*, *char2*) tuples and
- values are the kern pair value. For example, a kern pairs line like
- ``KPX A y -50``
-
- will be represented as::
-
- d[ ('A', 'y') ] = -50
-
- """
-
- line = fh.readline()
- if not line.startswith(b'StartKernPairs'):
- raise RuntimeError('Bad start of kern pairs data: %s' % line)
-
- d = {}
- while 1:
- line = fh.readline()
- if not line:
- break
- line = line.rstrip()
- if len(line) == 0:
- continue
- if line.startswith(b'EndKernPairs'):
- fh.readline() # EndKernData
- return d
- vals = line.split()
- if len(vals) != 4 or vals[0] != b'KPX':
- raise RuntimeError('Bad kern pairs line: %s' % line)
- c1, c2, val = _to_str(vals[1]), _to_str(vals[2]), _to_float(vals[3])
- d[(c1, c2)] = val
- raise RuntimeError('Bad kern pairs parse')
-
-
-def _parse_composites(fh):
- """
- Return a composites dictionary. Keys are the names of the
- composites. Values are a num parts list of composite information,
- with each element being a (*name*, *dx*, *dy*) tuple. Thus a
- composites line reading:
-
- CC Aacute 2 ; PCC A 0 0 ; PCC acute 160 170 ;
-
- will be represented as::
-
- d['Aacute'] = [ ('A', 0, 0), ('acute', 160, 170) ]
-
- """
- d = {}
- while 1:
- line = fh.readline()
- if not line:
- break
- line = line.rstrip()
- if len(line) == 0:
- continue
- if line.startswith(b'EndComposites'):
- return d
- vals = line.split(b';')
- cc = vals[0].split()
- name, numParts = cc[1], _to_int(cc[2])
- pccParts = []
- for s in vals[1:-1]:
- pcc = s.split()
- name, dx, dy = pcc[1], _to_float(pcc[2]), _to_float(pcc[3])
- pccParts.append((name, dx, dy))
- d[name] = pccParts
-
- raise RuntimeError('Bad composites parse')
-
-
-def _parse_optional(fh):
- """
- Parse the optional fields for kern pair data and composites
-
- return value is a (*kernDict*, *compositeDict*) which are the
- return values from :func:`_parse_kern_pairs`, and
- :func:`_parse_composites` if the data exists, or empty dicts
- otherwise
- """
- optional = {
- b'StartKernData': _parse_kern_pairs,
- b'StartComposites': _parse_composites,
- }
-
- d = {b'StartKernData': {}, b'StartComposites': {}}
- while 1:
- line = fh.readline()
- if not line:
- break
- line = line.rstrip()
- if len(line) == 0:
- continue
- key = line.split()[0]
-
- if key in optional:
- d[key] = optional[key](fh)
-
- l = (d[b'StartKernData'], d[b'StartComposites'])
- return l
-
-
-def parse_afm(fh):
- """
- Parse the Adobe Font Metics file in file handle *fh*. Return value
- is a (*dhead*, *dcmetrics*, *dkernpairs*, *dcomposite*) tuple where
- *dhead* is a :func:`_parse_header` dict, *dcmetrics* is a
- :func:`_parse_composites` dict, *dkernpairs* is a
- :func:`_parse_kern_pairs` dict (possibly {}), and *dcomposite* is a
- :func:`_parse_composites` dict (possibly {})
- """
- _sanity_check(fh)
- dhead = _parse_header(fh)
- dcmetrics_ascii, dcmetrics_name = _parse_char_metrics(fh)
- doptional = _parse_optional(fh)
- return dhead, dcmetrics_ascii, dcmetrics_name, doptional[0], doptional[1]
-
-
-class AFM(object):
-
- def __init__(self, fh):
- """
- Parse the AFM file in file object *fh*
- """
- (dhead, dcmetrics_ascii, dcmetrics_name, dkernpairs, dcomposite) = \
- parse_afm(fh)
- self._header = dhead
- self._kern = dkernpairs
- self._metrics = dcmetrics_ascii
- self._metrics_by_name = dcmetrics_name
- self._composite = dcomposite
-
- def get_bbox_char(self, c, isord=False):
- if not isord:
- c = ord(c)
- wx, name, bbox = self._metrics[c]
- return bbox
-
- def string_width_height(self, s):
- """
- Return the string width (including kerning) and string height
- as a (*w*, *h*) tuple.
- """
- if not len(s):
- return 0, 0
- totalw = 0
- namelast = None
- miny = 1e9
- maxy = 0
- for c in s:
- if c == '\n':
- continue
- wx, name, bbox = self._metrics[ord(c)]
- l, b, w, h = bbox
-
- # find the width with kerning
- try:
- kp = self._kern[(namelast, name)]
- except KeyError:
- kp = 0
- totalw += wx + kp
-
- # find the max y
- thismax = b + h
- if thismax > maxy:
- maxy = thismax
-
- # find the min y
- thismin = b
- if thismin < miny:
- miny = thismin
- namelast = name
-
- return totalw, maxy - miny
-
- def get_str_bbox_and_descent(self, s):
- """
- Return the string bounding box
- """
- if not len(s):
- return 0, 0, 0, 0
- totalw = 0
- namelast = None
- miny = 1e9
- maxy = 0
- left = 0
- if not isinstance(s, six.text_type):
- s = s.decode('ascii')
- for c in s:
- if c == '\n':
- continue
- name = uni2type1.get(ord(c), 'question')
- try:
- wx, bbox = self._metrics_by_name[name]
- except KeyError:
- name = 'question'
- wx, bbox = self._metrics_by_name[name]
- l, b, w, h = bbox
- if l < left:
- left = l
- # find the width with kerning
- try:
- kp = self._kern[(namelast, name)]
- except KeyError:
- kp = 0
- totalw += wx + kp
-
- # find the max y
- thismax = b + h
- if thismax > maxy:
- maxy = thismax
-
- # find the min y
- thismin = b
- if thismin < miny:
- miny = thismin
- namelast = name
-
- return left, miny, totalw, maxy - miny, -miny
-
- def get_str_bbox(self, s):
- """
- Return the string bounding box
- """
- return self.get_str_bbox_and_descent(s)[:4]
-
- def get_name_char(self, c, isord=False):
- """
- Get the name of the character, i.e., ';' is 'semicolon'
- """
- if not isord:
- c = ord(c)
- wx, name, bbox = self._metrics[c]
- return name
-
- def get_width_char(self, c, isord=False):
- """
- Get the width of the character from the character metric WX
- field
- """
- if not isord:
- c = ord(c)
- wx, name, bbox = self._metrics[c]
- return wx
-
- def get_width_from_char_name(self, name):
- """
- Get the width of the character from a type1 character name
- """
- wx, bbox = self._metrics_by_name[name]
- return wx
-
- def get_height_char(self, c, isord=False):
- """
- Get the height of character *c* from the bounding box. This
- is the ink height (space is 0)
- """
- if not isord:
- c = ord(c)
- wx, name, bbox = self._metrics[c]
- return bbox[-1]
-
- def get_kern_dist(self, c1, c2):
- """
- Return the kerning pair distance (possibly 0) for chars *c1*
- and *c2*
- """
- name1, name2 = self.get_name_char(c1), self.get_name_char(c2)
- return self.get_kern_dist_from_name(name1, name2)
-
- def get_kern_dist_from_name(self, name1, name2):
- """
- Return the kerning pair distance (possibly 0) for chars
- *name1* and *name2*
- """
- try:
- return self._kern[(name1, name2)]
- except:
- return 0
-
- def get_fontname(self):
- "Return the font name, e.g., 'Times-Roman'"
- return self._header[b'FontName']
-
- def get_fullname(self):
- "Return the font full name, e.g., 'Times-Roman'"
- name = self._header.get(b'FullName')
- if name is None: # use FontName as a substitute
- name = self._header[b'FontName']
- return name
-
- def get_familyname(self):
- "Return the font family name, e.g., 'Times'"
- name = self._header.get(b'FamilyName')
- if name is not None:
- return name
-
- # FamilyName not specified so we'll make a guess
- name = self.get_fullname()
- extras = br'(?i)([ -](regular|plain|italic|oblique|bold|semibold|light|ultralight|extra|condensed))+$'
- return re.sub(extras, '', name)
-
- def get_weight(self):
- "Return the font weight, e.g., 'Bold' or 'Roman'"
- return self._header[b'Weight']
-
- def get_angle(self):
- "Return the fontangle as float"
- return self._header[b'ItalicAngle']
-
- def get_capheight(self):
- "Return the cap height as float"
- return self._header[b'CapHeight']
-
- def get_xheight(self):
- "Return the xheight as float"
- return self._header[b'XHeight']
-
- def get_underline_thickness(self):
- "Return the underline thickness as float"
- return self._header[b'UnderlineThickness']
-
- def get_horizontal_stem_width(self):
- """
- Return the standard horizontal stem width as float, or *None* if
- not specified in AFM file.
- """
- return self._header.get(b'StdHW', None)
-
- def get_vertical_stem_width(self):
- """
- Return the standard vertical stem width as float, or *None* if
- not specified in AFM file.
- """
- return self._header.get(b'StdVW', None)
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/animation.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/animation.py
deleted file mode 100644
index 566d0b7..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/animation.py
+++ /dev/null
@@ -1,1106 +0,0 @@
-# TODO:
-# * Loop Delay is broken on GTKAgg. This is because source_remove() is not
-# working as we want. PyGTK bug?
-# * Documentation -- this will need a new section of the User's Guide.
-# Both for Animations and just timers.
-# - Also need to update http://www.scipy.org/Cookbook/Matplotlib/Animations
-# * Blit
-# * Currently broken with Qt4 for widgets that don't start on screen
-# * Still a few edge cases that aren't working correctly
-# * Can this integrate better with existing matplotlib animation artist flag?
-# - If animated removes from default draw(), perhaps we could use this to
-# simplify initial draw.
-# * Example
-# * Frameless animation - pure procedural with no loop
-# * Need example that uses something like inotify or subprocess
-# * Complex syncing examples
-# * Movies
-# * Can blit be enabled for movies?
-# * Need to consider event sources to allow clicking through multiple figures
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import xrange, zip
-
-import platform
-import sys
-import itertools
-import contextlib
-from matplotlib.cbook import iterable, is_string_like
-from matplotlib.compat import subprocess
-from matplotlib import verbose
-from matplotlib import rcParams
-
-# Process creation flag for subprocess to prevent it raising a terminal
-# window. See for example:
-# https://stackoverflow.com/questions/24130623/using-python-subprocess-popen-cant-prevent-exe-stopped-working-prompt
-if platform.system() == 'Windows':
- CREATE_NO_WINDOW = 0x08000000
- subprocess_creation_flags = CREATE_NO_WINDOW
-else:
- # Apparently None won't work here
- subprocess_creation_flags = 0
-
-# Other potential writing methods:
-# * http://pymedia.org/
-# * libmng (produces swf) python wrappers: https://github.com/libming/libming
-# * Wrap x264 API:
-
-# (http://stackoverflow.com/questions/2940671/
-# how-to-encode-series-of-images-into-h264-using-x264-api-c-c )
-
-
-# A registry for available MovieWriter classes
-class MovieWriterRegistry(object):
- def __init__(self):
- self.avail = dict()
-
- # Returns a decorator that can be used on classes to register them under
- # a name. As in:
- # @register('foo')
- # class Foo:
- # pass
- def register(self, name):
- def wrapper(writerClass):
- if writerClass.isAvailable():
- self.avail[name] = writerClass
- return writerClass
- return wrapper
-
- def list(self):
- ''' Get a list of available MovieWriters.'''
- return list(self.avail.keys())
-
- def is_available(self, name):
- return name in self.avail
-
- def __getitem__(self, name):
- if not self.avail:
- raise RuntimeError("No MovieWriters available!")
- return self.avail[name]
-
-writers = MovieWriterRegistry()
-
-
-class MovieWriter(object):
- '''
- Base class for writing movies. Fundamentally, what a MovieWriter does
- is provide is a way to grab frames by calling grab_frame(). setup()
- is called to start the process and finish() is called afterwards.
- This class is set up to provide for writing movie frame data to a pipe.
- saving() is provided as a context manager to facilitate this process as::
-
- with moviewriter.saving('myfile.mp4'):
- # Iterate over frames
- moviewriter.grab_frame()
-
- The use of the context manager ensures that setup and cleanup are
- performed as necessary.
-
- frame_format: string
- The format used in writing frame data, defaults to 'rgba'
- '''
- def __init__(self, fps=5, codec=None, bitrate=None, extra_args=None,
- metadata=None):
- '''
- Construct a new MovieWriter object.
-
- fps: int
- Framerate for movie.
- codec: string or None, optional
- The codec to use. If None (the default) the setting in the
- rcParam `animation.codec` is used.
- bitrate: int or None, optional
- The bitrate for the saved movie file, which is one way to control
- the output file size and quality. The default value is None,
- which uses the value stored in the rcParam `animation.bitrate`.
- A value of -1 implies that the bitrate should be determined
- automatically by the underlying utility.
- extra_args: list of strings or None
- A list of extra string arguments to be passed to the underlying
- movie utiltiy. The default is None, which passes the additional
- argurments in the 'animation.extra_args' rcParam.
- metadata: dict of string:string or None
- A dictionary of keys and values for metadata to include in the
- output file. Some keys that may be of use include:
- title, artist, genre, subject, copyright, srcform, comment.
- '''
- self.fps = fps
- self.frame_format = 'rgba'
-
- if codec is None:
- self.codec = rcParams['animation.codec']
- else:
- self.codec = codec
-
- if bitrate is None:
- self.bitrate = rcParams['animation.bitrate']
- else:
- self.bitrate = bitrate
-
- if extra_args is None:
- self.extra_args = list(rcParams[self.args_key])
- else:
- self.extra_args = extra_args
-
- if metadata is None:
- self.metadata = dict()
- else:
- self.metadata = metadata
-
- @property
- def frame_size(self):
- 'A tuple (width,height) in pixels of a movie frame.'
- width_inches, height_inches = self.fig.get_size_inches()
- return width_inches * self.dpi, height_inches * self.dpi
-
- def setup(self, fig, outfile, dpi, *args):
- '''
- Perform setup for writing the movie file.
-
- fig: `matplotlib.Figure` instance
- The figure object that contains the information for frames
- outfile: string
- The filename of the resulting movie file
- dpi: int
- The DPI (or resolution) for the file. This controls the size
- in pixels of the resulting movie file.
- '''
- self.outfile = outfile
- self.fig = fig
- self.dpi = dpi
-
- # Run here so that grab_frame() can write the data to a pipe. This
- # eliminates the need for temp files.
- self._run()
-
- @contextlib.contextmanager
- def saving(self, *args):
- '''
- Context manager to facilitate writing the movie file.
-
- ``*args`` are any parameters that should be passed to `setup`.
- '''
- # This particular sequence is what contextlib.contextmanager wants
- self.setup(*args)
- yield
- self.finish()
-
- def _run(self):
- # Uses subprocess to call the program for assembling frames into a
- # movie file. *args* returns the sequence of command line arguments
- # from a few configuration options.
- command = self._args()
- if verbose.ge('debug'):
- output = sys.stdout
- else:
- output = subprocess.PIPE
- verbose.report('MovieWriter.run: running command: %s' %
- ' '.join(command))
- self._proc = subprocess.Popen(command, shell=False,
- stdout=output, stderr=output,
- stdin=subprocess.PIPE,
- creationflags=subprocess_creation_flags)
-
- def finish(self):
- 'Finish any processing for writing the movie.'
- self.cleanup()
-
- def grab_frame(self, **savefig_kwargs):
- '''
- Grab the image information from the figure and save as a movie frame.
- All keyword arguments in savefig_kwargs are passed on to the 'savefig'
- command that saves the figure.
- '''
- verbose.report('MovieWriter.grab_frame: Grabbing frame.',
- level='debug')
- try:
- # Tell the figure to save its data to the sink, using the
- # frame format and dpi.
- self.fig.savefig(self._frame_sink(), format=self.frame_format,
- dpi=self.dpi, **savefig_kwargs)
- except RuntimeError:
- out, err = self._proc.communicate()
- verbose.report('MovieWriter -- Error '
- 'running proc:\n%s\n%s' % (out,
- err), level='helpful')
- raise
-
- def _frame_sink(self):
- 'Returns the place to which frames should be written.'
- return self._proc.stdin
-
- def _args(self):
- 'Assemble list of utility-specific command-line arguments.'
- return NotImplementedError("args needs to be implemented by subclass.")
-
- def cleanup(self):
- 'Clean-up and collect the process used to write the movie file.'
- out, err = self._proc.communicate()
- verbose.report('MovieWriter -- '
- 'Command stdout:\n%s' % out, level='debug')
- verbose.report('MovieWriter -- '
- 'Command stderr:\n%s' % err, level='debug')
-
- @classmethod
- def bin_path(cls):
- '''
- Returns the binary path to the commandline tool used by a specific
- subclass. This is a class method so that the tool can be looked for
- before making a particular MovieWriter subclass available.
- '''
- return rcParams[cls.exec_key]
-
- @classmethod
- def isAvailable(cls):
- '''
- Check to see if a MovieWriter subclass is actually available by
- running the commandline tool.
- '''
- try:
- p = subprocess.Popen(cls.bin_path(),
- shell=False,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- creationflags=subprocess_creation_flags)
- p.communicate()
- return True
- except OSError:
- return False
-
-
-class FileMovieWriter(MovieWriter):
- '`MovieWriter` subclass that handles writing to a file.'
- def __init__(self, *args, **kwargs):
- MovieWriter.__init__(self, *args, **kwargs)
- self.frame_format = rcParams['animation.frame_format']
-
- def setup(self, fig, outfile, dpi, frame_prefix='_tmp', clear_temp=True):
- '''
- Perform setup for writing the movie file.
-
- fig: `matplotlib.Figure` instance
- The figure object that contains the information for frames
- outfile: string
- The filename of the resulting movie file
- dpi: int
- The DPI (or resolution) for the file. This controls the size
- in pixels of the resulting movie file.
- frame_prefix: string, optional
- The filename prefix to use for the temporary files. Defaults
- to '_tmp'
- clear_temp: bool
- Specifies whether the temporary files should be deleted after
- the movie is written. (Useful for debugging.) Defaults to True.
- '''
- self.fig = fig
- self.outfile = outfile
- self.dpi = dpi
- self.clear_temp = clear_temp
- self.temp_prefix = frame_prefix
- self._frame_counter = 0 # used for generating sequential file names
- self._temp_names = list()
- self.fname_format_str = '%s%%07d.%s'
-
- @property
- def frame_format(self):
- '''
- Format (png, jpeg, etc.) to use for saving the frames, which can be
- decided by the individual subclasses.
- '''
- return self._frame_format
-
- @frame_format.setter
- def frame_format(self, frame_format):
- if frame_format in self.supported_formats:
- self._frame_format = frame_format
- else:
- self._frame_format = self.supported_formats[0]
-
- def _base_temp_name(self):
- # Generates a template name (without number) given the frame format
- # for extension and the prefix.
- return self.fname_format_str % (self.temp_prefix, self.frame_format)
-
- def _frame_sink(self):
- # Creates a filename for saving using the basename and the current
- # counter.
- fname = self._base_temp_name() % self._frame_counter
-
- # Save the filename so we can delete it later if necessary
- self._temp_names.append(fname)
- verbose.report(
- 'FileMovieWriter.frame_sink: saving frame %d to fname=%s' %
- (self._frame_counter, fname),
- level='debug')
- self._frame_counter += 1 # Ensures each created name is 'unique'
-
- # This file returned here will be closed once it's used by savefig()
- # because it will no longer be referenced and will be gc-ed.
- return open(fname, 'wb')
-
- def grab_frame(self, **savefig_kwargs):
- '''
- Grab the image information from the figure and save as a movie frame.
- All keyword arguments in savefig_kwargs are passed on to the 'savefig'
- command that saves the figure.
- '''
- # Overloaded to explicitly close temp file.
- verbose.report('MovieWriter.grab_frame: Grabbing frame.',
- level='debug')
- try:
- # Tell the figure to save its data to the sink, using the
- # frame format and dpi.
- myframesink = self._frame_sink()
- self.fig.savefig(myframesink, format=self.frame_format,
- dpi=self.dpi, **savefig_kwargs)
- myframesink.close()
-
- except RuntimeError:
- out, err = self._proc.communicate()
- verbose.report('MovieWriter -- Error '
- 'running proc:\n%s\n%s' % (out,
- err), level='helpful')
- raise
-
- def finish(self):
- # Call run here now that all frame grabbing is done. All temp files
- # are available to be assembled.
- self._run()
- MovieWriter.finish(self) # Will call clean-up
-
- # Check error code for creating file here, since we just run
- # the process here, rather than having an open pipe.
- if self._proc.returncode:
- raise RuntimeError('Error creating movie, return code: '
- + str(self._proc.returncode)
- + ' Try running with --verbose-debug')
-
- def cleanup(self):
- MovieWriter.cleanup(self)
-
- # Delete temporary files
- if self.clear_temp:
- import os
- verbose.report(
- 'MovieWriter: clearing temporary fnames=%s' %
- str(self._temp_names),
- level='debug')
- for fname in self._temp_names:
- os.remove(fname)
-
-
-# Base class of ffmpeg information. Has the config keys and the common set
-# of arguments that controls the *output* side of things.
-class FFMpegBase:
- exec_key = 'animation.ffmpeg_path'
- args_key = 'animation.ffmpeg_args'
-
- @property
- def output_args(self):
- # The %dk adds 'k' as a suffix so that ffmpeg treats our bitrate as in
- # kbps
- args = ['-vcodec', self.codec]
- if self.bitrate > 0:
- args.extend(['-b', '%dk' % self.bitrate])
- if self.extra_args:
- args.extend(self.extra_args)
- for k, v in six.iteritems(self.metadata):
- args.extend(['-metadata', '%s=%s' % (k, v)])
-
- return args + ['-y', self.outfile]
-
-
-# Combine FFMpeg options with pipe-based writing
-@writers.register('ffmpeg')
-class FFMpegWriter(MovieWriter, FFMpegBase):
- def _args(self):
- # Returns the command line parameters for subprocess to use
- # ffmpeg to create a movie using a pipe.
- args = [self.bin_path(), '-f', 'rawvideo', '-vcodec', 'rawvideo',
- '-s', '%dx%d' % self.frame_size, '-pix_fmt', self.frame_format,
- '-r', str(self.fps)]
- # Logging is quieted because subprocess.PIPE has limited buffer size.
- if not verbose.ge('debug'):
- args += ['-loglevel', 'quiet']
- args += ['-i', 'pipe:'] + self.output_args
- return args
-
-
-# Combine FFMpeg options with temp file-based writing
-@writers.register('ffmpeg_file')
-class FFMpegFileWriter(FileMovieWriter, FFMpegBase):
- supported_formats = ['png', 'jpeg', 'ppm', 'tiff', 'sgi', 'bmp',
- 'pbm', 'raw', 'rgba']
-
- def _args(self):
- # Returns the command line parameters for subprocess to use
- # ffmpeg to create a movie using a collection of temp images
- return [self.bin_path(), '-i', self._base_temp_name(),
- '-vframes', str(self._frame_counter),
- '-r', str(self.fps)] + self.output_args
-
-
-# Base class of avconv information. AVConv has identical arguments to
-# FFMpeg
-class AVConvBase(FFMpegBase):
- exec_key = 'animation.avconv_path'
- args_key = 'animation.avconv_args'
-
-
-# Combine AVConv options with pipe-based writing
-@writers.register('avconv')
-class AVConvWriter(AVConvBase, FFMpegWriter):
- pass
-
-
-# Combine AVConv options with file-based writing
-@writers.register('avconv_file')
-class AVConvFileWriter(AVConvBase, FFMpegFileWriter):
- pass
-
-
-# Base class of mencoder information. Contains configuration key information
-# as well as arguments for controlling *output*
-class MencoderBase:
- exec_key = 'animation.mencoder_path'
- args_key = 'animation.mencoder_args'
-
- # Mencoder only allows certain keys, other ones cause the program
- # to fail.
- allowed_metadata = ['name', 'artist', 'genre', 'subject', 'copyright',
- 'srcform', 'comment']
-
- # Mencoder mandates using name, but 'title' works better with ffmpeg.
- # If we find it, just put it's value into name
- def _remap_metadata(self):
- if 'title' in self.metadata:
- self.metadata['name'] = self.metadata['title']
-
- @property
- def output_args(self):
- self._remap_metadata()
- lavcopts = {'vcodec': self.codec}
- if self.bitrate > 0:
- lavcopts.update(vbitrate=self.bitrate)
- args = ['-o', self.outfile, '-ovc', 'lavc', '-lavcopts',
- ':'.join(itertools.starmap('{0}={1}'.format,
- lavcopts.items()))]
- if self.extra_args:
- args.extend(self.extra_args)
- if self.metadata:
- args.extend(['-info', ':'.join('%s=%s' % (k, v)
- for k, v in six.iteritems(self.metadata)
- if k in self.allowed_metadata)])
- return args
-
-
-# Combine Mencoder options with pipe-based writing
-@writers.register('mencoder')
-class MencoderWriter(MovieWriter, MencoderBase):
- def _args(self):
- # Returns the command line parameters for subprocess to use
- # mencoder to create a movie
- return [self.bin_path(), '-', '-demuxer', 'rawvideo', '-rawvideo',
- ('w=%i:h=%i:' % self.frame_size +
- 'fps=%i:format=%s' % (self.fps,
- self.frame_format))] + self.output_args
-
-
-# Combine Mencoder options with temp file-based writing
-@writers.register('mencoder_file')
-class MencoderFileWriter(FileMovieWriter, MencoderBase):
- supported_formats = ['png', 'jpeg', 'tga', 'sgi']
-
- def _args(self):
- # Returns the command line parameters for subprocess to use
- # mencoder to create a movie
- return [self.bin_path(),
- 'mf://%s*.%s' % (self.temp_prefix, self.frame_format),
- '-frames', str(self._frame_counter), '-mf',
- 'type=%s:fps=%d' % (self.frame_format,
- self.fps)] + self.output_args
-
-
-# Base class for animated GIFs with convert utility
-class ImageMagickBase:
- exec_key = 'animation.convert_path'
- args_key = 'animation.convert_args'
-
- @property
- def delay(self):
- return 100. / self.fps
-
- @property
- def output_args(self):
- return [self.outfile]
-
-
-@writers.register('imagemagick')
-class ImageMagickWriter(MovieWriter, ImageMagickBase):
- def _args(self):
- return ([self.bin_path(),
- '-size', '%ix%i' % self.frame_size, '-depth', '8',
- '-delay', str(self.delay), '-loop', '0',
- '%s:-' % self.frame_format]
- + self.output_args)
-
-
-@writers.register('imagemagick_file')
-class ImageMagickFileWriter(FileMovieWriter, ImageMagickBase):
- supported_formats = ['png', 'jpeg', 'ppm', 'tiff', 'sgi', 'bmp',
- 'pbm', 'raw', 'rgba']
-
- def _args(self):
- return ([self.bin_path(), '-delay', str(self.delay), '-loop', '0',
- '%s*.%s' % (self.temp_prefix, self.frame_format)]
- + self.output_args)
-
-
-class Animation(object):
- '''
- This class wraps the creation of an animation using matplotlib. It is
- only a base class which should be subclassed to provide needed behavior.
-
- *fig* is the figure object that is used to get draw, resize, and any
- other needed events.
-
- *event_source* is a class that can run a callback when desired events
- are generated, as well as be stopped and started. Examples include timers
- (see :class:`TimedAnimation`) and file system notifications.
-
- *blit* is a boolean that controls whether blitting is used to optimize
- drawing.
- '''
- def __init__(self, fig, event_source=None, blit=False):
- self._fig = fig
- # Disables blitting for backends that don't support it. This
- # allows users to request it if available, but still have a
- # fallback that works if it is not.
- self._blit = blit and fig.canvas.supports_blit
-
- # These are the basics of the animation. The frame sequence represents
- # information for each frame of the animation and depends on how the
- # drawing is handled by the subclasses. The event source fires events
- # that cause the frame sequence to be iterated.
- self.frame_seq = self.new_frame_seq()
- self.event_source = event_source
-
- # Clear the initial frame
- self._init_draw()
-
- # Instead of starting the event source now, we connect to the figure's
- # draw_event, so that we only start once the figure has been drawn.
- self._first_draw_id = fig.canvas.mpl_connect('draw_event', self._start)
-
- # Connect to the figure's close_event so that we don't continue to
- # fire events and try to draw to a deleted figure.
- self._close_id = self._fig.canvas.mpl_connect('close_event',
- self._stop)
- if self._blit:
- self._setup_blit()
-
- def _start(self, *args):
- '''
- Starts interactive animation. Adds the draw frame command to the GUI
- handler, calls show to start the event loop.
- '''
- # On start, we add our callback for stepping the animation and
- # actually start the event_source. We also disconnect _start
- # from the draw_events
- self.event_source.add_callback(self._step)
- self.event_source.start()
- self._fig.canvas.mpl_disconnect(self._first_draw_id)
- self._first_draw_id = None # So we can check on save
-
- def _stop(self, *args):
- # On stop we disconnect all of our events.
- if self._blit:
- self._fig.canvas.mpl_disconnect(self._resize_id)
- self._fig.canvas.mpl_disconnect(self._close_id)
- self.event_source.remove_callback(self._step)
- self.event_source = None
-
- def save(self, filename, writer=None, fps=None, dpi=None, codec=None,
- bitrate=None, extra_args=None, metadata=None, extra_anim=None,
- savefig_kwargs=None):
- '''
- Saves a movie file by drawing every frame.
-
- *filename* is the output filename, e.g., :file:`mymovie.mp4`
-
- *writer* is either an instance of :class:`MovieWriter` or a string
- key that identifies a class to use, such as 'ffmpeg' or 'mencoder'.
- If nothing is passed, the value of the rcparam `animation.writer` is
- used.
-
- *fps* is the frames per second in the movie. Defaults to None,
- which will use the animation's specified interval to set the frames
- per second.
-
- *dpi* controls the dots per inch for the movie frames. This combined
- with the figure's size in inches controls the size of the movie.
-
- *codec* is the video codec to be used. Not all codecs are supported
- by a given :class:`MovieWriter`. If none is given, this defaults to the
- value specified by the rcparam `animation.codec`.
-
- *bitrate* specifies the amount of bits used per second in the
- compressed movie, in kilobits per second. A higher number means a
- higher quality movie, but at the cost of increased file size. If no
- value is given, this defaults to the value given by the rcparam
- `animation.bitrate`.
-
- *extra_args* is a list of extra string arguments to be passed to the
- underlying movie utiltiy. The default is None, which passes the
- additional argurments in the 'animation.extra_args' rcParam.
-
- *metadata* is a dictionary of keys and values for metadata to include
- in the output file. Some keys that may be of use include:
- title, artist, genre, subject, copyright, srcform, comment.
-
- *extra_anim* is a list of additional `Animation` objects that should
- be included in the saved movie file. These need to be from the same
- `matplotlib.Figure` instance. Also, animation frames will just be
- simply combined, so there should be a 1:1 correspondence between
- the frames from the different animations.
-
- *savefig_kwargs* is a dictionary containing keyword arguments to be
- passed on to the 'savefig' command which is called repeatedly to save
- the individual frames. This can be used to set tight bounding boxes,
- for example.
- '''
- if savefig_kwargs is None:
- savefig_kwargs = {}
-
- # FIXME: Using 'bbox_inches' doesn't currently work with
- # writers that pipe the data to the command because this
- # requires a fixed frame size (see Ryan May's reply in this
- # thread: [1]). Thus we drop the 'bbox_inches' argument if it
- # exists in savefig_kwargs.
- #
- # [1] (http://matplotlib.1069221.n5.nabble.com/
- # Animation-class-let-save-accept-kwargs-which-
- # are-passed-on-to-savefig-td39627.html)
- #
- if 'bbox_inches' in savefig_kwargs:
- if not (writer in ['ffmpeg_file', 'mencoder_file'] or
- isinstance(writer,
- (FFMpegFileWriter, MencoderFileWriter))):
- print("Warning: discarding the 'bbox_inches' argument in "
- "'savefig_kwargs' as it is only currently supported "
- "with the writers 'ffmpeg_file' and 'mencoder_file' "
- "(writer used: "
- "'{}').".format(
- writer if isinstance(writer, six.string_types)
- else writer.__class__.__name__))
- savefig_kwargs.pop('bbox_inches')
-
- # Need to disconnect the first draw callback, since we'll be doing
- # draws. Otherwise, we'll end up starting the animation.
- if self._first_draw_id is not None:
- self._fig.canvas.mpl_disconnect(self._first_draw_id)
- reconnect_first_draw = True
- else:
- reconnect_first_draw = False
-
- if fps is None and hasattr(self, '_interval'):
- # Convert interval in ms to frames per second
- fps = 1000. / self._interval
-
- # If the writer is None, use the rc param to find the name of the one
- # to use
- if writer is None:
- writer = rcParams['animation.writer']
-
- # Re-use the savefig DPI for ours if none is given
- if dpi is None:
- dpi = rcParams['savefig.dpi']
-
- if codec is None:
- codec = rcParams['animation.codec']
-
- if bitrate is None:
- bitrate = rcParams['animation.bitrate']
-
- all_anim = [self]
- if extra_anim is not None:
- all_anim.extend(anim
- for anim
- in extra_anim if anim._fig is self._fig)
-
- # If we have the name of a writer, instantiate an instance of the
- # registered class.
- if is_string_like(writer):
- if writer in writers.avail:
- writer = writers[writer](fps, codec, bitrate,
- extra_args=extra_args,
- metadata=metadata)
- else:
- import warnings
- warnings.warn("MovieWriter %s unavailable" % writer)
-
- try:
- writer = writers[writers.list()[0]](fps, codec, bitrate,
- extra_args=extra_args,
- metadata=metadata)
- except IndexError:
- raise ValueError("Cannot save animation: no writers are "
- "available. Please install mencoder or "
- "ffmpeg to save animations.")
-
- verbose.report('Animation.save using %s' % type(writer),
- level='helpful')
- # Create a new sequence of frames for saved data. This is different
- # from new_frame_seq() to give the ability to save 'live' generated
- # frame information to be saved later.
- # TODO: Right now, after closing the figure, saving a movie won't work
- # since GUI widgets are gone. Either need to remove extra code to
- # allow for this non-existant use case or find a way to make it work.
- with writer.saving(self._fig, filename, dpi):
- for data in zip(*[a.new_saved_frame_seq()
- for a in all_anim]):
- for anim, d in zip(all_anim, data):
- # TODO: Need to see if turning off blit is really necessary
- anim._draw_next_frame(d, blit=False)
- writer.grab_frame(**savefig_kwargs)
-
- # Reconnect signal for first draw if necessary
- if reconnect_first_draw:
- self._first_draw_id = self._fig.canvas.mpl_connect('draw_event',
- self._start)
-
- def _step(self, *args):
- '''
- Handler for getting events. By default, gets the next frame in the
- sequence and hands the data off to be drawn.
- '''
- # Returns True to indicate that the event source should continue to
- # call _step, until the frame sequence reaches the end of iteration,
- # at which point False will be returned.
- try:
- framedata = next(self.frame_seq)
- self._draw_next_frame(framedata, self._blit)
- return True
- except StopIteration:
- return False
-
- def new_frame_seq(self):
- 'Creates a new sequence of frame information.'
- # Default implementation is just an iterator over self._framedata
- return iter(self._framedata)
-
- def new_saved_frame_seq(self):
- 'Creates a new sequence of saved/cached frame information.'
- # Default is the same as the regular frame sequence
- return self.new_frame_seq()
-
- def _draw_next_frame(self, framedata, blit):
- # Breaks down the drawing of the next frame into steps of pre- and
- # post- draw, as well as the drawing of the frame itself.
- self._pre_draw(framedata, blit)
- self._draw_frame(framedata)
- self._post_draw(framedata, blit)
-
- def _init_draw(self):
- # Initial draw to clear the frame. Also used by the blitting code
- # when a clean base is required.
- pass
-
- def _pre_draw(self, framedata, blit):
- # Perform any cleaning or whatnot before the drawing of the frame.
- # This default implementation allows blit to clear the frame.
- if blit:
- self._blit_clear(self._drawn_artists, self._blit_cache)
-
- def _draw_frame(self, framedata):
- # Performs actual drawing of the frame.
- raise NotImplementedError('Needs to be implemented by subclasses to'
- ' actually make an animation.')
-
- def _post_draw(self, framedata, blit):
- # After the frame is rendered, this handles the actual flushing of
- # the draw, which can be a direct draw_idle() or make use of the
- # blitting.
- if blit and self._drawn_artists:
- self._blit_draw(self._drawn_artists, self._blit_cache)
- else:
- self._fig.canvas.draw_idle()
-
- # The rest of the code in this class is to facilitate easy blitting
- def _blit_draw(self, artists, bg_cache):
- # Handles blitted drawing, which renders only the artists given instead
- # of the entire figure.
- updated_ax = []
- for a in artists:
- # If we haven't cached the background for this axes object, do
- # so now. This might not always be reliable, but it's an attempt
- # to automate the process.
- if a.axes not in bg_cache:
- bg_cache[a.axes] = a.figure.canvas.copy_from_bbox(a.axes.bbox)
- a.axes.draw_artist(a)
- updated_ax.append(a.axes)
-
- # After rendering all the needed artists, blit each axes individually.
- for ax in set(updated_ax):
- ax.figure.canvas.blit(ax.bbox)
-
- def _blit_clear(self, artists, bg_cache):
- # Get a list of the axes that need clearing from the artists that
- # have been drawn. Grab the appropriate saved background from the
- # cache and restore.
- axes = set(a.axes for a in artists)
- for a in axes:
- a.figure.canvas.restore_region(bg_cache[a])
-
- def _setup_blit(self):
- # Setting up the blit requires: a cache of the background for the
- # axes
- self._blit_cache = dict()
- self._drawn_artists = []
- self._resize_id = self._fig.canvas.mpl_connect('resize_event',
- self._handle_resize)
- self._post_draw(None, self._blit)
-
- def _handle_resize(self, *args):
- # On resize, we need to disable the resize event handling so we don't
- # get too many events. Also stop the animation events, so that
- # we're paused. Reset the cache and re-init. Set up an event handler
- # to catch once the draw has actually taken place.
- self._fig.canvas.mpl_disconnect(self._resize_id)
- self.event_source.stop()
- self._blit_cache.clear()
- self._init_draw()
- self._resize_id = self._fig.canvas.mpl_connect('draw_event',
- self._end_redraw)
-
- def _end_redraw(self, evt):
- # Now that the redraw has happened, do the post draw flushing and
- # blit handling. Then re-enable all of the original events.
- self._post_draw(None, self._blit)
- self.event_source.start()
- self._fig.canvas.mpl_disconnect(self._resize_id)
- self._resize_id = self._fig.canvas.mpl_connect('resize_event',
- self._handle_resize)
-
-
-class TimedAnimation(Animation):
- '''
- :class:`Animation` subclass that supports time-based animation, drawing
- a new frame every *interval* milliseconds.
-
- *repeat* controls whether the animation should repeat when the sequence
- of frames is completed.
-
- *repeat_delay* optionally adds a delay in milliseconds before repeating
- the animation.
- '''
- def __init__(self, fig, interval=200, repeat_delay=None, repeat=True,
- event_source=None, *args, **kwargs):
- # Store the timing information
- self._interval = interval
- self._repeat_delay = repeat_delay
- self.repeat = repeat
-
- # If we're not given an event source, create a new timer. This permits
- # sharing timers between animation objects for syncing animations.
- if event_source is None:
- event_source = fig.canvas.new_timer()
- event_source.interval = self._interval
-
- Animation.__init__(self, fig, event_source=event_source,
- *args, **kwargs)
-
- def _step(self, *args):
- '''
- Handler for getting events.
- '''
- # Extends the _step() method for the Animation class. If
- # Animation._step signals that it reached the end and we want to
- # repeat, we refresh the frame sequence and return True. If
- # _repeat_delay is set, change the event_source's interval to our loop
- # delay and set the callback to one which will then set the interval
- # back.
- still_going = Animation._step(self, *args)
- if not still_going and self.repeat:
- self.frame_seq = self.new_frame_seq()
- if self._repeat_delay:
- self.event_source.remove_callback(self._step)
- self.event_source.add_callback(self._loop_delay)
- self.event_source.interval = self._repeat_delay
- return True
- else:
- return Animation._step(self, *args)
- else:
- return still_going
-
- def _stop(self, *args):
- # If we stop in the middle of a loop delay (which is relatively likely
- # given the potential pause here, remove the loop_delay callback as
- # well.
- self.event_source.remove_callback(self._loop_delay)
- Animation._stop(self)
-
- def _loop_delay(self, *args):
- # Reset the interval and change callbacks after the delay.
- self.event_source.remove_callback(self._loop_delay)
- self.event_source.interval = self._interval
- self.event_source.add_callback(self._step)
- Animation._step(self)
-
-
-class ArtistAnimation(TimedAnimation):
- '''
- Before calling this function, all plotting should have taken place
- and the relevant artists saved.
-
- frame_info is a list, with each list entry a collection of artists that
- represent what needs to be enabled on each frame. These will be disabled
- for other frames.
- '''
- def __init__(self, fig, artists, *args, **kwargs):
- # Internal list of artists drawn in the most recent frame.
- self._drawn_artists = []
-
- # Use the list of artists as the framedata, which will be iterated
- # over by the machinery.
- self._framedata = artists
- TimedAnimation.__init__(self, fig, *args, **kwargs)
-
- def _init_draw(self):
- # Make all the artists involved in *any* frame invisible
- axes = []
- for f in self.new_frame_seq():
- for artist in f:
- artist.set_visible(False)
- # Assemble a list of unique axes that need flushing
- if artist.axes not in axes:
- axes.append(artist.axes)
-
- # Flush the needed axes
- for ax in axes:
- ax.figure.canvas.draw()
-
- def _pre_draw(self, framedata, blit):
- '''
- Clears artists from the last frame.
- '''
- if blit:
- # Let blit handle clearing
- self._blit_clear(self._drawn_artists, self._blit_cache)
- else:
- # Otherwise, make all the artists from the previous frame invisible
- for artist in self._drawn_artists:
- artist.set_visible(False)
-
- def _draw_frame(self, artists):
- # Save the artists that were passed in as framedata for the other
- # steps (esp. blitting) to use.
- self._drawn_artists = artists
-
- # Make all the artists from the current frame visible
- for artist in artists:
- artist.set_visible(True)
-
-
-class FuncAnimation(TimedAnimation):
- '''
- Makes an animation by repeatedly calling a function *func*, passing in
- (optional) arguments in *fargs*.
-
- *frames* can be a generator, an iterable, or a number of frames.
-
- *init_func* is a function used to draw a clear frame. If not given, the
- results of drawing from the first item in the frames sequence will be
- used. This function will be called once before the first frame.
-
- If blit=True, *func* and *init_func* should return an iterable of
- drawables to clear.
-
- *kwargs* include *repeat*, *repeat_delay*, and *interval*:
- *interval* draws a new frame every *interval* milliseconds.
- *repeat* controls whether the animation should repeat when the sequence
- of frames is completed.
- *repeat_delay* optionally adds a delay in milliseconds before repeating
- the animation.
- '''
- def __init__(self, fig, func, frames=None, init_func=None, fargs=None,
- save_count=None, **kwargs):
- if fargs:
- self._args = fargs
- else:
- self._args = ()
- self._func = func
-
- # Amount of framedata to keep around for saving movies. This is only
- # used if we don't know how many frames there will be: in the case
- # of no generator or in the case of a callable.
- self.save_count = save_count
-
- # Set up a function that creates a new iterable when needed. If nothing
- # is passed in for frames, just use itertools.count, which will just
- # keep counting from 0. A callable passed in for frames is assumed to
- # be a generator. An iterable will be used as is, and anything else
- # will be treated as a number of frames.
- if frames is None:
- self._iter_gen = itertools.count
- elif six.callable(frames):
- self._iter_gen = frames
- elif iterable(frames):
- self._iter_gen = lambda: iter(frames)
- if hasattr(frames, '__len__'):
- self.save_count = len(frames)
- else:
- self._iter_gen = lambda: xrange(frames).__iter__()
- self.save_count = frames
-
- # If we're passed in and using the default, set it to 100.
- if self.save_count is None:
- self.save_count = 100
-
- self._init_func = init_func
-
- # Needs to be initialized so the draw functions work without checking
- self._save_seq = []
-
- TimedAnimation.__init__(self, fig, **kwargs)
-
- # Need to reset the saved seq, since right now it will contain data
- # for a single frame from init, which is not what we want.
- self._save_seq = []
-
- def new_frame_seq(self):
- # Use the generating function to generate a new frame sequence
- return self._iter_gen()
-
- def new_saved_frame_seq(self):
- # Generate an iterator for the sequence of saved data. If there are
- # no saved frames, generate a new frame sequence and take the first
- # save_count entries in it.
- if self._save_seq:
- return iter(self._save_seq)
- else:
- return itertools.islice(self.new_frame_seq(), self.save_count)
-
- def _init_draw(self):
- # Initialize the drawing either using the given init_func or by
- # calling the draw function with the first item of the frame sequence.
- # For blitting, the init_func should return a sequence of modified
- # artists.
- if self._init_func is None:
- self._draw_frame(next(self.new_frame_seq()))
- else:
- self._drawn_artists = self._init_func()
-
- def _draw_frame(self, framedata):
- # Save the data for potential saving of movies.
- self._save_seq.append(framedata)
-
- # Make sure to respect save_count (keep only the last save_count
- # around)
- self._save_seq = self._save_seq[-self.save_count:]
-
- # Call the func with framedata and args. If blitting is desired,
- # func needs to return a sequence of any artists that were modified.
- self._drawn_artists = self._func(framedata, *self._args)
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/artist.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/artist.py
deleted file mode 100644
index d1ef2e5..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/artist.py
+++ /dev/null
@@ -1,1330 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import re
-import warnings
-import inspect
-import matplotlib
-import matplotlib.cbook as cbook
-from matplotlib import docstring, rcParams
-from .transforms import Bbox, IdentityTransform, TransformedBbox, \
- TransformedPath, Transform
-from .path import Path
-
-## Note, matplotlib artists use the doc strings for set and get
-# methods to enable the introspection methods of setp and getp. Every
-# set_* method should have a docstring containing the line
-#
-# ACCEPTS: [ legal | values ]
-#
-# and aliases for setters and getters should have a docstring that
-# starts with 'alias for ', as in 'alias for set_somemethod'
-#
-# You may wonder why we use so much boiler-plate manually defining the
-# set_alias and get_alias functions, rather than using some clever
-# python trick. The answer is that I need to be able to manipulate
-# the docstring, and there is no clever way to do that in python 2.2,
-# as far as I can see - see
-# http://groups.google.com/groups?hl=en&lr=&threadm=mailman.5090.1098044946.5135.python-list%40python.org&rnum=1&prev=/groups%3Fq%3D__doc__%2Bauthor%253Ajdhunter%2540ace.bsd.uchicago.edu%26hl%3Den%26btnG%3DGoogle%2BSearch
-
-
-def allow_rasterization(draw):
- """
- Decorator for Artist.draw method. Provides routines
- that run before and after the draw call. The before and after functions
- are useful for changing artist-dependant renderer attributes or making
- other setup function calls, such as starting and flushing a mixed-mode
- renderer.
- """
- def before(artist, renderer):
- if artist.get_rasterized():
- renderer.start_rasterizing()
-
- if artist.get_agg_filter() is not None:
- renderer.start_filter()
-
- def after(artist, renderer):
-
- if artist.get_agg_filter() is not None:
- renderer.stop_filter(artist.get_agg_filter())
-
- if artist.get_rasterized():
- renderer.stop_rasterizing()
-
- # the axes class has a second argument inframe for its draw method.
- def draw_wrapper(artist, renderer, *args, **kwargs):
- before(artist, renderer)
- draw(artist, renderer, *args, **kwargs)
- after(artist, renderer)
-
- # "safe wrapping" to exactly replicate anything we haven't overridden above
- draw_wrapper.__name__ = draw.__name__
- draw_wrapper.__dict__ = draw.__dict__
- draw_wrapper.__doc__ = draw.__doc__
- draw_wrapper._supports_rasterization = True
- return draw_wrapper
-
-
-class Artist(object):
- """
- Abstract base class for someone who renders into a
- :class:`FigureCanvas`.
- """
-
- aname = 'Artist'
- zorder = 0
-
- def __init__(self):
- self.figure = None
-
- self._transform = None
- self._transformSet = False
- self._visible = True
- self._animated = False
- self._alpha = None
- self.clipbox = None
- self._clippath = None
- self._clipon = True
- self._lod = False
- self._label = ''
- self._picker = None
- self._contains = None
- self._rasterized = None
- self._agg_filter = None
-
- self.eventson = False # fire events only if eventson
- self._oid = 0 # an observer id
- self._propobservers = {} # a dict from oids to funcs
- try:
- self.axes = None
- except AttributeError:
- # Handle self.axes as a read-only property, as in Figure.
- pass
- self._remove_method = None
- self._url = None
- self._gid = None
- self._snap = None
- self._sketch = rcParams['path.sketch']
- self._path_effects = rcParams['path.effects']
-
- def __getstate__(self):
- d = self.__dict__.copy()
- # remove the unpicklable remove method, this will get re-added on load
- # (by the axes) if the artist lives on an axes.
- d['_remove_method'] = None
- return d
-
- def remove(self):
- """
- Remove the artist from the figure if possible. The effect
- will not be visible until the figure is redrawn, e.g., with
- :meth:`matplotlib.axes.Axes.draw_idle`. Call
- :meth:`matplotlib.axes.Axes.relim` to update the axes limits
- if desired.
-
- Note: :meth:`~matplotlib.axes.Axes.relim` will not see
- collections even if the collection was added to axes with
- *autolim* = True.
-
- Note: there is no support for removing the artist's legend entry.
- """
-
- # There is no method to set the callback. Instead the parent should
- # set the _remove_method attribute directly. This would be a
- # protected attribute if Python supported that sort of thing. The
- # callback has one parameter, which is the child to be removed.
- if self._remove_method is not None:
- self._remove_method(self)
- else:
- raise NotImplementedError('cannot remove artist')
- # TODO: the fix for the collections relim problem is to move the
- # limits calculation into the artist itself, including the property of
- # whether or not the artist should affect the limits. Then there will
- # be no distinction between axes.add_line, axes.add_patch, etc.
- # TODO: add legend support
-
- def have_units(self):
- 'Return *True* if units are set on the *x* or *y* axes'
- ax = self.axes
- if ax is None or ax.xaxis is None:
- return False
- return ax.xaxis.have_units() or ax.yaxis.have_units()
-
- def convert_xunits(self, x):
- """For artists in an axes, if the xaxis has units support,
- convert *x* using xaxis unit type
- """
- ax = getattr(self, 'axes', None)
- if ax is None or ax.xaxis is None:
- #print 'artist.convert_xunits no conversion: ax=%s'%ax
- return x
- return ax.xaxis.convert_units(x)
-
- def convert_yunits(self, y):
- """For artists in an axes, if the yaxis has units support,
- convert *y* using yaxis unit type
- """
- ax = getattr(self, 'axes', None)
- if ax is None or ax.yaxis is None:
- return y
- return ax.yaxis.convert_units(y)
-
- def set_axes(self, axes):
- """
- Set the :class:`~matplotlib.axes.Axes` instance in which the
- artist resides, if any.
-
- ACCEPTS: an :class:`~matplotlib.axes.Axes` instance
- """
- self.axes = axes
-
- def get_axes(self):
- """
- Return the :class:`~matplotlib.axes.Axes` instance the artist
- resides in, or *None*
- """
- return self.axes
-
- def get_window_extent(self, renderer):
- """
- Get the axes bounding box in display space.
- Subclasses should override for inclusion in the bounding box
- "tight" calculation. Default is to return an empty bounding
- box at 0, 0.
-
- Be careful when using this function, the results will not update
- if the artist window extent of the artist changes. The extent
- can change due to any changes in the transform stack, such as
- changing the axes limits, the figure size, or the canvas used
- (as is done when saving a figure). This can lead to unexpected
- behavior where interactive figures will look fine on the screen,
- but will save incorrectly.
- """
- return Bbox([[0, 0], [0, 0]])
-
- def add_callback(self, func):
- """
- Adds a callback function that will be called whenever one of
- the :class:`Artist`'s properties changes.
-
- Returns an *id* that is useful for removing the callback with
- :meth:`remove_callback` later.
- """
- oid = self._oid
- self._propobservers[oid] = func
- self._oid += 1
- return oid
-
- def remove_callback(self, oid):
- """
- Remove a callback based on its *id*.
-
- .. seealso::
-
- :meth:`add_callback`
- For adding callbacks
-
- """
- try:
- del self._propobservers[oid]
- except KeyError:
- pass
-
- def pchanged(self):
- """
- Fire an event when property changed, calling all of the
- registered callbacks.
- """
- for oid, func in six.iteritems(self._propobservers):
- func(self)
-
- def is_transform_set(self):
- """
- Returns *True* if :class:`Artist` has a transform explicitly
- set.
- """
- return self._transformSet
-
- def set_transform(self, t):
- """
- Set the :class:`~matplotlib.transforms.Transform` instance
- used by this artist.
-
- ACCEPTS: :class:`~matplotlib.transforms.Transform` instance
- """
- self._transform = t
- self._transformSet = True
- self.pchanged()
-
- def get_transform(self):
- """
- Return the :class:`~matplotlib.transforms.Transform`
- instance used by this artist.
- """
- if self._transform is None:
- self._transform = IdentityTransform()
- elif (not isinstance(self._transform, Transform)
- and hasattr(self._transform, '_as_mpl_transform')):
- self._transform = self._transform._as_mpl_transform(self.axes)
- return self._transform
-
- def hitlist(self, event):
- """
- List the children of the artist which contain the mouse event *event*.
- """
- L = []
- try:
- hascursor, info = self.contains(event)
- if hascursor:
- L.append(self)
- except:
- import traceback
- traceback.print_exc()
- print("while checking", self.__class__)
-
- for a in self.get_children():
- L.extend(a.hitlist(event))
- return L
-
- def get_children(self):
- """
- Return a list of the child :class:`Artist`s this
- :class:`Artist` contains.
- """
- return []
-
- def contains(self, mouseevent):
- """Test whether the artist contains the mouse event.
-
- Returns the truth value and a dictionary of artist specific details of
- selection, such as which points are contained in the pick radius. See
- individual artists for details.
- """
- if six.callable(self._contains):
- return self._contains(self, mouseevent)
- warnings.warn("'%s' needs 'contains' method" % self.__class__.__name__)
- return False, {}
-
- def set_contains(self, picker):
- """
- Replace the contains test used by this artist. The new picker
- should be a callable function which determines whether the
- artist is hit by the mouse event::
-
- hit, props = picker(artist, mouseevent)
-
- If the mouse event is over the artist, return *hit* = *True*
- and *props* is a dictionary of properties you want returned
- with the contains test.
-
- ACCEPTS: a callable function
- """
- self._contains = picker
-
- def get_contains(self):
- """
- Return the _contains test used by the artist, or *None* for default.
- """
- return self._contains
-
- def pickable(self):
- 'Return *True* if :class:`Artist` is pickable.'
- return (self.figure is not None and
- self.figure.canvas is not None and
- self._picker is not None)
-
- def pick(self, mouseevent):
- """
- call signature::
-
- pick(mouseevent)
-
- each child artist will fire a pick event if *mouseevent* is over
- the artist and the artist has picker set
- """
- # Pick self
- if self.pickable():
- picker = self.get_picker()
- if six.callable(picker):
- inside, prop = picker(self, mouseevent)
- else:
- inside, prop = self.contains(mouseevent)
- if inside:
- self.figure.canvas.pick_event(mouseevent, self, **prop)
-
- # Pick children
- for a in self.get_children():
- # make sure the event happened in the same axes
- ax = getattr(a, 'axes', None)
- if mouseevent.inaxes is None or ax is None or \
- mouseevent.inaxes == ax:
- # we need to check if mouseevent.inaxes is None
- # because some objects associated with an axes (e.g., a
- # tick label) can be outside the bounding box of the
- # axes and inaxes will be None
- # also check that ax is None so that it traverse objects
- # which do no have an axes property but children might
- a.pick(mouseevent)
-
- def set_picker(self, picker):
- """
- Set the epsilon for picking used by this artist
-
- *picker* can be one of the following:
-
- * *None*: picking is disabled for this artist (default)
-
- * A boolean: if *True* then picking will be enabled and the
- artist will fire a pick event if the mouse event is over
- the artist
-
- * A float: if picker is a number it is interpreted as an
- epsilon tolerance in points and the artist will fire
- off an event if it's data is within epsilon of the mouse
- event. For some artists like lines and patch collections,
- the artist may provide additional data to the pick event
- that is generated, e.g., the indices of the data within
- epsilon of the pick event
-
- * A function: if picker is callable, it is a user supplied
- function which determines whether the artist is hit by the
- mouse event::
-
- hit, props = picker(artist, mouseevent)
-
- to determine the hit test. if the mouse event is over the
- artist, return *hit=True* and props is a dictionary of
- properties you want added to the PickEvent attributes.
-
- ACCEPTS: [None|float|boolean|callable]
- """
- self._picker = picker
-
- def get_picker(self):
- 'Return the picker object used by this artist'
- return self._picker
-
- def is_figure_set(self):
- """
- Returns True if the artist is assigned to a
- :class:`~matplotlib.figure.Figure`.
- """
- return self.figure is not None
-
- def get_url(self):
- """
- Returns the url
- """
- return self._url
-
- def set_url(self, url):
- """
- Sets the url for the artist
-
- ACCEPTS: a url string
- """
- self._url = url
-
- def get_gid(self):
- """
- Returns the group id
- """
- return self._gid
-
- def set_gid(self, gid):
- """
- Sets the (group) id for the artist
-
- ACCEPTS: an id string
- """
- self._gid = gid
-
- def get_snap(self):
- """
- Returns the snap setting which may be:
-
- * True: snap vertices to the nearest pixel center
-
- * False: leave vertices as-is
-
- * None: (auto) If the path contains only rectilinear line
- segments, round to the nearest pixel center
-
- Only supported by the Agg and MacOSX backends.
- """
- if rcParams['path.snap']:
- return self._snap
- else:
- return False
-
- def set_snap(self, snap):
- """
- Sets the snap setting which may be:
-
- * True: snap vertices to the nearest pixel center
-
- * False: leave vertices as-is
-
- * None: (auto) If the path contains only rectilinear line
- segments, round to the nearest pixel center
-
- Only supported by the Agg and MacOSX backends.
- """
- self._snap = snap
-
- def get_sketch_params(self):
- """
- Returns the sketch parameters for the artist.
-
- Returns
- -------
- sketch_params : tuple or `None`
-
- A 3-tuple with the following elements:
-
- * `scale`: The amplitude of the wiggle perpendicular to the
- source line.
-
- * `length`: The length of the wiggle along the line.
-
- * `randomness`: The scale factor by which the length is
- shrunken or expanded.
-
- May return `None` if no sketch parameters were set.
- """
- return self._sketch
-
- def set_sketch_params(self, scale=None, length=None, randomness=None):
- """
- Sets the the sketch parameters.
-
- Parameters
- ----------
-
- scale : float, optional
- The amplitude of the wiggle perpendicular to the source
- line, in pixels. If scale is `None`, or not provided, no
- sketch filter will be provided.
-
- length : float, optional
- The length of the wiggle along the line, in pixels
- (default 128.0)
-
- randomness : float, optional
- The scale factor by which the length is shrunken or
- expanded (default 16.0)
- """
- if scale is None:
- self._sketch = None
- else:
- self._sketch = (scale, length or 128.0, randomness or 16.0)
-
- def set_path_effects(self, path_effects):
- """
- set path_effects, which should be a list of instances of
- matplotlib.patheffect._Base class or its derivatives.
- """
- self._path_effects = path_effects
-
- def get_path_effects(self):
- return self._path_effects
-
- def get_figure(self):
- """
- Return the :class:`~matplotlib.figure.Figure` instance the
- artist belongs to.
- """
- return self.figure
-
- def set_figure(self, fig):
- """
- Set the :class:`~matplotlib.figure.Figure` instance the artist
- belongs to.
-
- ACCEPTS: a :class:`matplotlib.figure.Figure` instance
- """
- self.figure = fig
- self.pchanged()
-
- def set_clip_box(self, clipbox):
- """
- Set the artist's clip :class:`~matplotlib.transforms.Bbox`.
-
- ACCEPTS: a :class:`matplotlib.transforms.Bbox` instance
- """
- self.clipbox = clipbox
- self.pchanged()
-
- def set_clip_path(self, path, transform=None):
- """
- Set the artist's clip path, which may be:
-
- * a :class:`~matplotlib.patches.Patch` (or subclass) instance
-
- * a :class:`~matplotlib.path.Path` instance, in which case
- an optional :class:`~matplotlib.transforms.Transform`
- instance may be provided, which will be applied to the
- path before using it for clipping.
-
- * *None*, to remove the clipping path
-
- For efficiency, if the path happens to be an axis-aligned
- rectangle, this method will set the clipping box to the
- corresponding rectangle and set the clipping path to *None*.
-
- ACCEPTS: [ (:class:`~matplotlib.path.Path`,
- :class:`~matplotlib.transforms.Transform`) |
- :class:`~matplotlib.patches.Patch` | None ]
- """
- from matplotlib.patches import Patch, Rectangle
-
- success = False
- if transform is None:
- if isinstance(path, Rectangle):
- self.clipbox = TransformedBbox(Bbox.unit(),
- path.get_transform())
- self._clippath = None
- success = True
- elif isinstance(path, Patch):
- self._clippath = TransformedPath(
- path.get_path(),
- path.get_transform())
- success = True
- elif isinstance(path, tuple):
- path, transform = path
-
- if path is None:
- self._clippath = None
- success = True
- elif isinstance(path, Path):
- self._clippath = TransformedPath(path, transform)
- success = True
- elif isinstance(path, TransformedPath):
- self._clippath = path
- success = True
-
- if not success:
- print(type(path), type(transform))
- raise TypeError("Invalid arguments to set_clip_path")
-
- self.pchanged()
-
- def get_alpha(self):
- """
- Return the alpha value used for blending - not supported on all
- backends
- """
- return self._alpha
-
- def get_visible(self):
- "Return the artist's visiblity"
- return self._visible
-
- def get_animated(self):
- "Return the artist's animated state"
- return self._animated
-
- def get_clip_on(self):
- 'Return whether artist uses clipping'
- return self._clipon
-
- def get_clip_box(self):
- 'Return artist clipbox'
- return self.clipbox
-
- def get_clip_path(self):
- 'Return artist clip path'
- return self._clippath
-
- def get_transformed_clip_path_and_affine(self):
- '''
- Return the clip path with the non-affine part of its
- transformation applied, and the remaining affine part of its
- transformation.
- '''
- if self._clippath is not None:
- return self._clippath.get_transformed_path_and_affine()
- return None, None
-
- def set_clip_on(self, b):
- """
- Set whether artist uses clipping.
-
- When False artists will be visible out side of the axes which
- can lead to unexpected results.
-
- ACCEPTS: [True | False]
- """
- self._clipon = b
- self.pchanged()
-
- def _set_gc_clip(self, gc):
- 'Set the clip properly for the gc'
- if self._clipon:
- if self.clipbox is not None:
- gc.set_clip_rectangle(self.clipbox)
- gc.set_clip_path(self._clippath)
- else:
- gc.set_clip_rectangle(None)
- gc.set_clip_path(None)
-
- def get_rasterized(self):
- "return True if the artist is to be rasterized"
- return self._rasterized
-
- def set_rasterized(self, rasterized):
- """
- Force rasterized (bitmap) drawing in vector backend output.
-
- Defaults to None, which implies the backend's default behavior
-
- ACCEPTS: [True | False | None]
- """
- if rasterized and not hasattr(self.draw, "_supports_rasterization"):
- warnings.warn("Rasterization of '%s' will be ignored" % self)
-
- self._rasterized = rasterized
-
- def get_agg_filter(self):
- "return filter function to be used for agg filter"
- return self._agg_filter
-
- def set_agg_filter(self, filter_func):
- """
- set agg_filter fuction.
-
- """
- self._agg_filter = filter_func
-
- def draw(self, renderer, *args, **kwargs):
- 'Derived classes drawing method'
- if not self.get_visible():
- return
-
- def set_alpha(self, alpha):
- """
- Set the alpha value used for blending - not supported on
- all backends.
-
- ACCEPTS: float (0.0 transparent through 1.0 opaque)
- """
- self._alpha = alpha
- self.pchanged()
-
- def set_lod(self, on):
- """
- Set Level of Detail on or off. If on, the artists may examine
- things like the pixel width of the axes and draw a subset of
- their contents accordingly
-
- ACCEPTS: [True | False]
- """
- self._lod = on
- self.pchanged()
-
- def set_visible(self, b):
- """
- Set the artist's visiblity.
-
- ACCEPTS: [True | False]
- """
- self._visible = b
- self.pchanged()
-
- def set_animated(self, b):
- """
- Set the artist's animation state.
-
- ACCEPTS: [True | False]
- """
- self._animated = b
- self.pchanged()
-
- def update(self, props):
- """
- Update the properties of this :class:`Artist` from the
- dictionary *prop*.
- """
- store = self.eventson
- self.eventson = False
- changed = False
-
- for k, v in six.iteritems(props):
- func = getattr(self, 'set_' + k, None)
- if func is None or not six.callable(func):
- raise AttributeError('Unknown property %s' % k)
- func(v)
- changed = True
- self.eventson = store
- if changed:
- self.pchanged()
-
- def get_label(self):
- """
- Get the label used for this artist in the legend.
- """
- return self._label
-
- def set_label(self, s):
- """
- Set the label to *s* for auto legend.
-
- ACCEPTS: string or anything printable with '%s' conversion.
- """
- if s is not None:
- self._label = '%s' % (s, )
- else:
- self._label = None
- self.pchanged()
-
- def get_zorder(self):
- """
- Return the :class:`Artist`'s zorder.
- """
- return self.zorder
-
- def set_zorder(self, level):
- """
- Set the zorder for the artist. Artists with lower zorder
- values are drawn first.
-
- ACCEPTS: any number
- """
- self.zorder = level
- self.pchanged()
-
- def update_from(self, other):
- 'Copy properties from *other* to *self*.'
- self._transform = other._transform
- self._transformSet = other._transformSet
- self._visible = other._visible
- self._alpha = other._alpha
- self.clipbox = other.clipbox
- self._clipon = other._clipon
- self._clippath = other._clippath
- self._lod = other._lod
- self._label = other._label
- self._sketch = other._sketch
- self._path_effects = other._path_effects
- self.pchanged()
-
- def properties(self):
- """
- return a dictionary mapping property name -> value for all Artist props
- """
- return ArtistInspector(self).properties()
-
- def set(self, **kwargs):
- """
- A tkstyle set command, pass *kwargs* to set properties
- """
- ret = []
- for k, v in six.iteritems(kwargs):
- k = k.lower()
- funcName = "set_%s" % k
- func = getattr(self, funcName)
- ret.extend([func(v)])
- return ret
-
- def findobj(self, match=None, include_self=True):
- """
- Find artist objects.
-
- Recursively find all :class:`~matplotlib.artist.Artist` instances
- contained in self.
-
- *match* can be
-
- - None: return all objects contained in artist.
-
- - function with signature ``boolean = match(artist)``
- used to filter matches
-
- - class instance: e.g., Line2D. Only return artists of class type.
-
- If *include_self* is True (default), include self in the list to be
- checked for a match.
-
- """
- if match is None: # always return True
- def matchfunc(x):
- return True
- elif cbook.issubclass_safe(match, Artist):
- def matchfunc(x):
- return isinstance(x, match)
- elif six.callable(match):
- matchfunc = match
- else:
- raise ValueError('match must be None, a matplotlib.artist.Artist '
- 'subclass, or a callable')
-
- artists = []
-
- for c in self.get_children():
- if matchfunc(c):
- artists.append(c)
- artists.extend([thisc for thisc in
- c.findobj(matchfunc, include_self=False)
- if matchfunc(thisc)])
-
- if include_self and matchfunc(self):
- artists.append(self)
- return artists
-
-
-class ArtistInspector:
- """
- A helper class to inspect an :class:`~matplotlib.artist.Artist`
- and return information about it's settable properties and their
- current values.
- """
- def __init__(self, o):
- """
- Initialize the artist inspector with an
- :class:`~matplotlib.artist.Artist` or sequence of :class:`Artists`.
- If a sequence is used, we assume it is a homogeneous sequence (all
- :class:`Artists` are of the same type) and it is your responsibility
- to make sure this is so.
- """
- if cbook.iterable(o) and len(o):
- o = o[0]
-
- self.oorig = o
- if not isinstance(o, type):
- o = type(o)
- self.o = o
-
- self.aliasd = self.get_aliases()
-
- def get_aliases(self):
- """
- Get a dict mapping *fullname* -> *alias* for each *alias* in
- the :class:`~matplotlib.artist.ArtistInspector`.
-
- e.g., for lines::
-
- {'markerfacecolor': 'mfc',
- 'linewidth' : 'lw',
- }
-
- """
- names = [name for name in dir(self.o) if
- (name.startswith('set_') or name.startswith('get_'))
- and six.callable(getattr(self.o, name))]
- aliases = {}
- for name in names:
- func = getattr(self.o, name)
- if not self.is_alias(func):
- continue
- docstring = func.__doc__
- fullname = docstring[10:]
- aliases.setdefault(fullname[4:], {})[name[4:]] = None
- return aliases
-
- _get_valid_values_regex = re.compile(
- r"\n\s*ACCEPTS:\s*((?:.|\n)*?)(?:$|(?:\n\n))")
-
- def get_valid_values(self, attr):
- """
- Get the legal arguments for the setter associated with *attr*.
-
- This is done by querying the docstring of the function *set_attr*
- for a line that begins with ACCEPTS:
-
- e.g., for a line linestyle, return
- "[ ``'-'`` | ``'--'`` | ``'-.'`` | ``':'`` | ``'steps'`` | ``'None'`` ]"
- """
-
- name = 'set_%s' % attr
- if not hasattr(self.o, name):
- raise AttributeError('%s has no function %s' % (self.o, name))
- func = getattr(self.o, name)
-
- docstring = func.__doc__
- if docstring is None:
- return 'unknown'
-
- if docstring.startswith('alias for '):
- return None
-
- match = self._get_valid_values_regex.search(docstring)
- if match is not None:
- return match.group(1).replace('\n', ' ')
- return 'unknown'
-
- def _get_setters_and_targets(self):
- """
- Get the attribute strings and a full path to where the setter
- is defined for all setters in an object.
- """
-
- setters = []
- for name in dir(self.o):
- if not name.startswith('set_'):
- continue
- o = getattr(self.o, name)
- if not six.callable(o):
- continue
- if len(inspect.getargspec(o)[0]) < 2:
- continue
- func = o
- if self.is_alias(func):
- continue
- source_class = self.o.__module__ + "." + self.o.__name__
- for cls in self.o.mro():
- if name in cls.__dict__:
- source_class = cls.__module__ + "." + cls.__name__
- break
- setters.append((name[4:], source_class + "." + name))
- return setters
-
- def get_setters(self):
- """
- Get the attribute strings with setters for object. e.g., for a line,
- return ``['markerfacecolor', 'linewidth', ....]``.
- """
-
- return [prop for prop, target in self._get_setters_and_targets()]
-
- def is_alias(self, o):
- """
- Return *True* if method object *o* is an alias for another
- function.
- """
- ds = o.__doc__
- if ds is None:
- return False
- return ds.startswith('alias for ')
-
- def aliased_name(self, s):
- """
- return 'PROPNAME or alias' if *s* has an alias, else return
- PROPNAME.
-
- e.g., for the line markerfacecolor property, which has an
- alias, return 'markerfacecolor or mfc' and for the transform
- property, which does not, return 'transform'
- """
-
- if s in self.aliasd:
- return s + ''.join([' or %s' % x
- for x
- in six.iterkeys(self.aliasd[s])])
- else:
- return s
-
- def aliased_name_rest(self, s, target):
- """
- return 'PROPNAME or alias' if *s* has an alias, else return
- PROPNAME formatted for ReST
-
- e.g., for the line markerfacecolor property, which has an
- alias, return 'markerfacecolor or mfc' and for the transform
- property, which does not, return 'transform'
- """
-
- if s in self.aliasd:
- aliases = ''.join([' or %s' % x
- for x
- in six.iterkeys(self.aliasd[s])])
- else:
- aliases = ''
- return ':meth:`%s <%s>`%s' % (s, target, aliases)
-
- def pprint_setters(self, prop=None, leadingspace=2):
- """
- If *prop* is *None*, return a list of strings of all settable properies
- and their valid values.
-
- If *prop* is not *None*, it is a valid property name and that
- property will be returned as a string of property : valid
- values.
- """
- if leadingspace:
- pad = ' ' * leadingspace
- else:
- pad = ''
- if prop is not None:
- accepts = self.get_valid_values(prop)
- return '%s%s: %s' % (pad, prop, accepts)
-
- attrs = self._get_setters_and_targets()
- attrs.sort()
- lines = []
-
- for prop, path in attrs:
- accepts = self.get_valid_values(prop)
- name = self.aliased_name(prop)
-
- lines.append('%s%s: %s' % (pad, name, accepts))
- return lines
-
- def pprint_setters_rest(self, prop=None, leadingspace=2):
- """
- If *prop* is *None*, return a list of strings of all settable properies
- and their valid values. Format the output for ReST
-
- If *prop* is not *None*, it is a valid property name and that
- property will be returned as a string of property : valid
- values.
- """
- if leadingspace:
- pad = ' ' * leadingspace
- else:
- pad = ''
- if prop is not None:
- accepts = self.get_valid_values(prop)
- return '%s%s: %s' % (pad, prop, accepts)
-
- attrs = self._get_setters_and_targets()
- attrs.sort()
- lines = []
-
- ########
- names = [self.aliased_name_rest(prop, target)
- for prop, target
- in attrs]
- accepts = [self.get_valid_values(prop) for prop, target in attrs]
-
- col0_len = max([len(n) for n in names])
- col1_len = max([len(a) for a in accepts])
- table_formatstr = pad + '=' * col0_len + ' ' + '=' * col1_len
-
- lines.append('')
- lines.append(table_formatstr)
- lines.append(pad + 'Property'.ljust(col0_len + 3) + \
- 'Description'.ljust(col1_len))
- lines.append(table_formatstr)
-
- lines.extend([pad + n.ljust(col0_len + 3) + a.ljust(col1_len)
- for n, a in zip(names, accepts)])
-
- lines.append(table_formatstr)
- lines.append('')
- return lines
- ########
-
- for prop, path in attrs:
- accepts = self.get_valid_values(prop)
- name = self.aliased_name_rest(prop, path)
-
- lines.append('%s%s: %s' % (pad, name, accepts))
- return lines
-
- def properties(self):
- """
- return a dictionary mapping property name -> value
- """
- o = self.oorig
- getters = [name for name in dir(o)
- if name.startswith('get_')
- and six.callable(getattr(o, name))]
- #print getters
- getters.sort()
- d = dict()
- for name in getters:
- func = getattr(o, name)
- if self.is_alias(func):
- continue
-
- try:
- val = func()
- except:
- continue
- else:
- d[name[4:]] = val
-
- return d
-
- def pprint_getters(self):
- """
- Return the getters and actual values as list of strings.
- """
-
- d = self.properties()
- names = list(six.iterkeys(d))
- names.sort()
- lines = []
- for name in names:
- val = d[name]
- if getattr(val, 'shape', ()) != () and len(val) > 6:
- s = str(val[:6]) + '...'
- else:
- s = str(val)
- s = s.replace('\n', ' ')
- if len(s) > 50:
- s = s[:50] + '...'
- name = self.aliased_name(name)
- lines.append(' %s = %s' % (name, s))
- return lines
-
- def findobj(self, match=None):
- """
- Recursively find all :class:`matplotlib.artist.Artist`
- instances contained in *self*.
-
- If *match* is not None, it can be
-
- - function with signature ``boolean = match(artist)``
-
- - class instance: e.g., :class:`~matplotlib.lines.Line2D`
-
- used to filter matches.
- """
- if match is None: # always return True
- def matchfunc(x):
- return True
- elif issubclass(match, Artist):
- def matchfunc(x):
- return isinstance(x, match)
- elif six.callable(match):
- matchfunc = func
- else:
- raise ValueError('match must be None, an '
- 'matplotlib.artist.Artist '
- 'subclass, or a callable')
-
- artists = []
-
- for c in self.get_children():
- if matchfunc(c):
- artists.append(c)
- artists.extend([thisc
- for thisc
- in c.findobj(matchfunc)
- if matchfunc(thisc)])
-
- if matchfunc(self):
- artists.append(self)
- return artists
-
-
-def getp(obj, property=None):
- """
- Return the value of object's property. *property* is an optional string
- for the property you want to return
-
- Example usage::
-
- getp(obj) # get all the object properties
- getp(obj, 'linestyle') # get the linestyle property
-
- *obj* is a :class:`Artist` instance, e.g.,
- :class:`~matplotllib.lines.Line2D` or an instance of a
- :class:`~matplotlib.axes.Axes` or :class:`matplotlib.text.Text`.
- If the *property* is 'somename', this function returns
-
- obj.get_somename()
-
- :func:`getp` can be used to query all the gettable properties with
- ``getp(obj)``. Many properties have aliases for shorter typing, e.g.
- 'lw' is an alias for 'linewidth'. In the output, aliases and full
- property names will be listed as:
-
- property or alias = value
-
- e.g.:
-
- linewidth or lw = 2
- """
- if property is None:
- insp = ArtistInspector(obj)
- ret = insp.pprint_getters()
- print('\n'.join(ret))
- return
-
- func = getattr(obj, 'get_' + property)
- return func()
-
-# alias
-get = getp
-
-
-def setp(obj, *args, **kwargs):
- """
- Set a property on an artist object.
-
- matplotlib supports the use of :func:`setp` ("set property") and
- :func:`getp` to set and get object properties, as well as to do
- introspection on the object. For example, to set the linestyle of a
- line to be dashed, you can do::
-
- >>> line, = plot([1,2,3])
- >>> setp(line, linestyle='--')
-
- If you want to know the valid types of arguments, you can provide the
- name of the property you want to set without a value::
-
- >>> setp(line, 'linestyle')
- linestyle: [ '-' | '--' | '-.' | ':' | 'steps' | 'None' ]
-
- If you want to see all the properties that can be set, and their
- possible values, you can do::
-
- >>> setp(line)
- ... long output listing omitted
-
- :func:`setp` operates on a single instance or a list of instances.
- If you are in query mode introspecting the possible values, only
- the first instance in the sequence is used. When actually setting
- values, all the instances will be set. e.g., suppose you have a
- list of two lines, the following will make both lines thicker and
- red::
-
- >>> x = arange(0,1.0,0.01)
- >>> y1 = sin(2*pi*x)
- >>> y2 = sin(4*pi*x)
- >>> lines = plot(x, y1, x, y2)
- >>> setp(lines, linewidth=2, color='r')
-
- :func:`setp` works with the MATLAB style string/value pairs or
- with python kwargs. For example, the following are equivalent::
-
- >>> setp(lines, 'linewidth', 2, 'color', 'r') # MATLAB style
- >>> setp(lines, linewidth=2, color='r') # python style
- """
-
- insp = ArtistInspector(obj)
-
- if len(kwargs) == 0 and len(args) == 0:
- print('\n'.join(insp.pprint_setters()))
- return
-
- if len(kwargs) == 0 and len(args) == 1:
- print(insp.pprint_setters(prop=args[0]))
- return
-
- if not cbook.iterable(obj):
- objs = [obj]
- else:
- objs = cbook.flatten(obj)
-
- if len(args) % 2:
- raise ValueError('The set args must be string, value pairs')
-
- funcvals = []
- for i in range(0, len(args) - 1, 2):
- funcvals.append((args[i], args[i + 1]))
- funcvals.extend(kwargs.items())
-
- ret = []
- for o in objs:
- for s, val in funcvals:
- s = s.lower()
- funcName = "set_%s" % s
- func = getattr(o, funcName)
- ret.extend([func(val)])
- return [x for x in cbook.flatten(ret)]
-
-
-def kwdoc(a):
- hardcopy = matplotlib.rcParams['docstring.hardcopy']
- if hardcopy:
- return '\n'.join(ArtistInspector(a).pprint_setters_rest(
- leadingspace=2))
- else:
- return '\n'.join(ArtistInspector(a).pprint_setters(leadingspace=2))
-
-docstring.interpd.update(Artist=kwdoc(Artist))
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/axes/__init__.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/axes/__init__.py
deleted file mode 100644
index 82c5438..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/axes/__init__.py
+++ /dev/null
@@ -1,5 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-from ._subplots import *
-from ._axes import *
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/axes/_axes.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/axes/_axes.py
deleted file mode 100644
index 43c7feb..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/axes/_axes.py
+++ /dev/null
@@ -1,7162 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import reduce, xrange, zip, zip_longest
-
-import math
-import warnings
-
-import numpy as np
-from numpy import ma
-
-import matplotlib
-rcParams = matplotlib.rcParams
-
-import matplotlib.cbook as cbook
-from matplotlib.cbook import _string_to_bool, mplDeprecation
-import matplotlib.collections as mcoll
-import matplotlib.colors as mcolors
-import matplotlib.contour as mcontour
-import matplotlib.dates as _ # <-registers a date unit converter
-from matplotlib import docstring
-import matplotlib.image as mimage
-import matplotlib.legend as mlegend
-import matplotlib.lines as mlines
-import matplotlib.markers as mmarkers
-import matplotlib.mlab as mlab
-import matplotlib.path as mpath
-import matplotlib.patches as mpatches
-import matplotlib.quiver as mquiver
-import matplotlib.stackplot as mstack
-import matplotlib.streamplot as mstream
-import matplotlib.table as mtable
-import matplotlib.text as mtext
-import matplotlib.ticker as mticker
-import matplotlib.transforms as mtransforms
-import matplotlib.tri as mtri
-import matplotlib.transforms as mtrans
-from matplotlib.container import BarContainer, ErrorbarContainer, StemContainer
-from matplotlib.axes._base import _AxesBase
-from matplotlib.axes._base import _process_plot_format
-
-iterable = cbook.iterable
-is_string_like = cbook.is_string_like
-is_sequence_of_strings = cbook.is_sequence_of_strings
-
-
-# The axes module contains all the wrappers to plotting functions.
-# All the other methods should go in the _AxesBase class.
-
-class Axes(_AxesBase):
- """
- The :class:`Axes` contains most of the figure elements:
- :class:`~matplotlib.axis.Axis`, :class:`~matplotlib.axis.Tick`,
- :class:`~matplotlib.lines.Line2D`, :class:`~matplotlib.text.Text`,
- :class:`~matplotlib.patches.Polygon`, etc., and sets the
- coordinate system.
-
- The :class:`Axes` instance supports callbacks through a callbacks
- attribute which is a :class:`~matplotlib.cbook.CallbackRegistry`
- instance. The events you can connect to are 'xlim_changed' and
- 'ylim_changed' and the callback will be called with func(*ax*)
- where *ax* is the :class:`Axes` instance.
- """
- ### Labelling, legend and texts
-
- def get_title(self, loc="center"):
- """Get an axes title.
-
- Get one of the three available axes titles. The available titles
- are positioned above the axes in the center, flush with the left
- edge, and flush with the right edge.
-
- Parameters
- ----------
- loc : {'center', 'left', 'right'}, str, optional
- Which title to get, defaults to 'center'
-
- Returns
- -------
- title: str
- The title text string.
-
- """
- try:
- title = {'left': self._left_title,
- 'center': self.title,
- 'right': self._right_title}[loc.lower()]
- except KeyError:
- raise ValueError("'%s' is not a valid location" % loc)
- return title.get_text()
-
- @docstring.dedent_interpd
- def set_title(self, label, fontdict=None, loc="center", **kwargs):
- """
- Set a title for the axes.
-
- Set one of the three available axes titles. The available titles
- are positioned above the axes in the center, flush with the left
- edge, and flush with the right edge.
-
- Parameters
- ----------
- label : str
- Text to use for the title
-
- fontdict : dict
- A dictionary controlling the appearance of the title text,
- the default `fontdict` is::
-
- {'fontsize': rcParams['axes.titlesize'],
- 'fontweight' : rcParams['axes.titleweight'],
- 'verticalalignment': 'baseline',
- 'horizontalalignment': loc}
-
- loc : {'center', 'left', 'right'}, str, optional
- Which title to set, defaults to 'center'
-
- Returns
- -------
- text : :class:`~matplotlib.text.Text`
- The matplotlib text instance representing the title
-
- Other parameters
- ----------------
- kwargs : text properties
- Other keyword arguments are text properties, see
- :class:`~matplotlib.text.Text` for a list of valid text
- properties.
- """
- try:
- title = {'left': self._left_title,
- 'center': self.title,
- 'right': self._right_title}[loc.lower()]
- except KeyError:
- raise ValueError("'%s' is not a valid location" % loc)
- default = {
- 'fontsize': rcParams['axes.titlesize'],
- 'fontweight': rcParams['axes.titleweight'],
- 'verticalalignment': 'baseline',
- 'horizontalalignment': loc.lower()}
- title.set_text(label)
- title.update(default)
- if fontdict is not None:
- title.update(fontdict)
- title.update(kwargs)
- return title
-
- def get_xlabel(self):
- """
- Get the xlabel text string.
- """
- label = self.xaxis.get_label()
- return label.get_text()
-
- @docstring.dedent_interpd
- def set_xlabel(self, xlabel, fontdict=None, labelpad=None, **kwargs):
- """
- Set the label for the xaxis.
-
- Parameters
- ----------
- xlabel : string
- x label
-
- labelpad : scalar, optional, default: None
- spacing in points between the label and the x-axis
-
- Other parameters
- ----------------
- kwargs : `~matplotlib.text.Text` properties
-
- See also
- --------
- text : for information on how override and the optional args work
- """
- if labelpad is not None:
- self.xaxis.labelpad = labelpad
- return self.xaxis.set_label_text(xlabel, fontdict, **kwargs)
-
- def get_ylabel(self):
- """
- Get the ylabel text string.
- """
- label = self.yaxis.get_label()
- return label.get_text()
-
- @docstring.dedent_interpd
- def set_ylabel(self, ylabel, fontdict=None, labelpad=None, **kwargs):
- """
- Set the label for the yaxis
-
- Parameters
- ----------
- ylabel : string
- y label
-
- labelpad : scalar, optional, default: None
- spacing in points between the label and the x-axis
-
- Other parameters
- ----------------
- kwargs : `~matplotlib.text.Text` properties
-
- See also
- --------
- text : for information on how override and the optional args work
-
- """
- if labelpad is not None:
- self.yaxis.labelpad = labelpad
- return self.yaxis.set_label_text(ylabel, fontdict, **kwargs)
-
- def _get_legend_handles(self, legend_handler_map=None):
- """
- Return a generator of artists that can be used as handles in
- a legend.
-
- """
- handles_original = (self.lines + self.patches +
- self.collections + self.containers)
- handler_map = mlegend.Legend.get_default_handler_map()
-
- if legend_handler_map is not None:
- handler_map = handler_map.copy()
- handler_map.update(legend_handler_map)
-
- has_handler = mlegend.Legend.get_legend_handler
-
- for handle in handles_original:
- label = handle.get_label()
- if label != '_nolegend_' and has_handler(handler_map, handle):
- yield handle
-
- def get_legend_handles_labels(self, legend_handler_map=None):
- """
- Return handles and labels for legend
-
- ``ax.legend()`` is equivalent to ::
-
- h, l = ax.get_legend_handles_labels()
- ax.legend(h, l)
-
- """
- handles = []
- labels = []
- for handle in self._get_legend_handles(legend_handler_map):
- label = handle.get_label()
- if label and not label.startswith('_'):
- handles.append(handle)
- labels.append(label)
-
- return handles, labels
-
- def legend(self, *args, **kwargs):
- """
- Places a legend on the axes.
-
- To make a legend for lines which already exist on the axes
- (via plot for instance), simply call this function with an iterable
- of strings, one for each legend item. For example::
-
- ax.plot([1, 2, 3])
- ax.legend(['A simple line'])
-
- However, in order to keep the "label" and the legend element
- instance together, it is preferable to specify the label either at
- artist creation, or by calling the
- :meth:`~matplotlib.artist.Artist.set_label` method on the artist::
-
- line, = ax.plot([1, 2, 3], label='Inline label')
- # Overwrite the label by calling the method.
- line.set_label('Label via method')
- ax.legend()
-
- Specific lines can be excluded from the automatic legend element
- selection by defining a label starting with an underscore.
- This is default for all artists, so calling :meth:`legend` without
- any arguments and without setting the labels manually will result in
- no legend being drawn.
-
- For full control of which artists have a legend entry, it is possible
- to pass an iterable of legend artists followed by an iterable of
- legend labels respectively::
-
- legend((line1, line2, line3), ('label1', 'label2', 'label3'))
-
- Parameters
- ----------
- loc : int or string or pair of floats, default: 0
- The location of the legend. Possible codes are:
-
- =============== =============
- Location String Location Code
- =============== =============
- 'best' 0
- 'upper right' 1
- 'upper left' 2
- 'lower left' 3
- 'lower right' 4
- 'right' 5
- 'center left' 6
- 'center right' 7
- 'lower center' 8
- 'upper center' 9
- 'center' 10
- =============== =============
-
-
- Alternatively can be a 2-tuple giving ``x, y`` of the lower-left
- corner of the legend in axes coordinates (in which case
- ``bbox_to_anchor`` will be ignored).
-
- bbox_to_anchor : :class:`matplotlib.transforms.BboxBase` instance \
- or tuple of floats
- Specify any arbitrary location for the legend in `bbox_transform`
- coordinates (default Axes coordinates).
-
- For example, to put the legend's upper right hand corner in the
- center of the axes the following keywords can be used::
-
- loc='upper right', bbox_to_anchor=(0.5, 0.5)
-
- ncol : integer
- The number of columns that the legend has. Default is 1.
-
- prop : None or :class:`matplotlib.font_manager.FontProperties` or dict
- The font properties of the legend. If None (default), the current
- :data:`matplotlib.rcParams` will be used.
-
- fontsize : int or float or {'xx-small', 'x-small', 'small', 'medium',\
- 'large', 'x-large', 'xx-large'}
- Controls the font size of the legend. If the value is numeric the
- size will be the absolute font size in points. String values are
- relative to the current default font size. This argument is only
- used if `prop` is not specified.
-
- numpoints : None or int
- The number of marker points in the legend when creating a legend
- entry for a line/:class:`matplotlib.lines.Line2D`.
- Default is ``None`` which will take the value from the
- ``legend.numpoints`` :data:`rcParam`.
-
- scatterpoints : None or int
- The number of marker points in the legend when creating a legend
- entry for a scatter plot/
- :class:`matplotlib.collections.PathCollection`.
- Default is ``None`` which will take the value from the
- ``legend.scatterpoints`` :data:`rcParam`.
-
- scatteryoffsets : iterable of floats
- The vertical offset (relative to the font size) for the markers
- created for a scatter plot legend entry. 0.0 is at the base the
- legend text, and 1.0 is at the top. To draw all markers at the
- same height, set to ``[0.5]``. Default ``[0.375, 0.5, 0.3125]``.
-
- markerscale : None or int or float
- The relative size of legend markers compared with the originally
- drawn ones. Default is ``None`` which will take the value from
- the ``legend.markerscale`` :data:`rcParam `.
-
- frameon : None or bool
- Control whether a frame should be drawn around the legend.
- Default is ``None`` which will take the value from the
- ``legend.frameon`` :data:`rcParam`.
-
- fancybox : None or bool
- Control whether round edges should be enabled around
- the :class:`~matplotlib.patches.FancyBboxPatch` which
- makes up the legend's background.
- Default is ``None`` which will take the value from the
- ``legend.fancybox`` :data:`rcParam`.
-
- shadow : None or bool
- Control whether to draw a shadow behind the legend.
- Default is ``None`` which will take the value from the
- ``legend.shadow`` :data:`rcParam`.
-
- framealpha : None or float
- Control the alpha transparency of the legend's frame.
- Default is ``None`` which will take the value from the
- ``legend.framealpha`` :data:`rcParam`.
-
- mode : {"expand", None}
- If `mode` is set to ``"expand"`` the legend will be horizontally
- expanded to fill the axes area (or `bbox_to_anchor` if defines
- the legend's size).
-
- bbox_transform : None or :class:`matplotlib.transforms.Transform`
- The transform for the bounding box (`bbox_to_anchor`). For a value
- of ``None`` (default) the Axes'
- :data:`~matplotlib.axes.Axes.transAxes` transform will be used.
-
- title : str or None
- The legend's title. Default is no title (``None``).
-
- borderpad : float or None
- The fractional whitespace inside the legend border.
- Measured in font-size units.
- Default is ``None`` which will take the value from the
- ``legend.borderpad`` :data:`rcParam`.
-
- labelspacing : float or None
- The vertical space between the legend entries.
- Measured in font-size units.
- Default is ``None`` which will take the value from the
- ``legend.labelspacing`` :data:`rcParam`.
-
- handlelength : float or None
- The length of the legend handles.
- Measured in font-size units.
- Default is ``None`` which will take the value from the
- ``legend.handlelength`` :data:`rcParam`.
-
- handletextpad : float or None
- The pad between the legend handle and text.
- Measured in font-size units.
- Default is ``None`` which will take the value from the
- ``legend.handletextpad`` :data:`rcParam`.
-
- borderaxespad : float or None
- The pad between the axes and legend border.
- Measured in font-size units.
- Default is ``None`` which will take the value from the
- ``legend.borderaxespad`` :data:`rcParam`.
-
- columnspacing : float or None
- The spacing between columns.
- Measured in font-size units.
- Default is ``None`` which will take the value from the
- ``legend.columnspacing`` :data:`rcParam`.
-
- handler_map : dict or None
- The custom dictionary mapping instances or types to a legend
- handler. This `handler_map` updates the default handler map
- found at :func:`matplotlib.legend.Legend.get_legend_handler_map`.
-
- Notes
- -----
-
- Not all kinds of artist are supported by the legend command.
- See :ref:`plotting-guide-legend` for details.
-
- Examples
- --------
-
- .. plot:: mpl_examples/api/legend_demo.py
-
- """
- handlers = kwargs.get('handler_map', {}) or {}
-
- # Support handles and labels being passed as keywords.
- handles = kwargs.pop('handles', None)
- labels = kwargs.pop('labels', None)
-
- if handles is not None and labels is None:
- labels = [handle.get_label() for handle in handles]
- for label, handle in zip(labels[:], handles[:]):
- if label.startswith('_'):
- warnings.warn('The handle {!r} has a label of {!r} which '
- 'cannot be automatically added to the '
- 'legend.'.format(handle, label))
- labels.remove(label)
- handles.remove(handle)
-
- elif labels is not None and handles is None:
- # Get as many handles as there are labels.
- handles = [handle for handle, _
- in zip(self._get_legend_handles(handlers), labels)]
-
- # No arguments - automatically detect labels and handles.
- elif len(args) == 0:
- handles, labels = self.get_legend_handles_labels(handlers)
- if not handles:
- warnings.warn("No labelled objects found. "
- "Use label='...' kwarg on individual plots.")
- return None
-
- # One argument. User defined labels - automatic handle detection.
- elif len(args) == 1:
- labels, = args
- # Get as many handles as there are labels.
- handles = [handle for handle, _
- in zip(self._get_legend_handles(handlers), labels)]
-
- # Two arguments. Either:
- # * user defined handles and labels
- # * user defined labels and location (deprecated)
- elif len(args) == 2:
- if is_string_like(args[1]) or isinstance(args[1], int):
- cbook.warn_deprecated('1.4', 'The "loc" positional argument '
- 'to legend is deprecated. Please use '
- 'the "loc" keyword instead.')
- labels, loc = args
- handles = [handle for handle, _
- in zip(self._get_legend_handles(handlers), labels)]
- kwargs['loc'] = loc
- else:
- handles, labels = args
-
- # Three arguments. User defined handles, labels and
- # location (deprecated).
- elif len(args) == 3:
- cbook.warn_deprecated('1.4', 'The "loc" positional argument '
- 'to legend is deprecated. Please '
- 'use the "loc" keyword instead.')
- handles, labels, loc = args
- kwargs['loc'] = loc
-
- else:
- raise TypeError('Invalid arguments to legend.')
-
- self.legend_ = mlegend.Legend(self, handles, labels, **kwargs)
- self.legend_._remove_method = lambda h: setattr(self, 'legend_', None)
- return self.legend_
-
- def text(self, x, y, s, fontdict=None,
- withdash=False, **kwargs):
- """
- Add text to the axes.
-
- Add text in string `s` to axis at location `x`, `y`, data
- coordinates.
-
- Parameters
- ----------
- x, y : scalars
- data coordinates
-
- s : string
- text
-
- fontdict : dictionary, optional, default: None
- A dictionary to override the default text properties. If fontdict
- is None, the defaults are determined by your rc parameters.
-
- withdash : boolean, optional, default: False
- Creates a `~matplotlib.text.TextWithDash` instance instead of a
- `~matplotlib.text.Text` instance.
-
- Other parameters
- ----------------
- kwargs : `~matplotlib.text.Text` properties.
- Other miscellaneous text parameters.
-
- Examples
- --------
- Individual keyword arguments can be used to override any given
- parameter::
-
- >>> text(x, y, s, fontsize=12)
-
- The default transform specifies that text is in data coords,
- alternatively, you can specify text in axis coords (0,0 is
- lower-left and 1,1 is upper-right). The example below places
- text in the center of the axes::
-
- >>> text(0.5, 0.5,'matplotlib', horizontalalignment='center',
- ... verticalalignment='center',
- ... transform=ax.transAxes)
-
- You can put a rectangular box around the text instance (e.g., to
- set a background color) by using the keyword `bbox`. `bbox` is
- a dictionary of `~matplotlib.patches.Rectangle`
- properties. For example::
-
- >>> text(x, y, s, bbox=dict(facecolor='red', alpha=0.5))
- """
- default = {
- 'verticalalignment': 'baseline',
- 'horizontalalignment': 'left',
- 'transform': self.transData,
- 'clip_on': False}
-
- # At some point if we feel confident that TextWithDash
- # is robust as a drop-in replacement for Text and that
- # the performance impact of the heavier-weight class
- # isn't too significant, it may make sense to eliminate
- # the withdash kwarg and simply delegate whether there's
- # a dash to TextWithDash and dashlength.
- if withdash:
- t = mtext.TextWithDash(
- x=x, y=y, text=s)
- else:
- t = mtext.Text(
- x=x, y=y, text=s)
- self._set_artist_props(t)
-
- t.update(default)
- if fontdict is not None:
- t.update(fontdict)
- t.update(kwargs)
- self.texts.append(t)
- t._remove_method = lambda h: self.texts.remove(h)
-
- t.set_clip_path(self.patch)
- return t
-
- @docstring.dedent_interpd
- def annotate(self, *args, **kwargs):
- """
- Create an annotation: a piece of text referring to a data
- point.
-
- Parameters
- ----------
- s : string
- label
-
- xy : (x, y)
- position of element to annotate
-
- xytext : (x, y) , optional, default: None
- position of the label `s`
-
- xycoords : string, optional, default: "data"
- string that indicates what type of coordinates `xy` is. Examples:
- "figure points", "figure pixels", "figure fraction", "axes
- points", .... See `matplotlib.text.Annotation` for more details.
-
- textcoords : string, optional
- string that indicates what type of coordinates `text` is. Examples:
- "figure points", "figure pixels", "figure fraction", "axes
- points", .... See `matplotlib.text.Annotation` for more details.
- Default is None.
-
- arrowprops : `matplotlib.lines.Line2D` properties, optional
- Dictionary of line properties for the arrow that connects
- the annotation to the point. If the dictionnary has a key
- `arrowstyle`, a `~matplotlib.patches.FancyArrowPatch`
- instance is created and drawn. See
- `matplotlib.text.Annotation` for more details on valid
- options. Default is None.
-
- Returns
- -------
- a : `~matplotlib.text.Annotation`
-
-
- Notes
- -----
-
- %(Annotation)s
-
- Examples
- --------
-
- .. plot:: mpl_examples/pylab_examples/annotation_demo2.py
- """
- a = mtext.Annotation(*args, **kwargs)
- a.set_transform(mtransforms.IdentityTransform())
- self._set_artist_props(a)
- if 'clip_on' in kwargs:
- a.set_clip_path(self.patch)
- self.texts.append(a)
- a._remove_method = lambda h: self.texts.remove(h)
- return a
-
- #### Lines and spans
-
- @docstring.dedent_interpd
- def axhline(self, y=0, xmin=0, xmax=1, **kwargs):
- """
- Add a horizontal line across the axis.
-
- Parameters
- ----------
- y : scalar, optional, default: 0
- y position in data coordinates of the horizontal line.
-
- xmin : scalar, optional, default: 0
- Should be between 0 and 1, 0 being the far left of the plot, 1 the
- far right of the plot.
-
- xmax : scalar, optional, default: 1
- Should be between 0 and 1, 0 being the far left of the plot, 1 the
- far right of the plot.
-
- Returns
- -------
- `~matplotlib.lines.Line2D`
-
- Notes
- -----
- kwargs are the same as kwargs to plot, and can be
- used to control the line properties. e.g.,
-
- Examples
- --------
-
- * draw a thick red hline at 'y' = 0 that spans the xrange::
-
- >>> axhline(linewidth=4, color='r')
-
- * draw a default hline at 'y' = 1 that spans the xrange::
-
- >>> axhline(y=1)
-
- * draw a default hline at 'y' = .5 that spans the the middle half of
- the xrange::
-
- >>> axhline(y=.5, xmin=0.25, xmax=0.75)
-
- Valid kwargs are :class:`~matplotlib.lines.Line2D` properties,
- with the exception of 'transform':
-
- %(Line2D)s
-
- See also
- --------
- axhspan : for example plot and source code
- """
-
- if "transform" in kwargs:
- raise ValueError(
- "'transform' is not allowed as a kwarg;"
- + "axhline generates its own transform.")
- ymin, ymax = self.get_ybound()
-
- # We need to strip away the units for comparison with
- # non-unitized bounds
- self._process_unit_info(ydata=y, kwargs=kwargs)
- yy = self.convert_yunits(y)
- scaley = (yy < ymin) or (yy > ymax)
-
- trans = self.get_yaxis_transform(which='grid')
- l = mlines.Line2D([xmin, xmax], [y, y], transform=trans, **kwargs)
- self.add_line(l)
- self.autoscale_view(scalex=False, scaley=scaley)
- return l
-
- @docstring.dedent_interpd
- def axvline(self, x=0, ymin=0, ymax=1, **kwargs):
- """
- Add a vertical line across the axes.
-
- Parameters
- ----------
- x : scalar, optional, default: 0
- x position in data coordinates of the vertical line.
-
- ymin : scalar, optional, default: 0
- Should be between 0 and 1, 0 being the far left of the plot, 1 the
- far right of the plot.
-
- ymax : scalar, optional, default: 1
- Should be between 0 and 1, 0 being the far left of the plot, 1 the
- far right of the plot.
-
- Returns
- -------
- `~matplotlib.lines.Line2D`
-
-
- Examples
- ---------
- * draw a thick red vline at *x* = 0 that spans the yrange::
-
- >>> axvline(linewidth=4, color='r')
-
- * draw a default vline at *x* = 1 that spans the yrange::
-
- >>> axvline(x=1)
-
- * draw a default vline at *x* = .5 that spans the the middle half of
- the yrange::
-
- >>> axvline(x=.5, ymin=0.25, ymax=0.75)
-
- Valid kwargs are :class:`~matplotlib.lines.Line2D` properties,
- with the exception of 'transform':
-
- %(Line2D)s
-
- See also
- --------
- axhspan : for example plot and source code
- """
-
- if "transform" in kwargs:
- raise ValueError(
- "'transform' is not allowed as a kwarg;"
- + "axvline generates its own transform.")
- xmin, xmax = self.get_xbound()
-
- # We need to strip away the units for comparison with
- # non-unitized bounds
- self._process_unit_info(xdata=x, kwargs=kwargs)
- xx = self.convert_xunits(x)
- scalex = (xx < xmin) or (xx > xmax)
-
- trans = self.get_xaxis_transform(which='grid')
- l = mlines.Line2D([x, x], [ymin, ymax], transform=trans, **kwargs)
- self.add_line(l)
- self.autoscale_view(scalex=scalex, scaley=False)
- return l
-
- @docstring.dedent_interpd
- def axhspan(self, ymin, ymax, xmin=0, xmax=1, **kwargs):
- """
- Add a horizontal span (rectangle) across the axis.
-
- Call signature::
-
- axhspan(ymin, ymax, xmin=0, xmax=1, **kwargs)
-
- *y* coords are in data units and *x* coords are in axes (relative
- 0-1) units.
-
- Draw a horizontal span (rectangle) from *ymin* to *ymax*.
- With the default values of *xmin* = 0 and *xmax* = 1, this
- always spans the xrange, regardless of the xlim settings, even
- if you change them, e.g., with the :meth:`set_xlim` command.
- That is, the horizontal extent is in axes coords: 0=left,
- 0.5=middle, 1.0=right but the *y* location is in data
- coordinates.
-
- Return value is a :class:`matplotlib.patches.Polygon`
- instance.
-
- Examples:
-
- * draw a gray rectangle from *y* = 0.25-0.75 that spans the
- horizontal extent of the axes::
-
- >>> axhspan(0.25, 0.75, facecolor='0.5', alpha=0.5)
-
- Valid kwargs are :class:`~matplotlib.patches.Polygon` properties:
-
- %(Polygon)s
-
- **Example:**
-
- .. plot:: mpl_examples/pylab_examples/axhspan_demo.py
-
- """
- trans = self.get_yaxis_transform(which='grid')
-
- # process the unit information
- self._process_unit_info([xmin, xmax], [ymin, ymax], kwargs=kwargs)
-
- # first we need to strip away the units
- xmin, xmax = self.convert_xunits([xmin, xmax])
- ymin, ymax = self.convert_yunits([ymin, ymax])
-
- verts = (xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin)
- p = mpatches.Polygon(verts, **kwargs)
- p.set_transform(trans)
- self.add_patch(p)
- self.autoscale_view(scalex=False)
- return p
-
- @docstring.dedent_interpd
- def axvspan(self, xmin, xmax, ymin=0, ymax=1, **kwargs):
- """
- Add a vertical span (rectangle) across the axes.
-
- Call signature::
-
- axvspan(xmin, xmax, ymin=0, ymax=1, **kwargs)
-
- *x* coords are in data units and *y* coords are in axes (relative
- 0-1) units.
-
- Draw a vertical span (rectangle) from *xmin* to *xmax*. With
- the default values of *ymin* = 0 and *ymax* = 1, this always
- spans the yrange, regardless of the ylim settings, even if you
- change them, e.g., with the :meth:`set_ylim` command. That is,
- the vertical extent is in axes coords: 0=bottom, 0.5=middle,
- 1.0=top but the *y* location is in data coordinates.
-
- Return value is the :class:`matplotlib.patches.Polygon`
- instance.
-
- Examples:
-
- * draw a vertical green translucent rectangle from x=1.25 to 1.55 that
- spans the yrange of the axes::
-
- >>> axvspan(1.25, 1.55, facecolor='g', alpha=0.5)
-
- Valid kwargs are :class:`~matplotlib.patches.Polygon`
- properties:
-
- %(Polygon)s
-
- .. seealso::
-
- :meth:`axhspan`
- for example plot and source code
- """
- trans = self.get_xaxis_transform(which='grid')
-
- # process the unit information
- self._process_unit_info([xmin, xmax], [ymin, ymax], kwargs=kwargs)
-
- # first we need to strip away the units
- xmin, xmax = self.convert_xunits([xmin, xmax])
- ymin, ymax = self.convert_yunits([ymin, ymax])
-
- verts = [(xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin)]
- p = mpatches.Polygon(verts, **kwargs)
- p.set_transform(trans)
- self.add_patch(p)
- self.autoscale_view(scaley=False)
- return p
-
- @docstring.dedent
- def hlines(self, y, xmin, xmax, colors='k', linestyles='solid',
- label='', **kwargs):
- """
- Plot horizontal lines at each `y` from `xmin` to `xmax`.
-
- Parameters
- ----------
- y : scalar or sequence of scalar
- y-indexes where to plot the lines.
-
- xmin, xmax : scalar or 1D array_like
- Respective beginning and end of each line. If scalars are
- provided, all lines will have same length.
-
- colors : array_like of colors, optional, default: 'k'
-
- linestyles : ['solid' | 'dashed' | 'dashdot' | 'dotted'], optional
-
- label : string, optional, default: ''
-
- Returns
- -------
- lines : `~matplotlib.collections.LineCollection`
-
- Other parameters
- ----------------
- kwargs : `~matplotlib.collections.LineCollection` properties.
-
- See also
- --------
- vlines : vertical lines
-
- Examples
- --------
- .. plot:: mpl_examples/pylab_examples/vline_hline_demo.py
-
- """
-
- # We do the conversion first since not all unitized data is uniform
- # process the unit information
- self._process_unit_info([xmin, xmax], y, kwargs=kwargs)
- y = self.convert_yunits(y)
- xmin = self.convert_xunits(xmin)
- xmax = self.convert_xunits(xmax)
-
- if not iterable(y):
- y = [y]
- if not iterable(xmin):
- xmin = [xmin]
- if not iterable(xmax):
- xmax = [xmax]
-
- y = np.ravel(y)
-
- xmin = np.resize(xmin, y.shape)
- xmax = np.resize(xmax, y.shape)
-
- verts = [((thisxmin, thisy), (thisxmax, thisy))
- for thisxmin, thisxmax, thisy in zip(xmin, xmax, y)]
- coll = mcoll.LineCollection(verts, colors=colors,
- linestyles=linestyles, label=label)
- self.add_collection(coll, autolim=False)
- coll.update(kwargs)
-
- if len(y) > 0:
- minx = min(xmin.min(), xmax.min())
- maxx = max(xmin.max(), xmax.max())
- miny = y.min()
- maxy = y.max()
-
- corners = (minx, miny), (maxx, maxy)
-
- self.update_datalim(corners)
- self.autoscale_view()
-
- return coll
-
- @docstring.dedent_interpd
- def vlines(self, x, ymin, ymax, colors='k', linestyles='solid',
- label='', **kwargs):
- """
- Plot vertical lines.
-
- Plot vertical lines at each `x` from `ymin` to `ymax`.
-
- Parameters
- ----------
- x : scalar or 1D array_like
- x-indexes where to plot the lines.
-
- ymin, ymax : scalar or 1D array_like
- Respective beginning and end of each line. If scalars are
- provided, all lines will have same length.
-
- colors : array_like of colors, optional, default: 'k'
-
- linestyles : ['solid' | 'dashed' | 'dashdot' | 'dotted'], optional
-
- label : string, optional, default: ''
-
- Returns
- -------
- lines : `~matplotlib.collections.LineCollection`
-
- Other parameters
- ----------------
- kwargs : `~matplotlib.collections.LineCollection` properties.
-
- See also
- --------
- hlines : horizontal lines
-
- Examples
- ---------
- .. plot:: mpl_examples/pylab_examples/vline_hline_demo.py
-
- """
-
- self._process_unit_info(xdata=x, ydata=[ymin, ymax], kwargs=kwargs)
-
- # We do the conversion first since not all unitized data is uniform
- x = self.convert_xunits(x)
- ymin = self.convert_yunits(ymin)
- ymax = self.convert_yunits(ymax)
-
- if not iterable(x):
- x = [x]
- if not iterable(ymin):
- ymin = [ymin]
- if not iterable(ymax):
- ymax = [ymax]
-
- x = np.ravel(x)
- ymin = np.resize(ymin, x.shape)
- ymax = np.resize(ymax, x.shape)
-
- verts = [((thisx, thisymin), (thisx, thisymax))
- for thisx, thisymin, thisymax in zip(x, ymin, ymax)]
- #print 'creating line collection'
- coll = mcoll.LineCollection(verts, colors=colors,
- linestyles=linestyles, label=label)
- self.add_collection(coll, autolim=False)
- coll.update(kwargs)
-
- if len(x) > 0:
- minx = min(x)
- maxx = max(x)
-
- miny = min(min(ymin), min(ymax))
- maxy = max(max(ymin), max(ymax))
-
- corners = (minx, miny), (maxx, maxy)
- self.update_datalim(corners)
- self.autoscale_view()
-
- return coll
-
- @docstring.dedent_interpd
- def eventplot(self, positions, orientation='horizontal', lineoffsets=1,
- linelengths=1, linewidths=None, colors=None,
- linestyles='solid', **kwargs):
- """
- Plot identical parallel lines at specific positions.
-
- Call signature::
-
- eventplot(positions, orientation='horizontal', lineoffsets=0,
- linelengths=1, linewidths=None, color =None,
- linestyles='solid'
-
- Plot parallel lines at the given positions. positions should be a 1D
- or 2D array-like object, with each row corresponding to a row or column
- of lines.
-
- This type of plot is commonly used in neuroscience for representing
- neural events, where it is commonly called a spike raster, dot raster,
- or raster plot.
-
- However, it is useful in any situation where you wish to show the
- timing or position of multiple sets of discrete events, such as the
- arrival times of people to a business on each day of the month or the
- date of hurricanes each year of the last century.
-
- *orientation* : [ 'horizonal' | 'vertical' ]
- 'horizonal' : the lines will be vertical and arranged in rows
- "vertical' : lines will be horizontal and arranged in columns
-
- *lineoffsets* :
- A float or array-like containing floats.
-
- *linelengths* :
- A float or array-like containing floats.
-
- *linewidths* :
- A float or array-like containing floats.
-
- *colors*
- must be a sequence of RGBA tuples (e.g., arbitrary color
- strings, etc, not allowed) or a list of such sequences
-
- *linestyles* :
- [ 'solid' | 'dashed' | 'dashdot' | 'dotted' ] or an array of these
- values
-
- For linelengths, linewidths, colors, and linestyles, if only a single
- value is given, that value is applied to all lines. If an array-like
- is given, it must have the same length as positions, and each value
- will be applied to the corresponding row or column in positions.
-
- Returns a list of :class:`matplotlib.collections.EventCollection`
- objects that were added.
-
- kwargs are :class:`~matplotlib.collections.LineCollection` properties:
-
- %(LineCollection)s
-
- **Example:**
-
- .. plot:: mpl_examples/pylab_examples/eventplot_demo.py
- """
- self._process_unit_info(xdata=positions,
- ydata=[lineoffsets, linelengths],
- kwargs=kwargs)
-
- # We do the conversion first since not all unitized data is uniform
- positions = self.convert_xunits(positions)
- lineoffsets = self.convert_yunits(lineoffsets)
- linelengths = self.convert_yunits(linelengths)
-
- if not iterable(positions):
- positions = [positions]
- elif any(iterable(position) for position in positions):
- positions = [np.asanyarray(position) for position in positions]
- else:
- positions = [np.asanyarray(positions)]
-
- if len(positions) == 0:
- return []
-
- if not iterable(lineoffsets):
- lineoffsets = [lineoffsets]
- if not iterable(linelengths):
- linelengths = [linelengths]
- if not iterable(linewidths):
- linewidths = [linewidths]
- if not iterable(colors):
- colors = [colors]
- if hasattr(linestyles, 'lower') or not iterable(linestyles):
- linestyles = [linestyles]
-
- lineoffsets = np.asarray(lineoffsets)
- linelengths = np.asarray(linelengths)
- linewidths = np.asarray(linewidths)
-
- if len(lineoffsets) == 0:
- lineoffsets = [None]
- if len(linelengths) == 0:
- linelengths = [None]
- if len(linewidths) == 0:
- lineoffsets = [None]
- if len(linewidths) == 0:
- lineoffsets = [None]
- if len(colors) == 0:
- colors = [None]
-
- if len(lineoffsets) == 1 and len(positions) != 1:
- lineoffsets = np.tile(lineoffsets, len(positions))
- lineoffsets[0] = 0
- lineoffsets = np.cumsum(lineoffsets)
- if len(linelengths) == 1:
- linelengths = np.tile(linelengths, len(positions))
- if len(linewidths) == 1:
- linewidths = np.tile(linewidths, len(positions))
- if len(colors) == 1:
- colors = list(colors)
- colors = colors * len(positions)
- if len(linestyles) == 1:
- linestyles = [linestyles] * len(positions)
-
- if len(lineoffsets) != len(positions):
- raise ValueError('lineoffsets and positions are unequal sized '
- 'sequences')
- if len(linelengths) != len(positions):
- raise ValueError('linelengths and positions are unequal sized '
- 'sequences')
- if len(linewidths) != len(positions):
- raise ValueError('linewidths and positions are unequal sized '
- 'sequences')
- if len(colors) != len(positions):
- raise ValueError('colors and positions are unequal sized '
- 'sequences')
- if len(linestyles) != len(positions):
- raise ValueError('linestyles and positions are unequal sized '
- 'sequences')
-
- colls = []
- for position, lineoffset, linelength, linewidth, color, linestyle in \
- zip(positions, lineoffsets, linelengths, linewidths,
- colors, linestyles):
- coll = mcoll.EventCollection(position,
- orientation=orientation,
- lineoffset=lineoffset,
- linelength=linelength,
- linewidth=linewidth,
- color=color,
- linestyle=linestyle)
- self.add_collection(coll, autolim=False)
- coll.update(kwargs)
- colls.append(coll)
-
- if len(positions) > 0:
- # try to get min/max
- min_max = [(np.min(_p), np.max(_p)) for _p in positions
- if len(_p) > 0]
- # if we have any non-empty positions, try to autoscale
- if len(min_max) > 0:
- mins, maxes = zip(*min_max)
- minpos = np.min(mins)
- maxpos = np.max(maxes)
-
- minline = (lineoffsets - linelengths).min()
- maxline = (lineoffsets + linelengths).max()
-
- if colls[0].is_horizontal():
- corners = (minpos, minline), (maxpos, maxline)
- else:
- corners = (minline, minpos), (maxline, maxpos)
- self.update_datalim(corners)
- self.autoscale_view()
-
- return colls
-
- #### Basic plotting
- @docstring.dedent_interpd
- def plot(self, *args, **kwargs):
- """
- Plot lines and/or markers to the
- :class:`~matplotlib.axes.Axes`. *args* is a variable length
- argument, allowing for multiple *x*, *y* pairs with an
- optional format string. For example, each of the following is
- legal::
-
- plot(x, y) # plot x and y using default line style and color
- plot(x, y, 'bo') # plot x and y using blue circle markers
- plot(y) # plot y using x as index array 0..N-1
- plot(y, 'r+') # ditto, but with red plusses
-
- If *x* and/or *y* is 2-dimensional, then the corresponding columns
- will be plotted.
-
- An arbitrary number of *x*, *y*, *fmt* groups can be
- specified, as in::
-
- a.plot(x1, y1, 'g^', x2, y2, 'g-')
-
- Return value is a list of lines that were added.
-
- By default, each line is assigned a different color specified by a
- 'color cycle'. To change this behavior, you can edit the
- axes.color_cycle rcParam.
-
- The following format string characters are accepted to control
- the line style or marker:
-
- ================ ===============================
- character description
- ================ ===============================
- ``'-'`` solid line style
- ``'--'`` dashed line style
- ``'-.'`` dash-dot line style
- ``':'`` dotted line style
- ``'.'`` point marker
- ``','`` pixel marker
- ``'o'`` circle marker
- ``'v'`` triangle_down marker
- ``'^'`` triangle_up marker
- ``'<'`` triangle_left marker
- ``'>'`` triangle_right marker
- ``'1'`` tri_down marker
- ``'2'`` tri_up marker
- ``'3'`` tri_left marker
- ``'4'`` tri_right marker
- ``'s'`` square marker
- ``'p'`` pentagon marker
- ``'*'`` star marker
- ``'h'`` hexagon1 marker
- ``'H'`` hexagon2 marker
- ``'+'`` plus marker
- ``'x'`` x marker
- ``'D'`` diamond marker
- ``'d'`` thin_diamond marker
- ``'|'`` vline marker
- ``'_'`` hline marker
- ================ ===============================
-
-
- The following color abbreviations are supported:
-
- ========== ========
- character color
- ========== ========
- 'b' blue
- 'g' green
- 'r' red
- 'c' cyan
- 'm' magenta
- 'y' yellow
- 'k' black
- 'w' white
- ========== ========
-
- In addition, you can specify colors in many weird and
- wonderful ways, including full names (``'green'``), hex
- strings (``'#008000'``), RGB or RGBA tuples (``(0,1,0,1)``) or
- grayscale intensities as a string (``'0.8'``). Of these, the
- string specifications can be used in place of a ``fmt`` group,
- but the tuple forms can be used only as ``kwargs``.
-
- Line styles and colors are combined in a single format string, as in
- ``'bo'`` for blue circles.
-
- The *kwargs* can be used to set line properties (any property that has
- a ``set_*`` method). You can use this to set a line label (for auto
- legends), linewidth, anitialising, marker face color, etc. Here is an
- example::
-
- plot([1,2,3], [1,2,3], 'go-', label='line 1', linewidth=2)
- plot([1,2,3], [1,4,9], 'rs', label='line 2')
- axis([0, 4, 0, 10])
- legend()
-
- If you make multiple lines with one plot command, the kwargs
- apply to all those lines, e.g.::
-
- plot(x1, y1, x2, y2, antialised=False)
-
- Neither line will be antialiased.
-
- You do not need to use format strings, which are just
- abbreviations. All of the line properties can be controlled
- by keyword arguments. For example, you can set the color,
- marker, linestyle, and markercolor with::
-
- plot(x, y, color='green', linestyle='dashed', marker='o',
- markerfacecolor='blue', markersize=12).
-
- See :class:`~matplotlib.lines.Line2D` for details.
-
- The kwargs are :class:`~matplotlib.lines.Line2D` properties:
-
- %(Line2D)s
-
- kwargs *scalex* and *scaley*, if defined, are passed on to
- :meth:`~matplotlib.axes.Axes.autoscale_view` to determine
- whether the *x* and *y* axes are autoscaled; the default is
- *True*.
- """
- scalex = kwargs.pop('scalex', True)
- scaley = kwargs.pop('scaley', True)
-
- if not self._hold:
- self.cla()
- lines = []
-
- for line in self._get_lines(*args, **kwargs):
- self.add_line(line)
- lines.append(line)
-
- self.autoscale_view(scalex=scalex, scaley=scaley)
- return lines
-
- @docstring.dedent_interpd
- def plot_date(self, x, y, fmt='o', tz=None, xdate=True, ydate=False,
- **kwargs):
- """
- Plot with data with dates.
-
- Call signature::
-
- plot_date(x, y, fmt='bo', tz=None, xdate=True,
- ydate=False, **kwargs)
-
- Similar to the :func:`~matplotlib.pyplot.plot` command, except
- the *x* or *y* (or both) data is considered to be dates, and the
- axis is labeled accordingly.
-
- *x* and/or *y* can be a sequence of dates represented as float
- days since 0001-01-01 UTC.
-
- Keyword arguments:
-
- *fmt*: string
- The plot format string.
-
- *tz*: [ *None* | timezone string | :class:`tzinfo` instance]
- The time zone to use in labeling dates. If *None*, defaults to rc
- value.
-
- *xdate*: [ *True* | *False* ]
- If *True*, the *x*-axis will be labeled with dates.
-
- *ydate*: [ *False* | *True* ]
- If *True*, the *y*-axis will be labeled with dates.
-
- Note if you are using custom date tickers and formatters, it
- may be necessary to set the formatters/locators after the call
- to :meth:`plot_date` since :meth:`plot_date` will set the
- default tick locator to
- :class:`matplotlib.dates.AutoDateLocator` (if the tick
- locator is not already set to a
- :class:`matplotlib.dates.DateLocator` instance) and the
- default tick formatter to
- :class:`matplotlib.dates.AutoDateFormatter` (if the tick
- formatter is not already set to a
- :class:`matplotlib.dates.DateFormatter` instance).
-
- Valid kwargs are :class:`~matplotlib.lines.Line2D` properties:
-
- %(Line2D)s
-
- .. seealso::
-
- :mod:`~matplotlib.dates` for helper functions
-
- :func:`~matplotlib.dates.date2num`,
- :func:`~matplotlib.dates.num2date` and
- :func:`~matplotlib.dates.drange` for help on creating the required
- floating point dates.
- """
-
- if not self._hold:
- self.cla()
-
- ret = self.plot(x, y, fmt, **kwargs)
-
- if xdate:
- self.xaxis_date(tz)
- if ydate:
- self.yaxis_date(tz)
-
- self.autoscale_view()
-
- return ret
-
- @docstring.dedent_interpd
- def loglog(self, *args, **kwargs):
- """
- Make a plot with log scaling on both the *x* and *y* axis.
-
- Call signature::
-
- loglog(*args, **kwargs)
-
- :func:`~matplotlib.pyplot.loglog` supports all the keyword
- arguments of :func:`~matplotlib.pyplot.plot` and
- :meth:`matplotlib.axes.Axes.set_xscale` /
- :meth:`matplotlib.axes.Axes.set_yscale`.
-
- Notable keyword arguments:
-
- *basex*/*basey*: scalar > 1
- Base of the *x*/*y* logarithm
-
- *subsx*/*subsy*: [ *None* | sequence ]
- The location of the minor *x*/*y* ticks; *None* defaults
- to autosubs, which depend on the number of decades in the
- plot; see :meth:`matplotlib.axes.Axes.set_xscale` /
- :meth:`matplotlib.axes.Axes.set_yscale` for details
-
- *nonposx*/*nonposy*: ['mask' | 'clip' ]
- Non-positive values in *x* or *y* can be masked as
- invalid, or clipped to a very small positive number
-
- The remaining valid kwargs are
- :class:`~matplotlib.lines.Line2D` properties:
-
- %(Line2D)s
-
- **Example:**
-
- .. plot:: mpl_examples/pylab_examples/log_demo.py
-
- """
- if not self._hold:
- self.cla()
-
- dx = {'basex': kwargs.pop('basex', 10),
- 'subsx': kwargs.pop('subsx', None),
- 'nonposx': kwargs.pop('nonposx', 'mask'),
- }
- dy = {'basey': kwargs.pop('basey', 10),
- 'subsy': kwargs.pop('subsy', None),
- 'nonposy': kwargs.pop('nonposy', 'mask'),
- }
-
- self.set_xscale('log', **dx)
- self.set_yscale('log', **dy)
-
- b = self._hold
- self._hold = True # we've already processed the hold
- l = self.plot(*args, **kwargs)
- self._hold = b # restore the hold
-
- return l
-
- @docstring.dedent_interpd
- def semilogx(self, *args, **kwargs):
- """
- Make a plot with log scaling on the *x* axis.
-
- Call signature::
-
- semilogx(*args, **kwargs)
-
- :func:`semilogx` supports all the keyword arguments of
- :func:`~matplotlib.pyplot.plot` and
- :meth:`matplotlib.axes.Axes.set_xscale`.
-
- Notable keyword arguments:
-
- *basex*: scalar > 1
- Base of the *x* logarithm
-
- *subsx*: [ *None* | sequence ]
- The location of the minor xticks; *None* defaults to
- autosubs, which depend on the number of decades in the
- plot; see :meth:`~matplotlib.axes.Axes.set_xscale` for
- details.
-
- *nonposx*: [ 'mask' | 'clip' ]
- Non-positive values in *x* can be masked as
- invalid, or clipped to a very small positive number
-
- The remaining valid kwargs are
- :class:`~matplotlib.lines.Line2D` properties:
-
- %(Line2D)s
-
- .. seealso::
-
- :meth:`loglog`
- For example code and figure
- """
- if not self._hold:
- self.cla()
- d = {'basex': kwargs.pop('basex', 10),
- 'subsx': kwargs.pop('subsx', None),
- 'nonposx': kwargs.pop('nonposx', 'mask'),
- }
-
- self.set_xscale('log', **d)
- b = self._hold
- self._hold = True # we've already processed the hold
- l = self.plot(*args, **kwargs)
- self._hold = b # restore the hold
- return l
-
- @docstring.dedent_interpd
- def semilogy(self, *args, **kwargs):
- """
- Make a plot with log scaling on the *y* axis.
-
- call signature::
-
- semilogy(*args, **kwargs)
-
- :func:`semilogy` supports all the keyword arguments of
- :func:`~matplotlib.pylab.plot` and
- :meth:`matplotlib.axes.Axes.set_yscale`.
-
- Notable keyword arguments:
-
- *basey*: scalar > 1
- Base of the *y* logarithm
-
- *subsy*: [ *None* | sequence ]
- The location of the minor yticks; *None* defaults to
- autosubs, which depend on the number of decades in the
- plot; see :meth:`~matplotlib.axes.Axes.set_yscale` for
- details.
-
- *nonposy*: [ 'mask' | 'clip' ]
- Non-positive values in *y* can be masked as
- invalid, or clipped to a very small positive number
-
- The remaining valid kwargs are
- :class:`~matplotlib.lines.Line2D` properties:
-
- %(Line2D)s
-
- .. seealso::
-
- :meth:`loglog`
- For example code and figure
- """
- if not self._hold:
- self.cla()
- d = {'basey': kwargs.pop('basey', 10),
- 'subsy': kwargs.pop('subsy', None),
- 'nonposy': kwargs.pop('nonposy', 'mask'),
- }
- self.set_yscale('log', **d)
- b = self._hold
- self._hold = True # we've already processed the hold
- l = self.plot(*args, **kwargs)
- self._hold = b # restore the hold
-
- return l
-
- @docstring.dedent_interpd
- def acorr(self, x, **kwargs):
- """
- Plot the autocorrelation of `x`.
-
- Parameters
- ----------
-
- x : sequence of scalar
-
- hold : boolean, optional, default: True
-
- detrend : callable, optional, default: `mlab.detrend_none`
- x is detrended by the `detrend` callable. Default is no
- normalization.
-
- normed : boolean, optional, default: True
- if True, normalize the data by the autocorrelation at the 0-th
- lag.
-
- usevlines : boolean, optional, default: True
- if True, Axes.vlines is used to plot the vertical lines from the
- origin to the acorr. Otherwise, Axes.plot is used.
-
- maxlags : integer, optional, default: 10
- number of lags to show. If None, will return all 2 * len(x) - 1
- lags.
-
- Returns
- -------
- (lags, c, line, b) : where:
-
- - `lags` are a length 2`maxlags+1 lag vector.
- - `c` is the 2`maxlags+1 auto correlation vectorI
- - `line` is a `~matplotlib.lines.Line2D` instance returned by
- `plot`.
- - `b` is the x-axis.
-
- Other parameters
- -----------------
- linestyle : `~matplotlib.lines.Line2D` prop, optional, default: None
- Only used if usevlines is False.
-
- marker : string, optional, default: 'o'
-
- Notes
- -----
- The cross correlation is performed with :func:`numpy.correlate` with
- `mode` = 2.
-
- Examples
- --------
-
- `~matplotlib.pyplot.xcorr` is top graph, and
- `~matplotlib.pyplot.acorr` is bottom graph.
-
- .. plot:: mpl_examples/pylab_examples/xcorr_demo.py
-
- """
- return self.xcorr(x, x, **kwargs)
-
- @docstring.dedent_interpd
- def xcorr(self, x, y, normed=True, detrend=mlab.detrend_none,
- usevlines=True, maxlags=10, **kwargs):
- """
- Plot the cross correlation between *x* and *y*.
-
- Parameters
- ----------
-
- x : sequence of scalars of length n
-
- y : sequence of scalars of length n
-
- hold : boolean, optional, default: True
-
- detrend : callable, optional, default: `mlab.detrend_none`
- x is detrended by the `detrend` callable. Default is no
- normalization.
-
- normed : boolean, optional, default: True
- if True, normalize the data by the autocorrelation at the 0-th
- lag.
-
- usevlines : boolean, optional, default: True
- if True, Axes.vlines is used to plot the vertical lines from the
- origin to the acorr. Otherwise, Axes.plot is used.
-
- maxlags : integer, optional, default: 10
- number of lags to show. If None, will return all 2 * len(x) - 1
- lags.
-
- Returns
- -------
- (lags, c, line, b) : where:
-
- - `lags` are a length 2`maxlags+1 lag vector.
- - `c` is the 2`maxlags+1 auto correlation vectorI
- - `line` is a `~matplotlib.lines.Line2D` instance returned by
- `plot`.
- - `b` is the x-axis (none, if plot is used).
-
- Other parameters
- -----------------
- linestyle : `~matplotlib.lines.Line2D` prop, optional, default: None
- Only used if usevlines is False.
-
- marker : string, optional, default: 'o'
-
- Notes
- -----
- The cross correlation is performed with :func:`numpy.correlate` with
- `mode` = 2.
- """
-
- Nx = len(x)
- if Nx != len(y):
- raise ValueError('x and y must be equal length')
-
- x = detrend(np.asarray(x))
- y = detrend(np.asarray(y))
-
- c = np.correlate(x, y, mode=2)
-
- if normed:
- c /= np.sqrt(np.dot(x, x) * np.dot(y, y))
-
- if maxlags is None:
- maxlags = Nx - 1
-
- if maxlags >= Nx or maxlags < 1:
- raise ValueError('maglags must be None or strictly '
- 'positive < %d' % Nx)
-
- lags = np.arange(-maxlags, maxlags + 1)
- c = c[Nx - 1 - maxlags:Nx + maxlags]
-
- if usevlines:
- a = self.vlines(lags, [0], c, **kwargs)
- b = self.axhline(**kwargs)
- else:
-
- kwargs.setdefault('marker', 'o')
- kwargs.setdefault('linestyle', 'None')
- a, = self.plot(lags, c, **kwargs)
- b = None
- return lags, c, a, b
-
- #### Specialized plotting
-
- def step(self, x, y, *args, **kwargs):
- """
- Make a step plot.
-
- Call signature::
-
- step(x, y, *args, **kwargs)
-
- Additional keyword args to :func:`step` are the same as those
- for :func:`~matplotlib.pyplot.plot`.
-
- *x* and *y* must be 1-D sequences, and it is assumed, but not checked,
- that *x* is uniformly increasing.
-
- Keyword arguments:
-
- *where*: [ 'pre' | 'post' | 'mid' ]
- If 'pre', the interval from x[i] to x[i+1] has level y[i+1]
-
- If 'post', that interval has level y[i]
-
- If 'mid', the jumps in *y* occur half-way between the
- *x*-values.
- """
-
- where = kwargs.pop('where', 'pre')
- if where not in ('pre', 'post', 'mid'):
- raise ValueError("'where' argument to step must be "
- "'pre', 'post' or 'mid'")
- usr_linestyle = kwargs.pop('linestyle', '')
- kwargs['linestyle'] = 'steps-' + where + usr_linestyle
-
- return self.plot(x, y, *args, **kwargs)
-
- @docstring.dedent_interpd
- def bar(self, left, height, width=0.8, bottom=None, **kwargs):
- """
- Make a bar plot.
-
- Make a bar plot with rectangles bounded by:
-
- `left`, `left` + `width`, `bottom`, `bottom` + `height`
- (left, right, bottom and top edges)
-
- Parameters
- ----------
- left : sequence of scalars
- the x coordinates of the left sides of the bars
-
- height : sequence of scalars
- the heights of the bars
-
- width : scalar or array-like, optional, default: 0.8
- the width(s) of the bars
-
- bottom : scalar or array-like, optional, default: None
- the y coordinate(s) of the bars
-
- color : scalar or array-like, optional
- the colors of the bar faces
-
- edgecolor : scalar or array-like, optional
- the colors of the bar edges
-
- linewidth : scalar or array-like, optional, default: None
- width of bar edge(s). If None, use default
- linewidth; If 0, don't draw edges.
-
- xerr : scalar or array-like, optional, default: None
- if not None, will be used to generate errorbar(s) on the bar chart
-
- yerr : scalar or array-like, optional, default: None
- if not None, will be used to generate errorbar(s) on the bar chart
-
- ecolor : scalar or array-like, optional, default: None
- specifies the color of errorbar(s)
-
- capsize : integer, optional, default: 3
- determines the length in points of the error bar caps
-
- error_kw :
- dictionary of kwargs to be passed to errorbar method. *ecolor* and
- *capsize* may be specified here rather than as independent kwargs.
-
- align : ['edge' | 'center'], optional, default: 'edge'
- If `edge`, aligns bars by their left edges (for vertical bars) and
- by their bottom edges (for horizontal bars). If `center`, interpret
- the `left` argument as the coordinates of the centers of the bars.
-
- orientation : 'vertical' | 'horizontal', optional, default: 'vertical'
- The orientation of the bars.
-
- log : boolean, optional, default: False
- If true, sets the axis to be log scale
-
- Returns
- -------
- `matplotlib.patches.Rectangle` instances.
-
- Notes
- -----
- The optional arguments `color`, `edgecolor`, `linewidth`,
- `xerr`, and `yerr` can be either scalars or sequences of
- length equal to the number of bars. This enables you to use
- bar as the basis for stacked bar charts, or candlestick plots.
- Detail: `xerr` and `yerr` are passed directly to
- :meth:`errorbar`, so they can also have shape 2xN for
- independent specification of lower and upper errors.
-
- Other optional kwargs:
-
- %(Rectangle)s
-
- See also
- --------
- barh: Plot a horizontal bar plot.
-
- Examples
- --------
-
- **Example:** A stacked bar chart.
-
- .. plot:: mpl_examples/pylab_examples/bar_stacked.py
- """
- if not self._hold:
- self.cla()
- color = kwargs.pop('color', None)
- edgecolor = kwargs.pop('edgecolor', None)
- linewidth = kwargs.pop('linewidth', None)
-
- # Because xerr and yerr will be passed to errorbar,
- # most dimension checking and processing will be left
- # to the errorbar method.
- xerr = kwargs.pop('xerr', None)
- yerr = kwargs.pop('yerr', None)
- error_kw = kwargs.pop('error_kw', dict())
- ecolor = kwargs.pop('ecolor', None)
- capsize = kwargs.pop('capsize', 3)
- error_kw.setdefault('ecolor', ecolor)
- error_kw.setdefault('capsize', capsize)
-
- align = kwargs.pop('align', 'edge')
- orientation = kwargs.pop('orientation', 'vertical')
- log = kwargs.pop('log', False)
- label = kwargs.pop('label', '')
-
- def make_iterable(x):
- if not iterable(x):
- return [x]
- else:
- return x
-
- # make them safe to take len() of
- _left = left
- left = make_iterable(left)
- height = make_iterable(height)
- width = make_iterable(width)
- _bottom = bottom
- bottom = make_iterable(bottom)
- linewidth = make_iterable(linewidth)
-
- adjust_ylim = False
- adjust_xlim = False
- if orientation == 'vertical':
- self._process_unit_info(xdata=left, ydata=height, kwargs=kwargs)
- if log:
- self.set_yscale('log', nonposy='clip')
- # size width and bottom according to length of left
- if _bottom is None:
- if self.get_yscale() == 'log':
- adjust_ylim = True
- bottom = [0]
-
- nbars = len(left)
- if len(width) == 1:
- width *= nbars
- if len(bottom) == 1:
- bottom *= nbars
- elif orientation == 'horizontal':
- self._process_unit_info(xdata=width, ydata=bottom, kwargs=kwargs)
- if log:
- self.set_xscale('log', nonposx='clip')
- # size left and height according to length of bottom
- if _left is None:
- if self.get_xscale() == 'log':
- adjust_xlim = True
- left = [0]
-
- nbars = len(bottom)
- if len(left) == 1:
- left *= nbars
- if len(height) == 1:
- height *= nbars
- else:
- raise ValueError('invalid orientation: %s' % orientation)
-
- if len(linewidth) < nbars:
- linewidth *= nbars
-
- if color is None:
- color = [None] * nbars
- else:
- color = list(mcolors.colorConverter.to_rgba_array(color))
- if len(color) == 0: # until to_rgba_array is changed
- color = [[0, 0, 0, 0]]
- if len(color) < nbars:
- color *= nbars
-
- if edgecolor is None:
- edgecolor = [None] * nbars
- else:
- edgecolor = list(mcolors.colorConverter.to_rgba_array(edgecolor))
- if len(edgecolor) == 0: # until to_rgba_array is changed
- edgecolor = [[0, 0, 0, 0]]
- if len(edgecolor) < nbars:
- edgecolor *= nbars
-
- # FIXME: convert the following to proper input validation
- # raising ValueError; don't use assert for this.
- assert len(left) == nbars, ("incompatible sizes: argument 'left' must "
- "be length %d or scalar" % nbars)
- assert len(height) == nbars, ("incompatible sizes: argument 'height' "
- "must be length %d or scalar" %
- nbars)
- assert len(width) == nbars, ("incompatible sizes: argument 'width' "
- "must be length %d or scalar" %
- nbars)
- assert len(bottom) == nbars, ("incompatible sizes: argument 'bottom' "
- "must be length %d or scalar" %
- nbars)
-
- patches = []
-
- # lets do some conversions now since some types cannot be
- # subtracted uniformly
- if self.xaxis is not None:
- left = self.convert_xunits(left)
- width = self.convert_xunits(width)
- if xerr is not None:
- xerr = self.convert_xunits(xerr)
-
- if self.yaxis is not None:
- bottom = self.convert_yunits(bottom)
- height = self.convert_yunits(height)
- if yerr is not None:
- yerr = self.convert_yunits(yerr)
-
- if align == 'edge':
- pass
- elif align == 'center':
- if orientation == 'vertical':
- left = [left[i] - width[i] / 2. for i in xrange(len(left))]
- elif orientation == 'horizontal':
- bottom = [bottom[i] - height[i] / 2.
- for i in xrange(len(bottom))]
-
- else:
- raise ValueError('invalid alignment: %s' % align)
-
- args = zip(left, bottom, width, height, color, edgecolor, linewidth)
- for l, b, w, h, c, e, lw in args:
- if h < 0:
- b += h
- h = abs(h)
- if w < 0:
- l += w
- w = abs(w)
- r = mpatches.Rectangle(
- xy=(l, b), width=w, height=h,
- facecolor=c,
- edgecolor=e,
- linewidth=lw,
- label='_nolegend_'
- )
- r.update(kwargs)
- r.get_path()._interpolation_steps = 100
- #print r.get_label(), label, 'label' in kwargs
- self.add_patch(r)
- patches.append(r)
-
- holdstate = self._hold
- self.hold(True) # ensure hold is on before plotting errorbars
-
- if xerr is not None or yerr is not None:
- if orientation == 'vertical':
- # using list comps rather than arrays to preserve unit info
- x = [l + 0.5 * w for l, w in zip(left, width)]
- y = [b + h for b, h in zip(bottom, height)]
-
- elif orientation == 'horizontal':
- # using list comps rather than arrays to preserve unit info
- x = [l + w for l, w in zip(left, width)]
- y = [b + 0.5 * h for b, h in zip(bottom, height)]
-
- if "label" not in error_kw:
- error_kw["label"] = '_nolegend_'
-
- errorbar = self.errorbar(x, y,
- yerr=yerr, xerr=xerr,
- fmt='none', **error_kw)
- else:
- errorbar = None
-
- self.hold(holdstate) # restore previous hold state
-
- if adjust_xlim:
- xmin, xmax = self.dataLim.intervalx
- xmin = np.amin([w for w in width if w > 0])
- if xerr is not None:
- xmin = xmin - np.amax(xerr)
- xmin = max(xmin * 0.9, 1e-100)
- self.dataLim.intervalx = (xmin, xmax)
-
- if adjust_ylim:
- ymin, ymax = self.dataLim.intervaly
- ymin = np.amin([h for h in height if h > 0])
- if yerr is not None:
- ymin = ymin - np.amax(yerr)
- ymin = max(ymin * 0.9, 1e-100)
- self.dataLim.intervaly = (ymin, ymax)
- self.autoscale_view()
-
- bar_container = BarContainer(patches, errorbar, label=label)
- self.add_container(bar_container)
-
- return bar_container
-
- @docstring.dedent_interpd
- def barh(self, bottom, width, height=0.8, left=None, **kwargs):
- """
- Make a horizontal bar plot.
-
- Make a horizontal bar plot with rectangles bounded by:
-
- `left`, `left` + `width`, `bottom`, `bottom` + `height`
- (left, right, bottom and top edges)
-
- `bottom`, `width`, `height`, and `left` can be either scalars
- or sequences
-
- Parameters
- ----------
- bottom : scalar or array-like
- the y coordinate(s) of the bars
-
- width : scalar or array-like
- the width(s) of the bars
-
- height : sequence of scalars, optional, default: 0.8
- the heights of the bars
-
- left : sequence of scalars
- the x coordinates of the left sides of the bars
-
- Returns
- --------
- `matplotlib.patches.Rectangle` instances.
-
- Other parameters
- ----------------
- color : scalar or array-like, optional
- the colors of the bars
-
- edgecolor : scalar or array-like, optional
- the colors of the bar edges
-
- linewidth : scalar or array-like, optional, default: None
- width of bar edge(s). If None, use default
- linewidth; If 0, don't draw edges.
-
- xerr : scalar or array-like, optional, default: None
- if not None, will be used to generate errorbar(s) on the bar chart
-
- yerr : scalar or array-like, optional, default: None
- if not None, will be used to generate errorbar(s) on the bar chart
-
- ecolor : scalar or array-like, optional, default: None
- specifies the color of errorbar(s)
-
- capsize : integer, optional, default: 3
- determines the length in points of the error bar caps
-
- error_kw :
- dictionary of kwargs to be passed to errorbar method. `ecolor` and
- `capsize` may be specified here rather than as independent kwargs.
-
- align : ['edge' | 'center'], optional, default: 'edge'
- If `edge`, aligns bars by their left edges (for vertical bars) and
- by their bottom edges (for horizontal bars). If `center`, interpret
- the `left` argument as the coordinates of the centers of the bars.
-
- orientation : 'vertical' | 'horizontal', optional, default: 'vertical'
- The orientation of the bars.
-
- log : boolean, optional, default: False
- If true, sets the axis to be log scale
-
- Notes
- -----
- The optional arguments `color`, `edgecolor`, `linewidth`,
- `xerr`, and `yerr` can be either scalars or sequences of
- length equal to the number of bars. This enables you to use
- bar as the basis for stacked bar charts, or candlestick plots.
- Detail: `xerr` and `yerr` are passed directly to
- :meth:`errorbar`, so they can also have shape 2xN for
- independent specification of lower and upper errors.
-
- Other optional kwargs:
-
- %(Rectangle)s
-
- See also
- --------
- bar: Plot a vertical bar plot.
- """
-
- patches = self.bar(left=left, height=height, width=width,
- bottom=bottom, orientation='horizontal', **kwargs)
- return patches
-
- @docstring.dedent_interpd
- def broken_barh(self, xranges, yrange, **kwargs):
- """
- Plot horizontal bars.
-
- Call signature::
-
- broken_barh(self, xranges, yrange, **kwargs)
-
- A collection of horizontal bars spanning *yrange* with a sequence of
- *xranges*.
-
- Required arguments:
-
- ========= ==============================
- Argument Description
- ========= ==============================
- *xranges* sequence of (*xmin*, *xwidth*)
- *yrange* sequence of (*ymin*, *ywidth*)
- ========= ==============================
-
- kwargs are
- :class:`matplotlib.collections.BrokenBarHCollection`
- properties:
-
- %(BrokenBarHCollection)s
-
- these can either be a single argument, i.e.,::
-
- facecolors = 'black'
-
- or a sequence of arguments for the various bars, i.e.,::
-
- facecolors = ('black', 'red', 'green')
-
- **Example:**
-
- .. plot:: mpl_examples/pylab_examples/broken_barh.py
- """
- col = mcoll.BrokenBarHCollection(xranges, yrange, **kwargs)
- self.add_collection(col, autolim=True)
- self.autoscale_view()
-
- return col
-
- def stem(self, *args, **kwargs):
- """
- Create a stem plot.
-
- Call signatures::
-
- stem(y, linefmt='b-', markerfmt='bo', basefmt='r-')
- stem(x, y, linefmt='b-', markerfmt='bo', basefmt='r-')
-
- A stem plot plots vertical lines (using *linefmt*) at each *x*
- location from the baseline to *y*, and places a marker there
- using *markerfmt*. A horizontal line at 0 is is plotted using
- *basefmt*.
-
- If no *x* values are provided, the default is (0, 1, ..., len(y) - 1)
-
- Return value is a tuple (*markerline*, *stemlines*,
- *baseline*).
-
- .. seealso::
- This
- `document `_
- for details.
-
-
- **Example:**
-
- .. plot:: mpl_examples/pylab_examples/stem_plot.py
- """
- remember_hold = self._hold
- if not self._hold:
- self.cla()
- self.hold(True)
-
- # Assume there's at least one data array
- y = np.asarray(args[0])
- args = args[1:]
-
- # Try a second one
- try:
- second = np.asarray(args[0], dtype=np.float)
- x, y = y, second
- args = args[1:]
- except (IndexError, ValueError):
- # The second array doesn't make sense, or it doesn't exist
- second = np.arange(len(y))
- x = second
-
- # Popping some defaults
- try:
- linefmt = kwargs.pop('linefmt', args[0])
- except IndexError:
- linefmt = kwargs.pop('linefmt', 'b-')
- try:
- markerfmt = kwargs.pop('markerfmt', args[1])
- except IndexError:
- markerfmt = kwargs.pop('markerfmt', 'bo')
- try:
- basefmt = kwargs.pop('basefmt', args[2])
- except IndexError:
- basefmt = kwargs.pop('basefmt', 'r-')
-
- bottom = kwargs.pop('bottom', None)
- label = kwargs.pop('label', None)
-
- markerline, = self.plot(x, y, markerfmt, label="_nolegend_")
-
- if bottom is None:
- bottom = 0
-
- stemlines = []
- for thisx, thisy in zip(x, y):
- l, = self.plot([thisx, thisx], [bottom, thisy], linefmt,
- label="_nolegend_")
- stemlines.append(l)
-
- baseline, = self.plot([np.amin(x), np.amax(x)], [bottom, bottom],
- basefmt, label="_nolegend_")
-
- self.hold(remember_hold)
-
- stem_container = StemContainer((markerline, stemlines, baseline),
- label=label)
- self.add_container(stem_container)
-
- return stem_container
-
- def pie(self, x, explode=None, labels=None, colors=None,
- autopct=None, pctdistance=0.6, shadow=False, labeldistance=1.1,
- startangle=None, radius=None, counterclock=True,
- wedgeprops=None, textprops=None):
- r"""
- Plot a pie chart.
-
- Call signature::
-
- pie(x, explode=None, labels=None,
- colors=('b', 'g', 'r', 'c', 'm', 'y', 'k', 'w'),
- autopct=None, pctdistance=0.6, shadow=False,
- labeldistance=1.1, startangle=None, radius=None,
- counterclock=True, wedgeprops=None, textprops=None)
-
- Make a pie chart of array *x*. The fractional area of each
- wedge is given by x/sum(x). If sum(x) <= 1, then the values
- of x give the fractional area directly and the array will not
- be normalized. The wedges are plotted counterclockwise,
- by default starting from the x-axis.
-
- Keyword arguments:
-
- *explode*: [ *None* | len(x) sequence ]
- If not *None*, is a ``len(x)`` array which specifies the
- fraction of the radius with which to offset each wedge.
-
- *colors*: [ *None* | color sequence ]
- A sequence of matplotlib color args through which the pie chart
- will cycle.
-
- *labels*: [ *None* | len(x) sequence of strings ]
- A sequence of strings providing the labels for each wedge
-
- *autopct*: [ *None* | format string | format function ]
- If not *None*, is a string or function used to label the wedges
- with their numeric value. The label will be placed inside the
- wedge. If it is a format string, the label will be ``fmt%pct``.
- If it is a function, it will be called.
-
- *pctdistance*: scalar
- The ratio between the center of each pie slice and the
- start of the text generated by *autopct*. Ignored if
- *autopct* is *None*; default is 0.6.
-
- *labeldistance*: scalar
- The radial distance at which the pie labels are drawn
-
- *shadow*: [ *False* | *True* ]
- Draw a shadow beneath the pie.
-
- *startangle*: [ *None* | Offset angle ]
- If not *None*, rotates the start of the pie chart by *angle*
- degrees counterclockwise from the x-axis.
-
- *radius*: [ *None* | scalar ]
- The radius of the pie, if *radius* is *None* it will be set to 1.
-
- *counterclock*: [ *False* | *True* ]
- Specify fractions direction, clockwise or counterclockwise.
-
- *wedgeprops*: [ *None* | dict of key value pairs ]
- Dict of arguments passed to the wedge objects making the pie.
- For example, you can pass in wedgeprops = { 'linewidth' : 3 }
- to set the width of the wedge border lines equal to 3.
- For more details, look at the doc/arguments of the wedge object.
- By default `clip_on=False`.
-
- *textprops*: [ *None* | dict of key value pairs ]
- Dict of arguments to pass to the text objects.
-
-
- The pie chart will probably look best if the figure and axes are
- square, or the Axes aspect is equal. e.g.::
-
- figure(figsize=(8,8))
- ax = axes([0.1, 0.1, 0.8, 0.8])
-
- or::
-
- axes(aspect=1)
-
- Return value:
- If *autopct* is *None*, return the tuple (*patches*, *texts*):
-
- - *patches* is a sequence of
- :class:`matplotlib.patches.Wedge` instances
-
- - *texts* is a list of the label
- :class:`matplotlib.text.Text` instances.
-
- If *autopct* is not *None*, return the tuple (*patches*,
- *texts*, *autotexts*), where *patches* and *texts* are as
- above, and *autotexts* is a list of
- :class:`~matplotlib.text.Text` instances for the numeric
- labels.
- """
- self.set_frame_on(False)
-
- x = np.asarray(x).astype(np.float32)
-
- sx = float(x.sum())
- if sx > 1:
- x = np.divide(x, sx)
-
- if labels is None:
- labels = [''] * len(x)
- if explode is None:
- explode = [0] * len(x)
- assert(len(x) == len(labels))
- assert(len(x) == len(explode))
- if colors is None:
- colors = ('b', 'g', 'r', 'c', 'm', 'y', 'k', 'w')
-
- center = 0, 0
- if radius is None:
- radius = 1
-
- # Starting theta1 is the start fraction of the circle
- if startangle is None:
- theta1 = 0
- else:
- theta1 = startangle / 360.0
-
- # set default values in wedge_prop
- if wedgeprops is None:
- wedgeprops = {}
- if 'clip_on' not in wedgeprops:
- wedgeprops['clip_on'] = False
-
- if textprops is None:
- textprops = {}
- if 'clip_on' not in textprops:
- textprops['clip_on'] = False
-
- texts = []
- slices = []
- autotexts = []
-
- i = 0
- for frac, label, expl in cbook.safezip(x, labels, explode):
- x, y = center
- theta2 = (theta1 + frac) if counterclock else (theta1 - frac)
- thetam = 2 * math.pi * 0.5 * (theta1 + theta2)
- x += expl * math.cos(thetam)
- y += expl * math.sin(thetam)
-
- w = mpatches.Wedge((x, y), radius, 360. * min(theta1, theta2),
- 360. * max(theta1, theta2),
- facecolor=colors[i % len(colors)],
- **wedgeprops)
- slices.append(w)
- self.add_patch(w)
- w.set_label(label)
-
- if shadow:
- # make sure to add a shadow after the call to
- # add_patch so the figure and transform props will be
- # set
- shad = mpatches.Shadow(w, -0.02, -0.02)
- shad.set_zorder(0.9 * w.get_zorder())
- shad.set_label('_nolegend_')
- self.add_patch(shad)
-
- xt = x + labeldistance * radius * math.cos(thetam)
- yt = y + labeldistance * radius * math.sin(thetam)
- label_alignment = xt > 0 and 'left' or 'right'
-
- t = self.text(xt, yt, label,
- size=rcParams['xtick.labelsize'],
- horizontalalignment=label_alignment,
- verticalalignment='center',
- **textprops)
-
- texts.append(t)
-
- if autopct is not None:
- xt = x + pctdistance * radius * math.cos(thetam)
- yt = y + pctdistance * radius * math.sin(thetam)
- if is_string_like(autopct):
- s = autopct % (100. * frac)
- elif six.callable(autopct):
- s = autopct(100. * frac)
- else:
- raise TypeError(
- 'autopct must be callable or a format string')
-
- t = self.text(xt, yt, s,
- horizontalalignment='center',
- verticalalignment='center',
- **textprops)
-
- autotexts.append(t)
-
- theta1 = theta2
- i += 1
-
- self.set_xlim((-1.25, 1.25))
- self.set_ylim((-1.25, 1.25))
- self.set_xticks([])
- self.set_yticks([])
-
- if autopct is None:
- return slices, texts
- else:
- return slices, texts, autotexts
-
- @docstring.dedent_interpd
- def errorbar(self, x, y, yerr=None, xerr=None,
- fmt='', ecolor=None, elinewidth=None, capsize=3,
- barsabove=False, lolims=False, uplims=False,
- xlolims=False, xuplims=False, errorevery=1, capthick=None,
- **kwargs):
- """
- Plot an errorbar graph.
-
- Call signature::
-
- errorbar(x, y, yerr=None, xerr=None,
- fmt='', ecolor=None, elinewidth=None, capsize=3,
- barsabove=False, lolims=False, uplims=False,
- xlolims=False, xuplims=False, errorevery=1,
- capthick=None)
-
- Plot *x* versus *y* with error deltas in *yerr* and *xerr*.
- Vertical errorbars are plotted if *yerr* is not *None*.
- Horizontal errorbars are plotted if *xerr* is not *None*.
-
- *x*, *y*, *xerr*, and *yerr* can all be scalars, which plots a
- single error bar at *x*, *y*.
-
- Optional keyword arguments:
-
- *xerr*/*yerr*: [ scalar | N, Nx1, or 2xN array-like ]
- If a scalar number, len(N) array-like object, or an Nx1
- array-like object, errorbars are drawn at +/-value relative
- to the data.
-
- If a sequence of shape 2xN, errorbars are drawn at -row1
- and +row2 relative to the data.
-
- *fmt*: [ '' | 'none' | plot format string ]
- The plot format symbol. If *fmt* is 'none' (case-insensitive),
- only the errorbars are plotted. This is used for adding
- errorbars to a bar plot, for example. Default is '',
- an empty plot format string; properties are
- then identical to the defaults for :meth:`plot`.
-
- *ecolor*: [ *None* | mpl color ]
- A matplotlib color arg which gives the color the errorbar lines;
- if *None*, use the color of the line connecting the markers.
-
- *elinewidth*: scalar
- The linewidth of the errorbar lines. If *None*, use the linewidth.
-
- *capsize*: scalar
- The length of the error bar caps in points
-
- *capthick*: scalar
- An alias kwarg to *markeredgewidth* (a.k.a. - *mew*). This
- setting is a more sensible name for the property that
- controls the thickness of the error bar cap in points. For
- backwards compatibility, if *mew* or *markeredgewidth* are given,
- then they will over-ride *capthick*. This may change in future
- releases.
-
- *barsabove*: [ *True* | *False* ]
- if *True*, will plot the errorbars above the plot
- symbols. Default is below.
-
- *lolims* / *uplims* / *xlolims* / *xuplims*: [ *False* | *True* ]
- These arguments can be used to indicate that a value gives
- only upper/lower limits. In that case a caret symbol is
- used to indicate this. lims-arguments may be of the same
- type as *xerr* and *yerr*. To use limits with inverted
- axes, :meth:`set_xlim` or :meth:`set_ylim` must be called
- before :meth:`errorbar`.
-
- *errorevery*: positive integer
- subsamples the errorbars. e.g., if everyerror=5, errorbars for
- every 5-th datapoint will be plotted. The data plot itself still
- shows all data points.
-
- All other keyword arguments are passed on to the plot command for the
- markers. For example, this code makes big red squares with
- thick green edges::
-
- x,y,yerr = rand(3,10)
- errorbar(x, y, yerr, marker='s',
- mfc='red', mec='green', ms=20, mew=4)
-
- where *mfc*, *mec*, *ms* and *mew* are aliases for the longer
- property names, *markerfacecolor*, *markeredgecolor*, *markersize*
- and *markeredgewith*.
-
- valid kwargs for the marker properties are
-
- %(Line2D)s
-
- Returns (*plotline*, *caplines*, *barlinecols*):
-
- *plotline*: :class:`~matplotlib.lines.Line2D` instance
- *x*, *y* plot markers and/or line
-
- *caplines*: list of error bar cap
- :class:`~matplotlib.lines.Line2D` instances
- *barlinecols*: list of
- :class:`~matplotlib.collections.LineCollection` instances for
- the horizontal and vertical error ranges.
-
- **Example:**
-
- .. plot:: mpl_examples/statistics/errorbar_demo.py
-
- """
-
- if errorevery < 1:
- raise ValueError(
- 'errorevery has to be a strictly positive integer')
-
- self._process_unit_info(xdata=x, ydata=y, kwargs=kwargs)
- if not self._hold:
- self.cla()
- holdstate = self._hold
- self._hold = True
-
- if fmt is None:
- fmt = 'none'
- msg = ('Use of None object as fmt keyword argument to '
- + 'suppress plotting of data values is deprecated '
- + 'since 1.4; use the string "none" instead.')
- warnings.warn(msg, mplDeprecation, stacklevel=1)
-
- plot_line = (fmt.lower() != 'none')
-
- label = kwargs.pop("label", None)
-
- # make sure all the args are iterable; use lists not arrays to
- # preserve units
- if not iterable(x):
- x = [x]
-
- if not iterable(y):
- y = [y]
-
- if xerr is not None:
- if not iterable(xerr):
- xerr = [xerr] * len(x)
-
- if yerr is not None:
- if not iterable(yerr):
- yerr = [yerr] * len(y)
-
- l0 = None
-
- # Instead of using zorder, the line plot is being added
- # either here, or after all the errorbar plot elements.
- if barsabove and plot_line:
- l0, = self.plot(x, y, fmt, label="_nolegend_", **kwargs)
-
- barcols = []
- caplines = []
-
- lines_kw = {'label': '_nolegend_'}
- if elinewidth:
- lines_kw['linewidth'] = elinewidth
- else:
- for key in ('linewidth', 'lw'):
- if key in kwargs:
- lines_kw[key] = kwargs[key]
- for key in ('transform', 'alpha', 'zorder'):
- if key in kwargs:
- lines_kw[key] = kwargs[key]
-
- # arrays fine here, they are booleans and hence not units
- if not iterable(lolims):
- lolims = np.asarray([lolims] * len(x), bool)
- else:
- lolims = np.asarray(lolims, bool)
-
- if not iterable(uplims):
- uplims = np.array([uplims] * len(x), bool)
- else:
- uplims = np.asarray(uplims, bool)
-
- if not iterable(xlolims):
- xlolims = np.array([xlolims] * len(x), bool)
- else:
- xlolims = np.asarray(xlolims, bool)
-
- if not iterable(xuplims):
- xuplims = np.array([xuplims] * len(x), bool)
- else:
- xuplims = np.asarray(xuplims, bool)
-
- everymask = np.arange(len(x)) % errorevery == 0
-
- def xywhere(xs, ys, mask):
- """
- return xs[mask], ys[mask] where mask is True but xs and
- ys are not arrays
- """
- assert len(xs) == len(ys)
- assert len(xs) == len(mask)
- xs = [thisx for thisx, b in zip(xs, mask) if b]
- ys = [thisy for thisy, b in zip(ys, mask) if b]
- return xs, ys
-
- plot_kw = {'label': '_nolegend_'}
- if capsize > 0:
- plot_kw['ms'] = 2. * capsize
- if capthick is not None:
- # 'mew' has higher priority, I believe,
- # if both 'mew' and 'markeredgewidth' exists.
- # So, save capthick to markeredgewidth so that
- # explicitly setting mew or markeredgewidth will
- # over-write capthick.
- plot_kw['markeredgewidth'] = capthick
- # For backwards-compat, allow explicit setting of
- # 'mew' or 'markeredgewidth' to over-ride capthick.
- for key in ('markeredgewidth', 'mew', 'transform', 'alpha', 'zorder'):
- if key in kwargs:
- plot_kw[key] = kwargs[key]
-
- if xerr is not None:
- if (iterable(xerr) and len(xerr) == 2 and
- iterable(xerr[0]) and iterable(xerr[1])):
- # using list comps rather than arrays to preserve units
- left = [thisx - thiserr for (thisx, thiserr)
- in cbook.safezip(x, xerr[0])]
- right = [thisx + thiserr for (thisx, thiserr)
- in cbook.safezip(x, xerr[1])]
- else:
- # using list comps rather than arrays to preserve units
- left = [thisx - thiserr for (thisx, thiserr)
- in cbook.safezip(x, xerr)]
- right = [thisx + thiserr for (thisx, thiserr)
- in cbook.safezip(x, xerr)]
-
- # select points without upper/lower limits in x and
- # draw normal errorbars for these points
- noxlims = ~(xlolims | xuplims)
- if noxlims.any():
- yo, _ = xywhere(y, right, noxlims & everymask)
- lo, ro = xywhere(left, right, noxlims & everymask)
- barcols.append(self.hlines(yo, lo, ro, **lines_kw))
- if capsize > 0:
- caplines.extend(self.plot(lo, yo, 'k|', **plot_kw))
- caplines.extend(self.plot(ro, yo, 'k|', **plot_kw))
-
- if xlolims.any():
- yo, _ = xywhere(y, right, xlolims & everymask)
- lo, ro = xywhere(x, right, xlolims & everymask)
- barcols.append(self.hlines(yo, lo, ro, **lines_kw))
- rightup, yup = xywhere(right, y, xlolims & everymask)
- if self.xaxis_inverted():
- marker = mlines.CARETLEFT
- else:
- marker = mlines.CARETRIGHT
- caplines.extend(
- self.plot(rightup, yup, ls='None', marker=marker,
- **plot_kw))
- if capsize > 0:
- xlo, ylo = xywhere(x, y, xlolims & everymask)
- caplines.extend(self.plot(xlo, ylo, 'k|', **plot_kw))
-
- if xuplims.any():
- yo, _ = xywhere(y, right, xuplims & everymask)
- lo, ro = xywhere(left, x, xuplims & everymask)
- barcols.append(self.hlines(yo, lo, ro, **lines_kw))
- leftlo, ylo = xywhere(left, y, xuplims & everymask)
- if self.xaxis_inverted():
- marker = mlines.CARETRIGHT
- else:
- marker = mlines.CARETLEFT
- caplines.extend(
- self.plot(leftlo, ylo, ls='None', marker=marker,
- **plot_kw))
- if capsize > 0:
- xup, yup = xywhere(x, y, xuplims & everymask)
- caplines.extend(self.plot(xup, yup, 'k|', **plot_kw))
-
- if yerr is not None:
- if (iterable(yerr) and len(yerr) == 2 and
- iterable(yerr[0]) and iterable(yerr[1])):
- # using list comps rather than arrays to preserve units
- lower = [thisy - thiserr for (thisy, thiserr)
- in cbook.safezip(y, yerr[0])]
- upper = [thisy + thiserr for (thisy, thiserr)
- in cbook.safezip(y, yerr[1])]
- else:
- # using list comps rather than arrays to preserve units
- lower = [thisy - thiserr for (thisy, thiserr)
- in cbook.safezip(y, yerr)]
- upper = [thisy + thiserr for (thisy, thiserr)
- in cbook.safezip(y, yerr)]
-
- # select points without upper/lower limits in y and
- # draw normal errorbars for these points
- noylims = ~(lolims | uplims)
- if noylims.any():
- xo, _ = xywhere(x, lower, noylims & everymask)
- lo, uo = xywhere(lower, upper, noylims & everymask)
- barcols.append(self.vlines(xo, lo, uo, **lines_kw))
- if capsize > 0:
- caplines.extend(self.plot(xo, lo, 'k_', **plot_kw))
- caplines.extend(self.plot(xo, uo, 'k_', **plot_kw))
-
- if lolims.any():
- xo, _ = xywhere(x, lower, lolims & everymask)
- lo, uo = xywhere(y, upper, lolims & everymask)
- barcols.append(self.vlines(xo, lo, uo, **lines_kw))
- xup, upperup = xywhere(x, upper, lolims & everymask)
- if self.yaxis_inverted():
- marker = mlines.CARETDOWN
- else:
- marker = mlines.CARETUP
- caplines.extend(
- self.plot(xup, upperup, ls='None', marker=marker,
- **plot_kw))
- if capsize > 0:
- xlo, ylo = xywhere(x, y, lolims & everymask)
- caplines.extend(self.plot(xlo, ylo, 'k_', **plot_kw))
-
- if uplims.any():
- xo, _ = xywhere(x, lower, uplims & everymask)
- lo, uo = xywhere(lower, y, uplims & everymask)
- barcols.append(self.vlines(xo, lo, uo, **lines_kw))
- xlo, lowerlo = xywhere(x, lower, uplims & everymask)
- if self.yaxis_inverted():
- marker = mlines.CARETUP
- else:
- marker = mlines.CARETDOWN
- caplines.extend(
- self.plot(xlo, lowerlo, ls='None', marker=marker,
- **plot_kw))
- if capsize > 0:
- xup, yup = xywhere(x, y, uplims & everymask)
- caplines.extend(self.plot(xup, yup, 'k_', **plot_kw))
-
- if not barsabove and plot_line:
- l0, = self.plot(x, y, fmt, **kwargs)
-
- if ecolor is None:
- if l0 is None:
- ecolor = six.next(self._get_lines.color_cycle)
- else:
- ecolor = l0.get_color()
-
- for l in barcols:
- l.set_color(ecolor)
- for l in caplines:
- l.set_color(ecolor)
-
- self.autoscale_view()
- self._hold = holdstate
-
- errorbar_container = ErrorbarContainer((l0, tuple(caplines),
- tuple(barcols)),
- has_xerr=(xerr is not None),
- has_yerr=(yerr is not None),
- label=label)
- self.containers.append(errorbar_container)
-
- return errorbar_container # (l0, caplines, barcols)
-
- def boxplot(self, x, notch=False, sym=None, vert=True, whis=1.5,
- positions=None, widths=None, patch_artist=False,
- bootstrap=None, usermedians=None, conf_intervals=None,
- meanline=False, showmeans=False, showcaps=True,
- showbox=True, showfliers=True, boxprops=None, labels=None,
- flierprops=None, medianprops=None, meanprops=None,
- capprops=None, whiskerprops=None, manage_xticks=True):
- """
- Make a box and whisker plot.
-
- Call signature::
-
- boxplot(self, x, notch=False, sym='b+', vert=True, whis=1.5,
- positions=None, widths=None, patch_artist=False,
- bootstrap=None, usermedians=None, conf_intervals=None,
- meanline=False, showmeans=False, showcaps=True,
- showbox=True, showfliers=True, boxprops=None, labels=None,
- flierprops=None, medianprops=None, meanprops=None,
- capprops=None, whiskerprops=None, manage_xticks=True):
-
- Make a box and whisker plot for each column of *x* or each
- vector in sequence *x*. The box extends from the lower to
- upper quartile values of the data, with a line at the median.
- The whiskers extend from the box to show the range of the
- data. Flier points are those past the end of the whiskers.
-
- Parameters
- ----------
-
- x : Array or a sequence of vectors.
- The input data.
-
- notch : bool, default = False
- If False, produces a rectangular box plot.
- If True, will produce a notched box plot
-
- sym : str or None, default = None
- The default symbol for flier points.
- Enter an empty string ('') if you don't want to show fliers.
- If `None`, then the fliers default to 'b+' If you want more
- control use the flierprops kwarg.
-
- vert : bool, default = True
- If True (default), makes the boxes vertical.
- If False, makes horizontal boxes.
-
- whis : float, sequence (default = 1.5) or string
- As a float, determines the reach of the whiskers past the first
- and third quartiles (e.g., Q3 + whis*IQR, IQR = interquartile
- range, Q3-Q1). Beyond the whiskers, data are considered outliers
- and are plotted as individual points. Set this to an unreasonably
- high value to force the whiskers to show the min and max values.
- Alternatively, set this to an ascending sequence of percentile
- (e.g., [5, 95]) to set the whiskers at specific percentiles of
- the data. Finally, *whis* can be the string 'range' to force the
- whiskers to the min and max of the data. In the edge case that
- the 25th and 75th percentiles are equivalent, *whis* will be
- automatically set to 'range'.
-
- bootstrap : None (default) or integer
- Specifies whether to bootstrap the confidence intervals
- around the median for notched boxplots. If bootstrap==None,
- no bootstrapping is performed, and notches are calculated
- using a Gaussian-based asymptotic approximation (see McGill, R.,
- Tukey, J.W., and Larsen, W.A., 1978, and Kendall and Stuart,
- 1967). Otherwise, bootstrap specifies the number of times to
- bootstrap the median to determine it's 95% confidence intervals.
- Values between 1000 and 10000 are recommended.
-
- usermedians : array-like or None (default)
- An array or sequence whose first dimension (or length) is
- compatible with *x*. This overrides the medians computed by
- matplotlib for each element of *usermedians* that is not None.
- When an element of *usermedians* == None, the median will be
- computed by matplotlib as normal.
-
- conf_intervals : array-like or None (default)
- Array or sequence whose first dimension (or length) is compatible
- with *x* and whose second dimension is 2. When the current element
- of *conf_intervals* is not None, the notch locations computed by
- matplotlib are overridden (assuming notch is True). When an
- element of *conf_intervals* is None, boxplot compute notches the
- method specified by the other kwargs (e.g., *bootstrap*).
-
- positions : array-like, default = [1, 2, ..., n]
- Sets the positions of the boxes. The ticks and limits
- are automatically set to match the positions.
-
- widths : array-like, default = 0.5
- Either a scalar or a vector and sets the width of each box. The
- default is 0.5, or ``0.15*(distance between extreme positions)``
- if that is smaller.
-
- labels : sequence or None (default)
- Labels for each dataset. Length must be compatible with
- dimensions of *x*
-
- patch_artist : bool, default = False
- If False produces boxes with the Line2D artist
- If True produces boxes with the Patch artist
-
- showmeans : bool, default = False
- If True, will toggle one the rendering of the means
-
- showcaps : bool, default = True
- If True, will toggle one the rendering of the caps
-
- showbox : bool, default = True
- If True, will toggle one the rendering of box
-
- showfliers : bool, default = True
- If True, will toggle one the rendering of the fliers
-
- boxprops : dict or None (default)
- If provided, will set the plotting style of the boxes
-
- whiskerprops : dict or None (default)
- If provided, will set the plotting style of the whiskers
-
- capprops : dict or None (default)
- If provided, will set the plotting style of the caps
-
- flierprops : dict or None (default)
- If provided, will set the plotting style of the fliers
-
- medianprops : dict or None (default)
- If provided, will set the plotting style of the medians
-
- meanprops : dict or None (default)
- If provided, will set the plotting style of the means
-
- meanline : bool, default = False
- If True (and *showmeans* is True), will try to render the mean
- as a line spanning the full width of the box according to
- *meanprops*. Not recommended if *shownotches* is also True.
- Otherwise, means will be shown as points.
-
- Returns
- -------
-
- result : dict
- A dictionary mapping each component of the boxplot
- to a list of the :class:`matplotlib.lines.Line2D`
- instances created. That dictionary has the following keys
- (assuming vertical boxplots):
-
- - boxes: the main body of the boxplot showing the quartiles
- and the median's confidence intervals if enabled.
- - medians: horizonal lines at the median of each box.
- - whiskers: the vertical lines extending to the most extreme,
- n-outlier data points.
- - caps: the horizontal lines at the ends of the whiskers.
- - fliers: points representing data that extend beyond the
- whiskers (outliers).
- - means: points or lines representing the means.
-
- Examples
- --------
-
- .. plot:: mpl_examples/statistics/boxplot_demo.py
- """
- bxpstats = cbook.boxplot_stats(x, whis=whis, bootstrap=bootstrap,
- labels=labels)
- # make sure we have a dictionary
- if flierprops is None:
- flierprops = dict()
- # if non-default sym value, put it into the flier dictionary
- # the logic for providing the default symbol ('b+') now lives
- # in bxp in the initial value of final_flierprops
- # handle all of the `sym` related logic here so we only have to pass
- # on the flierprops dict.
- if sym is not None:
- # no-flier case, which should really be done with
- # 'showfliers=False' but none-the-less deal with it to keep back
- # compatibility
- if sym == '':
- # blow away existing dict and make one for invisible markers
- flierprops = dict(linestyle='none', marker='',
- color='none')
- # turn the fliers off just to be safe
- showfliers = False
- # now process the symbol string
- else:
- # process the symbol string
- # discarded linestyle
- _, marker, color = _process_plot_format(sym)
- # if we have a marker, use it
- if marker is not None:
- flierprops['marker'] = marker
- # if we have a color, use it
- if color is not None:
- # assume that if color is passed in the user want
- # filled symbol, if the users want more control use
- # flierprops
- flierprops['color'] = color
-
- # replace medians if necessary:
- if usermedians is not None:
- if (len(np.ravel(usermedians)) != len(bxpstats) or
- np.shape(usermedians)[0] != len(bxpstats)):
- medmsg = 'usermedians length not compatible with x'
- raise ValueError(medmsg)
- else:
- # reassign medians as necessary
- for stats, med in zip(bxpstats, usermedians):
- if med is not None:
- stats['med'] = med
-
- if conf_intervals is not None:
- if np.shape(conf_intervals)[0] != len(bxpstats):
- raise ValueError('conf_intervals length not '
- 'compatible with x')
- else:
- for stats, ci in zip(bxpstats, conf_intervals):
- if ci is not None:
- if len(ci) != 2:
- raise ValueError('each confidence interval must '
- 'have two values')
- else:
- if ci[0] is not None:
- stats['cilo'] = ci[0]
- if ci[1] is not None:
- stats['cihi'] = ci[1]
-
- artists = self.bxp(bxpstats, positions=positions, widths=widths,
- vert=vert, patch_artist=patch_artist,
- shownotches=notch, showmeans=showmeans,
- showcaps=showcaps, showbox=showbox,
- boxprops=boxprops, flierprops=flierprops,
- medianprops=medianprops, meanprops=meanprops,
- meanline=meanline, showfliers=showfliers,
- capprops=capprops, whiskerprops=whiskerprops,
- manage_xticks=manage_xticks)
- return artists
-
- def bxp(self, bxpstats, positions=None, widths=None, vert=True,
- patch_artist=False, shownotches=False, showmeans=False,
- showcaps=True, showbox=True, showfliers=True,
- boxprops=None, whiskerprops=None, flierprops=None,
- medianprops=None, capprops=None, meanprops=None,
- meanline=False, manage_xticks=True):
- """
- Drawing function for box and whisker plots.
-
- Call signature::
-
- bxp(self, bxpstats, positions=None, widths=None, vert=True,
- patch_artist=False, shownotches=False, showmeans=False,
- showcaps=True, showbox=True, showfliers=True,
- boxprops=None, whiskerprops=None, flierprops=None,
- medianprops=None, capprops=None, meanprops=None,
- meanline=False, manage_xticks=True):
-
- Make a box and whisker plot for each column of *x* or each
- vector in sequence *x*. The box extends from the lower to
- upper quartile values of the data, with a line at the median.
- The whiskers extend from the box to show the range of the
- data. Flier points are those past the end of the whiskers.
-
- Parameters
- ----------
-
- bxpstats : list of dicts
- A list of dictionaries containing stats for each boxplot.
- Required keys are:
-
- - ``med``: The median (scalar float).
-
- - ``q1``: The first quartile (25th percentile) (scalar
- float).
-
- - ``q3``: The first quartile (50th percentile) (scalar
- float).
-
- - ``whislo``: Lower bound of the lower whisker (scalar
- float).
-
- - ``whishi``: Upper bound of the upper whisker (scalar
- float).
-
- Optional keys are:
-
- - ``mean``: The mean (scalar float). Needed if
- ``showmeans=True``.
-
- - ``fliers``: Data beyond the whiskers (sequence of floats).
- Needed if ``showfliers=True``.
-
- - ``cilo`` & ``cihi``: Lower and upper confidence intervals
- about the median. Needed if ``shownotches=True``.
-
- - ``label``: Name of the dataset (string). If available,
- this will be used a tick label for the boxplot
-
- positions : array-like, default = [1, 2, ..., n]
- Sets the positions of the boxes. The ticks and limits
- are automatically set to match the positions.
-
- widths : array-like, default = 0.5
- Either a scalar or a vector and sets the width of each
- box. The default is 0.5, or ``0.15*(distance between extreme
- positions)`` if that is smaller.
-
- vert : bool, default = False
- If `True` (default), makes the boxes vertical. If `False`,
- makes horizontal boxes.
-
- patch_artist : bool, default = False
- If `False` produces boxes with the
- `~matplotlib.lines.Line2D` artist. If `True` produces boxes
- with the `~matplotlib.patches.Patch` artist.
-
- shownotches : bool, default = False
- If `False` (default), produces a rectangular box plot.
- If `True`, will produce a notched box plot
-
- showmeans : bool, default = False
- If `True`, will toggle one the rendering of the means
-
- showcaps : bool, default = True
- If `True`, will toggle one the rendering of the caps
-
- showbox : bool, default = True
- If `True`, will toggle one the rendering of box
-
- showfliers : bool, default = True
- If `True`, will toggle one the rendering of the fliers
-
- boxprops : dict or None (default)
- If provided, will set the plotting style of the boxes
-
- whiskerprops : dict or None (default)
- If provided, will set the plotting style of the whiskers
-
- capprops : dict or None (default)
- If provided, will set the plotting style of the caps
-
- flierprops : dict or None (default)
- If provided will set the plotting style of the fliers
-
- medianprops : dict or None (default)
- If provided, will set the plotting style of the medians
-
- meanprops : dict or None (default)
- If provided, will set the plotting style of the means
-
- meanline : bool, default = False
- If `True` (and *showmeans* is `True`), will try to render the mean
- as a line spanning the full width of the box according to
- *meanprops*. Not recommended if *shownotches* is also True.
- Otherwise, means will be shown as points.
-
- manage_xticks : bool, default = True
- If the function should adjust the xlim and xtick locations.
-
- Returns
- -------
- result : dict
- A dictionary mapping each component of the boxplot to a list
- of the :class:`matplotlib.lines.Line2D` instances
- created. That dictionary has the following keys (assuming
- vertical boxplots):
-
- - ``boxes``: the main body of the boxplot showing the
- quartiles and the median's confidence intervals if
- enabled.
-
- - ``medians``: horizonal lines at the median of each box.
-
- - ``whiskers``: the vertical lines extending to the most
- extreme, n-outlier data points.
-
- - ``caps``: the horizontal lines at the ends of the
- whiskers.
-
- - ``fliers``: points representing data that extend beyond
- the whiskers (fliers).
-
- - ``means``: points or lines representing the means.
-
- Examples
- --------
-
- .. plot:: mpl_examples/statistics/bxp_demo.py
-
- """
- # lists of artists to be output
- whiskers = []
- caps = []
- boxes = []
- medians = []
- means = []
- fliers = []
-
- # empty list of xticklabels
- datalabels = []
-
- # translates between line2D and patch linestyles
- linestyle_map = {
- 'solid': '-',
- 'dashed': '--',
- 'dashdot': '-.',
- 'dotted': ':'
- }
-
- # box properties
- if patch_artist:
- final_boxprops = dict(linestyle='solid', edgecolor='black',
- facecolor='white', linewidth=1)
- else:
- final_boxprops = dict(linestyle='-', color='blue')
-
- if boxprops is not None:
- final_boxprops.update(boxprops)
-
- # other (cap, whisker) properties
- final_whiskerprops = dict(
- linestyle='--',
- color='blue',
- )
-
- final_capprops = dict(
- linestyle='-',
- color='black',
- )
-
- if capprops is not None:
- final_capprops.update(capprops)
-
- if whiskerprops is not None:
- final_whiskerprops.update(whiskerprops)
-
- # set up the default flier properties
- final_flierprops = dict(linestyle='none', marker='+', color='blue')
-
- # flier (outlier) properties
- if flierprops is not None:
- final_flierprops.update(flierprops)
-
- # median line properties
- final_medianprops = dict(linestyle='-', color='red')
- if medianprops is not None:
- final_medianprops.update(medianprops)
-
- # mean (line or point) properties
- if meanline:
- final_meanprops = dict(linestyle='--', color='black')
- else:
- final_meanprops = dict(linestyle='none', markerfacecolor='red',
- marker='s')
- if meanprops is not None:
- final_meanprops.update(meanprops)
-
- def to_vc(xs, ys):
- # convert arguments to verts and codes
- verts = []
- #codes = []
- for xi, yi in zip(xs, ys):
- verts.append((xi, yi))
- verts.append((0, 0)) # ignored
- codes = [mpath.Path.MOVETO] + \
- [mpath.Path.LINETO] * (len(verts) - 2) + \
- [mpath.Path.CLOSEPOLY]
- return verts, codes
-
- def patch_list(xs, ys, **kwargs):
- verts, codes = to_vc(xs, ys)
- path = mpath.Path(verts, codes)
- patch = mpatches.PathPatch(path, **kwargs)
- self.add_artist(patch)
- return [patch]
-
- # vertical or horizontal plot?
- if vert:
- def doplot(*args, **kwargs):
- return self.plot(*args, **kwargs)
-
- def dopatch(xs, ys, **kwargs):
- return patch_list(xs, ys, **kwargs)
-
- else:
- def doplot(*args, **kwargs):
- shuffled = []
- for i in xrange(0, len(args), 2):
- shuffled.extend([args[i + 1], args[i]])
- return self.plot(*shuffled, **kwargs)
-
- def dopatch(xs, ys, **kwargs):
- xs, ys = ys, xs # flip X, Y
- return patch_list(xs, ys, **kwargs)
-
- # input validation
- N = len(bxpstats)
- datashape_message = ("List of boxplot statistics and `{0}` "
- "values must have same the length")
- # check position
- if positions is None:
- positions = list(xrange(1, N + 1))
- elif len(positions) != N:
- raise ValueError(datashape_message.format("positions"))
-
- # width
- if widths is None:
- distance = max(positions) - min(positions)
- widths = [min(0.15 * max(distance, 1.0), 0.5)] * N
- elif np.isscalar(widths):
- widths = [widths] * N
- elif len(widths) != N:
- raise ValueError(datashape_message.format("widths"))
-
- # check and save the `hold` state of the current axes
- if not self._hold:
- self.cla()
- holdStatus = self._hold
- for pos, width, stats in zip(positions, widths, bxpstats):
- # try to find a new label
- datalabels.append(stats.get('label', pos))
- # fliers coords
- flier_x = np.ones(len(stats['fliers'])) * pos
- flier_y = stats['fliers']
-
- # whisker coords
- whisker_x = np.ones(2) * pos
- whiskerlo_y = np.array([stats['q1'], stats['whislo']])
- whiskerhi_y = np.array([stats['q3'], stats['whishi']])
-
- # cap coords
- cap_left = pos - width * 0.25
- cap_right = pos + width * 0.25
- cap_x = np.array([cap_left, cap_right])
- cap_lo = np.ones(2) * stats['whislo']
- cap_hi = np.ones(2) * stats['whishi']
-
- # box and median coords
- box_left = pos - width * 0.5
- box_right = pos + width * 0.5
- med_y = [stats['med'], stats['med']]
-
- # notched boxes
- if shownotches:
- box_x = [box_left, box_right, box_right, cap_right, box_right,
- box_right, box_left, box_left, cap_left, box_left,
- box_left]
- box_y = [stats['q1'], stats['q1'], stats['cilo'],
- stats['med'], stats['cihi'], stats['q3'],
- stats['q3'], stats['cihi'], stats['med'],
- stats['cilo'], stats['q1']]
- med_x = cap_x
-
- # plain boxes
- else:
- box_x = [box_left, box_right, box_right, box_left, box_left]
- box_y = [stats['q1'], stats['q1'], stats['q3'], stats['q3'],
- stats['q1']]
- med_x = [box_left, box_right]
-
- # maybe draw the box:
- if showbox:
- if patch_artist:
- boxes.extend(dopatch(box_x, box_y, **final_boxprops))
- else:
- boxes.extend(doplot(box_x, box_y, **final_boxprops))
-
- # draw the whiskers
- whiskers.extend(doplot(
- whisker_x, whiskerlo_y, **final_whiskerprops
- ))
- whiskers.extend(doplot(
- whisker_x, whiskerhi_y, **final_whiskerprops
- ))
-
- # maybe draw the caps:
- if showcaps:
- caps.extend(doplot(cap_x, cap_lo, **final_capprops))
- caps.extend(doplot(cap_x, cap_hi, **final_capprops))
-
- # draw the medians
- medians.extend(doplot(med_x, med_y, **final_medianprops))
-
- # maybe draw the means
- if showmeans:
- if meanline:
- means.extend(doplot(
- [box_left, box_right], [stats['mean'], stats['mean']],
- **final_meanprops
- ))
- else:
- means.extend(doplot(
- [pos], [stats['mean']], **final_meanprops
- ))
-
- # maybe draw the fliers
- if showfliers:
- fliers.extend(doplot(
- flier_x, flier_y, **final_flierprops
- ))
-
- # fix our axes/ticks up a little
- if vert:
- setticks = self.set_xticks
- setlim = self.set_xlim
- setlabels = self.set_xticklabels
- else:
- setticks = self.set_yticks
- setlim = self.set_ylim
- setlabels = self.set_yticklabels
-
- if manage_xticks:
- newlimits = min(positions) - 0.5, max(positions) + 0.5
- setlim(newlimits)
- setticks(positions)
- setlabels(datalabels)
-
- # reset hold status
- self.hold(holdStatus)
-
- return dict(whiskers=whiskers, caps=caps, boxes=boxes,
- medians=medians, fliers=fliers, means=means)
-
- @docstring.dedent_interpd
- def scatter(self, x, y, s=20, c='b', marker='o', cmap=None, norm=None,
- vmin=None, vmax=None, alpha=None, linewidths=None,
- verts=None, **kwargs):
- """
- Make a scatter plot of x vs y, where x and y are sequence like objects
- of the same lengths.
-
- Parameters
- ----------
- x, y : array_like, shape (n, )
- Input data
-
- s : scalar or array_like, shape (n, ), optional, default: 20
- size in points^2.
-
- c : color or sequence of color, optional, default : 'b'
- `c` can be a single color format string, or a sequence of color
- specifications of length `N`, or a sequence of `N` numbers to be
- mapped to colors using the `cmap` and `norm` specified via kwargs
- (see below). Note that `c` should not be a single numeric RGB or
- RGBA sequence because that is indistinguishable from an array of
- values to be colormapped. `c` can be a 2-D array in which the
- rows are RGB or RGBA, however.
-
- marker : `~matplotlib.markers.MarkerStyle`, optional, default: 'o'
- See `~matplotlib.markers` for more information on the different
- styles of markers scatter supports.
-
- cmap : `~matplotlib.colors.Colormap`, optional, default: None
- A `~matplotlib.colors.Colormap` instance or registered name.
- `cmap` is only used if `c` is an array of floats. If None,
- defaults to rc `image.cmap`.
-
- norm : `~matplotlib.colors.Normalize`, optional, default: None
- A `~matplotlib.colors.Normalize` instance is used to scale
- luminance data to 0, 1. `norm` is only used if `c` is an array of
- floats. If `None`, use the default :func:`normalize`.
-
- vmin, vmax : scalar, optional, default: None
- `vmin` and `vmax` are used in conjunction with `norm` to normalize
- luminance data. If either are `None`, the min and max of the
- color array is used. Note if you pass a `norm` instance, your
- settings for `vmin` and `vmax` will be ignored.
-
- alpha : scalar, optional, default: None
- The alpha blending value, between 0 (transparent) and 1 (opaque)
-
- linewidths : scalar or array_like, optional, default: None
- If None, defaults to (lines.linewidth,). Note that this is a
- tuple, and if you set the linewidths argument you must set it as a
- sequence of floats, as required by
- `~matplotlib.collections.RegularPolyCollection`.
-
- Returns
- -------
- paths : `~matplotlib.collections.PathCollection`
-
- Other parameters
- ----------------
- kwargs : `~matplotlib.collections.Collection` properties
-
- Notes
- ------
- Any or all of `x`, `y`, `s`, and `c` may be masked arrays, in
- which case all masks will be combined and only unmasked points
- will be plotted.
-
- Examples
- --------
- .. plot:: mpl_examples/shapes_and_collections/scatter_demo.py
-
- """
-
- if not self._hold:
- self.cla()
-
- self._process_unit_info(xdata=x, ydata=y, kwargs=kwargs)
- x = self.convert_xunits(x)
- y = self.convert_yunits(y)
-
- # np.ma.ravel yields an ndarray, not a masked array,
- # unless its argument is a masked array.
- x = np.ma.ravel(x)
- y = np.ma.ravel(y)
- if x.size != y.size:
- raise ValueError("x and y must be the same size")
-
- s = np.ma.ravel(s) # This doesn't have to match x, y in size.
-
- c_is_stringy = is_string_like(c) or is_sequence_of_strings(c)
- if not c_is_stringy:
- c = np.asanyarray(c)
- if c.size == x.size:
- c = np.ma.ravel(c)
-
- x, y, s, c = cbook.delete_masked_points(x, y, s, c)
-
- scales = s # Renamed for readability below.
-
- if c_is_stringy:
- colors = mcolors.colorConverter.to_rgba_array(c, alpha)
- else:
- # The inherent ambiguity is resolved in favor of color
- # mapping, not interpretation as rgb or rgba:
- if c.size == x.size:
- colors = None # use cmap, norm after collection is created
- else:
- colors = mcolors.colorConverter.to_rgba_array(c, alpha)
-
- faceted = kwargs.pop('faceted', None)
- edgecolors = kwargs.get('edgecolors', None)
- if faceted is not None:
- cbook.warn_deprecated(
- '1.2', name='faceted', alternative='edgecolor',
- obj_type='option')
- if faceted:
- edgecolors = None
- else:
- edgecolors = 'none'
-
- # to be API compatible
- if marker is None and not (verts is None):
- marker = (verts, 0)
- verts = None
-
- marker_obj = mmarkers.MarkerStyle(marker)
- path = marker_obj.get_path().transformed(
- marker_obj.get_transform())
- if not marker_obj.is_filled():
- edgecolors = 'face'
-
- offsets = np.dstack((x, y))
-
- collection = mcoll.PathCollection(
- (path,), scales,
- facecolors=colors,
- edgecolors=edgecolors,
- linewidths=linewidths,
- offsets=offsets,
- transOffset=kwargs.pop('transform', self.transData),
- )
- collection.set_transform(mtransforms.IdentityTransform())
- collection.set_alpha(alpha)
- collection.update(kwargs)
-
- if colors is None:
- if norm is not None:
- assert(isinstance(norm, mcolors.Normalize))
- collection.set_array(np.asarray(c))
- collection.set_cmap(cmap)
- collection.set_norm(norm)
-
- if vmin is not None or vmax is not None:
- collection.set_clim(vmin, vmax)
- else:
- collection.autoscale_None()
-
- # The margin adjustment is a hack to deal with the fact that we don't
- # want to transform all the symbols whose scales are in points
- # to data coords to get the exact bounding box for efficiency
- # reasons. It can be done right if this is deemed important.
- # Also, only bother with this padding if there is anything to draw.
- if self._xmargin < 0.05 and x.size > 0:
- self.set_xmargin(0.05)
-
- if self._ymargin < 0.05 and x.size > 0:
- self.set_ymargin(0.05)
-
- self.add_collection(collection)
- self.autoscale_view()
-
- return collection
-
- @docstring.dedent_interpd
- def hexbin(self, x, y, C=None, gridsize=100, bins=None,
- xscale='linear', yscale='linear', extent=None,
- cmap=None, norm=None, vmin=None, vmax=None,
- alpha=None, linewidths=None, edgecolors='none',
- reduce_C_function=np.mean, mincnt=None, marginals=False,
- **kwargs):
- """
- Make a hexagonal binning plot.
-
- Call signature::
-
- hexbin(x, y, C = None, gridsize = 100, bins = None,
- xscale = 'linear', yscale = 'linear',
- cmap=None, norm=None, vmin=None, vmax=None,
- alpha=None, linewidths=None, edgecolors='none'
- reduce_C_function = np.mean, mincnt=None, marginals=True
- **kwargs)
-
- Make a hexagonal binning plot of *x* versus *y*, where *x*,
- *y* are 1-D sequences of the same length, *N*. If *C* is *None*
- (the default), this is a histogram of the number of occurences
- of the observations at (x[i],y[i]).
-
- If *C* is specified, it specifies values at the coordinate
- (x[i],y[i]). These values are accumulated for each hexagonal
- bin and then reduced according to *reduce_C_function*, which
- defaults to numpy's mean function (np.mean). (If *C* is
- specified, it must also be a 1-D sequence of the same length
- as *x* and *y*.)
-
- *x*, *y* and/or *C* may be masked arrays, in which case only
- unmasked points will be plotted.
-
- Optional keyword arguments:
-
- *gridsize*: [ 100 | integer ]
- The number of hexagons in the *x*-direction, default is
- 100. The corresponding number of hexagons in the
- *y*-direction is chosen such that the hexagons are
- approximately regular. Alternatively, gridsize can be a
- tuple with two elements specifying the number of hexagons
- in the *x*-direction and the *y*-direction.
-
- *bins*: [ *None* | 'log' | integer | sequence ]
- If *None*, no binning is applied; the color of each hexagon
- directly corresponds to its count value.
-
- If 'log', use a logarithmic scale for the color
- map. Internally, :math:`log_{10}(i+1)` is used to
- determine the hexagon color.
-
- If an integer, divide the counts in the specified number
- of bins, and color the hexagons accordingly.
-
- If a sequence of values, the values of the lower bound of
- the bins to be used.
-
- *xscale*: [ 'linear' | 'log' ]
- Use a linear or log10 scale on the horizontal axis.
-
- *scale*: [ 'linear' | 'log' ]
- Use a linear or log10 scale on the vertical axis.
-
- *mincnt*: [ *None* | a positive integer ]
- If not *None*, only display cells with more than *mincnt*
- number of points in the cell
-
- *marginals*: [ *True* | *False* ]
- if marginals is *True*, plot the marginal density as
- colormapped rectagles along the bottom of the x-axis and
- left of the y-axis
-
- *extent*: [ *None* | scalars (left, right, bottom, top) ]
- The limits of the bins. The default assigns the limits
- based on gridsize, x, y, xscale and yscale.
-
- Other keyword arguments controlling color mapping and normalization
- arguments:
-
- *cmap*: [ *None* | Colormap ]
- a :class:`matplotlib.colors.Colormap` instance. If *None*,
- defaults to rc ``image.cmap``.
-
- *norm*: [ *None* | Normalize ]
- :class:`matplotlib.colors.Normalize` instance is used to
- scale luminance data to 0,1.
-
- *vmin* / *vmax*: scalar
- *vmin* and *vmax* are used in conjunction with *norm* to normalize
- luminance data. If either are *None*, the min and max of the color
- array *C* is used. Note if you pass a norm instance, your settings
- for *vmin* and *vmax* will be ignored.
-
- *alpha*: scalar between 0 and 1, or *None*
- the alpha value for the patches
-
- *linewidths*: [ *None* | scalar ]
- If *None*, defaults to rc lines.linewidth. Note that this
- is a tuple, and if you set the linewidths argument you
- must set it as a sequence of floats, as required by
- :class:`~matplotlib.collections.RegularPolyCollection`.
-
- Other keyword arguments controlling the Collection properties:
-
- *edgecolors*: [ *None* | ``'none'`` | mpl color | color sequence ]
- If ``'none'``, draws the edges in the same color as the fill color.
- This is the default, as it avoids unsightly unpainted pixels
- between the hexagons.
-
- If *None*, draws the outlines in the default color.
-
- If a matplotlib color arg or sequence of rgba tuples, draws the
- outlines in the specified color.
-
- Here are the standard descriptions of all the
- :class:`~matplotlib.collections.Collection` kwargs:
-
- %(Collection)s
-
- The return value is a
- :class:`~matplotlib.collections.PolyCollection` instance; use
- :meth:`~matplotlib.collections.PolyCollection.get_array` on
- this :class:`~matplotlib.collections.PolyCollection` to get
- the counts in each hexagon. If *marginals* is *True*, horizontal
- bar and vertical bar (both PolyCollections) will be attached
- to the return collection as attributes *hbar* and *vbar*.
-
-
- **Example:**
-
- .. plot:: mpl_examples/pylab_examples/hexbin_demo.py
-
- """
-
- if not self._hold:
- self.cla()
-
- self._process_unit_info(xdata=x, ydata=y, kwargs=kwargs)
-
- x, y, C = cbook.delete_masked_points(x, y, C)
-
- # Set the size of the hexagon grid
- if iterable(gridsize):
- nx, ny = gridsize
- else:
- nx = gridsize
- ny = int(nx / math.sqrt(3))
- # Count the number of data in each hexagon
- x = np.array(x, float)
- y = np.array(y, float)
- if xscale == 'log':
- if np.any(x <= 0.0):
- raise ValueError("x contains non-positive values, so can not"
- " be log-scaled")
- x = np.log10(x)
- if yscale == 'log':
- if np.any(y <= 0.0):
- raise ValueError("y contains non-positive values, so can not"
- " be log-scaled")
- y = np.log10(y)
- if extent is not None:
- xmin, xmax, ymin, ymax = extent
- else:
- xmin = np.amin(x)
- xmax = np.amax(x)
- ymin = np.amin(y)
- ymax = np.amax(y)
- # to avoid issues with singular data, expand the min/max pairs
- xmin, xmax = mtrans.nonsingular(xmin, xmax, expander=0.1)
- ymin, ymax = mtrans.nonsingular(ymin, ymax, expander=0.1)
-
- # In the x-direction, the hexagons exactly cover the region from
- # xmin to xmax. Need some padding to avoid roundoff errors.
- padding = 1.e-9 * (xmax - xmin)
- xmin -= padding
- xmax += padding
- sx = (xmax - xmin) / nx
- sy = (ymax - ymin) / ny
-
- if marginals:
- xorig = x.copy()
- yorig = y.copy()
-
- x = (x - xmin) / sx
- y = (y - ymin) / sy
- ix1 = np.round(x).astype(int)
- iy1 = np.round(y).astype(int)
- ix2 = np.floor(x).astype(int)
- iy2 = np.floor(y).astype(int)
-
- nx1 = nx + 1
- ny1 = ny + 1
- nx2 = nx
- ny2 = ny
- n = nx1 * ny1 + nx2 * ny2
-
- d1 = (x - ix1) ** 2 + 3.0 * (y - iy1) ** 2
- d2 = (x - ix2 - 0.5) ** 2 + 3.0 * (y - iy2 - 0.5) ** 2
- bdist = (d1 < d2)
- if C is None:
- accum = np.zeros(n)
- # Create appropriate views into "accum" array.
- lattice1 = accum[:nx1 * ny1]
- lattice2 = accum[nx1 * ny1:]
- lattice1.shape = (nx1, ny1)
- lattice2.shape = (nx2, ny2)
-
- for i in xrange(len(x)):
- if bdist[i]:
- if ((ix1[i] >= 0) and (ix1[i] < nx1) and
- (iy1[i] >= 0) and (iy1[i] < ny1)):
- lattice1[ix1[i], iy1[i]] += 1
- else:
- if ((ix2[i] >= 0) and (ix2[i] < nx2) and
- (iy2[i] >= 0) and (iy2[i] < ny2)):
- lattice2[ix2[i], iy2[i]] += 1
-
- # threshold
- if mincnt is not None:
- for i in xrange(nx1):
- for j in xrange(ny1):
- if lattice1[i, j] < mincnt:
- lattice1[i, j] = np.nan
- for i in xrange(nx2):
- for j in xrange(ny2):
- if lattice2[i, j] < mincnt:
- lattice2[i, j] = np.nan
- accum = np.hstack((lattice1.astype(float).ravel(),
- lattice2.astype(float).ravel()))
- good_idxs = ~np.isnan(accum)
-
- else:
- if mincnt is None:
- mincnt = 0
-
- # create accumulation arrays
- lattice1 = np.empty((nx1, ny1), dtype=object)
- for i in xrange(nx1):
- for j in xrange(ny1):
- lattice1[i, j] = []
- lattice2 = np.empty((nx2, ny2), dtype=object)
- for i in xrange(nx2):
- for j in xrange(ny2):
- lattice2[i, j] = []
-
- for i in xrange(len(x)):
- if bdist[i]:
- if ((ix1[i] >= 0) and (ix1[i] < nx1) and
- (iy1[i] >= 0) and (iy1[i] < ny1)):
- lattice1[ix1[i], iy1[i]].append(C[i])
- else:
- if ((ix2[i] >= 0) and (ix2[i] < nx2) and
- (iy2[i] >= 0) and (iy2[i] < ny2)):
- lattice2[ix2[i], iy2[i]].append(C[i])
-
- for i in xrange(nx1):
- for j in xrange(ny1):
- vals = lattice1[i, j]
- if len(vals) > mincnt:
- lattice1[i, j] = reduce_C_function(vals)
- else:
- lattice1[i, j] = np.nan
- for i in xrange(nx2):
- for j in xrange(ny2):
- vals = lattice2[i, j]
- if len(vals) > mincnt:
- lattice2[i, j] = reduce_C_function(vals)
- else:
- lattice2[i, j] = np.nan
-
- accum = np.hstack((lattice1.astype(float).ravel(),
- lattice2.astype(float).ravel()))
- good_idxs = ~np.isnan(accum)
-
- offsets = np.zeros((n, 2), float)
- offsets[:nx1 * ny1, 0] = np.repeat(np.arange(nx1), ny1)
- offsets[:nx1 * ny1, 1] = np.tile(np.arange(ny1), nx1)
- offsets[nx1 * ny1:, 0] = np.repeat(np.arange(nx2) + 0.5, ny2)
- offsets[nx1 * ny1:, 1] = np.tile(np.arange(ny2), nx2) + 0.5
- offsets[:, 0] *= sx
- offsets[:, 1] *= sy
- offsets[:, 0] += xmin
- offsets[:, 1] += ymin
- # remove accumulation bins with no data
- offsets = offsets[good_idxs, :]
- accum = accum[good_idxs]
-
- polygon = np.zeros((6, 2), float)
- polygon[:, 0] = sx * np.array([0.5, 0.5, 0.0, -0.5, -0.5, 0.0])
- polygon[:, 1] = sy * np.array([-0.5, 0.5, 1.0, 0.5, -0.5, -1.0]) / 3.0
-
- if edgecolors == 'none':
- edgecolors = 'face'
-
- if xscale == 'log' or yscale == 'log':
- polygons = np.expand_dims(polygon, 0) + np.expand_dims(offsets, 1)
- if xscale == 'log':
- polygons[:, :, 0] = 10.0 ** polygons[:, :, 0]
- xmin = 10.0 ** xmin
- xmax = 10.0 ** xmax
- self.set_xscale(xscale)
- if yscale == 'log':
- polygons[:, :, 1] = 10.0 ** polygons[:, :, 1]
- ymin = 10.0 ** ymin
- ymax = 10.0 ** ymax
- self.set_yscale(yscale)
- collection = mcoll.PolyCollection(
- polygons,
- edgecolors=edgecolors,
- linewidths=linewidths,
- )
- else:
- collection = mcoll.PolyCollection(
- [polygon],
- edgecolors=edgecolors,
- linewidths=linewidths,
- offsets=offsets,
- transOffset=mtransforms.IdentityTransform(),
- offset_position="data"
- )
-
- if isinstance(norm, mcolors.LogNorm):
- if (accum == 0).any():
- # make sure we have not zeros
- accum += 1
-
- # autoscale the norm with curren accum values if it hasn't
- # been set
- if norm is not None:
- if norm.vmin is None and norm.vmax is None:
- norm.autoscale(accum)
-
- # Transform accum if needed
- if bins == 'log':
- accum = np.log10(accum + 1)
- elif bins is not None:
- if not iterable(bins):
- minimum, maximum = min(accum), max(accum)
- bins -= 1 # one less edge than bins
- bins = minimum + (maximum - minimum) * np.arange(bins) / bins
- bins = np.sort(bins)
- accum = bins.searchsorted(accum)
-
- if norm is not None:
- assert(isinstance(norm, mcolors.Normalize))
- collection.set_array(accum)
- collection.set_cmap(cmap)
- collection.set_norm(norm)
- collection.set_alpha(alpha)
- collection.update(kwargs)
-
- if vmin is not None or vmax is not None:
- collection.set_clim(vmin, vmax)
- else:
- collection.autoscale_None()
-
- corners = ((xmin, ymin), (xmax, ymax))
- self.update_datalim(corners)
- self.autoscale_view(tight=True)
-
- # add the collection last
- self.add_collection(collection, autolim=False)
- if not marginals:
- return collection
-
- if C is None:
- C = np.ones(len(x))
-
- def coarse_bin(x, y, coarse):
- ind = coarse.searchsorted(x).clip(0, len(coarse) - 1)
- mus = np.zeros(len(coarse))
- for i in range(len(coarse)):
- mu = reduce_C_function(y[ind == i])
- mus[i] = mu
- return mus
-
- coarse = np.linspace(xmin, xmax, gridsize)
-
- xcoarse = coarse_bin(xorig, C, coarse)
- valid = ~np.isnan(xcoarse)
- verts, values = [], []
- for i, val in enumerate(xcoarse):
- thismin = coarse[i]
- if i < len(coarse) - 1:
- thismax = coarse[i + 1]
- else:
- thismax = thismin + np.diff(coarse)[-1]
-
- if not valid[i]:
- continue
-
- verts.append([(thismin, 0),
- (thismin, 0.05),
- (thismax, 0.05),
- (thismax, 0)])
- values.append(val)
-
- values = np.array(values)
- trans = self.get_xaxis_transform(which='grid')
-
- hbar = mcoll.PolyCollection(verts, transform=trans, edgecolors='face')
-
- hbar.set_array(values)
- hbar.set_cmap(cmap)
- hbar.set_norm(norm)
- hbar.set_alpha(alpha)
- hbar.update(kwargs)
- self.add_collection(hbar, autolim=False)
-
- coarse = np.linspace(ymin, ymax, gridsize)
- ycoarse = coarse_bin(yorig, C, coarse)
- valid = ~np.isnan(ycoarse)
- verts, values = [], []
- for i, val in enumerate(ycoarse):
- thismin = coarse[i]
- if i < len(coarse) - 1:
- thismax = coarse[i + 1]
- else:
- thismax = thismin + np.diff(coarse)[-1]
- if not valid[i]:
- continue
- verts.append([(0, thismin), (0.0, thismax),
- (0.05, thismax), (0.05, thismin)])
- values.append(val)
-
- values = np.array(values)
-
- trans = self.get_yaxis_transform(which='grid')
-
- vbar = mcoll.PolyCollection(verts, transform=trans, edgecolors='face')
- vbar.set_array(values)
- vbar.set_cmap(cmap)
- vbar.set_norm(norm)
- vbar.set_alpha(alpha)
- vbar.update(kwargs)
- self.add_collection(vbar, autolim=False)
-
- collection.hbar = hbar
- collection.vbar = vbar
-
- def on_changed(collection):
- hbar.set_cmap(collection.get_cmap())
- hbar.set_clim(collection.get_clim())
- vbar.set_cmap(collection.get_cmap())
- vbar.set_clim(collection.get_clim())
-
- collection.callbacksSM.connect('changed', on_changed)
-
- return collection
-
- @docstring.dedent_interpd
- def arrow(self, x, y, dx, dy, **kwargs):
- """
- Add an arrow to the axes.
-
- Call signature::
-
- arrow(x, y, dx, dy, **kwargs)
-
- Draws arrow on specified axis from (*x*, *y*) to (*x* + *dx*,
- *y* + *dy*). Uses FancyArrow patch to construct the arrow.
-
- The resulting arrow is affected by the axes aspect ratio and limits.
- This may produce an arrow whose head is not square with its stem. To
- create an arrow whose head is square with its stem, use
- :meth:`annotate` for example::
-
- ax.annotate("", xy=(0.5, 0.5), xytext=(0, 0),
- arrowprops=dict(arrowstyle="->"))
-
- Optional kwargs control the arrow construction and properties:
-
- %(FancyArrow)s
-
- **Example:**
-
- .. plot:: mpl_examples/pylab_examples/arrow_demo.py
- """
- # Strip away units for the underlying patch since units
- # do not make sense to most patch-like code
- x = self.convert_xunits(x)
- y = self.convert_yunits(y)
- dx = self.convert_xunits(dx)
- dy = self.convert_yunits(dy)
-
- a = mpatches.FancyArrow(x, y, dx, dy, **kwargs)
- self.add_artist(a)
- return a
-
- def quiverkey(self, *args, **kw):
- qk = mquiver.QuiverKey(*args, **kw)
- self.add_artist(qk)
- return qk
- quiverkey.__doc__ = mquiver.QuiverKey.quiverkey_doc
-
- def quiver(self, *args, **kw):
- if not self._hold:
- self.cla()
- q = mquiver.Quiver(self, *args, **kw)
-
- self.add_collection(q, autolim=True)
- self.autoscale_view()
- return q
- quiver.__doc__ = mquiver.Quiver.quiver_doc
-
- def stackplot(self, x, *args, **kwargs):
- return mstack.stackplot(self, x, *args, **kwargs)
- stackplot.__doc__ = mstack.stackplot.__doc__
-
- def streamplot(self, x, y, u, v, density=1, linewidth=None, color=None,
- cmap=None, norm=None, arrowsize=1, arrowstyle='-|>',
- minlength=0.1, transform=None, zorder=1):
- if not self._hold:
- self.cla()
- stream_container = mstream.streamplot(self, x, y, u, v,
- density=density,
- linewidth=linewidth,
- color=color,
- cmap=cmap,
- norm=norm,
- arrowsize=arrowsize,
- arrowstyle=arrowstyle,
- minlength=minlength,
- transform=transform,
- zorder=zorder)
- return stream_container
- streamplot.__doc__ = mstream.streamplot.__doc__
-
- @docstring.dedent_interpd
- def barbs(self, *args, **kw):
- """
- %(barbs_doc)s
-
- **Example:**
-
- .. plot:: mpl_examples/pylab_examples/barb_demo.py
- """
- if not self._hold:
- self.cla()
- b = mquiver.Barbs(self, *args, **kw)
- self.add_collection(b, autolim=True)
- self.autoscale_view()
- return b
-
- @docstring.dedent_interpd
- def fill(self, *args, **kwargs):
- """
- Plot filled polygons.
-
- Call signature::
-
- fill(*args, **kwargs)
-
- *args* is a variable length argument, allowing for multiple
- *x*, *y* pairs with an optional color format string; see
- :func:`~matplotlib.pyplot.plot` for details on the argument
- parsing. For example, to plot a polygon with vertices at *x*,
- *y* in blue.::
-
- ax.fill(x,y, 'b' )
-
- An arbitrary number of *x*, *y*, *color* groups can be specified::
-
- ax.fill(x1, y1, 'g', x2, y2, 'r')
-
- Return value is a list of :class:`~matplotlib.patches.Patch`
- instances that were added.
-
- The same color strings that :func:`~matplotlib.pyplot.plot`
- supports are supported by the fill format string.
-
- If you would like to fill below a curve, e.g., shade a region
- between 0 and *y* along *x*, use :meth:`fill_between`
-
- The *closed* kwarg will close the polygon when *True* (default).
-
- kwargs control the :class:`~matplotlib.patches.Polygon` properties:
-
- %(Polygon)s
-
- **Example:**
-
- .. plot:: mpl_examples/lines_bars_and_markers/fill_demo.py
-
- """
- if not self._hold:
- self.cla()
-
- patches = []
- for poly in self._get_patches_for_fill(*args, **kwargs):
- self.add_patch(poly)
- patches.append(poly)
- self.autoscale_view()
- return patches
-
- @docstring.dedent_interpd
- def fill_between(self, x, y1, y2=0, where=None, interpolate=False,
- **kwargs):
- """
- Make filled polygons between two curves.
-
- Call signature::
-
- fill_between(x, y1, y2=0, where=None, **kwargs)
-
- Create a :class:`~matplotlib.collections.PolyCollection`
- filling the regions between *y1* and *y2* where
- ``where==True``
-
- *x* :
- An N-length array of the x data
-
- *y1* :
- An N-length array (or scalar) of the y data
-
- *y2* :
- An N-length array (or scalar) of the y data
-
- *where* :
- If *None*, default to fill between everywhere. If not *None*,
- it is an N-length numpy boolean array and the fill will
- only happen over the regions where ``where==True``.
-
- *interpolate* :
- If *True*, interpolate between the two lines to find the
- precise point of intersection. Otherwise, the start and
- end points of the filled region will only occur on explicit
- values in the *x* array.
-
- *kwargs* :
- Keyword args passed on to the
- :class:`~matplotlib.collections.PolyCollection`.
-
- kwargs control the :class:`~matplotlib.patches.Polygon` properties:
-
- %(PolyCollection)s
-
- .. plot:: mpl_examples/pylab_examples/fill_between_demo.py
-
- .. seealso::
-
- :meth:`fill_betweenx`
- for filling between two sets of x-values
-
- """
- # Handle united data, such as dates
- self._process_unit_info(xdata=x, ydata=y1, kwargs=kwargs)
- self._process_unit_info(ydata=y2)
-
- # Convert the arrays so we can work with them
- x = ma.masked_invalid(self.convert_xunits(x))
- y1 = ma.masked_invalid(self.convert_yunits(y1))
- y2 = ma.masked_invalid(self.convert_yunits(y2))
-
- if y1.ndim == 0:
- y1 = np.ones_like(x) * y1
- if y2.ndim == 0:
- y2 = np.ones_like(x) * y2
-
- if where is None:
- where = np.ones(len(x), np.bool)
- else:
- where = np.asarray(where, np.bool)
-
- if not (x.shape == y1.shape == y2.shape == where.shape):
- raise ValueError("Argument dimensions are incompatible")
-
- mask = reduce(ma.mask_or, [ma.getmask(a) for a in (x, y1, y2)])
- if mask is not ma.nomask:
- where &= ~mask
-
- polys = []
- for ind0, ind1 in mlab.contiguous_regions(where):
- xslice = x[ind0:ind1]
- y1slice = y1[ind0:ind1]
- y2slice = y2[ind0:ind1]
-
- if not len(xslice):
- continue
-
- N = len(xslice)
- X = np.zeros((2 * N + 2, 2), np.float)
-
- if interpolate:
- def get_interp_point(ind):
- im1 = max(ind - 1, 0)
- x_values = x[im1:ind + 1]
- diff_values = y1[im1:ind + 1] - y2[im1:ind + 1]
- y1_values = y1[im1:ind + 1]
-
- if len(diff_values) == 2:
- if np.ma.is_masked(diff_values[1]):
- return x[im1], y1[im1]
- elif np.ma.is_masked(diff_values[0]):
- return x[ind], y1[ind]
-
- diff_order = diff_values.argsort()
- diff_root_x = np.interp(
- 0, diff_values[diff_order], x_values[diff_order])
- diff_root_y = np.interp(diff_root_x, x_values, y1_values)
- return diff_root_x, diff_root_y
-
- start = get_interp_point(ind0)
- end = get_interp_point(ind1)
- else:
- # the purpose of the next two lines is for when y2 is a
- # scalar like 0 and we want the fill to go all the way
- # down to 0 even if none of the y1 sample points do
- start = xslice[0], y2slice[0]
- end = xslice[-1], y2slice[-1]
-
- X[0] = start
- X[N + 1] = end
-
- X[1:N + 1, 0] = xslice
- X[1:N + 1, 1] = y1slice
- X[N + 2:, 0] = xslice[::-1]
- X[N + 2:, 1] = y2slice[::-1]
-
- polys.append(X)
-
- collection = mcoll.PolyCollection(polys, **kwargs)
-
- # now update the datalim and autoscale
- XY1 = np.array([x[where], y1[where]]).T
- XY2 = np.array([x[where], y2[where]]).T
- self.dataLim.update_from_data_xy(XY1, self.ignore_existing_data_limits,
- updatex=True, updatey=True)
- self.ignore_existing_data_limits = False
- self.dataLim.update_from_data_xy(XY2, self.ignore_existing_data_limits,
- updatex=False, updatey=True)
- self.add_collection(collection, autolim=False)
- self.autoscale_view()
- return collection
-
- @docstring.dedent_interpd
- def fill_betweenx(self, y, x1, x2=0, where=None, **kwargs):
- """
- Make filled polygons between two horizontal curves.
-
- Call signature::
-
- fill_betweenx(y, x1, x2=0, where=None, **kwargs)
-
- Create a :class:`~matplotlib.collections.PolyCollection`
- filling the regions between *x1* and *x2* where
- ``where==True``
-
- *y* :
- An N-length array of the y data
-
- *x1* :
- An N-length array (or scalar) of the x data
-
- *x2* :
- An N-length array (or scalar) of the x data
-
- *where* :
- If *None*, default to fill between everywhere. If not *None*,
- it is a N length numpy boolean array and the fill will
- only happen over the regions where ``where==True``
-
- *kwargs* :
- keyword args passed on to the
- :class:`~matplotlib.collections.PolyCollection`
-
- kwargs control the :class:`~matplotlib.patches.Polygon` properties:
-
- %(PolyCollection)s
-
- .. plot:: mpl_examples/pylab_examples/fill_betweenx_demo.py
-
- .. seealso::
-
- :meth:`fill_between`
- for filling between two sets of y-values
-
- """
- # Handle united data, such as dates
- self._process_unit_info(ydata=y, xdata=x1, kwargs=kwargs)
- self._process_unit_info(xdata=x2)
-
- # Convert the arrays so we can work with them
- y = ma.masked_invalid(self.convert_yunits(y))
- x1 = ma.masked_invalid(self.convert_xunits(x1))
- x2 = ma.masked_invalid(self.convert_xunits(x2))
-
- if x1.ndim == 0:
- x1 = np.ones_like(y) * x1
- if x2.ndim == 0:
- x2 = np.ones_like(y) * x2
-
- if where is None:
- where = np.ones(len(y), np.bool)
- else:
- where = np.asarray(where, np.bool)
-
- if not (y.shape == x1.shape == x2.shape == where.shape):
- raise ValueError("Argument dimensions are incompatible")
-
- mask = reduce(ma.mask_or, [ma.getmask(a) for a in (y, x1, x2)])
- if mask is not ma.nomask:
- where &= ~mask
-
- polys = []
- for ind0, ind1 in mlab.contiguous_regions(where):
- yslice = y[ind0:ind1]
- x1slice = x1[ind0:ind1]
- x2slice = x2[ind0:ind1]
-
- if not len(yslice):
- continue
-
- N = len(yslice)
- Y = np.zeros((2 * N + 2, 2), np.float)
-
- # the purpose of the next two lines is for when x2 is a
- # scalar like 0 and we want the fill to go all the way
- # down to 0 even if none of the x1 sample points do
- Y[0] = x2slice[0], yslice[0]
- Y[N + 1] = x2slice[-1], yslice[-1]
-
- Y[1:N + 1, 0] = x1slice
- Y[1:N + 1, 1] = yslice
- Y[N + 2:, 0] = x2slice[::-1]
- Y[N + 2:, 1] = yslice[::-1]
-
- polys.append(Y)
-
- collection = mcoll.PolyCollection(polys, **kwargs)
-
- # now update the datalim and autoscale
- X1Y = np.array([x1[where], y[where]]).T
- X2Y = np.array([x2[where], y[where]]).T
- self.dataLim.update_from_data_xy(X1Y, self.ignore_existing_data_limits,
- updatex=True, updatey=True)
- self.ignore_existing_data_limits = False
- self.dataLim.update_from_data_xy(X2Y, self.ignore_existing_data_limits,
- updatex=True, updatey=False)
- self.add_collection(collection, autolim=False)
- self.autoscale_view()
- return collection
-
- #### plotting z(x,y): imshow, pcolor and relatives, contour
-
- @docstring.dedent_interpd
- def imshow(self, X, cmap=None, norm=None, aspect=None,
- interpolation=None, alpha=None, vmin=None, vmax=None,
- origin=None, extent=None, shape=None, filternorm=1,
- filterrad=4.0, imlim=None, resample=None, url=None, **kwargs):
- """
- Display an image on the axes.
-
- Parameters
- -----------
- X : array_like, shape (n, m) or (n, m, 3) or (n, m, 4)
- Display the image in `X` to current axes. `X` may be a float
- array, a uint8 array or a PIL image. If `X` is an array, it
- can have the following shapes:
-
- - MxN -- luminance (grayscale, float array only)
- - MxNx3 -- RGB (float or uint8 array)
- - MxNx4 -- RGBA (float or uint8 array)
-
- The value for each component of MxNx3 and MxNx4 float arrays
- should be in the range 0.0 to 1.0; MxN float arrays may be
- normalised.
-
- cmap : `~matplotlib.colors.Colormap`, optional, default: None
- If None, default to rc `image.cmap` value. `cmap` is ignored when
- `X` has RGB(A) information
-
- aspect : ['auto' | 'equal' | scalar], optional, default: None
- If 'auto', changes the image aspect ratio to match that of the
- axes.
-
- If 'equal', and `extent` is None, changes the axes aspect ratio to
- match that of the image. If `extent` is not `None`, the axes
- aspect ratio is changed to match that of the extent.
-
- If None, default to rc ``image.aspect`` value.
-
- interpolation : string, optional, default: None
- Acceptable values are 'none', 'nearest', 'bilinear', 'bicubic',
- 'spline16', 'spline36', 'hanning', 'hamming', 'hermite', 'kaiser',
- 'quadric', 'catrom', 'gaussian', 'bessel', 'mitchell', 'sinc',
- 'lanczos'
-
- If `interpolation` is None, default to rc `image.interpolation`.
- See also the `filternorm` and `filterrad` parameters.
- If `interpolation` is 'none', then no interpolation is performed
- on the Agg, ps and pdf backends. Other backends will fall back to
- 'nearest'.
-
- norm : `~matplotlib.colors.Normalize`, optional, default: None
- A `~matplotlib.colors.Normalize` instance is used to scale
- luminance data to 0, 1. If `None`, use the default
- func:`normalize`. `norm` is only used if `X` is an array of
- floats.
-
- vmin, vmax : scalar, optional, default: None
- `vmin` and `vmax` are used in conjunction with norm to normalize
- luminance data. Note if you pass a `norm` instance, your
- settings for `vmin` and `vmax` will be ignored.
-
- alpha : scalar, optional, default: None
- The alpha blending value, between 0 (transparent) and 1 (opaque)
-
- origin : ['upper' | 'lower'], optional, default: None
- Place the [0,0] index of the array in the upper left or lower left
- corner of the axes. If None, default to rc `image.origin`.
-
- extent : scalars (left, right, bottom, top), optional, default: None
- The location, in data-coordinates, of the lower-left and
- upper-right corners. If `None`, the image is positioned such that
- the pixel centers fall on zero-based (row, column) indices.
-
- shape : scalars (columns, rows), optional, default: None
- For raw buffer images
-
- filternorm : scalar, optional, default: 1
- A parameter for the antigrain image resize filter. From the
- antigrain documentation, if `filternorm` = 1, the filter
- normalizes integer values and corrects the rounding errors. It
- doesn't do anything with the source floating point values, it
- corrects only integers according to the rule of 1.0 which means
- that any sum of pixel weights must be equal to 1.0. So, the
- filter function must produce a graph of the proper shape.
-
- filterrad : scalar, optional, default: 4.0
- The filter radius for filters that have a radius parameter, i.e.
- when interpolation is one of: 'sinc', 'lanczos' or 'blackman'
-
- Returns
- --------
- image : `~matplotlib.image.AxesImage`
-
- Other parameters
- ----------------
- kwargs : `~matplotlib.artist.Artist` properties.
-
- See also
- --------
- matshow : Plot a matrix or an array as an image.
-
- Examples
- --------
-
- .. plot:: mpl_examples/pylab_examples/image_demo.py
-
- """
-
- if not self._hold:
- self.cla()
-
- if norm is not None:
- assert(isinstance(norm, mcolors.Normalize))
- if aspect is None:
- aspect = rcParams['image.aspect']
- self.set_aspect(aspect)
- im = mimage.AxesImage(self, cmap, norm, interpolation, origin, extent,
- filternorm=filternorm,
- filterrad=filterrad, resample=resample, **kwargs)
-
- im.set_data(X)
- im.set_alpha(alpha)
- if im.get_clip_path() is None:
- # image does not already have clipping set, clip to axes patch
- im.set_clip_path(self.patch)
- #if norm is None and shape is None:
- # im.set_clim(vmin, vmax)
- if vmin is not None or vmax is not None:
- im.set_clim(vmin, vmax)
- else:
- im.autoscale_None()
- im.set_url(url)
-
- # update ax.dataLim, and, if autoscaling, set viewLim
- # to tightly fit the image, regardless of dataLim.
- im.set_extent(im.get_extent())
-
- self.add_image(im)
- return im
-
- @staticmethod
- def _pcolorargs(funcname, *args, **kw):
- # This takes one kwarg, allmatch.
- # If allmatch is True, then the incoming X, Y, C must
- # have matching dimensions, taking into account that
- # X and Y can be 1-D rather than 2-D. This perfect
- # match is required for Gouroud shading. For flat
- # shading, X and Y specify boundaries, so we need
- # one more boundary than color in each direction.
- # For convenience, and consistent with Matlab, we
- # discard the last row and/or column of C if necessary
- # to meet this condition. This is done if allmatch
- # is False.
-
- allmatch = kw.pop("allmatch", False)
-
- if len(args) == 1:
- C = args[0]
- numRows, numCols = C.shape
- if allmatch:
- X, Y = np.meshgrid(np.arange(numCols), np.arange(numRows))
- else:
- X, Y = np.meshgrid(np.arange(numCols + 1),
- np.arange(numRows + 1))
- return X, Y, C
-
- if len(args) == 3:
- X, Y, C = args
- numRows, numCols = C.shape
- else:
- raise TypeError(
- 'Illegal arguments to %s; see help(%s)' % (funcname, funcname))
-
- Nx = X.shape[-1]
- Ny = Y.shape[0]
- if len(X.shape) != 2 or X.shape[0] == 1:
- x = X.reshape(1, Nx)
- X = x.repeat(Ny, axis=0)
- if len(Y.shape) != 2 or Y.shape[1] == 1:
- y = Y.reshape(Ny, 1)
- Y = y.repeat(Nx, axis=1)
- if X.shape != Y.shape:
- raise TypeError(
- 'Incompatible X, Y inputs to %s; see help(%s)' % (
- funcname, funcname))
- if allmatch:
- if not (Nx == numCols and Ny == numRows):
- raise TypeError('Dimensions of C %s are incompatible with'
- ' X (%d) and/or Y (%d); see help(%s)' % (
- C.shape, Nx, Ny, funcname))
- else:
- if not (numCols in (Nx, Nx - 1) and numRows in (Ny, Ny - 1)):
- raise TypeError('Dimensions of C %s are incompatible with'
- ' X (%d) and/or Y (%d); see help(%s)' % (
- C.shape, Nx, Ny, funcname))
- C = C[:Ny - 1, :Nx - 1]
- return X, Y, C
-
- @docstring.dedent_interpd
- def pcolor(self, *args, **kwargs):
- """
- Create a pseudocolor plot of a 2-D array.
-
- .. note::
-
- pcolor can be very slow for large arrays; consider
- using the similar but much faster
- :func:`~matplotlib.pyplot.pcolormesh` instead.
-
- Call signatures::
-
- pcolor(C, **kwargs)
- pcolor(X, Y, C, **kwargs)
-
- *C* is the array of color values.
-
- *X* and *Y*, if given, specify the (*x*, *y*) coordinates of
- the colored quadrilaterals; the quadrilateral for C[i,j] has
- corners at::
-
- (X[i, j], Y[i, j]),
- (X[i, j+1], Y[i, j+1]),
- (X[i+1, j], Y[i+1, j]),
- (X[i+1, j+1], Y[i+1, j+1]).
-
- Ideally the dimensions of *X* and *Y* should be one greater
- than those of *C*; if the dimensions are the same, then the
- last row and column of *C* will be ignored.
-
- Note that the the column index corresponds to the
- *x*-coordinate, and the row index corresponds to *y*; for
- details, see the :ref:`Grid Orientation
- ` section below.
-
- If either or both of *X* and *Y* are 1-D arrays or column vectors,
- they will be expanded as needed into the appropriate 2-D arrays,
- making a rectangular grid.
-
- *X*, *Y* and *C* may be masked arrays. If either C[i, j], or one
- of the vertices surrounding C[i,j] (*X* or *Y* at [i, j], [i+1, j],
- [i, j+1],[i+1, j+1]) is masked, nothing is plotted.
-
- Keyword arguments:
-
- *cmap*: [ *None* | Colormap ]
- A :class:`matplotlib.colors.Colormap` instance. If *None*, use
- rc settings.
-
- *norm*: [ *None* | Normalize ]
- An :class:`matplotlib.colors.Normalize` instance is used
- to scale luminance data to 0,1. If *None*, defaults to
- :func:`normalize`.
-
- *vmin*/*vmax*: [ *None* | scalar ]
- *vmin* and *vmax* are used in conjunction with *norm* to
- normalize luminance data. If either is *None*, it
- is autoscaled to the respective min or max
- of the color array *C*. If not *None*, *vmin* or
- *vmax* passed in here override any pre-existing values
- supplied in the *norm* instance.
-
- *shading*: [ 'flat' | 'faceted' ]
- If 'faceted', a black grid is drawn around each rectangle; if
- 'flat', edges are not drawn. Default is 'flat', contrary to
- MATLAB.
-
- This kwarg is deprecated; please use 'edgecolors' instead:
- * shading='flat' -- edgecolors='none'
- * shading='faceted -- edgecolors='k'
-
- *edgecolors*: [ *None* | ``'none'`` | color | color sequence]
- If *None*, the rc setting is used by default.
-
- If ``'none'``, edges will not be visible.
-
- An mpl color or sequence of colors will set the edge color
-
- *alpha*: ``0 <= scalar <= 1`` or *None*
- the alpha blending value
-
- *snap*: bool
- Whether to snap the mesh to pixel boundaries.
-
- Return value is a :class:`matplotlib.collections.Collection`
- instance.
-
- .. _axes-pcolor-grid-orientation:
-
- The grid orientation follows the MATLAB convention: an
- array *C* with shape (*nrows*, *ncolumns*) is plotted with
- the column number as *X* and the row number as *Y*, increasing
- up; hence it is plotted the way the array would be printed,
- except that the *Y* axis is reversed. That is, *C* is taken
- as *C*(*y*, *x*).
-
- Similarly for :func:`meshgrid`::
-
- x = np.arange(5)
- y = np.arange(3)
- X, Y = np.meshgrid(x, y)
-
- is equivalent to::
-
- X = array([[0, 1, 2, 3, 4],
- [0, 1, 2, 3, 4],
- [0, 1, 2, 3, 4]])
-
- Y = array([[0, 0, 0, 0, 0],
- [1, 1, 1, 1, 1],
- [2, 2, 2, 2, 2]])
-
- so if you have::
-
- C = rand(len(x), len(y))
-
- then you need to transpose C::
-
- pcolor(X, Y, C.T)
-
- or::
-
- pcolor(C.T)
-
- MATLAB :func:`pcolor` always discards the last row and column
- of *C*, but matplotlib displays the last row and column if *X* and
- *Y* are not specified, or if *X* and *Y* have one more row and
- column than *C*.
-
- kwargs can be used to control the
- :class:`~matplotlib.collections.PolyCollection` properties:
-
- %(PolyCollection)s
-
- .. note::
-
- The default *antialiaseds* is False if the default
- *edgecolors*="none" is used. This eliminates artificial lines
- at patch boundaries, and works regardless of the value of
- alpha. If *edgecolors* is not "none", then the default
- *antialiaseds* is taken from
- rcParams['patch.antialiased'], which defaults to *True*.
- Stroking the edges may be preferred if *alpha* is 1, but
- will cause artifacts otherwise.
-
- .. seealso::
-
- :func:`~matplotlib.pyplot.pcolormesh`
- For an explanation of the differences between
- pcolor and pcolormesh.
- """
-
- if not self._hold:
- self.cla()
-
- alpha = kwargs.pop('alpha', None)
- norm = kwargs.pop('norm', None)
- cmap = kwargs.pop('cmap', None)
- vmin = kwargs.pop('vmin', None)
- vmax = kwargs.pop('vmax', None)
- if 'shading' in kwargs:
- cbook.warn_deprecated(
- '1.2', name='shading', alternative='edgecolors',
- obj_type='option')
- shading = kwargs.pop('shading', 'flat')
-
- X, Y, C = self._pcolorargs('pcolor', *args, allmatch=False)
- Ny, Nx = X.shape
-
- # unit conversion allows e.g. datetime objects as axis values
- self._process_unit_info(xdata=X, ydata=Y, kwargs=kwargs)
- X = self.convert_xunits(X)
- Y = self.convert_yunits(Y)
-
- # convert to MA, if necessary.
- C = ma.asarray(C)
- X = ma.asarray(X)
- Y = ma.asarray(Y)
-
- mask = ma.getmaskarray(X) + ma.getmaskarray(Y)
- xymask = (mask[0:-1, 0:-1] + mask[1:, 1:] +
- mask[0:-1, 1:] + mask[1:, 0:-1])
- # don't plot if C or any of the surrounding vertices are masked.
- mask = ma.getmaskarray(C) + xymask
-
- newaxis = np.newaxis
- compress = np.compress
-
- ravelmask = (mask == 0).ravel()
- X1 = compress(ravelmask, ma.filled(X[0:-1, 0:-1]).ravel())
- Y1 = compress(ravelmask, ma.filled(Y[0:-1, 0:-1]).ravel())
- X2 = compress(ravelmask, ma.filled(X[1:, 0:-1]).ravel())
- Y2 = compress(ravelmask, ma.filled(Y[1:, 0:-1]).ravel())
- X3 = compress(ravelmask, ma.filled(X[1:, 1:]).ravel())
- Y3 = compress(ravelmask, ma.filled(Y[1:, 1:]).ravel())
- X4 = compress(ravelmask, ma.filled(X[0:-1, 1:]).ravel())
- Y4 = compress(ravelmask, ma.filled(Y[0:-1, 1:]).ravel())
- npoly = len(X1)
-
- xy = np.concatenate((X1[:, newaxis], Y1[:, newaxis],
- X2[:, newaxis], Y2[:, newaxis],
- X3[:, newaxis], Y3[:, newaxis],
- X4[:, newaxis], Y4[:, newaxis],
- X1[:, newaxis], Y1[:, newaxis]),
- axis=1)
- verts = xy.reshape((npoly, 5, 2))
-
- C = compress(ravelmask, ma.filled(C[0:Ny - 1, 0:Nx - 1]).ravel())
-
- linewidths = (0.25,)
- if 'linewidth' in kwargs:
- kwargs['linewidths'] = kwargs.pop('linewidth')
- kwargs.setdefault('linewidths', linewidths)
-
- if shading == 'faceted':
- edgecolors = 'k',
- else:
- edgecolors = 'none'
-
- if 'edgecolor' in kwargs:
- kwargs['edgecolors'] = kwargs.pop('edgecolor')
- ec = kwargs.setdefault('edgecolors', edgecolors)
-
- # aa setting will default via collections to patch.antialiased
- # unless the boundary is not stroked, in which case the
- # default will be False; with unstroked boundaries, aa
- # makes artifacts that are often disturbing.
- if 'antialiased' in kwargs:
- kwargs['antialiaseds'] = kwargs.pop('antialiased')
- if 'antialiaseds' not in kwargs and (is_string_like(ec) and
- ec.lower() == "none"):
- kwargs['antialiaseds'] = False
-
- kwargs.setdefault('snap', False)
-
- collection = mcoll.PolyCollection(verts, **kwargs)
-
- collection.set_alpha(alpha)
- collection.set_array(C)
- if norm is not None:
- assert(isinstance(norm, mcolors.Normalize))
- collection.set_cmap(cmap)
- collection.set_norm(norm)
- collection.set_clim(vmin, vmax)
- collection.autoscale_None()
- self.grid(False)
-
- x = X.compressed()
- y = Y.compressed()
-
- # Transform from native to data coordinates?
- t = collection._transform
- if (not isinstance(t, mtransforms.Transform)
- and hasattr(t, '_as_mpl_transform')):
- t = t._as_mpl_transform(self.axes)
-
- if t and any(t.contains_branch_seperately(self.transData)):
- trans_to_data = t - self.transData
- pts = np.vstack([x, y]).T.astype(np.float)
- transformed_pts = trans_to_data.transform(pts)
- x = transformed_pts[..., 0]
- y = transformed_pts[..., 1]
-
- minx = np.amin(x)
- maxx = np.amax(x)
- miny = np.amin(y)
- maxy = np.amax(y)
-
- corners = (minx, miny), (maxx, maxy)
- self.update_datalim(corners)
- self.autoscale_view()
- self.add_collection(collection, autolim=False)
- return collection
-
- @docstring.dedent_interpd
- def pcolormesh(self, *args, **kwargs):
- """
- Plot a quadrilateral mesh.
-
- Call signatures::
-
- pcolormesh(C)
- pcolormesh(X, Y, C)
- pcolormesh(C, **kwargs)
-
- Create a pseudocolor plot of a 2-D array.
-
- pcolormesh is similar to :func:`~matplotlib.pyplot.pcolor`,
- but uses a different mechanism and returns a different
- object; pcolor returns a
- :class:`~matplotlib.collections.PolyCollection` but pcolormesh
- returns a
- :class:`~matplotlib.collections.QuadMesh`. It is much faster,
- so it is almost always preferred for large arrays.
-
- *C* may be a masked array, but *X* and *Y* may not. Masked
- array support is implemented via *cmap* and *norm*; in
- contrast, :func:`~matplotlib.pyplot.pcolor` simply does not
- draw quadrilaterals with masked colors or vertices.
-
- Keyword arguments:
-
- *cmap*: [ *None* | Colormap ]
- A :class:`matplotlib.colors.Colormap` instance. If *None*, use
- rc settings.
-
- *norm*: [ *None* | Normalize ]
- A :class:`matplotlib.colors.Normalize` instance is used to
- scale luminance data to 0,1. If *None*, defaults to
- :func:`normalize`.
-
- *vmin*/*vmax*: [ *None* | scalar ]
- *vmin* and *vmax* are used in conjunction with *norm* to
- normalize luminance data. If either is *None*, it
- is autoscaled to the respective min or max
- of the color array *C*. If not *None*, *vmin* or
- *vmax* passed in here override any pre-existing values
- supplied in the *norm* instance.
-
- *shading*: [ 'flat' | 'gouraud' ]
- 'flat' indicates a solid color for each quad. When
- 'gouraud', each quad will be Gouraud shaded. When gouraud
- shading, edgecolors is ignored.
-
- *edgecolors*: [*None* | ``'None'`` | ``'face'`` | color |
- color sequence]
-
- If *None*, the rc setting is used by default.
-
- If ``'None'``, edges will not be visible.
-
- If ``'face'``, edges will have the same color as the faces.
-
- An mpl color or sequence of colors will set the edge color
-
- *alpha*: ``0 <= scalar <= 1`` or *None*
- the alpha blending value
-
- Return value is a :class:`matplotlib.collections.QuadMesh`
- object.
-
- kwargs can be used to control the
- :class:`matplotlib.collections.QuadMesh` properties:
-
- %(QuadMesh)s
-
- .. seealso::
-
- :func:`~matplotlib.pyplot.pcolor`
- For an explanation of the grid orientation and the
- expansion of 1-D *X* and/or *Y* to 2-D arrays.
- """
- if not self._hold:
- self.cla()
-
- alpha = kwargs.pop('alpha', None)
- norm = kwargs.pop('norm', None)
- cmap = kwargs.pop('cmap', None)
- vmin = kwargs.pop('vmin', None)
- vmax = kwargs.pop('vmax', None)
- shading = kwargs.pop('shading', 'flat').lower()
- antialiased = kwargs.pop('antialiased', False)
- kwargs.setdefault('edgecolors', 'None')
-
- allmatch = (shading == 'gouraud')
-
- X, Y, C = self._pcolorargs('pcolormesh', *args, allmatch=allmatch)
- Ny, Nx = X.shape
-
- # convert to one dimensional arrays
- C = C.ravel()
- X = X.ravel()
- Y = Y.ravel()
-
- # unit conversion allows e.g. datetime objects as axis values
- self._process_unit_info(xdata=X, ydata=Y, kwargs=kwargs)
- X = self.convert_xunits(X)
- Y = self.convert_yunits(Y)
-
- coords = np.zeros(((Nx * Ny), 2), dtype=float)
- coords[:, 0] = X
- coords[:, 1] = Y
-
- collection = mcoll.QuadMesh(
- Nx - 1, Ny - 1, coords,
- antialiased=antialiased, shading=shading, **kwargs)
- collection.set_alpha(alpha)
- collection.set_array(C)
- if norm is not None:
- assert(isinstance(norm, mcolors.Normalize))
- collection.set_cmap(cmap)
- collection.set_norm(norm)
- collection.set_clim(vmin, vmax)
- collection.autoscale_None()
-
- self.grid(False)
-
- # Transform from native to data coordinates?
- t = collection._transform
- if (not isinstance(t, mtransforms.Transform)
- and hasattr(t, '_as_mpl_transform')):
- t = t._as_mpl_transform(self.axes)
-
- if t and any(t.contains_branch_seperately(self.transData)):
- trans_to_data = t - self.transData
- pts = np.vstack([X, Y]).T.astype(np.float)
- transformed_pts = trans_to_data.transform(pts)
- X = transformed_pts[..., 0]
- Y = transformed_pts[..., 1]
-
- minx = np.amin(X)
- maxx = np.amax(X)
- miny = np.amin(Y)
- maxy = np.amax(Y)
-
- corners = (minx, miny), (maxx, maxy)
- self.update_datalim(corners)
- self.autoscale_view()
- self.add_collection(collection, autolim=False)
- return collection
-
- @docstring.dedent_interpd
- def pcolorfast(self, *args, **kwargs):
- """
- pseudocolor plot of a 2-D array
-
- Experimental; this is a pcolor-type method that
- provides the fastest possible rendering with the Agg
- backend, and that can handle any quadrilateral grid.
- It supports only flat shading (no outlines), it lacks
- support for log scaling of the axes, and it does not
- have a pyplot wrapper.
-
- Call signatures::
-
- ax.pcolorfast(C, **kwargs)
- ax.pcolorfast(xr, yr, C, **kwargs)
- ax.pcolorfast(x, y, C, **kwargs)
- ax.pcolorfast(X, Y, C, **kwargs)
-
- C is the 2D array of color values corresponding to quadrilateral
- cells. Let (nr, nc) be its shape. C may be a masked array.
-
- ``ax.pcolorfast(C, **kwargs)`` is equivalent to
- ``ax.pcolorfast([0,nc], [0,nr], C, **kwargs)``
-
- *xr*, *yr* specify the ranges of *x* and *y* corresponding to the
- rectangular region bounding *C*. If::
-
- xr = [x0, x1]
-
- and::
-
- yr = [y0,y1]
-
- then *x* goes from *x0* to *x1* as the second index of *C* goes
- from 0 to *nc*, etc. (*x0*, *y0*) is the outermost corner of
- cell (0,0), and (*x1*, *y1*) is the outermost corner of cell
- (*nr*-1, *nc*-1). All cells are rectangles of the same size.
- This is the fastest version.
-
- *x*, *y* are 1D arrays of length *nc* +1 and *nr* +1, respectively,
- giving the x and y boundaries of the cells. Hence the cells are
- rectangular but the grid may be nonuniform. The speed is
- intermediate. (The grid is checked, and if found to be
- uniform the fast version is used.)
-
- *X* and *Y* are 2D arrays with shape (*nr* +1, *nc* +1) that specify
- the (x,y) coordinates of the corners of the colored
- quadrilaterals; the quadrilateral for C[i,j] has corners at
- (X[i,j],Y[i,j]), (X[i,j+1],Y[i,j+1]), (X[i+1,j],Y[i+1,j]),
- (X[i+1,j+1],Y[i+1,j+1]). The cells need not be rectangular.
- This is the most general, but the slowest to render. It may
- produce faster and more compact output using ps, pdf, and
- svg backends, however.
-
- Note that the the column index corresponds to the x-coordinate,
- and the row index corresponds to y; for details, see
- the "Grid Orientation" section below.
-
- Optional keyword arguments:
-
- *cmap*: [ *None* | Colormap ]
- A :class:`matplotlib.colors.Colormap` instance from cm. If *None*,
- use rc settings.
-
- *norm*: [ *None* | Normalize ]
- A :class:`matplotlib.colors.Normalize` instance is used to scale
- luminance data to 0,1. If *None*, defaults to normalize()
-
- *vmin*/*vmax*: [ *None* | scalar ]
- *vmin* and *vmax* are used in conjunction with norm to normalize
- luminance data. If either are *None*, the min and max
- of the color array *C* is used. If you pass a norm instance,
- *vmin* and *vmax* will be *None*.
-
- *alpha*: ``0 <= scalar <= 1`` or *None*
- the alpha blending value
-
- Return value is an image if a regular or rectangular grid
- is specified, and a :class:`~matplotlib.collections.QuadMesh`
- collection in the general quadrilateral case.
-
- """
-
- if not self._hold:
- self.cla()
-
- alpha = kwargs.pop('alpha', None)
- norm = kwargs.pop('norm', None)
- cmap = kwargs.pop('cmap', None)
- vmin = kwargs.pop('vmin', None)
- vmax = kwargs.pop('vmax', None)
- if norm is not None:
- assert(isinstance(norm, mcolors.Normalize))
-
- C = args[-1]
- nr, nc = C.shape
- if len(args) == 1:
- style = "image"
- x = [0, nc]
- y = [0, nr]
- elif len(args) == 3:
- x, y = args[:2]
- x = np.asarray(x)
- y = np.asarray(y)
- if x.ndim == 1 and y.ndim == 1:
- if x.size == 2 and y.size == 2:
- style = "image"
- else:
- dx = np.diff(x)
- dy = np.diff(y)
- if (np.ptp(dx) < 0.01 * np.abs(dx.mean()) and
- np.ptp(dy) < 0.01 * np.abs(dy.mean())):
- style = "image"
- else:
- style = "pcolorimage"
- elif x.ndim == 2 and y.ndim == 2:
- style = "quadmesh"
- else:
- raise TypeError("arguments do not match valid signatures")
- else:
- raise TypeError("need 1 argument or 3 arguments")
-
- if style == "quadmesh":
-
- # convert to one dimensional arrays
- # This should also be moved to the QuadMesh class
- C = ma.ravel(C) # data point in each cell is value
- # at lower left corner
- X = x.ravel()
- Y = y.ravel()
- Nx = nc + 1
- Ny = nr + 1
-
- # The following needs to be cleaned up; the renderer
- # requires separate contiguous arrays for X and Y,
- # but the QuadMesh class requires the 2D array.
- coords = np.empty(((Nx * Ny), 2), np.float64)
- coords[:, 0] = X
- coords[:, 1] = Y
-
- # The QuadMesh class can also be changed to
- # handle relevant superclass kwargs; the initializer
- # should do much more than it does now.
- collection = mcoll.QuadMesh(nc, nr, coords, 0, edgecolors="None")
- collection.set_alpha(alpha)
- collection.set_array(C)
- collection.set_cmap(cmap)
- collection.set_norm(norm)
- self.add_collection(collection, autolim=False)
- xl, xr, yb, yt = X.min(), X.max(), Y.min(), Y.max()
- ret = collection
-
- else:
- # One of the image styles:
- xl, xr, yb, yt = x[0], x[-1], y[0], y[-1]
- if style == "image":
-
- im = mimage.AxesImage(self, cmap, norm,
- interpolation='nearest',
- origin='lower',
- extent=(xl, xr, yb, yt),
- **kwargs)
- im.set_data(C)
- im.set_alpha(alpha)
- self.add_image(im)
- ret = im
-
- if style == "pcolorimage":
- im = mimage.PcolorImage(self, x, y, C,
- cmap=cmap,
- norm=norm,
- alpha=alpha,
- **kwargs)
- self.add_image(im)
- ret = im
-
- if vmin is not None or vmax is not None:
- ret.set_clim(vmin, vmax)
- else:
- ret.autoscale_None()
- self.update_datalim(np.array([[xl, yb], [xr, yt]]))
- self.autoscale_view(tight=True)
- return ret
-
- def contour(self, *args, **kwargs):
- if not self._hold:
- self.cla()
- kwargs['filled'] = False
- return mcontour.QuadContourSet(self, *args, **kwargs)
- contour.__doc__ = mcontour.QuadContourSet.contour_doc
-
- def contourf(self, *args, **kwargs):
- if not self._hold:
- self.cla()
- kwargs['filled'] = True
- return mcontour.QuadContourSet(self, *args, **kwargs)
- contourf.__doc__ = mcontour.QuadContourSet.contour_doc
-
- def clabel(self, CS, *args, **kwargs):
- return CS.clabel(*args, **kwargs)
- clabel.__doc__ = mcontour.ContourSet.clabel.__doc__
-
- @docstring.dedent_interpd
- def table(self, **kwargs):
- """
- Add a table to the current axes.
-
- Call signature::
-
- table(cellText=None, cellColours=None,
- cellLoc='right', colWidths=None,
- rowLabels=None, rowColours=None, rowLoc='left',
- colLabels=None, colColours=None, colLoc='center',
- loc='bottom', bbox=None):
-
- Returns a :class:`matplotlib.table.Table` instance. For finer
- grained control over tables, use the
- :class:`~matplotlib.table.Table` class and add it to the axes
- with :meth:`~matplotlib.axes.Axes.add_table`.
-
- Thanks to John Gill for providing the class and table.
-
- kwargs control the :class:`~matplotlib.table.Table`
- properties:
-
- %(Table)s
- """
- return mtable.table(self, **kwargs)
-
- #### Data analysis
-
- @docstring.dedent_interpd
- def hist(self, x, bins=10, range=None, normed=False, weights=None,
- cumulative=False, bottom=None, histtype='bar', align='mid',
- orientation='vertical', rwidth=None, log=False,
- color=None, label=None, stacked=False,
- **kwargs):
- """
- Plot a histogram.
-
- Compute and draw the histogram of *x*. The return value is a
- tuple (*n*, *bins*, *patches*) or ([*n0*, *n1*, ...], *bins*,
- [*patches0*, *patches1*,...]) if the input contains multiple
- data.
-
- Multiple data can be provided via *x* as a list of datasets
- of potentially different length ([*x0*, *x1*, ...]), or as
- a 2-D ndarray in which each column is a dataset. Note that
- the ndarray form is transposed relative to the list form.
-
- Masked arrays are not supported at present.
-
- Parameters
- ----------
- x : (n,) array or sequence of (n,) arrays
- Input values, this takes either a single array or a sequency of
- arrays which are not required to be of the same length
-
- bins : integer or array_like, optional
- If an integer is given, `bins + 1` bin edges are returned,
- consistently with :func:`numpy.histogram` for numpy version >=
- 1.3.
-
- Unequally spaced bins are supported if `bins` is a sequence.
-
- default is 10
-
- range : tuple or None, optional
- The lower and upper range of the bins. Lower and upper outliers
- are ignored. If not provided, `range` is (x.min(), x.max()). Range
- has no effect if `bins` is a sequence.
-
- If `bins` is a sequence or `range` is specified, autoscaling
- is based on the specified bin range instead of the
- range of x.
-
- Default is ``None``
-
- normed : boolean, optional
- If `True`, the first element of the return tuple will
- be the counts normalized to form a probability density, i.e.,
- ``n/(len(x)`dbin)``, i.e., the integral of the histogram will sum
- to 1. If *stacked* is also *True*, the sum of the histograms is
- normalized to 1.
-
- Default is ``False``
-
- weights : (n, ) array_like or None, optional
- An array of weights, of the same shape as `x`. Each value in `x`
- only contributes its associated weight towards the bin count
- (instead of 1). If `normed` is True, the weights are normalized,
- so that the integral of the density over the range remains 1.
-
- Default is ``None``
-
- cumulative : boolean, optional
- If `True`, then a histogram is computed where each bin gives the
- counts in that bin plus all bins for smaller values. The last bin
- gives the total number of datapoints. If `normed` is also `True`
- then the histogram is normalized such that the last bin equals 1.
- If `cumulative` evaluates to less than 0 (e.g., -1), the direction
- of accumulation is reversed. In this case, if `normed` is also
- `True`, then the histogram is normalized such that the first bin
- equals 1.
-
- Default is ``False``
-
- bottom : array_like, scalar, or None
- Location of the bottom baseline of each bin. If a scalar,
- the base line for each bin is shifted by the same amount.
- If an array, each bin is shifted independently and the length
- of bottom must match the number of bins. If None, defaults to 0.
-
- Default is ``None``
-
- histtype : {'bar', 'barstacked', 'step', 'stepfilled'}, optional
- The type of histogram to draw.
-
- - 'bar' is a traditional bar-type histogram. If multiple data
- are given the bars are aranged side by side.
-
- - 'barstacked' is a bar-type histogram where multiple
- data are stacked on top of each other.
-
- - 'step' generates a lineplot that is by default
- unfilled.
-
- - 'stepfilled' generates a lineplot that is by default
- filled.
-
- Default is 'bar'
-
- align : {'left', 'mid', 'right'}, optional
- Controls how the histogram is plotted.
-
- - 'left': bars are centered on the left bin edges.
-
- - 'mid': bars are centered between the bin edges.
-
- - 'right': bars are centered on the right bin edges.
-
- Default is 'mid'
-
- orientation : {'horizontal', 'vertical'}, optional
- If 'horizontal', `~matplotlib.pyplot.barh` will be used for
- bar-type histograms and the *bottom* kwarg will be the left edges.
-
- rwidth : scalar or None, optional
- The relative width of the bars as a fraction of the bin width. If
- `None`, automatically compute the width.
-
- Ignored if `histtype` is 'step' or 'stepfilled'.
-
- Default is ``None``
-
- log : boolean, optional
- If `True`, the histogram axis will be set to a log scale. If `log`
- is `True` and `x` is a 1D array, empty bins will be filtered out
- and only the non-empty (`n`, `bins`, `patches`) will be returned.
-
- Default is ``False``
-
- color : color or array_like of colors or None, optional
- Color spec or sequence of color specs, one per dataset. Default
- (`None`) uses the standard line color sequence.
-
- Default is ``None``
-
- label : string or None, optional
- String, or sequence of strings to match multiple datasets. Bar
- charts yield multiple patches per dataset, but only the first gets
- the label, so that the legend command will work as expected.
-
- default is ``None``
-
- stacked : boolean, optional
- If `True`, multiple data are stacked on top of each other If
- `False` multiple data are aranged side by side if histtype is
- 'bar' or on top of each other if histtype is 'step'
-
- Default is ``False``
-
- Returns
- -------
- n : array or list of arrays
- The values of the histogram bins. See **normed** and **weights**
- for a description of the possible semantics. If input **x** is an
- array, then this is an array of length **nbins**. If input is a
- sequence arrays ``[data1, data2,..]``, then this is a list of
- arrays with the values of the histograms for each of the arrays
- in the same order.
-
- bins : array
- The edges of the bins. Length nbins + 1 (nbins left edges and right
- edge of last bin). Always a single array even when multiple data
- sets are passed in.
-
- patches : list or list of lists
- Silent list of individual patches used to create the histogram
- or list of such list if multiple input datasets.
-
- Other Parameters
- ----------------
- kwargs : `~matplotlib.patches.Patch` properties
-
- See also
- --------
- hist2d : 2D histograms
-
- Notes
- -----
- Until numpy release 1.5, the underlying numpy histogram function was
- incorrect with `normed`=`True` if bin sizes were unequal. MPL
- inherited that error. It is now corrected within MPL when using
- earlier numpy versions.
-
- Examples
- --------
- .. plot:: mpl_examples/statistics/histogram_demo_features.py
-
- """
- if not self._hold:
- self.cla()
-
- # xrange becomes range after 2to3
- bin_range = range
- range = __builtins__["range"]
-
- # NOTE: the range keyword overwrites the built-in func range !!!
- # needs to be fixed in numpy !!!
-
- # Validate string inputs here so we don't have to clutter
- # subsequent code.
- if histtype not in ['bar', 'barstacked', 'step', 'stepfilled']:
- raise ValueError("histtype %s is not recognized" % histtype)
-
- if align not in ['left', 'mid', 'right']:
- raise ValueError("align kwarg %s is not recognized" % align)
-
- if orientation not in ['horizontal', 'vertical']:
- raise ValueError(
- "orientation kwarg %s is not recognized" % orientation)
-
- if histtype == 'barstacked' and not stacked:
- stacked = True
-
- # Check whether bins or range are given explicitly.
- binsgiven = (cbook.iterable(bins) or bin_range is not None)
-
- # basic input validation
- flat = np.ravel(x)
- if len(flat) == 0:
- raise ValueError("x must have at least one data point")
- elif len(flat) == 1 and not binsgiven:
- raise ValueError(
- "x has only one data point. bins or range kwarg must be given")
-
- # Massage 'x' for processing.
- # NOTE: Be sure any changes here is also done below to 'weights'
- if isinstance(x, np.ndarray) or not iterable(x[0]):
- # TODO: support masked arrays;
- x = np.asarray(x)
- if x.ndim == 2:
- x = x.T # 2-D input with columns as datasets; switch to rows
- elif x.ndim == 1:
- x = x.reshape(1, x.shape[0]) # new view, single row
- else:
- raise ValueError("x must be 1D or 2D")
- if x.shape[1] < x.shape[0]:
- warnings.warn(
- '2D hist input should be nsamples x nvariables;\n '
- 'this looks transposed (shape is %d x %d)' % x.shape[::-1])
- else:
- # multiple hist with data of different length
- x = [np.asarray(xi) for xi in x]
-
- nx = len(x) # number of datasets
-
- if color is None:
- color = [six.next(self._get_lines.color_cycle)
- for i in xrange(nx)]
- else:
- color = mcolors.colorConverter.to_rgba_array(color)
- if len(color) != nx:
- raise ValueError("color kwarg must have one color per dataset")
-
- # We need to do to 'weights' what was done to 'x'
- if weights is not None:
- if isinstance(weights, np.ndarray) or not iterable(weights[0]):
- w = np.array(weights)
- if w.ndim == 2:
- w = w.T
- elif w.ndim == 1:
- w.shape = (1, w.shape[0])
- else:
- raise ValueError("weights must be 1D or 2D")
- else:
- w = [np.asarray(wi) for wi in weights]
-
- if len(w) != nx:
- raise ValueError('weights should have the same shape as x')
- for i in xrange(nx):
- if len(w[i]) != len(x[i]):
- raise ValueError(
- 'weights should have the same shape as x')
- else:
- w = [None]*nx
-
- # Save the datalimits for the same reason:
- _saved_bounds = self.dataLim.bounds
-
- # If bins are not specified either explicitly or via range,
- # we need to figure out the range required for all datasets,
- # and supply that to np.histogram.
- if not binsgiven:
- xmin = np.inf
- xmax = -np.inf
- for xi in x:
- if len(xi) > 0:
- xmin = min(xmin, xi.min())
- xmax = max(xmax, xi.max())
- bin_range = (xmin, xmax)
-
- #hist_kwargs = dict(range=range, normed=bool(normed))
- # We will handle the normed kwarg within mpl until we
- # get to the point of requiring numpy >= 1.5.
- hist_kwargs = dict(range=bin_range)
-
- n = []
- mlast = None
- for i in xrange(nx):
- # this will automatically overwrite bins,
- # so that each histogram uses the same bins
- m, bins = np.histogram(x[i], bins, weights=w[i], **hist_kwargs)
- m = m.astype(float) # causes problems later if it's an int
- if mlast is None:
- mlast = np.zeros(len(bins)-1, m.dtype)
- if normed and not stacked:
- db = np.diff(bins)
- m = (m.astype(float) / db) / m.sum()
- if stacked:
- if mlast is None:
- mlast = np.zeros(len(bins)-1, m.dtype)
- m += mlast
- mlast[:] = m
- n.append(m)
-
- if stacked and normed:
- db = np.diff(bins)
- for m in n:
- m[:] = (m.astype(float) / db) / n[-1].sum()
- if cumulative:
- slc = slice(None)
- if cbook.is_numlike(cumulative) and cumulative < 0:
- slc = slice(None, None, -1)
-
- if normed:
- n = [(m * np.diff(bins))[slc].cumsum()[slc] for m in n]
- else:
- n = [m[slc].cumsum()[slc] for m in n]
-
- patches = []
-
- if histtype.startswith('bar'):
- # Save autoscale state for later restoration; turn autoscaling
- # off so we can do it all a single time at the end, instead
- # of having it done by bar or fill and then having to be redone.
- _saved_autoscalex = self.get_autoscalex_on()
- _saved_autoscaley = self.get_autoscaley_on()
- self.set_autoscalex_on(False)
- self.set_autoscaley_on(False)
-
- totwidth = np.diff(bins)
-
- if rwidth is not None:
- dr = min(1.0, max(0.0, rwidth))
- elif len(n) > 1:
- dr = 0.8
- else:
- dr = 1.0
-
- if histtype == 'bar' and not stacked:
- width = dr*totwidth/nx
- dw = width
-
- if nx > 1:
- boffset = -0.5*dr*totwidth*(1.0-1.0/nx)
- else:
- boffset = 0.0
- stacked = False
- elif histtype == 'barstacked' or stacked:
- width = dr*totwidth
- boffset, dw = 0.0, 0.0
-
- if align == 'mid' or align == 'edge':
- boffset += 0.5*totwidth
- elif align == 'right':
- boffset += totwidth
-
- if orientation == 'horizontal':
- _barfunc = self.barh
- bottom_kwarg = 'left'
- else: # orientation == 'vertical'
- _barfunc = self.bar
- bottom_kwarg = 'bottom'
-
- for m, c in zip(n, color):
- if bottom is None:
- bottom = np.zeros(len(m), np.float)
- if stacked:
- height = m - bottom
- else:
- height = m
- patch = _barfunc(bins[:-1]+boffset, height, width,
- align='center', log=log,
- color=c, **{bottom_kwarg: bottom})
- patches.append(patch)
- if stacked:
- bottom[:] = m
- boffset += dw
-
- self.set_autoscalex_on(_saved_autoscalex)
- self.set_autoscaley_on(_saved_autoscaley)
- self.autoscale_view()
-
- elif histtype.startswith('step'):
- # these define the perimeter of the polygon
- x = np.zeros(4 * len(bins) - 3, np.float)
- y = np.zeros(4 * len(bins) - 3, np.float)
-
- x[0:2*len(bins)-1:2], x[1:2*len(bins)-1:2] = bins, bins[:-1]
- x[2*len(bins)-1:] = x[1:2*len(bins)-1][::-1]
-
- if bottom is None:
- bottom = np.zeros(len(bins)-1, np.float)
-
- y[1:2*len(bins)-1:2], y[2:2*len(bins):2] = bottom, bottom
- y[2*len(bins)-1:] = y[1:2*len(bins)-1][::-1]
-
- if log:
- if orientation == 'horizontal':
- self.set_xscale('log', nonposx='clip')
- logbase = self.xaxis._scale.base
- else: # orientation == 'vertical'
- self.set_yscale('log', nonposy='clip')
- logbase = self.yaxis._scale.base
-
- # Setting a minimum of 0 results in problems for log plots
- if normed or weights is not None:
- # For normed data, set to log base * minimum data value
- # (gives 1 full tick-label unit for the lowest filled bin)
- ndata = np.array(n)
- minimum = (np.min(ndata[ndata > 0])) / logbase
- else:
- # For non-normed data, set the min to log base,
- # again so that there is 1 full tick-label unit
- # for the lowest bin
- minimum = 1.0 / logbase
-
- y[0], y[-1] = minimum, minimum
- else:
- minimum = np.min(bins)
-
- if align == 'left' or align == 'center':
- x -= 0.5*(bins[1]-bins[0])
- elif align == 'right':
- x += 0.5*(bins[1]-bins[0])
-
- # If fill kwarg is set, it will be passed to the patch collection,
- # overriding this
- fill = (histtype == 'stepfilled')
-
- xvals, yvals = [], []
- for m in n:
- if stacked:
- # starting point for drawing polygon
- y[0] = y[1]
- # top of the previous polygon becomes the bottom
- y[2*len(bins)-1:] = y[1:2*len(bins)-1][::-1]
- # set the top of this polygon
- y[1:2*len(bins)-1:2], y[2:2*len(bins):2] = (m + bottom,
- m + bottom)
- if log:
- y[y < minimum] = minimum
- if orientation == 'horizontal':
- xvals.append(y.copy())
- yvals.append(x.copy())
- else:
- xvals.append(x.copy())
- yvals.append(y.copy())
-
- if fill:
- # add patches in reverse order so that when stacking,
- # items lower in the stack are plottted on top of
- # items higher in the stack
- for x, y, c in reversed(list(zip(xvals, yvals, color))):
- patches.append(self.fill(
- x, y,
- closed=True,
- facecolor=c))
- else:
- for x, y, c in reversed(list(zip(xvals, yvals, color))):
- split = 2 * len(bins)
- patches.append(self.fill(
- x[:split], y[:split],
- closed=False, edgecolor=c,
- fill=False))
-
- # we return patches, so put it back in the expected order
- patches.reverse()
-
- # adopted from adjust_x/ylim part of the bar method
- if orientation == 'horizontal':
- xmin0 = max(_saved_bounds[0]*0.9, minimum)
- xmax = self.dataLim.intervalx[1]
- for m in n:
- if np.sum(m) > 0: # make sure there are counts
- xmin = np.amin(m[m != 0])
- # filter out the 0 height bins
- xmin = max(xmin*0.9, minimum)
- xmin = min(xmin0, xmin)
- self.dataLim.intervalx = (xmin, xmax)
- elif orientation == 'vertical':
- ymin0 = max(_saved_bounds[1]*0.9, minimum)
- ymax = self.dataLim.intervaly[1]
- for m in n:
- if np.sum(m) > 0: # make sure there are counts
- ymin = np.amin(m[m != 0])
- # filter out the 0 height bins
- ymin = max(ymin*0.9, minimum)
- ymin = min(ymin0, ymin)
- self.dataLim.intervaly = (ymin, ymax)
-
- if label is None:
- labels = [None]
- elif is_string_like(label):
- labels = [label]
- else:
- labels = [str(lab) for lab in label]
-
- for (patch, lbl) in zip_longest(patches, labels, fillvalue=None):
- if patch:
- p = patch[0]
- p.update(kwargs)
- if lbl is not None:
- p.set_label(lbl)
-
- p.set_snap(False)
-
- for p in patch[1:]:
- p.update(kwargs)
- p.set_label('_nolegend_')
-
- if binsgiven:
- if orientation == 'vertical':
- self.update_datalim(
- [(bins[0], 0), (bins[-1], 0)], updatey=False)
- else:
- self.update_datalim(
- [(0, bins[0]), (0, bins[-1])], updatex=False)
-
- if nx == 1:
- return n[0], bins, cbook.silent_list('Patch', patches[0])
- else:
- return n, bins, cbook.silent_list('Lists of Patches', patches)
-
- @docstring.dedent_interpd
- def hist2d(self, x, y, bins=10, range=None, normed=False, weights=None,
- cmin=None, cmax=None, **kwargs):
- """
- Make a 2D histogram plot.
-
- Parameters
- ----------
- x, y: array_like, shape (n, )
- Input values
-
- bins: [None | int | [int, int] | array_like | [array, array]]
-
- The bin specification:
-
- - If int, the number of bins for the two dimensions
- (nx=ny=bins).
-
- - If [int, int], the number of bins in each dimension
- (nx, ny = bins).
-
- - If array_like, the bin edges for the two dimensions
- (x_edges=y_edges=bins).
-
- - If [array, array], the bin edges in each dimension
- (x_edges, y_edges = bins).
-
- The default value is 10.
-
- range : array_like shape(2, 2), optional, default: None
- The leftmost and rightmost edges of the bins along each dimension
- (if not specified explicitly in the bins parameters): [[xmin,
- xmax], [ymin, ymax]]. All values outside of this range will be
- considered outliers and not tallied in the histogram.
-
- normed : boolean, optional, default: False
- Normalize histogram.
-
- weights : array_like, shape (n, ), optional, default: None
- An array of values w_i weighing each sample (x_i, y_i).
-
- cmin : scalar, optional, default: None
- All bins that has count less than cmin will not be displayed and
- these count values in the return value count histogram will also
- be set to nan upon return
-
- cmax : scalar, optional, default: None
- All bins that has count more than cmax will not be displayed (set
- to none before passing to imshow) and these count values in the
- return value count histogram will also be set to nan upon return
-
- Returns
- -------
- The return value is ``(counts, xedges, yedges, Image)``.
-
- Other parameters
- -----------------
- kwargs : :meth:`pcolorfast` properties.
-
- See also
- --------
- hist : 1D histogram
-
- Notes
- -----
- Rendering the histogram with a logarithmic color scale is
- accomplished by passing a :class:`colors.LogNorm` instance to
- the *norm* keyword argument. Likewise, power-law normalization
- (similar in effect to gamma correction) can be accomplished with
- :class:`colors.PowerNorm`.
-
- Examples
- --------
- .. plot:: mpl_examples/pylab_examples/hist2d_demo.py
- """
-
- # xrange becomes range after 2to3
- bin_range = range
- range = __builtins__["range"]
- h, xedges, yedges = np.histogram2d(x, y, bins=bins, range=bin_range,
- normed=normed, weights=weights)
-
- if cmin is not None:
- h[h < cmin] = None
- if cmax is not None:
- h[h > cmax] = None
-
- pc = self.pcolorfast(xedges, yedges, h.T, **kwargs)
- self.set_xlim(xedges[0], xedges[-1])
- self.set_ylim(yedges[0], yedges[-1])
-
- return h, xedges, yedges, pc
-
- @docstring.dedent_interpd
- def psd(self, x, NFFT=None, Fs=None, Fc=None, detrend=None,
- window=None, noverlap=None, pad_to=None,
- sides=None, scale_by_freq=None, return_line=None, **kwargs):
- """
- Plot the power spectral density.
-
- Call signature::
-
- psd(x, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none,
- window=mlab.window_hanning, noverlap=0, pad_to=None,
- sides='default', scale_by_freq=None, return_line=None, **kwargs)
-
- The power spectral density :math:`P_{xx}` by Welch's average
- periodogram method. The vector *x* is divided into *NFFT* length
- segments. Each segment is detrended by function *detrend* and
- windowed by function *window*. *noverlap* gives the length of
- the overlap between segments. The :math:`|\mathrm{fft}(i)|^2`
- of each segment :math:`i` are averaged to compute :math:`P_{xx}`,
- with a scaling to correct for power loss due to windowing.
-
- If len(*x*) < *NFFT*, it will be zero padded to *NFFT*.
-
- *x*: 1-D array or sequence
- Array or sequence containing the data
-
- %(Spectral)s
-
- %(PSD)s
-
- *noverlap*: integer
- The number of points of overlap between segments.
- The default value is 0 (no overlap).
-
- *Fc*: integer
- The center frequency of *x* (defaults to 0), which offsets
- the x extents of the plot to reflect the frequency range used
- when a signal is acquired and then filtered and downsampled to
- baseband.
-
- *return_line*: bool
- Whether to include the line object plotted in the returned values.
- Default is False.
-
- If *return_line* is False, returns the tuple (*Pxx*, *freqs*).
- If *return_line* is True, returns the tuple (*Pxx*, *freqs*. *line*):
-
- *Pxx*: 1-D array
- The values for the power spectrum `P_{xx}` before scaling
- (real valued)
-
- *freqs*: 1-D array
- The frequencies corresponding to the elements in *Pxx*
-
- *line*: a :class:`~matplotlib.lines.Line2D` instance
- The line created by this function.
- Only returend if *return_line* is True.
-
- For plotting, the power is plotted as
- :math:`10\log_{10}(P_{xx})` for decibels, though *Pxx* itself
- is returned.
-
- References:
- Bendat & Piersol -- Random Data: Analysis and Measurement
- Procedures, John Wiley & Sons (1986)
-
- kwargs control the :class:`~matplotlib.lines.Line2D` properties:
-
- %(Line2D)s
-
- **Example:**
-
- .. plot:: mpl_examples/pylab_examples/psd_demo.py
-
- .. seealso::
-
- :func:`specgram`
- :func:`specgram` differs in the default overlap; in not
- returning the mean of the segment periodograms; in returning
- the times of the segments; and in plotting a colormap instead
- of a line.
-
- :func:`magnitude_spectrum`
- :func:`magnitude_spectrum` plots the magnitude spectrum.
-
- :func:`csd`
- :func:`csd` plots the spectral density between two signals.
- """
- if not self._hold:
- self.cla()
-
- if Fc is None:
- Fc = 0
-
- pxx, freqs = mlab.psd(x=x, NFFT=NFFT, Fs=Fs, detrend=detrend,
- window=window, noverlap=noverlap, pad_to=pad_to,
- sides=sides, scale_by_freq=scale_by_freq)
- pxx.shape = len(freqs),
- freqs += Fc
-
- if scale_by_freq in (None, True):
- psd_units = 'dB/Hz'
- else:
- psd_units = 'dB'
-
- line = self.plot(freqs, 10 * np.log10(pxx), **kwargs)
- self.set_xlabel('Frequency')
- self.set_ylabel('Power Spectral Density (%s)' % psd_units)
- self.grid(True)
- vmin, vmax = self.viewLim.intervaly
- intv = vmax - vmin
- logi = int(np.log10(intv))
- if logi == 0:
- logi = .1
- step = 10 * logi
- #print vmin, vmax, step, intv, math.floor(vmin), math.ceil(vmax)+1
- ticks = np.arange(math.floor(vmin), math.ceil(vmax) + 1, step)
- self.set_yticks(ticks)
-
- if return_line is None or not return_line:
- return pxx, freqs
- else:
- return pxx, freqs, line
-
- @docstring.dedent_interpd
- def csd(self, x, y, NFFT=None, Fs=None, Fc=None, detrend=None,
- window=None, noverlap=None, pad_to=None,
- sides=None, scale_by_freq=None, return_line=None, **kwargs):
- """
- Plot the cross-spectral density.
-
- Call signature::
-
- csd(x, y, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none,
- window=mlab.window_hanning, noverlap=0, pad_to=None,
- sides='default', scale_by_freq=None, return_line=None, **kwargs)
-
- The cross spectral density :math:`P_{xy}` by Welch's average
- periodogram method. The vectors *x* and *y* are divided into
- *NFFT* length segments. Each segment is detrended by function
- *detrend* and windowed by function *window*. *noverlap* gives
- the length of the overlap between segments. The product of
- the direct FFTs of *x* and *y* are averaged over each segment
- to compute :math:`P_{xy}`, with a scaling to correct for power
- loss due to windowing.
-
- If len(*x*) < *NFFT* or len(*y*) < *NFFT*, they will be zero
- padded to *NFFT*.
-
- *x*, *y*: 1-D arrays or sequences
- Arrays or sequences containing the data
-
- %(Spectral)s
-
- %(PSD)s
-
- *noverlap*: integer
- The number of points of overlap between segments.
- The default value is 0 (no overlap).
-
- *Fc*: integer
- The center frequency of *x* (defaults to 0), which offsets
- the x extents of the plot to reflect the frequency range used
- when a signal is acquired and then filtered and downsampled to
- baseband.
-
- *return_line*: bool
- Whether to include the line object plotted in the returned values.
- Default is False.
-
- If *return_line* is False, returns the tuple (*Pxy*, *freqs*).
- If *return_line* is True, returns the tuple (*Pxy*, *freqs*. *line*):
-
- *Pxy*: 1-D array
- The values for the cross spectrum `P_{xy}` before scaling
- (complex valued)
-
- *freqs*: 1-D array
- The frequencies corresponding to the elements in *Pxy*
-
- *line*: a :class:`~matplotlib.lines.Line2D` instance
- The line created by this function.
- Only returend if *return_line* is True.
-
- For plotting, the power is plotted as
- :math:`10\log_{10}(P_{xy})` for decibels, though `P_{xy}` itself
- is returned.
-
- References:
- Bendat & Piersol -- Random Data: Analysis and Measurement
- Procedures, John Wiley & Sons (1986)
-
- kwargs control the Line2D properties:
-
- %(Line2D)s
-
- **Example:**
-
- .. plot:: mpl_examples/pylab_examples/csd_demo.py
-
- .. seealso::
-
- :func:`psd`
- :func:`psd` is the equivalent to setting y=x.
- """
- if not self._hold:
- self.cla()
-
- if Fc is None:
- Fc = 0
-
- pxy, freqs = mlab.csd(x=x, y=y, NFFT=NFFT, Fs=Fs, detrend=detrend,
- window=window, noverlap=noverlap, pad_to=pad_to,
- sides=sides, scale_by_freq=scale_by_freq)
- pxy.shape = len(freqs),
- # pxy is complex
- freqs += Fc
-
- line = self.plot(freqs, 10 * np.log10(np.absolute(pxy)), **kwargs)
- self.set_xlabel('Frequency')
- self.set_ylabel('Cross Spectrum Magnitude (dB)')
- self.grid(True)
- vmin, vmax = self.viewLim.intervaly
-
- intv = vmax - vmin
- step = 10 * int(np.log10(intv))
-
- ticks = np.arange(math.floor(vmin), math.ceil(vmax) + 1, step)
- self.set_yticks(ticks)
-
- if return_line is None or not return_line:
- return pxy, freqs
- else:
- return pxy, freqs, line
-
- @docstring.dedent_interpd
- def magnitude_spectrum(self, x, Fs=None, Fc=None, window=None,
- pad_to=None, sides=None, scale=None,
- **kwargs):
- """
- Plot the magnitude spectrum.
-
- Call signature::
-
- magnitude_spectrum(x, Fs=2, Fc=0, window=mlab.window_hanning,
- pad_to=None, sides='default', **kwargs)
-
- Compute the magnitude spectrum of *x*. Data is padded to a
- length of *pad_to* and the windowing function *window* is applied to
- the signal.
-
- *x*: 1-D array or sequence
- Array or sequence containing the data
-
- %(Spectral)s
-
- %(Single_Spectrum)s
-
- *scale*: [ 'default' | 'linear' | 'dB' ]
- The scaling of the values in the *spec*. 'linear' is no scaling.
- 'dB' returns the values in dB scale. When *mode* is 'density',
- this is dB power (10 * log10). Otherwise this is dB amplitude
- (20 * log10). 'default' is 'linear'.
-
- *Fc*: integer
- The center frequency of *x* (defaults to 0), which offsets
- the x extents of the plot to reflect the frequency range used
- when a signal is acquired and then filtered and downsampled to
- baseband.
-
- Returns the tuple (*spectrum*, *freqs*, *line*):
-
- *spectrum*: 1-D array
- The values for the magnitude spectrum before scaling (real valued)
-
- *freqs*: 1-D array
- The frequencies corresponding to the elements in *spectrum*
-
- *line*: a :class:`~matplotlib.lines.Line2D` instance
- The line created by this function
-
- kwargs control the :class:`~matplotlib.lines.Line2D` properties:
-
- %(Line2D)s
-
- **Example:**
-
- .. plot:: mpl_examples/pylab_examples/spectrum_demo.py
-
- .. seealso::
-
- :func:`psd`
- :func:`psd` plots the power spectral density.`.
-
- :func:`angle_spectrum`
- :func:`angle_spectrum` plots the angles of the corresponding
- frequencies.
-
- :func:`phase_spectrum`
- :func:`phase_spectrum` plots the phase (unwrapped angle) of the
- corresponding frequencies.
-
- :func:`specgram`
- :func:`specgram` can plot the magnitude spectrum of segments
- within the signal in a colormap.
- """
- if not self._hold:
- self.cla()
-
- if Fc is None:
- Fc = 0
-
- if scale is None or scale == 'default':
- scale = 'linear'
-
- spec, freqs = mlab.magnitude_spectrum(x=x, Fs=Fs, window=window,
- pad_to=pad_to, sides=sides)
- freqs += Fc
-
- if scale == 'linear':
- Z = spec
- yunits = 'energy'
- elif scale == 'dB':
- Z = 20. * np.log10(spec)
- yunits = 'dB'
- else:
- raise ValueError('Unknown scale %s', scale)
-
- lines = self.plot(freqs, Z, **kwargs)
- self.set_xlabel('Frequency')
- self.set_ylabel('Magnitude (%s)' % yunits)
-
- return spec, freqs, lines[0]
-
- @docstring.dedent_interpd
- def angle_spectrum(self, x, Fs=None, Fc=None, window=None,
- pad_to=None, sides=None, **kwargs):
- """
- Plot the angle spectrum.
-
- Call signature::
-
- angle_spectrum(x, Fs=2, Fc=0, window=mlab.window_hanning,
- pad_to=None, sides='default', **kwargs)
-
- Compute the angle spectrum (wrapped phase spectrum) of *x*.
- Data is padded to a length of *pad_to* and the windowing function
- *window* is applied to the signal.
-
- *x*: 1-D array or sequence
- Array or sequence containing the data
-
- %(Spectral)s
-
- %(Single_Spectrum)s
-
- *Fc*: integer
- The center frequency of *x* (defaults to 0), which offsets
- the x extents of the plot to reflect the frequency range used
- when a signal is acquired and then filtered and downsampled to
- baseband.
-
- Returns the tuple (*spectrum*, *freqs*, *line*):
-
- *spectrum*: 1-D array
- The values for the angle spectrum in radians (real valued)
-
- *freqs*: 1-D array
- The frequencies corresponding to the elements in *spectrum*
-
- *line*: a :class:`~matplotlib.lines.Line2D` instance
- The line created by this function
-
- kwargs control the :class:`~matplotlib.lines.Line2D` properties:
-
- %(Line2D)s
-
- **Example:**
-
- .. plot:: mpl_examples/pylab_examples/spectrum_demo.py
-
- .. seealso::
-
- :func:`magnitude_spectrum`
- :func:`angle_spectrum` plots the magnitudes of the
- corresponding frequencies.
-
- :func:`phase_spectrum`
- :func:`phase_spectrum` plots the unwrapped version of this
- function.
-
- :func:`specgram`
- :func:`specgram` can plot the angle spectrum of segments
- within the signal in a colormap.
- """
- if not self._hold:
- self.cla()
-
- if Fc is None:
- Fc = 0
-
- spec, freqs = mlab.angle_spectrum(x=x, Fs=Fs, window=window,
- pad_to=pad_to, sides=sides)
- freqs += Fc
-
- lines = self.plot(freqs, spec, **kwargs)
- self.set_xlabel('Frequency')
- self.set_ylabel('Angle (radians)')
-
- return spec, freqs, lines[0]
-
- @docstring.dedent_interpd
- def phase_spectrum(self, x, Fs=None, Fc=None, window=None,
- pad_to=None, sides=None, **kwargs):
- """
- Plot the phase spectrum.
-
- Call signature::
-
- phase_spectrum(x, Fs=2, Fc=0, window=mlab.window_hanning,
- pad_to=None, sides='default', **kwargs)
-
- Compute the phase spectrum (unwrapped angle spectrum) of *x*.
- Data is padded to a length of *pad_to* and the windowing function
- *window* is applied to the signal.
-
- *x*: 1-D array or sequence
- Array or sequence containing the data
-
- %(Spectral)s
-
- %(Single_Spectrum)s
-
- *Fc*: integer
- The center frequency of *x* (defaults to 0), which offsets
- the x extents of the plot to reflect the frequency range used
- when a signal is acquired and then filtered and downsampled to
- baseband.
-
- Returns the tuple (*spectrum*, *freqs*, *line*):
-
- *spectrum*: 1-D array
- The values for the phase spectrum in radians (real valued)
-
- *freqs*: 1-D array
- The frequencies corresponding to the elements in *spectrum*
-
- *line*: a :class:`~matplotlib.lines.Line2D` instance
- The line created by this function
-
- kwargs control the :class:`~matplotlib.lines.Line2D` properties:
-
- %(Line2D)s
-
- **Example:**
-
- .. plot:: mpl_examples/pylab_examples/spectrum_demo.py
-
- .. seealso::
-
- :func:`magnitude_spectrum`
- :func:`magnitude_spectrum` plots the magnitudes of the
- corresponding frequencies.
-
- :func:`angle_spectrum`
- :func:`angle_spectrum` plots the wrapped version of this
- function.
-
- :func:`specgram`
- :func:`specgram` can plot the phase spectrum of segments
- within the signal in a colormap.
- """
- if not self._hold:
- self.cla()
-
- if Fc is None:
- Fc = 0
-
- spec, freqs = mlab.phase_spectrum(x=x, Fs=Fs, window=window,
- pad_to=pad_to, sides=sides)
- freqs += Fc
-
- lines = self.plot(freqs, spec, **kwargs)
- self.set_xlabel('Frequency')
- self.set_ylabel('Phase (radians)')
-
- return spec, freqs, lines[0]
-
- @docstring.dedent_interpd
- def cohere(self, x, y, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none,
- window=mlab.window_hanning, noverlap=0, pad_to=None,
- sides='default', scale_by_freq=None, **kwargs):
- """
- Plot the coherence between *x* and *y*.
-
- Call signature::
-
- cohere(x, y, NFFT=256, Fs=2, Fc=0, detrend = mlab.detrend_none,
- window = mlab.window_hanning, noverlap=0, pad_to=None,
- sides='default', scale_by_freq=None, **kwargs)
-
- Plot the coherence between *x* and *y*. Coherence is the
- normalized cross spectral density:
-
- .. math::
-
- C_{xy} = \\frac{|P_{xy}|^2}{P_{xx}P_{yy}}
-
- %(Spectral)s
-
- %(PSD)s
-
- *noverlap*: integer
- The number of points of overlap between blocks. The
- default value is 0 (no overlap).
-
- *Fc*: integer
- The center frequency of *x* (defaults to 0), which offsets
- the x extents of the plot to reflect the frequency range used
- when a signal is acquired and then filtered and downsampled to
- baseband.
-
- The return value is a tuple (*Cxy*, *f*), where *f* are the
- frequencies of the coherence vector.
-
- kwargs are applied to the lines.
-
- References:
-
- * Bendat & Piersol -- Random Data: Analysis and Measurement
- Procedures, John Wiley & Sons (1986)
-
- kwargs control the :class:`~matplotlib.lines.Line2D`
- properties of the coherence plot:
-
- %(Line2D)s
-
- **Example:**
-
- .. plot:: mpl_examples/pylab_examples/cohere_demo.py
- """
- if not self._hold:
- self.cla()
- cxy, freqs = mlab.cohere(x=x, y=y, NFFT=NFFT, Fs=Fs, detrend=detrend,
- window=window, noverlap=noverlap,
- scale_by_freq=scale_by_freq)
- freqs += Fc
-
- self.plot(freqs, cxy, **kwargs)
- self.set_xlabel('Frequency')
- self.set_ylabel('Coherence')
- self.grid(True)
-
- return cxy, freqs
-
- @docstring.dedent_interpd
- def specgram(self, x, NFFT=None, Fs=None, Fc=None, detrend=None,
- window=None, noverlap=None,
- cmap=None, xextent=None, pad_to=None, sides=None,
- scale_by_freq=None, mode=None, scale=None,
- vmin=None, vmax=None, **kwargs):
- """
- Plot a spectrogram.
-
- Call signature::
-
- specgram(x, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none,
- window=mlab.window_hanning, noverlap=128,
- cmap=None, xextent=None, pad_to=None, sides='default',
- scale_by_freq=None, mode='default', scale='default',
- **kwargs)
-
- Compute and plot a spectrogram of data in *x*. Data are split into
- *NFFT* length segments and the spectrum of each section is
- computed. The windowing function *window* is applied to each
- segment, and the amount of overlap of each segment is
- specified with *noverlap*. The spectrogram is plotted as a colormap
- (using imshow).
-
- *x*: 1-D array or sequence
- Array or sequence containing the data
-
- %(Spectral)s
-
- %(PSD)s
-
- *mode*: [ 'default' | 'psd' | 'magnitude' | 'angle' | 'phase' ]
- What sort of spectrum to use. Default is 'psd'. which takes
- the power spectral density. 'complex' returns the complex-valued
- frequency spectrum. 'magnitude' returns the magnitude spectrum.
- 'angle' returns the phase spectrum without unwrapping. 'phase'
- returns the phase spectrum with unwrapping.
-
- *noverlap*: integer
- The number of points of overlap between blocks. The
- default value is 128.
-
- *scale*: [ 'default' | 'linear' | 'dB' ]
- The scaling of the values in the *spec*. 'linear' is no scaling.
- 'dB' returns the values in dB scale. When *mode* is 'psd',
- this is dB power (10 * log10). Otherwise this is dB amplitude
- (20 * log10). 'default' is 'dB' if *mode* is 'psd' or
- 'magnitude' and 'linear' otherwise. This must be 'linear'
- if *mode* is 'angle' or 'phase'.
-
- *Fc*: integer
- The center frequency of *x* (defaults to 0), which offsets
- the x extents of the plot to reflect the frequency range used
- when a signal is acquired and then filtered and downsampled to
- baseband.
-
- *cmap*:
- A :class:`matplotlib.colors.Colormap` instance; if *None*, use
- default determined by rc
-
- *xextent*:
- The image extent along the x-axis. xextent = (xmin,xmax)
- The default is (0,max(bins)), where bins is the return
- value from :func:`~matplotlib.mlab.specgram`
-
- *kwargs*:
- Additional kwargs are passed on to imshow which makes the
- specgram image
-
- .. note::
-
- *detrend* and *scale_by_freq* only apply when *mode* is set to
- 'psd'
-
- Returns the tuple (*spectrum*, *freqs*, *t*, *im*):
-
- *spectrum*: 2-D array
- columns are the periodograms of successive segments
-
- *freqs*: 1-D array
- The frequencies corresponding to the rows in *spectrum*
-
- *t*: 1-D array
- The times corresponding to midpoints of segments (i.e the columns
- in *spectrum*)
-
- *im*: instance of class :class:`~matplotlib.image.AxesImage`
- The image created by imshow containing the spectrogram
-
- **Example:**
-
- .. plot:: mpl_examples/pylab_examples/specgram_demo.py
-
- .. seealso::
-
- :func:`psd`
- :func:`psd` differs in the default overlap; in returning
- the mean of the segment periodograms; in not returning
- times; and in generating a line plot instead of colormap.
-
- :func:`magnitude_spectrum`
- A single spectrum, similar to having a single segment when
- *mode* is 'magnitude'. Plots a line instead of a colormap.
-
- :func:`angle_spectrum`
- A single spectrum, similar to having a single segment when
- *mode* is 'angle'. Plots a line instead of a colormap.
-
- :func:`phase_spectrum`
- A single spectrum, similar to having a single segment when
- *mode* is 'phase'. Plots a line instead of a colormap.
- """
- if not self._hold:
- self.cla()
-
- if Fc is None:
- Fc = 0
-
- if mode == 'complex':
- raise ValueError('Cannot plot a complex specgram')
-
- if scale is None or scale == 'default':
- if mode in ['angle', 'phase']:
- scale = 'linear'
- else:
- scale = 'dB'
- elif mode in ['angle', 'phase'] and scale == 'dB':
- raise ValueError('Cannot use dB scale with angle or phase mode')
-
- spec, freqs, t = mlab.specgram(x=x, NFFT=NFFT, Fs=Fs,
- detrend=detrend, window=window,
- noverlap=noverlap, pad_to=pad_to,
- sides=sides,
- scale_by_freq=scale_by_freq,
- mode=mode)
-
- if scale == 'linear':
- Z = spec
- elif scale == 'dB':
- if mode is None or mode == 'default' or mode == 'psd':
- Z = 10. * np.log10(spec)
- else:
- Z = 20. * np.log10(spec)
- else:
- raise ValueError('Unknown scale %s', scale)
-
- Z = np.flipud(Z)
-
- if xextent is None:
- xextent = 0, np.amax(t)
- xmin, xmax = xextent
- freqs += Fc
- extent = xmin, xmax, freqs[0], freqs[-1]
- im = self.imshow(Z, cmap, extent=extent, vmin=vmin, vmax=vmax,
- **kwargs)
- self.axis('auto')
-
- return spec, freqs, t, im
-
- def spy(self, Z, precision=0, marker=None, markersize=None,
- aspect='equal', origin="upper", **kwargs):
- """
- Plot the sparsity pattern on a 2-D array.
-
- ``spy(Z)`` plots the sparsity pattern of the 2-D array *Z*.
-
- Parameters
- ----------
-
- Z : sparse array (n, m)
- The array to be plotted.
-
- precision : float, optional, default: 0
- If *precision* is 0, any non-zero value will be plotted; else,
- values of :math:`|Z| > precision` will be plotted.
-
- For :class:`scipy.sparse.spmatrix` instances, there is a special
- case: if *precision* is 'present', any value present in the array
- will be plotted, even if it is identically zero.
-
- origin : ["upper", "lower"], optional, default: "upper"
- Place the [0,0] index of the array in the upper left or lower left
- corner of the axes.
-
- aspect : ['auto' | 'equal' | scalar], optional, default: "equal"
-
- If 'equal', and `extent` is None, changes the axes aspect ratio to
- match that of the image. If `extent` is not `None`, the axes
- aspect ratio is changed to match that of the extent.
-
-
- If 'auto', changes the image aspect ratio to match that of the
- axes.
-
- If None, default to rc ``image.aspect`` value.
-
- Two plotting styles are available: image or marker. Both
- are available for full arrays, but only the marker style
- works for :class:`scipy.sparse.spmatrix` instances.
-
- If *marker* and *markersize* are *None*, an image will be
- returned and any remaining kwargs are passed to
- :func:`~matplotlib.pyplot.imshow`; else, a
- :class:`~matplotlib.lines.Line2D` object will be returned with
- the value of marker determining the marker type, and any
- remaining kwargs passed to the
- :meth:`~matplotlib.axes.Axes.plot` method.
-
- If *marker* and *markersize* are *None*, useful kwargs include:
-
- * *cmap*
- * *alpha*
-
- See also
- --------
- imshow : for image options.
- plot : for plotting options
- """
- if marker is None and markersize is None and hasattr(Z, 'tocoo'):
- marker = 's'
- if marker is None and markersize is None:
- Z = np.asarray(Z)
- mask = np.absolute(Z) > precision
-
- if 'cmap' not in kwargs:
- kwargs['cmap'] = mcolors.ListedColormap(['w', 'k'],
- name='binary')
- nr, nc = Z.shape
- extent = [-0.5, nc - 0.5, nr - 0.5, -0.5]
- ret = self.imshow(mask, interpolation='nearest', aspect=aspect,
- extent=extent, origin=origin, **kwargs)
- else:
- if hasattr(Z, 'tocoo'):
- c = Z.tocoo()
- if precision == 'present':
- y = c.row
- x = c.col
- else:
- nonzero = np.absolute(c.data) > precision
- y = c.row[nonzero]
- x = c.col[nonzero]
- else:
- Z = np.asarray(Z)
- nonzero = np.absolute(Z) > precision
- y, x = np.nonzero(nonzero)
- if marker is None:
- marker = 's'
- if markersize is None:
- markersize = 10
- marks = mlines.Line2D(x, y, linestyle='None',
- marker=marker, markersize=markersize, **kwargs)
- self.add_line(marks)
- nr, nc = Z.shape
- self.set_xlim(xmin=-0.5, xmax=nc - 0.5)
- self.set_ylim(ymin=nr - 0.5, ymax=-0.5)
- self.set_aspect(aspect)
- ret = marks
- self.title.set_y(1.05)
- self.xaxis.tick_top()
- self.xaxis.set_ticks_position('both')
- self.xaxis.set_major_locator(mticker.MaxNLocator(nbins=9,
- steps=[1, 2, 5, 10],
- integer=True))
- self.yaxis.set_major_locator(mticker.MaxNLocator(nbins=9,
- steps=[1, 2, 5, 10],
- integer=True))
- return ret
-
- def matshow(self, Z, **kwargs):
- """
- Plot a matrix or array as an image.
-
- The matrix will be shown the way it would be printed, with the first
- row at the top. Row and column numbering is zero-based.
-
- Parameters
- ----------
- Z : array_like shape (n, m)
- The matrix to be displayed.
-
- Returns
- -------
- image : `~matplotlib.image.AxesImage`
-
- Other parameters
- ----------------
- kwargs : `~matplotlib.axes.Axes.imshow` arguments
- Sets `origin` to 'upper', 'interpolation' to 'nearest' and
- 'aspect' to equal.
-
- See also
- --------
- imshow : plot an image
-
- Examples
- --------
- .. plot:: mpl_examples/pylab_examples/matshow.py
-
- """
- Z = np.asanyarray(Z)
- nr, nc = Z.shape
- kw = {'origin': 'upper',
- 'interpolation': 'nearest',
- 'aspect': 'equal'} # (already the imshow default)
- kw.update(kwargs)
- im = self.imshow(Z, **kw)
- self.title.set_y(1.05)
- self.xaxis.tick_top()
- self.xaxis.set_ticks_position('both')
- self.xaxis.set_major_locator(mticker.MaxNLocator(nbins=9,
- steps=[1, 2, 5, 10],
- integer=True))
- self.yaxis.set_major_locator(mticker.MaxNLocator(nbins=9,
- steps=[1, 2, 5, 10],
- integer=True))
- return im
-
- def violinplot(self, dataset, positions=None, vert=True, widths=0.5,
- showmeans=False, showextrema=True, showmedians=False,
- points=100, bw_method=None):
- """Make a violin plot.
-
- Call signature::
-
- violinplot(dataset, positions=None, vert=True, widths=0.5,
- showmeans=False, showextrema=True, showmedians=False,
- points=100, bw_method=None):
-
- Make a violin plot for each column of *dataset* or each vector in
- sequence *dataset*. Each filled area extends to represent the
- entire data range, with optional lines at the mean, the median,
- the minimum, and the maximum.
-
- Parameters
- ----------
- dataset : Array or a sequence of vectors.
- The input data.
-
- positions : array-like, default = [1, 2, ..., n]
- Sets the positions of the violins. The ticks and limits are
- automatically set to match the positions.
-
- vert : bool, default = True.
- If true, creates a vertical violin plot.
- Otherwise, creates a horizontal violin plot.
-
- widths : array-like, default = 0.5
- Either a scalar or a vector that sets the maximal width of
- each violin. The default is 0.5, which uses about half of the
- available horizontal space.
-
- showmeans : bool, default = False
- If `True`, will toggle rendering of the means.
-
- showextrema : bool, default = True
- If `True`, will toggle rendering of the extrema.
-
- showmedians : bool, default = False
- If `True`, will toggle rendering of the medians.
-
- points : scalar, default = 100
- Defines the number of points to evaluate each of the
- gaussian kernel density estimations at.
-
- bw_method : str, scalar or callable, optional
- The method used to calculate the estimator bandwidth. This can be
- 'scott', 'silverman', a scalar constant or a callable. If a
- scalar, this will be used directly as `kde.factor`. If a
- callable, it should take a `GaussianKDE` instance as its only
- parameter and return a scalar. If None (default), 'scott' is used.
-
- Returns
- -------
-
- result : dict
- A dictionary mapping each component of the violinplot to a
- list of the corresponding collection instances created. The
- dictionary has the following keys:
-
- - ``bodies``: A list of the
- :class:`matplotlib.collections.PolyCollection` instances
- containing the filled area of each violin.
-
- - ``means``: A
- :class:`matplotlib.collections.LineCollection` instance
- created to identify the mean values of each of the
- violin's distribution.
-
- - ``mins``: A
- :class:`matplotlib.collections.LineCollection` instance
- created to identify the bottom of each violin's
- distribution.
-
- - ``maxes``: A
- :class:`matplotlib.collections.LineCollection` instance
- created to identify the top of each violin's
- distribution.
-
- - ``bars``: A
- :class:`matplotlib.collections.LineCollection` instance
- created to identify the centers of each violin's
- distribution.
-
- - ``medians``: A
- :class:`matplotlib.collections.LineCollection` instance
- created to identify the median values of each of the
- violin's distribution.
- """
-
- def _kde_method(X, coords):
- kde = mlab.GaussianKDE(X, bw_method)
- return kde.evaluate(coords)
-
- vpstats = cbook.violin_stats(dataset, _kde_method, points=points)
- return self.violin(vpstats, positions=positions, vert=vert,
- widths=widths, showmeans=showmeans,
- showextrema=showextrema, showmedians=showmedians)
-
- def violin(self, vpstats, positions=None, vert=True, widths=0.5,
- showmeans=False, showextrema=True, showmedians=False):
- """Drawing function for violin plots.
-
- Call signature::
-
- violin(vpstats, positions=None, vert=True, widths=0.5,
- showmeans=False, showextrema=True, showmedians=False):
-
- Draw a violin plot for each column of `vpstats`. Each filled area
- extends to represent the entire data range, with optional lines at the
- mean, the median, the minimum, and the maximum.
-
- Parameters
- ----------
-
- vpstats : list of dicts
- A list of dictionaries containing stats for each violin plot.
- Required keys are:
-
- - ``coords``: A list of scalars containing the coordinates that
- the violin's kernel density estimate were evaluated at.
-
- - ``vals``: A list of scalars containing the values of the
- kernel density estimate at each of the coordinates given
- in *coords*.
-
- - ``mean``: The mean value for this violin's dataset.
-
- - ``median``: The median value for this violin's dataset.
-
- - ``min``: The minimum value for this violin's dataset.
-
- - ``max``: The maximum value for this violin's dataset.
-
- positions : array-like, default = [1, 2, ..., n]
- Sets the positions of the violins. The ticks and limits are
- automatically set to match the positions.
-
- vert : bool, default = True.
- If true, plots the violins veritcally.
- Otherwise, plots the violins horizontally.
-
- widths : array-like, default = 0.5
- Either a scalar or a vector that sets the maximal width of
- each violin. The default is 0.5, which uses about half of the
- available horizontal space.
-
- showmeans : bool, default = False
- If true, will toggle rendering of the means.
-
- showextrema : bool, default = True
- If true, will toggle rendering of the extrema.
-
- showmedians : bool, default = False
- If true, will toggle rendering of the medians.
-
- Returns
- -------
- result : dict
- A dictionary mapping each component of the violinplot to a
- list of the corresponding collection instances created. The
- dictionary has the following keys:
-
- - ``bodies``: A list of the
- :class:`matplotlib.collections.PolyCollection` instances
- containing the filled area of each violin.
-
- - ``means``: A
- :class:`matplotlib.collections.LineCollection` instance
- created to identify the mean values of each of the
- violin's distribution.
-
- - ``mins``: A
- :class:`matplotlib.collections.LineCollection` instance
- created to identify the bottom of each violin's
- distribution.
-
- - ``maxes``: A
- :class:`matplotlib.collections.LineCollection` instance
- created to identify the top of each violin's
- distribution.
-
- - ``bars``: A
- :class:`matplotlib.collections.LineCollection` instance
- created to identify the centers of each violin's
- distribution.
-
- - ``medians``: A
- :class:`matplotlib.collections.LineCollection` instance
- created to identify the median values of each of the
- violin's distribution.
-
- """
-
- # Statistical quantities to be plotted on the violins
- means = []
- mins = []
- maxes = []
- medians = []
-
- # Collections to be returned
- artists = {}
-
- N = len(vpstats)
- datashape_message = ("List of violinplot statistics and `{0}` "
- "values must have the same length")
-
- # Validate positions
- if positions is None:
- positions = range(1, N + 1)
- elif len(positions) != N:
- raise ValueError(datashape_message.format("positions"))
-
- # Validate widths
- if np.isscalar(widths):
- widths = [widths] * N
- elif len(widths) != N:
- raise ValueError(datashape_message.format("widths"))
-
- # Calculate ranges for statistics lines
- pmins = -0.25 * np.array(widths) + positions
- pmaxes = 0.25 * np.array(widths) + positions
-
- # Check whether we are rendering vertically or horizontally
- if vert:
- fill = self.fill_betweenx
- perp_lines = self.hlines
- par_lines = self.vlines
- else:
- fill = self.fill_between
- perp_lines = self.vlines
- par_lines = self.hlines
-
- # Render violins
- bodies = []
- for stats, pos, width in zip(vpstats, positions, widths):
- # The 0.5 factor reflects the fact that we plot from v-p to
- # v+p
- vals = np.array(stats['vals'])
- vals = 0.5 * width * vals / vals.max()
- bodies += [fill(stats['coords'],
- -vals + pos,
- vals + pos,
- facecolor='y',
- alpha=0.3)]
- means.append(stats['mean'])
- mins.append(stats['min'])
- maxes.append(stats['max'])
- medians.append(stats['median'])
- artists['bodies'] = bodies
-
- # Render means
- if showmeans:
- artists['cmeans'] = perp_lines(means, pmins, pmaxes, colors='r')
-
- # Render extrema
- if showextrema:
- artists['cmaxes'] = perp_lines(maxes, pmins, pmaxes, colors='r')
- artists['cmins'] = perp_lines(mins, pmins, pmaxes, colors='r')
- artists['cbars'] = par_lines(positions, mins, maxes, colors='r')
-
- # Render medians
- if showmedians:
- artists['cmedians'] = perp_lines(medians,
- pmins,
- pmaxes,
- colors='r')
-
- return artists
-
- def tricontour(self, *args, **kwargs):
- return mtri.tricontour(self, *args, **kwargs)
- tricontour.__doc__ = mtri.TriContourSet.tricontour_doc
-
- def tricontourf(self, *args, **kwargs):
- return mtri.tricontourf(self, *args, **kwargs)
- tricontourf.__doc__ = mtri.TriContourSet.tricontour_doc
-
- def tripcolor(self, *args, **kwargs):
- return mtri.tripcolor(self, *args, **kwargs)
- tripcolor.__doc__ = mtri.tripcolor.__doc__
-
- def triplot(self, *args, **kwargs):
- return mtri.triplot(self, *args, **kwargs)
- triplot.__doc__ = mtri.triplot.__doc__
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/axes/_base.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/axes/_base.py
deleted file mode 100644
index 8dbc664..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/axes/_base.py
+++ /dev/null
@@ -1,3350 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import xrange
-
-import itertools
-import warnings
-import math
-from operator import itemgetter
-
-import numpy as np
-from numpy import ma
-
-import matplotlib
-rcParams = matplotlib.rcParams
-
-from matplotlib import cbook
-from matplotlib.cbook import _string_to_bool
-from matplotlib import docstring
-import matplotlib.colors as mcolors
-import matplotlib.lines as mlines
-import matplotlib.patches as mpatches
-import matplotlib.artist as martist
-import matplotlib.transforms as mtransforms
-import matplotlib.ticker as mticker
-import matplotlib.axis as maxis
-import matplotlib.scale as mscale
-import matplotlib.spines as mspines
-import matplotlib.font_manager as font_manager
-import matplotlib.text as mtext
-import matplotlib.image as mimage
-from matplotlib.artist import allow_rasterization
-
-
-from matplotlib.cbook import iterable
-
-
-is_string_like = cbook.is_string_like
-is_sequence_of_strings = cbook.is_sequence_of_strings
-
-
-def _process_plot_format(fmt):
- """
- Process a MATLAB style color/line style format string. Return a
- (*linestyle*, *color*) tuple as a result of the processing. Default
- values are ('-', 'b'). Example format strings include:
-
- * 'ko': black circles
- * '.b': blue dots
- * 'r--': red dashed lines
-
- .. seealso::
-
- :func:`~matplotlib.Line2D.lineStyles` and
- :func:`~matplotlib.pyplot.colors`
- for all possible styles and color format string.
- """
-
- linestyle = None
- marker = None
- color = None
-
- # Is fmt just a colorspec?
- try:
- color = mcolors.colorConverter.to_rgb(fmt)
-
- # We need to differentiate grayscale '1.0' from tri_down marker '1'
- try:
- fmtint = str(int(fmt))
- except ValueError:
- return linestyle, marker, color # Yes
- else:
- if fmt != fmtint:
- # user definitely doesn't want tri_down marker
- return linestyle, marker, color # Yes
- else:
- # ignore converted color
- color = None
- except ValueError:
- pass # No, not just a color.
-
- # handle the multi char special cases and strip them from the
- # string
- if fmt.find('--') >= 0:
- linestyle = '--'
- fmt = fmt.replace('--', '')
- if fmt.find('-.') >= 0:
- linestyle = '-.'
- fmt = fmt.replace('-.', '')
- if fmt.find(' ') >= 0:
- linestyle = 'None'
- fmt = fmt.replace(' ', '')
-
- chars = [c for c in fmt]
-
- for c in chars:
- if c in mlines.lineStyles:
- if linestyle is not None:
- raise ValueError(
- 'Illegal format string "%s"; two linestyle symbols' % fmt)
- linestyle = c
- elif c in mlines.lineMarkers:
- if marker is not None:
- raise ValueError(
- 'Illegal format string "%s"; two marker symbols' % fmt)
- marker = c
- elif c in mcolors.colorConverter.colors:
- if color is not None:
- raise ValueError(
- 'Illegal format string "%s"; two color symbols' % fmt)
- color = c
- else:
- raise ValueError(
- 'Unrecognized character %c in format string' % c)
-
- if linestyle is None and marker is None:
- linestyle = rcParams['lines.linestyle']
- if linestyle is None:
- linestyle = 'None'
- if marker is None:
- marker = 'None'
-
- return linestyle, marker, color
-
-
-class _process_plot_var_args(object):
- """
- Process variable length arguments to the plot command, so that
- plot commands like the following are supported::
-
- plot(t, s)
- plot(t1, s1, t2, s2)
- plot(t1, s1, 'ko', t2, s2)
- plot(t1, s1, 'ko', t2, s2, 'r--', t3, e3)
-
- an arbitrary number of *x*, *y*, *fmt* are allowed
- """
- def __init__(self, axes, command='plot'):
- self.axes = axes
- self.command = command
- self.set_color_cycle()
-
- def __getstate__(self):
- # note: it is not possible to pickle a itertools.cycle instance
- return {'axes': self.axes, 'command': self.command}
-
- def __setstate__(self, state):
- self.__dict__ = state.copy()
- self.set_color_cycle()
-
- def set_color_cycle(self, clist=None):
- if clist is None:
- clist = rcParams['axes.color_cycle']
- self.color_cycle = itertools.cycle(clist)
-
- def __call__(self, *args, **kwargs):
-
- if self.axes.xaxis is not None and self.axes.yaxis is not None:
- xunits = kwargs.pop('xunits', self.axes.xaxis.units)
-
- if self.axes.name == 'polar':
- xunits = kwargs.pop('thetaunits', xunits)
-
- yunits = kwargs.pop('yunits', self.axes.yaxis.units)
-
- if self.axes.name == 'polar':
- yunits = kwargs.pop('runits', yunits)
-
- if xunits != self.axes.xaxis.units:
- self.axes.xaxis.set_units(xunits)
-
- if yunits != self.axes.yaxis.units:
- self.axes.yaxis.set_units(yunits)
-
- ret = self._grab_next_args(*args, **kwargs)
- return ret
-
- def set_lineprops(self, line, **kwargs):
- assert self.command == 'plot', 'set_lineprops only works with "plot"'
- for key, val in six.iteritems(kwargs):
- funcName = "set_%s" % key
- if not hasattr(line, funcName):
- raise TypeError('There is no line property "%s"' % key)
- func = getattr(line, funcName)
- func(val)
-
- def set_patchprops(self, fill_poly, **kwargs):
- assert self.command == 'fill', 'set_patchprops only works with "fill"'
- for key, val in six.iteritems(kwargs):
- funcName = "set_%s" % key
- if not hasattr(fill_poly, funcName):
- raise TypeError('There is no patch property "%s"' % key)
- func = getattr(fill_poly, funcName)
- func(val)
-
- def _xy_from_xy(self, x, y):
- if self.axes.xaxis is not None and self.axes.yaxis is not None:
- bx = self.axes.xaxis.update_units(x)
- by = self.axes.yaxis.update_units(y)
-
- if self.command != 'plot':
- # the Line2D class can handle unitized data, with
- # support for post hoc unit changes etc. Other mpl
- # artists, e.g., Polygon which _process_plot_var_args
- # also serves on calls to fill, cannot. So this is a
- # hack to say: if you are not "plot", which is
- # creating Line2D, then convert the data now to
- # floats. If you are plot, pass the raw data through
- # to Line2D which will handle the conversion. So
- # polygons will not support post hoc conversions of
- # the unit type since they are not storing the orig
- # data. Hopefully we can rationalize this at a later
- # date - JDH
- if bx:
- x = self.axes.convert_xunits(x)
- if by:
- y = self.axes.convert_yunits(y)
-
- x = np.atleast_1d(x) # like asanyarray, but converts scalar to array
- y = np.atleast_1d(y)
- if x.shape[0] != y.shape[0]:
- raise ValueError("x and y must have same first dimension")
- if x.ndim > 2 or y.ndim > 2:
- raise ValueError("x and y can be no greater than 2-D")
-
- if x.ndim == 1:
- x = x[:, np.newaxis]
- if y.ndim == 1:
- y = y[:, np.newaxis]
- return x, y
-
- def _makeline(self, x, y, kw, kwargs):
- kw = kw.copy() # Don't modify the original kw.
- kwargs = kwargs.copy()
- if kw.get('color', None) is None and kwargs.get('color', None) is None:
- kwargs['color'] = kw['color'] = six.next(self.color_cycle)
- # (can't use setdefault because it always evaluates
- # its second argument)
- seg = mlines.Line2D(x, y,
- axes=self.axes,
- **kw
- )
- self.set_lineprops(seg, **kwargs)
- return seg
-
- def _makefill(self, x, y, kw, kwargs):
- try:
- facecolor = kw['color']
- except KeyError:
- facecolor = six.next(self.color_cycle)
- seg = mpatches.Polygon(np.hstack((x[:, np.newaxis],
- y[:, np.newaxis])),
- facecolor=facecolor,
- fill=True,
- closed=kw['closed'])
- self.set_patchprops(seg, **kwargs)
- return seg
-
- def _plot_args(self, tup, kwargs):
- ret = []
- if len(tup) > 1 and is_string_like(tup[-1]):
- linestyle, marker, color = _process_plot_format(tup[-1])
- tup = tup[:-1]
- elif len(tup) == 3:
- raise ValueError('third arg must be a format string')
- else:
- linestyle, marker, color = None, None, None
- kw = {}
- for k, v in zip(('linestyle', 'marker', 'color'),
- (linestyle, marker, color)):
- if v is not None:
- kw[k] = v
-
- y = np.atleast_1d(tup[-1])
-
- if len(tup) == 2:
- x = np.atleast_1d(tup[0])
- else:
- x = np.arange(y.shape[0], dtype=float)
-
- x, y = self._xy_from_xy(x, y)
-
- if self.command == 'plot':
- func = self._makeline
- else:
- kw['closed'] = kwargs.get('closed', True)
- func = self._makefill
-
- ncx, ncy = x.shape[1], y.shape[1]
- for j in xrange(max(ncx, ncy)):
- seg = func(x[:, j % ncx], y[:, j % ncy], kw, kwargs)
- ret.append(seg)
- return ret
-
- def _grab_next_args(self, *args, **kwargs):
-
- remaining = args
- while 1:
-
- if len(remaining) == 0:
- return
- if len(remaining) <= 3:
- for seg in self._plot_args(remaining, kwargs):
- yield seg
- return
-
- if is_string_like(remaining[2]):
- isplit = 3
- else:
- isplit = 2
-
- for seg in self._plot_args(remaining[:isplit], kwargs):
- yield seg
- remaining = remaining[isplit:]
-
-
-class _AxesBase(martist.Artist):
- """
- """
- name = "rectilinear"
-
- _shared_x_axes = cbook.Grouper()
- _shared_y_axes = cbook.Grouper()
-
- def __str__(self):
- return "Axes(%g,%g;%gx%g)" % tuple(self._position.bounds)
-
- def __init__(self, fig, rect,
- axisbg=None, # defaults to rc axes.facecolor
- frameon=True,
- sharex=None, # use Axes instance's xaxis info
- sharey=None, # use Axes instance's yaxis info
- label='',
- xscale=None,
- yscale=None,
- **kwargs
- ):
- """
- Build an :class:`Axes` instance in
- :class:`~matplotlib.figure.Figure` *fig* with
- *rect=[left, bottom, width, height]* in
- :class:`~matplotlib.figure.Figure` coordinates
-
- Optional keyword arguments:
-
- ================ =========================================
- Keyword Description
- ================ =========================================
- *adjustable* [ 'box' | 'datalim' | 'box-forced']
- *alpha* float: the alpha transparency (can be None)
- *anchor* [ 'C', 'SW', 'S', 'SE', 'E', 'NE', 'N',
- 'NW', 'W' ]
- *aspect* [ 'auto' | 'equal' | aspect_ratio ]
- *autoscale_on* [ *True* | *False* ] whether or not to
- autoscale the *viewlim*
- *axis_bgcolor* any matplotlib color, see
- :func:`~matplotlib.pyplot.colors`
- *axisbelow* draw the grids and ticks below the other
- artists
- *cursor_props* a (*float*, *color*) tuple
- *figure* a :class:`~matplotlib.figure.Figure`
- instance
- *frame_on* a boolean - draw the axes frame
- *label* the axes label
- *navigate* [ *True* | *False* ]
- *navigate_mode* [ 'PAN' | 'ZOOM' | None ] the navigation
- toolbar button status
- *position* [left, bottom, width, height] in
- class:`~matplotlib.figure.Figure` coords
- *sharex* an class:`~matplotlib.axes.Axes` instance
- to share the x-axis with
- *sharey* an class:`~matplotlib.axes.Axes` instance
- to share the y-axis with
- *title* the title string
- *visible* [ *True* | *False* ] whether the axes is
- visible
- *xlabel* the xlabel
- *xlim* (*xmin*, *xmax*) view limits
- *xscale* [%(scale)s]
- *xticklabels* sequence of strings
- *xticks* sequence of floats
- *ylabel* the ylabel strings
- *ylim* (*ymin*, *ymax*) view limits
- *yscale* [%(scale)s]
- *yticklabels* sequence of strings
- *yticks* sequence of floats
- ================ =========================================
- """ % {'scale': ' | '.join(
- [repr(x) for x in mscale.get_scale_names()])}
- martist.Artist.__init__(self)
- if isinstance(rect, mtransforms.Bbox):
- self._position = rect
- else:
- self._position = mtransforms.Bbox.from_bounds(*rect)
- self._originalPosition = self._position.frozen()
- self.set_axes(self)
- self.set_aspect('auto')
- self._adjustable = 'box'
- self.set_anchor('C')
- self._sharex = sharex
- self._sharey = sharey
- if sharex is not None:
- self._shared_x_axes.join(self, sharex)
- if sharex._adjustable == 'box':
- sharex._adjustable = 'datalim'
- #warnings.warn(
- # 'shared axes: "adjustable" is being changed to "datalim"')
- self._adjustable = 'datalim'
- if sharey is not None:
- self._shared_y_axes.join(self, sharey)
- if sharey._adjustable == 'box':
- sharey._adjustable = 'datalim'
- #warnings.warn(
- # 'shared axes: "adjustable" is being changed to "datalim"')
- self._adjustable = 'datalim'
- self.set_label(label)
- self.set_figure(fig)
-
- self.set_axes_locator(kwargs.get("axes_locator", None))
-
- self.spines = self._gen_axes_spines()
-
- # this call may differ for non-sep axes, e.g., polar
- self._init_axis()
-
- if axisbg is None:
- axisbg = rcParams['axes.facecolor']
- self._axisbg = axisbg
- self._frameon = frameon
- self._axisbelow = rcParams['axes.axisbelow']
-
- self._rasterization_zorder = None
-
- self._hold = rcParams['axes.hold']
- self._connected = {} # a dict from events to (id, func)
- self.cla()
- # funcs used to format x and y - fall back on major formatters
- self.fmt_xdata = None
- self.fmt_ydata = None
-
- self.set_cursor_props((1, 'k')) # set the cursor properties for axes
-
- self._cachedRenderer = None
- self.set_navigate(True)
- self.set_navigate_mode(None)
-
- if xscale:
- self.set_xscale(xscale)
- if yscale:
- self.set_yscale(yscale)
-
- if len(kwargs):
- self.update(kwargs)
-
- if self.xaxis is not None:
- self._xcid = self.xaxis.callbacks.connect('units finalize',
- self.relim)
-
- if self.yaxis is not None:
- self._ycid = self.yaxis.callbacks.connect('units finalize',
- self.relim)
-
- def __setstate__(self, state):
- self.__dict__ = state
- # put the _remove_method back on all artists contained within the axes
- for container_name in ['lines', 'collections', 'tables', 'patches',
- 'texts', 'images']:
- container = getattr(self, container_name)
- for artist in container:
- artist._remove_method = container.remove
-
- def get_window_extent(self, *args, **kwargs):
- """
- get the axes bounding box in display space; *args* and
- *kwargs* are empty
- """
- return self.bbox
-
- def _init_axis(self):
- "move this out of __init__ because non-separable axes don't use it"
- self.xaxis = maxis.XAxis(self)
- self.spines['bottom'].register_axis(self.xaxis)
- self.spines['top'].register_axis(self.xaxis)
- self.yaxis = maxis.YAxis(self)
- self.spines['left'].register_axis(self.yaxis)
- self.spines['right'].register_axis(self.yaxis)
- self._update_transScale()
-
- def set_figure(self, fig):
- """
- Set the class:`~matplotlib.axes.Axes` figure
-
- accepts a class:`~matplotlib.figure.Figure` instance
- """
- martist.Artist.set_figure(self, fig)
-
- self.bbox = mtransforms.TransformedBbox(self._position,
- fig.transFigure)
- # these will be updated later as data is added
- self.dataLim = mtransforms.Bbox.null()
- self.viewLim = mtransforms.Bbox.unit()
- self.transScale = mtransforms.TransformWrapper(
- mtransforms.IdentityTransform())
-
- self._set_lim_and_transforms()
-
- def _set_lim_and_transforms(self):
- """
- set the *dataLim* and *viewLim*
- :class:`~matplotlib.transforms.Bbox` attributes and the
- *transScale*, *transData*, *transLimits* and *transAxes*
- transformations.
-
- .. note::
-
- This method is primarily used by rectilinear projections
- of the :class:`~matplotlib.axes.Axes` class, and is meant
- to be overridden by new kinds of projection axes that need
- different transformations and limits. (See
- :class:`~matplotlib.projections.polar.PolarAxes` for an
- example.
-
- """
- self.transAxes = mtransforms.BboxTransformTo(self.bbox)
-
- # Transforms the x and y axis separately by a scale factor.
- # It is assumed that this part will have non-linear components
- # (e.g., for a log scale).
- self.transScale = mtransforms.TransformWrapper(
- mtransforms.IdentityTransform())
-
- # An affine transformation on the data, generally to limit the
- # range of the axes
- self.transLimits = mtransforms.BboxTransformFrom(
- mtransforms.TransformedBbox(self.viewLim, self.transScale))
-
- # The parentheses are important for efficiency here -- they
- # group the last two (which are usually affines) separately
- # from the first (which, with log-scaling can be non-affine).
- self.transData = self.transScale + (self.transLimits + self.transAxes)
-
- self._xaxis_transform = mtransforms.blended_transform_factory(
- self.transData, self.transAxes)
- self._yaxis_transform = mtransforms.blended_transform_factory(
- self.transAxes, self.transData)
-
- def get_xaxis_transform(self, which='grid'):
- """
- Get the transformation used for drawing x-axis labels, ticks
- and gridlines. The x-direction is in data coordinates and the
- y-direction is in axis coordinates.
-
- .. note::
-
- This transformation is primarily used by the
- :class:`~matplotlib.axis.Axis` class, and is meant to be
- overridden by new kinds of projections that may need to
- place axis elements in different locations.
-
- """
- if which == 'grid':
- return self._xaxis_transform
- elif which == 'tick1':
- # for cartesian projection, this is bottom spine
- return self.spines['bottom'].get_spine_transform()
- elif which == 'tick2':
- # for cartesian projection, this is top spine
- return self.spines['top'].get_spine_transform()
- else:
- raise ValueError('unknown value for which')
-
- def get_xaxis_text1_transform(self, pad_points):
- """
- Get the transformation used for drawing x-axis labels, which
- will add the given amount of padding (in points) between the
- axes and the label. The x-direction is in data coordinates
- and the y-direction is in axis coordinates. Returns a
- 3-tuple of the form::
-
- (transform, valign, halign)
-
- where *valign* and *halign* are requested alignments for the
- text.
-
- .. note::
-
- This transformation is primarily used by the
- :class:`~matplotlib.axis.Axis` class, and is meant to be
- overridden by new kinds of projections that may need to
- place axis elements in different locations.
-
- """
- return (self.get_xaxis_transform(which='tick1') +
- mtransforms.ScaledTranslation(0, -1 * pad_points / 72.0,
- self.figure.dpi_scale_trans),
- "top", "center")
-
- def get_xaxis_text2_transform(self, pad_points):
- """
- Get the transformation used for drawing the secondary x-axis
- labels, which will add the given amount of padding (in points)
- between the axes and the label. The x-direction is in data
- coordinates and the y-direction is in axis coordinates.
- Returns a 3-tuple of the form::
-
- (transform, valign, halign)
-
- where *valign* and *halign* are requested alignments for the
- text.
-
- .. note::
-
- This transformation is primarily used by the
- :class:`~matplotlib.axis.Axis` class, and is meant to be
- overridden by new kinds of projections that may need to
- place axis elements in different locations.
-
- """
- return (self.get_xaxis_transform(which='tick2') +
- mtransforms.ScaledTranslation(0, pad_points / 72.0,
- self.figure.dpi_scale_trans),
- "bottom", "center")
-
- def get_yaxis_transform(self, which='grid'):
- """
- Get the transformation used for drawing y-axis labels, ticks
- and gridlines. The x-direction is in axis coordinates and the
- y-direction is in data coordinates.
-
- .. note::
-
- This transformation is primarily used by the
- :class:`~matplotlib.axis.Axis` class, and is meant to be
- overridden by new kinds of projections that may need to
- place axis elements in different locations.
-
- """
- if which == 'grid':
- return self._yaxis_transform
- elif which == 'tick1':
- # for cartesian projection, this is bottom spine
- return self.spines['left'].get_spine_transform()
- elif which == 'tick2':
- # for cartesian projection, this is top spine
- return self.spines['right'].get_spine_transform()
- else:
- raise ValueError('unknown value for which')
-
- def get_yaxis_text1_transform(self, pad_points):
- """
- Get the transformation used for drawing y-axis labels, which
- will add the given amount of padding (in points) between the
- axes and the label. The x-direction is in axis coordinates
- and the y-direction is in data coordinates. Returns a 3-tuple
- of the form::
-
- (transform, valign, halign)
-
- where *valign* and *halign* are requested alignments for the
- text.
-
- .. note::
-
- This transformation is primarily used by the
- :class:`~matplotlib.axis.Axis` class, and is meant to be
- overridden by new kinds of projections that may need to
- place axis elements in different locations.
-
- """
- return (self.get_yaxis_transform(which='tick1') +
- mtransforms.ScaledTranslation(-1 * pad_points / 72.0, 0,
- self.figure.dpi_scale_trans),
- "center", "right")
-
- def get_yaxis_text2_transform(self, pad_points):
- """
- Get the transformation used for drawing the secondary y-axis
- labels, which will add the given amount of padding (in points)
- between the axes and the label. The x-direction is in axis
- coordinates and the y-direction is in data coordinates.
- Returns a 3-tuple of the form::
-
- (transform, valign, halign)
-
- where *valign* and *halign* are requested alignments for the
- text.
-
- .. note::
-
- This transformation is primarily used by the
- :class:`~matplotlib.axis.Axis` class, and is meant to be
- overridden by new kinds of projections that may need to
- place axis elements in different locations.
-
- """
- return (self.get_yaxis_transform(which='tick2') +
- mtransforms.ScaledTranslation(pad_points / 72.0, 0,
- self.figure.dpi_scale_trans),
- "center", "left")
-
- def _update_transScale(self):
- self.transScale.set(
- mtransforms.blended_transform_factory(
- self.xaxis.get_transform(), self.yaxis.get_transform()))
- if hasattr(self, "lines"):
- for line in self.lines:
- try:
- line._transformed_path.invalidate()
- except AttributeError:
- pass
-
- def get_position(self, original=False):
- 'Return the a copy of the axes rectangle as a Bbox'
- if original:
- return self._originalPosition.frozen()
- else:
- return self._position.frozen()
-
- def set_position(self, pos, which='both'):
- """
- Set the axes position with::
-
- pos = [left, bottom, width, height]
-
- in relative 0,1 coords, or *pos* can be a
- :class:`~matplotlib.transforms.Bbox`
-
- There are two position variables: one which is ultimately
- used, but which may be modified by :meth:`apply_aspect`, and a
- second which is the starting point for :meth:`apply_aspect`.
-
-
- Optional keyword arguments:
- *which*
-
- ========== ====================
- value description
- ========== ====================
- 'active' to change the first
- 'original' to change the second
- 'both' to change both
- ========== ====================
-
- """
- if not isinstance(pos, mtransforms.BboxBase):
- pos = mtransforms.Bbox.from_bounds(*pos)
- if which in ('both', 'active'):
- self._position.set(pos)
- if which in ('both', 'original'):
- self._originalPosition.set(pos)
-
- def reset_position(self):
- """Make the original position the active position"""
- pos = self.get_position(original=True)
- self.set_position(pos, which='active')
-
- def set_axes_locator(self, locator):
- """
- set axes_locator
-
- ACCEPT: a callable object which takes an axes instance and renderer and
- returns a bbox.
- """
- self._axes_locator = locator
-
- def get_axes_locator(self):
- """
- return axes_locator
- """
- return self._axes_locator
-
- def _set_artist_props(self, a):
- """set the boilerplate props for artists added to axes"""
- a.set_figure(self.figure)
- if not a.is_transform_set():
- a.set_transform(self.transData)
-
- a.set_axes(self)
-
- def _gen_axes_patch(self):
- """
- Returns the patch used to draw the background of the axes. It
- is also used as the clipping path for any data elements on the
- axes.
-
- In the standard axes, this is a rectangle, but in other
- projections it may not be.
-
- .. note::
-
- Intended to be overridden by new projection types.
-
- """
- return mpatches.Rectangle((0.0, 0.0), 1.0, 1.0)
-
- def _gen_axes_spines(self, locations=None, offset=0.0, units='inches'):
- """
- Returns a dict whose keys are spine names and values are
- Line2D or Patch instances. Each element is used to draw a
- spine of the axes.
-
- In the standard axes, this is a single line segment, but in
- other projections it may not be.
-
- .. note::
-
- Intended to be overridden by new projection types.
-
- """
- return {
- 'left': mspines.Spine.linear_spine(self, 'left'),
- 'right': mspines.Spine.linear_spine(self, 'right'),
- 'bottom': mspines.Spine.linear_spine(self, 'bottom'),
- 'top': mspines.Spine.linear_spine(self, 'top'), }
-
- def cla(self):
- """Clear the current axes."""
- # Note: this is called by Axes.__init__()
-
- # stash the current visibility state
- if hasattr(self, 'patch'):
- patch_visible = self.patch.get_visible()
- else:
- patch_visible = True
-
- xaxis_visible = self.xaxis.get_visible()
- yaxis_visible = self.yaxis.get_visible()
-
- self.xaxis.cla()
- self.yaxis.cla()
- for name, spine in six.iteritems(self.spines):
- spine.cla()
-
- self.ignore_existing_data_limits = True
- self.callbacks = cbook.CallbackRegistry()
-
- if self._sharex is not None:
- # major and minor are class instances with
- # locator and formatter attributes
- self.xaxis.major = self._sharex.xaxis.major
- self.xaxis.minor = self._sharex.xaxis.minor
- x0, x1 = self._sharex.get_xlim()
- self.set_xlim(x0, x1, emit=False, auto=None)
-
- # Save the current formatter/locator so we don't lose it
- majf = self._sharex.xaxis.get_major_formatter()
- minf = self._sharex.xaxis.get_minor_formatter()
- majl = self._sharex.xaxis.get_major_locator()
- minl = self._sharex.xaxis.get_minor_locator()
-
- # This overwrites the current formatter/locator
- self.xaxis._set_scale(self._sharex.xaxis.get_scale())
-
- # Reset the formatter/locator
- self.xaxis.set_major_formatter(majf)
- self.xaxis.set_minor_formatter(minf)
- self.xaxis.set_major_locator(majl)
- self.xaxis.set_minor_locator(minl)
- else:
- self.xaxis._set_scale('linear')
-
- if self._sharey is not None:
- self.yaxis.major = self._sharey.yaxis.major
- self.yaxis.minor = self._sharey.yaxis.minor
- y0, y1 = self._sharey.get_ylim()
- self.set_ylim(y0, y1, emit=False, auto=None)
-
- # Save the current formatter/locator so we don't lose it
- majf = self._sharey.yaxis.get_major_formatter()
- minf = self._sharey.yaxis.get_minor_formatter()
- majl = self._sharey.yaxis.get_major_locator()
- minl = self._sharey.yaxis.get_minor_locator()
-
- # This overwrites the current formatter/locator
- self.yaxis._set_scale(self._sharey.yaxis.get_scale())
-
- # Reset the formatter/locator
- self.yaxis.set_major_formatter(majf)
- self.yaxis.set_minor_formatter(minf)
- self.yaxis.set_major_locator(majl)
- self.yaxis.set_minor_locator(minl)
- else:
- self.yaxis._set_scale('linear')
-
- self._autoscaleXon = True
- self._autoscaleYon = True
- self._xmargin = rcParams['axes.xmargin']
- self._ymargin = rcParams['axes.ymargin']
- self._tight = False
- self._update_transScale() # needed?
-
- self._get_lines = _process_plot_var_args(self)
- self._get_patches_for_fill = _process_plot_var_args(self, 'fill')
-
- self._gridOn = rcParams['axes.grid']
- self.lines = []
- self.patches = []
- self.texts = []
- self.tables = []
- self.artists = []
- self.images = []
- self._current_image = None # strictly for pyplot via _sci, _gci
- self.legend_ = None
- self.collections = [] # collection.Collection instances
- self.containers = []
-
- self.grid(self._gridOn, which=rcParams['axes.grid.which'])
- props = font_manager.FontProperties(size=rcParams['axes.titlesize'],
- weight=rcParams['axes.titleweight'])
-
- self.titleOffsetTrans = mtransforms.ScaledTranslation(
- 0.0, 5.0 / 72.0, self.figure.dpi_scale_trans)
- self.title = mtext.Text(
- x=0.5, y=1.0, text='',
- fontproperties=props,
- verticalalignment='baseline',
- horizontalalignment='center',
- )
- self._left_title = mtext.Text(
- x=0.0, y=1.0, text='',
- fontproperties=props.copy(),
- verticalalignment='baseline',
- horizontalalignment='left', )
- self._right_title = mtext.Text(
- x=1.0, y=1.0, text='',
- fontproperties=props.copy(),
- verticalalignment='baseline',
- horizontalalignment='right',
- )
-
- for _title in (self.title, self._left_title, self._right_title):
- _title.set_transform(self.transAxes + self.titleOffsetTrans)
- _title.set_clip_box(None)
- self._set_artist_props(_title)
-
- # the patch draws the background of the axes. we want this to
- # be below the other artists; the axesPatch name is
- # deprecated. We use the frame to draw the edges so we are
- # setting the edgecolor to None
- self.patch = self.axesPatch = self._gen_axes_patch()
- self.patch.set_figure(self.figure)
- self.patch.set_facecolor(self._axisbg)
- self.patch.set_edgecolor('None')
- self.patch.set_linewidth(0)
- self.patch.set_transform(self.transAxes)
-
- self.axison = True
-
- self.xaxis.set_clip_path(self.patch)
- self.yaxis.set_clip_path(self.patch)
-
- self._shared_x_axes.clean()
- self._shared_y_axes.clean()
- if self._sharex:
- self.xaxis.set_visible(xaxis_visible)
- self.patch.set_visible(patch_visible)
-
- if self._sharey:
- self.yaxis.set_visible(yaxis_visible)
- self.patch.set_visible(patch_visible)
-
- def clear(self):
- """clear the axes"""
- self.cla()
-
- def set_color_cycle(self, clist):
- """
- Set the color cycle for any future plot commands on this Axes.
-
- *clist* is a list of mpl color specifiers.
- """
- self._get_lines.set_color_cycle(clist)
- self._get_patches_for_fill.set_color_cycle(clist)
-
- def ishold(self):
- """return the HOLD status of the axes"""
- return self._hold
-
- def hold(self, b=None):
- """
- Call signature::
-
- hold(b=None)
-
- Set the hold state. If *hold* is *None* (default), toggle the
- *hold* state. Else set the *hold* state to boolean value *b*.
-
- Examples::
-
- # toggle hold
- hold()
-
- # turn hold on
- hold(True)
-
- # turn hold off
- hold(False)
-
- When hold is *True*, subsequent plot commands will be added to
- the current axes. When hold is *False*, the current axes and
- figure will be cleared on the next plot command
-
- """
- if b is None:
- self._hold = not self._hold
- else:
- self._hold = b
-
- def get_aspect(self):
- return self._aspect
-
- def set_aspect(self, aspect, adjustable=None, anchor=None):
- """
- *aspect*
-
- ======== ================================================
- value description
- ======== ================================================
- 'auto' automatic; fill position rectangle with data
- 'normal' same as 'auto'; deprecated
- 'equal' same scaling from data to plot units for x and y
- num a circle will be stretched such that the height
- is num times the width. aspect=1 is the same as
- aspect='equal'.
- ======== ================================================
-
- *adjustable*
-
- ============ =====================================
- value description
- ============ =====================================
- 'box' change physical size of axes
- 'datalim' change xlim or ylim
- 'box-forced' same as 'box', but axes can be shared
- ============ =====================================
-
- 'box' does not allow axes sharing, as this can cause
- unintended side effect. For cases when sharing axes is
- fine, use 'box-forced'.
-
- *anchor*
-
- ===== =====================
- value description
- ===== =====================
- 'C' centered
- 'SW' lower left corner
- 'S' middle of bottom edge
- 'SE' lower right corner
- etc.
- ===== =====================
-
- .. deprecated:: 1.2
- the option 'normal' for aspect is deprecated. Use 'auto' instead.
- """
- if aspect == 'normal':
- cbook.warn_deprecated(
- '1.2', name='normal', alternative='auto', obj_type='aspect')
- self._aspect = 'auto'
-
- elif aspect in ('equal', 'auto'):
- self._aspect = aspect
- else:
- self._aspect = float(aspect) # raise ValueError if necessary
-
- if adjustable is not None:
- self.set_adjustable(adjustable)
- if anchor is not None:
- self.set_anchor(anchor)
-
- def get_adjustable(self):
- return self._adjustable
-
- def set_adjustable(self, adjustable):
- """
- ACCEPTS: [ 'box' | 'datalim' | 'box-forced']
- """
- if adjustable in ('box', 'datalim', 'box-forced'):
- if self in self._shared_x_axes or self in self._shared_y_axes:
- if adjustable == 'box':
- raise ValueError(
- 'adjustable must be "datalim" for shared axes')
- self._adjustable = adjustable
- else:
- raise ValueError('argument must be "box", or "datalim"')
-
- def get_anchor(self):
- return self._anchor
-
- def set_anchor(self, anchor):
- """
- *anchor*
-
- ===== ============
- value description
- ===== ============
- 'C' Center
- 'SW' bottom left
- 'S' bottom
- 'SE' bottom right
- 'E' right
- 'NE' top right
- 'N' top
- 'NW' top left
- 'W' left
- ===== ============
-
- """
- if (anchor in list(six.iterkeys(mtransforms.Bbox.coefs)) or
- len(anchor) == 2):
- self._anchor = anchor
- else:
- raise ValueError('argument must be among %s' %
- ', '.join(six.iterkeys(mtransforms.Bbox.coefs)))
-
- def get_data_ratio(self):
- """
- Returns the aspect ratio of the raw data.
-
- This method is intended to be overridden by new projection
- types.
- """
- xmin, xmax = self.get_xbound()
- ymin, ymax = self.get_ybound()
-
- xsize = max(math.fabs(xmax - xmin), 1e-30)
- ysize = max(math.fabs(ymax - ymin), 1e-30)
-
- return ysize / xsize
-
- def get_data_ratio_log(self):
- """
- Returns the aspect ratio of the raw data in log scale.
- Will be used when both axis scales are in log.
- """
- xmin, xmax = self.get_xbound()
- ymin, ymax = self.get_ybound()
-
- xsize = max(math.fabs(math.log10(xmax) - math.log10(xmin)), 1e-30)
- ysize = max(math.fabs(math.log10(ymax) - math.log10(ymin)), 1e-30)
-
- return ysize / xsize
-
- def apply_aspect(self, position=None):
- """
- Use :meth:`_aspect` and :meth:`_adjustable` to modify the
- axes box or the view limits.
- """
- if position is None:
- position = self.get_position(original=True)
-
- aspect = self.get_aspect()
-
- if self.name != 'polar':
- xscale, yscale = self.get_xscale(), self.get_yscale()
- if xscale == "linear" and yscale == "linear":
- aspect_scale_mode = "linear"
- elif xscale == "log" and yscale == "log":
- aspect_scale_mode = "log"
- elif ((xscale == "linear" and yscale == "log") or
- (xscale == "log" and yscale == "linear")):
- if aspect != "auto":
- warnings.warn(
- 'aspect is not supported for Axes with xscale=%s, '
- 'yscale=%s' % (xscale, yscale))
- aspect = "auto"
- else: # some custom projections have their own scales.
- pass
- else:
- aspect_scale_mode = "linear"
-
- if aspect == 'auto':
- self.set_position(position, which='active')
- return
-
- if aspect == 'equal':
- A = 1
- else:
- A = aspect
-
- #Ensure at drawing time that any Axes involved in axis-sharing
- # does not have its position changed.
- if self in self._shared_x_axes or self in self._shared_y_axes:
- if self._adjustable == 'box':
- self._adjustable = 'datalim'
- warnings.warn(
- 'shared axes: "adjustable" is being changed to "datalim"')
-
- figW, figH = self.get_figure().get_size_inches()
- fig_aspect = figH / figW
- if self._adjustable in ['box', 'box-forced']:
- if aspect_scale_mode == "log":
- box_aspect = A * self.get_data_ratio_log()
- else:
- box_aspect = A * self.get_data_ratio()
- pb = position.frozen()
- pb1 = pb.shrunk_to_aspect(box_aspect, pb, fig_aspect)
- self.set_position(pb1.anchored(self.get_anchor(), pb), 'active')
- return
-
- # reset active to original in case it had been changed
- # by prior use of 'box'
- self.set_position(position, which='active')
-
- xmin, xmax = self.get_xbound()
- ymin, ymax = self.get_ybound()
-
- if aspect_scale_mode == "log":
- xmin, xmax = math.log10(xmin), math.log10(xmax)
- ymin, ymax = math.log10(ymin), math.log10(ymax)
-
- xsize = max(math.fabs(xmax - xmin), 1e-30)
- ysize = max(math.fabs(ymax - ymin), 1e-30)
-
- l, b, w, h = position.bounds
- box_aspect = fig_aspect * (h / w)
- data_ratio = box_aspect / A
-
- y_expander = (data_ratio * xsize / ysize - 1.0)
- #print 'y_expander', y_expander
- # If y_expander > 0, the dy/dx viewLim ratio needs to increase
- if abs(y_expander) < 0.005:
- #print 'good enough already'
- return
-
- if aspect_scale_mode == "log":
- dL = self.dataLim
- dL_width = math.log10(dL.x1) - math.log10(dL.x0)
- dL_height = math.log10(dL.y1) - math.log10(dL.y0)
- xr = 1.05 * dL_width
- yr = 1.05 * dL_height
- else:
- dL = self.dataLim
- xr = 1.05 * dL.width
- yr = 1.05 * dL.height
-
- xmarg = xsize - xr
- ymarg = ysize - yr
- Ysize = data_ratio * xsize
- Xsize = ysize / data_ratio
- Xmarg = Xsize - xr
- Ymarg = Ysize - yr
- xm = 0 # Setting these targets to, e.g., 0.05*xr does not seem to
- # help.
- ym = 0
- #print 'xmin, xmax, ymin, ymax', xmin, xmax, ymin, ymax
- #print 'xsize, Xsize, ysize, Ysize', xsize, Xsize, ysize, Ysize
-
- changex = (self in self._shared_y_axes
- and self not in self._shared_x_axes)
- changey = (self in self._shared_x_axes
- and self not in self._shared_y_axes)
- if changex and changey:
- warnings.warn("adjustable='datalim' cannot work with shared "
- "x and y axes")
- return
- if changex:
- adjust_y = False
- else:
- #print 'xmarg, ymarg, Xmarg, Ymarg', xmarg, ymarg, Xmarg, Ymarg
- if xmarg > xm and ymarg > ym:
- adjy = ((Ymarg > 0 and y_expander < 0)
- or (Xmarg < 0 and y_expander > 0))
- else:
- adjy = y_expander > 0
- #print 'y_expander, adjy', y_expander, adjy
- adjust_y = changey or adjy # (Ymarg > xmarg)
- if adjust_y:
- yc = 0.5 * (ymin + ymax)
- y0 = yc - Ysize / 2.0
- y1 = yc + Ysize / 2.0
- if aspect_scale_mode == "log":
- self.set_ybound((10. ** y0, 10. ** y1))
- else:
- self.set_ybound((y0, y1))
- #print 'New y0, y1:', y0, y1
- #print 'New ysize, ysize/xsize', y1-y0, (y1-y0)/xsize
- else:
- xc = 0.5 * (xmin + xmax)
- x0 = xc - Xsize / 2.0
- x1 = xc + Xsize / 2.0
- if aspect_scale_mode == "log":
- self.set_xbound((10. ** x0, 10. ** x1))
- else:
- self.set_xbound((x0, x1))
- #print 'New x0, x1:', x0, x1
- #print 'New xsize, ysize/xsize', x1-x0, ysize/(x1-x0)
-
- def axis(self, *v, **kwargs):
- """
- Convenience method for manipulating the x and y view limits
- and the aspect ratio of the plot. For details, see
- :func:`~matplotlib.pyplot.axis`.
-
- *kwargs* are passed on to :meth:`set_xlim` and
- :meth:`set_ylim`
- """
- if len(v) == 0 and len(kwargs) == 0:
- xmin, xmax = self.get_xlim()
- ymin, ymax = self.get_ylim()
- return xmin, xmax, ymin, ymax
-
- if len(v) == 1 and is_string_like(v[0]):
- s = v[0].lower()
- if s == 'on':
- self.set_axis_on()
- elif s == 'off':
- self.set_axis_off()
- elif s in ('equal', 'tight', 'scaled', 'normal', 'auto', 'image'):
- self.set_autoscale_on(True)
- self.set_aspect('auto')
- self.autoscale_view(tight=False)
- # self.apply_aspect()
- if s == 'equal':
- self.set_aspect('equal', adjustable='datalim')
- elif s == 'scaled':
- self.set_aspect('equal', adjustable='box', anchor='C')
- self.set_autoscale_on(False) # Req. by Mark Bakker
- elif s == 'tight':
- self.autoscale_view(tight=True)
- self.set_autoscale_on(False)
- elif s == 'image':
- self.autoscale_view(tight=True)
- self.set_autoscale_on(False)
- self.set_aspect('equal', adjustable='box', anchor='C')
-
- else:
- raise ValueError('Unrecognized string %s to axis; '
- 'try on or off' % s)
- xmin, xmax = self.get_xlim()
- ymin, ymax = self.get_ylim()
- return xmin, xmax, ymin, ymax
-
- emit = kwargs.get('emit', True)
- try:
- v[0]
- except IndexError:
- xmin = kwargs.get('xmin', None)
- xmax = kwargs.get('xmax', None)
- auto = False # turn off autoscaling, unless...
- if xmin is None and xmax is None:
- auto = None # leave autoscaling state alone
- xmin, xmax = self.set_xlim(xmin, xmax, emit=emit, auto=auto)
-
- ymin = kwargs.get('ymin', None)
- ymax = kwargs.get('ymax', None)
- auto = False # turn off autoscaling, unless...
- if ymin is None and ymax is None:
- auto = None # leave autoscaling state alone
- ymin, ymax = self.set_ylim(ymin, ymax, emit=emit, auto=auto)
- return xmin, xmax, ymin, ymax
-
- v = v[0]
- if len(v) != 4:
- raise ValueError('v must contain [xmin xmax ymin ymax]')
-
- self.set_xlim([v[0], v[1]], emit=emit, auto=False)
- self.set_ylim([v[2], v[3]], emit=emit, auto=False)
-
- return v
-
- def get_legend(self):
- """
- Return the legend.Legend instance, or None if no legend is defined
- """
- return self.legend_
-
- def get_images(self):
- """return a list of Axes images contained by the Axes"""
- return cbook.silent_list('AxesImage', self.images)
-
- def get_lines(self):
- """Return a list of lines contained by the Axes"""
- return cbook.silent_list('Line2D', self.lines)
-
- def get_xaxis(self):
- """Return the XAxis instance"""
- return self.xaxis
-
- def get_xgridlines(self):
- """Get the x grid lines as a list of Line2D instances"""
- return cbook.silent_list('Line2D xgridline',
- self.xaxis.get_gridlines())
-
- def get_xticklines(self):
- """Get the xtick lines as a list of Line2D instances"""
- return cbook.silent_list('Text xtickline',
- self.xaxis.get_ticklines())
-
- def get_yaxis(self):
- """Return the YAxis instance"""
- return self.yaxis
-
- def get_ygridlines(self):
- """Get the y grid lines as a list of Line2D instances"""
- return cbook.silent_list('Line2D ygridline',
- self.yaxis.get_gridlines())
-
- def get_yticklines(self):
- """Get the ytick lines as a list of Line2D instances"""
- return cbook.silent_list('Line2D ytickline',
- self.yaxis.get_ticklines())
-
- #### Adding and tracking artists
-
- def _sci(self, im):
- """
- helper for :func:`~matplotlib.pyplot.sci`;
- do not use elsewhere.
- """
- if isinstance(im, matplotlib.contour.ContourSet):
- if im.collections[0] not in self.collections:
- raise ValueError(
- "ContourSet must be in current Axes")
- elif im not in self.images and im not in self.collections:
- raise ValueError(
- "Argument must be an image, collection, or ContourSet in "
- "this Axes")
- self._current_image = im
-
- def _gci(self):
- """
- Helper for :func:`~matplotlib.pyplot.gci`;
- do not use elsewhere.
- """
- return self._current_image
-
- def has_data(self):
- """
- Return *True* if any artists have been added to axes.
-
- This should not be used to determine whether the *dataLim*
- need to be updated, and may not actually be useful for
- anything.
- """
- return (
- len(self.collections) +
- len(self.images) +
- len(self.lines) +
- len(self.patches)) > 0
-
- def add_artist(self, a):
- """Add any :class:`~matplotlib.artist.Artist` to the axes.
-
- Use `add_artist` only for artists for which there is no dedicated
- "add" method; and if necessary, use a method such as
- `update_datalim` or `update_datalim_numerix` to manually update the
- dataLim if the artist is to be included in autoscaling.
-
- Returns the artist.
- """
- a.set_axes(self)
- self.artists.append(a)
- self._set_artist_props(a)
- a.set_clip_path(self.patch)
- a._remove_method = lambda h: self.artists.remove(h)
- return a
-
- def add_collection(self, collection, autolim=True):
- """
- Add a :class:`~matplotlib.collections.Collection` instance
- to the axes.
-
- Returns the collection.
- """
- label = collection.get_label()
- if not label:
- collection.set_label('_collection%d' % len(self.collections))
- self.collections.append(collection)
- self._set_artist_props(collection)
-
- if collection.get_clip_path() is None:
- collection.set_clip_path(self.patch)
-
- if autolim:
- self.update_datalim(collection.get_datalim(self.transData))
-
- collection._remove_method = lambda h: self.collections.remove(h)
- return collection
-
- def add_image(self, image):
- """
- Add a :class:`~matplotlib.image.AxesImage` to the axes.
-
- Returns the image.
- """
- self._set_artist_props(image)
- self.images.append(image)
- image._remove_method = lambda h: self.images.remove(h)
- return image
-
- def add_line(self, line):
- """
- Add a :class:`~matplotlib.lines.Line2D` to the list of plot
- lines
-
- Returns the line.
- """
- self._set_artist_props(line)
- if line.get_clip_path() is None:
- line.set_clip_path(self.patch)
-
- self._update_line_limits(line)
- if not line.get_label():
- line.set_label('_line%d' % len(self.lines))
- self.lines.append(line)
- line._remove_method = lambda h: self.lines.remove(h)
- return line
-
- def _update_line_limits(self, line):
- """
- Figures out the data limit of the given line, updating self.dataLim.
- """
- path = line.get_path()
- if path.vertices.size == 0:
- return
-
- line_trans = line.get_transform()
-
- if line_trans == self.transData:
- data_path = path
-
- elif any(line_trans.contains_branch_seperately(self.transData)):
- # identify the transform to go from line's coordinates
- # to data coordinates
- trans_to_data = line_trans - self.transData
-
- # if transData is affine we can use the cached non-affine component
- # of line's path. (since the non-affine part of line_trans is
- # entirely encapsulated in trans_to_data).
- if self.transData.is_affine:
- line_trans_path = line._get_transformed_path()
- na_path, _ = line_trans_path.get_transformed_path_and_affine()
- data_path = trans_to_data.transform_path_affine(na_path)
- else:
- data_path = trans_to_data.transform_path(path)
- else:
- # for backwards compatibility we update the dataLim with the
- # coordinate range of the given path, even though the coordinate
- # systems are completely different. This may occur in situations
- # such as when ax.transAxes is passed through for absolute
- # positioning.
- data_path = path
-
- if data_path.vertices.size > 0:
- updatex, updatey = line_trans.contains_branch_seperately(
- self.transData)
- self.dataLim.update_from_path(data_path,
- self.ignore_existing_data_limits,
- updatex=updatex,
- updatey=updatey)
- self.ignore_existing_data_limits = False
-
- def add_patch(self, p):
- """
- Add a :class:`~matplotlib.patches.Patch` *p* to the list of
- axes patches; the clipbox will be set to the Axes clipping
- box. If the transform is not set, it will be set to
- :attr:`transData`.
-
- Returns the patch.
- """
-
- self._set_artist_props(p)
- if p.get_clip_path() is None:
- p.set_clip_path(self.patch)
- self._update_patch_limits(p)
- self.patches.append(p)
- p._remove_method = lambda h: self.patches.remove(h)
- return p
-
- def _update_patch_limits(self, patch):
- """update the data limits for patch *p*"""
- # hist can add zero height Rectangles, which is useful to keep
- # the bins, counts and patches lined up, but it throws off log
- # scaling. We'll ignore rects with zero height or width in
- # the auto-scaling
-
- # cannot check for '==0' since unitized data may not compare to zero
- # issue #2150 - we update the limits if patch has non zero width
- # or height.
- if (isinstance(patch, mpatches.Rectangle) and
- ((not patch.get_width()) and (not patch.get_height()))):
- return
- vertices = patch.get_path().vertices
- if vertices.size > 0:
- xys = patch.get_patch_transform().transform(vertices)
- if patch.get_data_transform() != self.transData:
- patch_to_data = (patch.get_data_transform() -
- self.transData)
- xys = patch_to_data.transform(xys)
-
- updatex, updatey = patch.get_transform().\
- contains_branch_seperately(self.transData)
- self.update_datalim(xys, updatex=updatex,
- updatey=updatey)
-
- def add_table(self, tab):
- """
- Add a :class:`~matplotlib.tables.Table` instance to the
- list of axes tables
-
- Returns the table.
- """
- self._set_artist_props(tab)
- self.tables.append(tab)
- tab.set_clip_path(self.patch)
- tab._remove_method = lambda h: self.tables.remove(h)
- return tab
-
- def add_container(self, container):
- """
- Add a :class:`~matplotlib.container.Container` instance
- to the axes.
-
- Returns the collection.
- """
- label = container.get_label()
- if not label:
- container.set_label('_container%d' % len(self.containers))
- self.containers.append(container)
- container.set_remove_method(lambda h: self.containers.remove(h))
- return container
-
- def relim(self, visible_only=False):
- """
- Recompute the data limits based on current artists. If you want to
- exclude invisible artists from the calculation, set
- ``visible_only=True``
-
- At present, :class:`~matplotlib.collections.Collection`
- instances are not supported.
- """
- # Collections are deliberately not supported (yet); see
- # the TODO note in artists.py.
- self.dataLim.ignore(True)
- self.dataLim.set_points(mtransforms.Bbox.null().get_points())
- self.ignore_existing_data_limits = True
-
- for line in self.lines:
- if not visible_only or line.get_visible():
- self._update_line_limits(line)
-
- for p in self.patches:
- if not visible_only or p.get_visible():
- self._update_patch_limits(p)
-
- def update_datalim(self, xys, updatex=True, updatey=True):
- """
- Update the data lim bbox with seq of xy tups or equiv. 2-D array
- """
- # if no data is set currently, the bbox will ignore its
- # limits and set the bound to be the bounds of the xydata.
- # Otherwise, it will compute the bounds of it's current data
- # and the data in xydata
-
- if iterable(xys) and not len(xys):
- return
- if not ma.isMaskedArray(xys):
- xys = np.asarray(xys)
- self.dataLim.update_from_data_xy(xys, self.ignore_existing_data_limits,
- updatex=updatex, updatey=updatey)
- self.ignore_existing_data_limits = False
-
- def update_datalim_numerix(self, x, y):
- """
- Update the data lim bbox with seq of xy tups
- """
- # if no data is set currently, the bbox will ignore it's
- # limits and set the bound to be the bounds of the xydata.
- # Otherwise, it will compute the bounds of it's current data
- # and the data in xydata
- if iterable(x) and not len(x):
- return
- self.dataLim.update_from_data(x, y, self.ignore_existing_data_limits)
- self.ignore_existing_data_limits = False
-
- def update_datalim_bounds(self, bounds):
- """
- Update the datalim to include the given
- :class:`~matplotlib.transforms.Bbox` *bounds*
- """
- self.dataLim.set(mtransforms.Bbox.union([self.dataLim, bounds]))
-
- def _process_unit_info(self, xdata=None, ydata=None, kwargs=None):
- """Look for unit *kwargs* and update the axis instances as necessary"""
-
- if self.xaxis is None or self.yaxis is None:
- return
-
- #print 'processing', self.get_geometry()
- if xdata is not None:
- # we only need to update if there is nothing set yet.
- if not self.xaxis.have_units():
- self.xaxis.update_units(xdata)
- #print '\tset from xdata', self.xaxis.units
-
- if ydata is not None:
- # we only need to update if there is nothing set yet.
- if not self.yaxis.have_units():
- self.yaxis.update_units(ydata)
- #print '\tset from ydata', self.yaxis.units
-
- # process kwargs 2nd since these will override default units
- if kwargs is not None:
- xunits = kwargs.pop('xunits', self.xaxis.units)
- if self.name == 'polar':
- xunits = kwargs.pop('thetaunits', xunits)
- if xunits != self.xaxis.units:
- #print '\tkw setting xunits', xunits
- self.xaxis.set_units(xunits)
- # If the units being set imply a different converter,
- # we need to update.
- if xdata is not None:
- self.xaxis.update_units(xdata)
-
- yunits = kwargs.pop('yunits', self.yaxis.units)
- if self.name == 'polar':
- yunits = kwargs.pop('runits', yunits)
- if yunits != self.yaxis.units:
- #print '\tkw setting yunits', yunits
- self.yaxis.set_units(yunits)
- # If the units being set imply a different converter,
- # we need to update.
- if ydata is not None:
- self.yaxis.update_units(ydata)
-
- def in_axes(self, mouseevent):
- """
- Return *True* if the given *mouseevent* (in display coords)
- is in the Axes
- """
- return self.patch.contains(mouseevent)[0]
-
- def get_autoscale_on(self):
- """
- Get whether autoscaling is applied for both axes on plot commands
- """
- return self._autoscaleXon and self._autoscaleYon
-
- def get_autoscalex_on(self):
- """
- Get whether autoscaling for the x-axis is applied on plot commands
- """
- return self._autoscaleXon
-
- def get_autoscaley_on(self):
- """
- Get whether autoscaling for the y-axis is applied on plot commands
- """
- return self._autoscaleYon
-
- def set_autoscale_on(self, b):
- """
- Set whether autoscaling is applied on plot commands
-
- accepts: [ *True* | *False* ]
- """
- self._autoscaleXon = b
- self._autoscaleYon = b
-
- def set_autoscalex_on(self, b):
- """
- Set whether autoscaling for the x-axis is applied on plot commands
-
- accepts: [ *True* | *False* ]
- """
- self._autoscaleXon = b
-
- def set_autoscaley_on(self, b):
- """
- Set whether autoscaling for the y-axis is applied on plot commands
-
- accepts: [ *True* | *False* ]
- """
- self._autoscaleYon = b
-
- def set_xmargin(self, m):
- """
- Set padding of X data limits prior to autoscaling.
-
- *m* times the data interval will be added to each
- end of that interval before it is used in autoscaling.
-
- accepts: float in range 0 to 1
- """
- if m < 0 or m > 1:
- raise ValueError("margin must be in range 0 to 1")
- self._xmargin = m
-
- def set_ymargin(self, m):
- """
- Set padding of Y data limits prior to autoscaling.
-
- *m* times the data interval will be added to each
- end of that interval before it is used in autoscaling.
-
- accepts: float in range 0 to 1
- """
- if m < 0 or m > 1:
- raise ValueError("margin must be in range 0 to 1")
- self._ymargin = m
-
- def margins(self, *args, **kw):
- """
- Set or retrieve autoscaling margins.
-
- signatures::
-
- margins()
-
- returns xmargin, ymargin
-
- ::
-
- margins(margin)
-
- margins(xmargin, ymargin)
-
- margins(x=xmargin, y=ymargin)
-
- margins(..., tight=False)
-
- All three forms above set the xmargin and ymargin parameters.
- All keyword parameters are optional. A single argument
- specifies both xmargin and ymargin. The *tight* parameter
- is passed to :meth:`autoscale_view`, which is executed after
- a margin is changed; the default here is *True*, on the
- assumption that when margins are specified, no additional
- padding to match tick marks is usually desired. Setting
- *tight* to *None* will preserve the previous setting.
-
- Specifying any margin changes only the autoscaling; for example,
- if *xmargin* is not None, then *xmargin* times the X data
- interval will be added to each end of that interval before
- it is used in autoscaling.
-
- """
- if not args and not kw:
- return self._xmargin, self._ymargin
-
- tight = kw.pop('tight', True)
- mx = kw.pop('x', None)
- my = kw.pop('y', None)
- if len(args) == 1:
- mx = my = args[0]
- elif len(args) == 2:
- mx, my = args
- elif len(args) > 2:
- raise ValueError("more than two arguments were supplied")
- if mx is not None:
- self.set_xmargin(mx)
- if my is not None:
- self.set_ymargin(my)
-
- scalex = (mx is not None)
- scaley = (my is not None)
-
- self.autoscale_view(tight=tight, scalex=scalex, scaley=scaley)
-
- def set_rasterization_zorder(self, z):
- """
- Set zorder value below which artists will be rasterized. Set
- to `None` to disable rasterizing of artists below a particular
- zorder.
- """
- self._rasterization_zorder = z
-
- def get_rasterization_zorder(self):
- """
- Get zorder value below which artists will be rasterized
- """
- return self._rasterization_zorder
-
- def autoscale(self, enable=True, axis='both', tight=None):
- """
- Autoscale the axis view to the data (toggle).
-
- Convenience method for simple axis view autoscaling.
- It turns autoscaling on or off, and then,
- if autoscaling for either axis is on, it performs
- the autoscaling on the specified axis or axes.
-
- *enable*: [True | False | None]
- True (default) turns autoscaling on, False turns it off.
- None leaves the autoscaling state unchanged.
-
- *axis*: ['x' | 'y' | 'both']
- which axis to operate on; default is 'both'
-
- *tight*: [True | False | None]
- If True, set view limits to data limits;
- if False, let the locator and margins expand the view limits;
- if None, use tight scaling if the only artist is an image,
- otherwise treat *tight* as False.
- The *tight* setting is retained for future autoscaling
- until it is explicitly changed.
-
-
- Returns None.
- """
- if enable is None:
- scalex = True
- scaley = True
- else:
- scalex = False
- scaley = False
- if axis in ['x', 'both']:
- self._autoscaleXon = bool(enable)
- scalex = self._autoscaleXon
- if axis in ['y', 'both']:
- self._autoscaleYon = bool(enable)
- scaley = self._autoscaleYon
- self.autoscale_view(tight=tight, scalex=scalex, scaley=scaley)
-
- def autoscale_view(self, tight=None, scalex=True, scaley=True):
- """
- Autoscale the view limits using the data limits. You can
- selectively autoscale only a single axis, e.g., the xaxis by
- setting *scaley* to *False*. The autoscaling preserves any
- axis direction reversal that has already been done.
-
- The data limits are not updated automatically when artist data are
- changed after the artist has been added to an Axes instance. In that
- case, use :meth:`matplotlib.axes.Axes.relim` prior to calling
- autoscale_view.
- """
- if tight is None:
- # if image data only just use the datalim
- _tight = self._tight or (len(self.images) > 0 and
- len(self.lines) == 0 and
- len(self.patches) == 0)
- else:
- _tight = self._tight = bool(tight)
-
- if scalex and self._autoscaleXon:
- xshared = self._shared_x_axes.get_siblings(self)
- dl = [ax.dataLim for ax in xshared]
- #ignore non-finite data limits if good limits exist
- finite_dl = [d for d in dl if np.isfinite(d).all()]
- if len(finite_dl):
- dl = finite_dl
-
- bb = mtransforms.BboxBase.union(dl)
- x0, x1 = bb.intervalx
- xlocator = self.xaxis.get_major_locator()
- try:
- # e.g., DateLocator has its own nonsingular()
- x0, x1 = xlocator.nonsingular(x0, x1)
- except AttributeError:
- # Default nonsingular for, e.g., MaxNLocator
- x0, x1 = mtransforms.nonsingular(x0, x1, increasing=False,
- expander=0.05)
- if self._xmargin > 0:
- delta = (x1 - x0) * self._xmargin
- x0 -= delta
- x1 += delta
- if not _tight:
- x0, x1 = xlocator.view_limits(x0, x1)
- self.set_xbound(x0, x1)
-
- if scaley and self._autoscaleYon:
- yshared = self._shared_y_axes.get_siblings(self)
- dl = [ax.dataLim for ax in yshared]
- #ignore non-finite data limits if good limits exist
- finite_dl = [d for d in dl if np.isfinite(d).all()]
- if len(finite_dl):
- dl = finite_dl
-
- bb = mtransforms.BboxBase.union(dl)
- y0, y1 = bb.intervaly
- ylocator = self.yaxis.get_major_locator()
- try:
- y0, y1 = ylocator.nonsingular(y0, y1)
- except AttributeError:
- y0, y1 = mtransforms.nonsingular(y0, y1, increasing=False,
- expander=0.05)
- if self._ymargin > 0:
- delta = (y1 - y0) * self._ymargin
- y0 -= delta
- y1 += delta
- if not _tight:
- y0, y1 = ylocator.view_limits(y0, y1)
- self.set_ybound(y0, y1)
-
- #### Drawing
-
- @allow_rasterization
- def draw(self, renderer=None, inframe=False):
- """Draw everything (plot lines, axes, labels)"""
- if renderer is None:
- renderer = self._cachedRenderer
-
- if renderer is None:
- raise RuntimeError('No renderer defined')
- if not self.get_visible():
- return
- renderer.open_group('axes')
-
- locator = self.get_axes_locator()
- if locator:
- pos = locator(self, renderer)
- self.apply_aspect(pos)
- else:
- self.apply_aspect()
-
- artists = []
-
- artists.extend(self.collections)
- artists.extend(self.patches)
- artists.extend(self.lines)
- artists.extend(self.texts)
- artists.extend(self.artists)
-
- # the frame draws the edges around the axes patch -- we
- # decouple these so the patch can be in the background and the
- # frame in the foreground. Do this before drawing the axis
- # objects so that the spine has the opportunity to update them.
- if self.axison and self._frameon:
- artists.extend(six.itervalues(self.spines))
-
- if self.axison and not inframe:
- if self._axisbelow:
- self.xaxis.set_zorder(0.5)
- self.yaxis.set_zorder(0.5)
- else:
- self.xaxis.set_zorder(2.5)
- self.yaxis.set_zorder(2.5)
- artists.extend([self.xaxis, self.yaxis])
- if not inframe:
- artists.append(self.title)
- artists.append(self._left_title)
- artists.append(self._right_title)
- artists.extend(self.tables)
- if self.legend_ is not None:
- artists.append(self.legend_)
-
- if self.figure.canvas.is_saving():
- dsu = [(a.zorder, a) for a in artists]
- else:
- dsu = [(a.zorder, a) for a in artists
- if not a.get_animated()]
-
- # add images to dsu if the backend support compositing.
- # otherwise, does the manaul compositing without adding images to dsu.
- if len(self.images) <= 1 or renderer.option_image_nocomposite():
- dsu.extend([(im.zorder, im) for im in self.images])
- _do_composite = False
- else:
- _do_composite = True
-
- dsu.sort(key=itemgetter(0))
-
- # rasterize artists with negative zorder
- # if the minimum zorder is negative, start rasterization
- rasterization_zorder = self._rasterization_zorder
- if (rasterization_zorder is not None and
- len(dsu) > 0 and dsu[0][0] < rasterization_zorder):
- renderer.start_rasterizing()
- dsu_rasterized = [l for l in dsu if l[0] < rasterization_zorder]
- dsu = [l for l in dsu if l[0] >= rasterization_zorder]
- else:
- dsu_rasterized = []
-
- # the patch draws the background rectangle -- the frame below
- # will draw the edges
- if self.axison and self._frameon:
- self.patch.draw(renderer)
-
- if _do_composite:
- # make a composite image blending alpha
- # list of (mimage.Image, ox, oy)
-
- zorder_images = [(im.zorder, im) for im in self.images
- if im.get_visible()]
- zorder_images.sort(key=lambda x: x[0])
-
- mag = renderer.get_image_magnification()
- ims = [(im.make_image(mag), 0, 0, im.get_alpha())
- for z, im in zorder_images]
-
- l, b, r, t = self.bbox.extents
- width = mag * ((round(r) + 0.5) - (round(l) - 0.5))
- height = mag * ((round(t) + 0.5) - (round(b) - 0.5))
- im = mimage.from_images(height,
- width,
- ims)
-
- im.is_grayscale = False
- l, b, w, h = self.bbox.bounds
- # composite images need special args so they will not
- # respect z-order for now
-
- gc = renderer.new_gc()
- gc.set_clip_rectangle(self.bbox)
- gc.set_clip_path(mtransforms.TransformedPath(
- self.patch.get_path(),
- self.patch.get_transform()))
-
- renderer.draw_image(gc, round(l), round(b), im)
- gc.restore()
-
- if dsu_rasterized:
- for zorder, a in dsu_rasterized:
- a.draw(renderer)
- renderer.stop_rasterizing()
-
- for zorder, a in dsu:
- a.draw(renderer)
-
- renderer.close_group('axes')
- self._cachedRenderer = renderer
-
- def draw_artist(self, a):
- """
- This method can only be used after an initial draw which
- caches the renderer. It is used to efficiently update Axes
- data (axis ticks, labels, etc are not updated)
- """
- assert self._cachedRenderer is not None
- a.draw(self._cachedRenderer)
-
- def redraw_in_frame(self):
- """
- This method can only be used after an initial draw which
- caches the renderer. It is used to efficiently update Axes
- data (axis ticks, labels, etc are not updated)
- """
- assert self._cachedRenderer is not None
- self.draw(self._cachedRenderer, inframe=True)
-
- def get_renderer_cache(self):
- return self._cachedRenderer
-
- #### Axes rectangle characteristics
-
- def get_frame_on(self):
- """
- Get whether the axes rectangle patch is drawn
- """
- return self._frameon
-
- def set_frame_on(self, b):
- """
- Set whether the axes rectangle patch is drawn
-
- ACCEPTS: [ *True* | *False* ]
- """
- self._frameon = b
-
- def get_axisbelow(self):
- """
- Get whether axis below is true or not
- """
- return self._axisbelow
-
- def set_axisbelow(self, b):
- """
- Set whether the axis ticks and gridlines are above or below most
- artists
-
- ACCEPTS: [ *True* | *False* ]
- """
- self._axisbelow = b
-
- @docstring.dedent_interpd
- def grid(self, b=None, which='major', axis='both', **kwargs):
- """
- Turn the axes grids on or off.
-
- Call signature::
-
- grid(self, b=None, which='major', axis='both', **kwargs)
-
- Set the axes grids on or off; *b* is a boolean. (For MATLAB
- compatibility, *b* may also be a string, 'on' or 'off'.)
-
- If *b* is *None* and ``len(kwargs)==0``, toggle the grid state. If
- *kwargs* are supplied, it is assumed that you want a grid and *b*
- is thus set to *True*.
-
- *which* can be 'major' (default), 'minor', or 'both' to control
- whether major tick grids, minor tick grids, or both are affected.
-
- *axis* can be 'both' (default), 'x', or 'y' to control which
- set of gridlines are drawn.
-
- *kwargs* are used to set the grid line properties, e.g.,::
-
- ax.grid(color='r', linestyle='-', linewidth=2)
-
- Valid :class:`~matplotlib.lines.Line2D` kwargs are
-
- %(Line2D)s
-
- """
- if len(kwargs):
- b = True
- b = _string_to_bool(b)
-
- if axis == 'x' or axis == 'both':
- self.xaxis.grid(b, which=which, **kwargs)
- if axis == 'y' or axis == 'both':
- self.yaxis.grid(b, which=which, **kwargs)
-
- def ticklabel_format(self, **kwargs):
- """
- Change the `~matplotlib.ticker.ScalarFormatter` used by
- default for linear axes.
-
- Optional keyword arguments:
-
- ============ =========================================
- Keyword Description
- ============ =========================================
- *style* [ 'sci' (or 'scientific') | 'plain' ]
- plain turns off scientific notation
- *scilimits* (m, n), pair of integers; if *style*
- is 'sci', scientific notation will
- be used for numbers outside the range
- 10`m`:sup: to 10`n`:sup:.
- Use (0,0) to include all numbers.
- *useOffset* [True | False | offset]; if True,
- the offset will be calculated as needed;
- if False, no offset will be used; if a
- numeric offset is specified, it will be
- used.
- *axis* [ 'x' | 'y' | 'both' ]
- *useLocale* If True, format the number according to
- the current locale. This affects things
- such as the character used for the
- decimal separator. If False, use
- C-style (English) formatting. The
- default setting is controlled by the
- axes.formatter.use_locale rcparam.
- ============ =========================================
-
- Only the major ticks are affected.
- If the method is called when the
- :class:`~matplotlib.ticker.ScalarFormatter` is not the
- :class:`~matplotlib.ticker.Formatter` being used, an
- :exc:`AttributeError` will be raised.
-
- """
- style = kwargs.pop('style', '').lower()
- scilimits = kwargs.pop('scilimits', None)
- useOffset = kwargs.pop('useOffset', None)
- useLocale = kwargs.pop('useLocale', None)
- axis = kwargs.pop('axis', 'both').lower()
- if scilimits is not None:
- try:
- m, n = scilimits
- m + n + 1 # check that both are numbers
- except (ValueError, TypeError):
- raise ValueError("scilimits must be a sequence of 2 integers")
- if style[:3] == 'sci':
- sb = True
- elif style in ['plain', 'comma']:
- sb = False
- if style == 'plain':
- cb = False
- else:
- cb = True
- raise NotImplementedError("comma style remains to be added")
- elif style == '':
- sb = None
- else:
- raise ValueError("%s is not a valid style value")
- try:
- if sb is not None:
- if axis == 'both' or axis == 'x':
- self.xaxis.major.formatter.set_scientific(sb)
- if axis == 'both' or axis == 'y':
- self.yaxis.major.formatter.set_scientific(sb)
- if scilimits is not None:
- if axis == 'both' or axis == 'x':
- self.xaxis.major.formatter.set_powerlimits(scilimits)
- if axis == 'both' or axis == 'y':
- self.yaxis.major.formatter.set_powerlimits(scilimits)
- if useOffset is not None:
- if axis == 'both' or axis == 'x':
- self.xaxis.major.formatter.set_useOffset(useOffset)
- if axis == 'both' or axis == 'y':
- self.yaxis.major.formatter.set_useOffset(useOffset)
- if useLocale is not None:
- if axis == 'both' or axis == 'x':
- self.xaxis.major.formatter.set_useLocale(useLocale)
- if axis == 'both' or axis == 'y':
- self.yaxis.major.formatter.set_useLocale(useLocale)
- except AttributeError:
- raise AttributeError(
- "This method only works with the ScalarFormatter.")
-
- def locator_params(self, axis='both', tight=None, **kwargs):
- """
- Control behavior of tick locators.
-
- Keyword arguments:
-
- *axis*
- ['x' | 'y' | 'both'] Axis on which to operate;
- default is 'both'.
-
- *tight*
- [True | False | None] Parameter passed to :meth:`autoscale_view`.
- Default is None, for no change.
-
- Remaining keyword arguments are passed to directly to the
- :meth:`~matplotlib.ticker.MaxNLocator.set_params` method.
-
- Typically one might want to reduce the maximum number
- of ticks and use tight bounds when plotting small
- subplots, for example::
-
- ax.locator_params(tight=True, nbins=4)
-
- Because the locator is involved in autoscaling,
- :meth:`autoscale_view` is called automatically after
- the parameters are changed.
-
- This presently works only for the
- :class:`~matplotlib.ticker.MaxNLocator` used
- by default on linear axes, but it may be generalized.
- """
- _x = axis in ['x', 'both']
- _y = axis in ['y', 'both']
- if _x:
- self.xaxis.get_major_locator().set_params(**kwargs)
- if _y:
- self.yaxis.get_major_locator().set_params(**kwargs)
- self.autoscale_view(tight=tight, scalex=_x, scaley=_y)
-
- def tick_params(self, axis='both', **kwargs):
- """
- Change the appearance of ticks and tick labels.
-
- Keyword arguments:
-
- *axis* : ['x' | 'y' | 'both']
- Axis on which to operate; default is 'both'.
-
- *reset* : [True | False]
- If *True*, set all parameters to defaults
- before processing other keyword arguments. Default is
- *False*.
-
- *which* : ['major' | 'minor' | 'both']
- Default is 'major'; apply arguments to *which* ticks.
-
- *direction* : ['in' | 'out' | 'inout']
- Puts ticks inside the axes, outside the axes, or both.
-
- *length*
- Tick length in points.
-
- *width*
- Tick width in points.
-
- *color*
- Tick color; accepts any mpl color spec.
-
- *pad*
- Distance in points between tick and label.
-
- *labelsize*
- Tick label font size in points or as a string (e.g., 'large').
-
- *labelcolor*
- Tick label color; mpl color spec.
-
- *colors*
- Changes the tick color and the label color to the same value:
- mpl color spec.
-
- *zorder*
- Tick and label zorder.
-
- *bottom*, *top*, *left*, *right* : [bool | 'on' | 'off']
- controls whether to draw the respective ticks.
-
- *labelbottom*, *labeltop*, *labelleft*, *labelright*
- Boolean or ['on' | 'off'], controls whether to draw the
- respective tick labels.
-
- Example::
-
- ax.tick_params(direction='out', length=6, width=2, colors='r')
-
- This will make all major ticks be red, pointing out of the box,
- and with dimensions 6 points by 2 points. Tick labels will
- also be red.
-
- """
- if axis in ['x', 'both']:
- xkw = dict(kwargs)
- xkw.pop('left', None)
- xkw.pop('right', None)
- xkw.pop('labelleft', None)
- xkw.pop('labelright', None)
- self.xaxis.set_tick_params(**xkw)
- if axis in ['y', 'both']:
- ykw = dict(kwargs)
- ykw.pop('top', None)
- ykw.pop('bottom', None)
- ykw.pop('labeltop', None)
- ykw.pop('labelbottom', None)
- self.yaxis.set_tick_params(**ykw)
-
- def set_axis_off(self):
- """turn off the axis"""
- self.axison = False
-
- def set_axis_on(self):
- """turn on the axis"""
- self.axison = True
-
- def get_axis_bgcolor(self):
- """Return the axis background color"""
- return self._axisbg
-
- def set_axis_bgcolor(self, color):
- """
- set the axes background color
-
- ACCEPTS: any matplotlib color - see
- :func:`~matplotlib.pyplot.colors`
- """
-
- self._axisbg = color
- self.patch.set_facecolor(color)
-
- ### data limits, ticks, tick labels, and formatting
-
- def invert_xaxis(self):
- "Invert the x-axis."
- left, right = self.get_xlim()
- self.set_xlim(right, left, auto=None)
-
- def xaxis_inverted(self):
- """Returns *True* if the x-axis is inverted."""
- left, right = self.get_xlim()
- return right < left
-
- def get_xbound(self):
- """
- Returns the x-axis numerical bounds where::
-
- lowerBound < upperBound
-
- """
- left, right = self.get_xlim()
- if left < right:
- return left, right
- else:
- return right, left
-
- def set_xbound(self, lower=None, upper=None):
- """
- Set the lower and upper numerical bounds of the x-axis.
- This method will honor axes inversion regardless of parameter order.
- It will not change the _autoscaleXon attribute.
- """
- if upper is None and iterable(lower):
- lower, upper = lower
-
- old_lower, old_upper = self.get_xbound()
-
- if lower is None:
- lower = old_lower
- if upper is None:
- upper = old_upper
-
- if self.xaxis_inverted():
- if lower < upper:
- self.set_xlim(upper, lower, auto=None)
- else:
- self.set_xlim(lower, upper, auto=None)
- else:
- if lower < upper:
- self.set_xlim(lower, upper, auto=None)
- else:
- self.set_xlim(upper, lower, auto=None)
-
- def get_xlim(self):
- """
- Get the x-axis range [*left*, *right*]
- """
- return tuple(self.viewLim.intervalx)
-
- def set_xlim(self, left=None, right=None, emit=True, auto=False, **kw):
- """
- Call signature::
-
- set_xlim(self, *args, **kwargs):
-
- Set the data limits for the xaxis
-
- Examples::
-
- set_xlim((left, right))
- set_xlim(left, right)
- set_xlim(left=1) # right unchanged
- set_xlim(right=1) # left unchanged
-
- Keyword arguments:
-
- *left*: scalar
- The left xlim; *xmin*, the previous name, may still be used
-
- *right*: scalar
- The right xlim; *xmax*, the previous name, may still be used
-
- *emit*: [ *True* | *False* ]
- Notify observers of limit change
-
- *auto*: [ *True* | *False* | *None* ]
- Turn *x* autoscaling on (*True*), off (*False*; default),
- or leave unchanged (*None*)
-
- Note, the *left* (formerly *xmin*) value may be greater than
- the *right* (formerly *xmax*).
- For example, suppose *x* is years before present.
- Then one might use::
-
- set_ylim(5000, 0)
-
- so 5000 years ago is on the left of the plot and the
- present is on the right.
-
- Returns the current xlimits as a length 2 tuple
-
- ACCEPTS: length 2 sequence of floats
- """
- if 'xmin' in kw:
- left = kw.pop('xmin')
- if 'xmax' in kw:
- right = kw.pop('xmax')
- if kw:
- raise ValueError("unrecognized kwargs: %s" %
- list(six.iterkeys(kw)))
-
- if right is None and iterable(left):
- left, right = left
-
- self._process_unit_info(xdata=(left, right))
- if left is not None:
- left = self.convert_xunits(left)
- if right is not None:
- right = self.convert_xunits(right)
-
- old_left, old_right = self.get_xlim()
- if left is None:
- left = old_left
- if right is None:
- right = old_right
-
- if left == right:
- warnings.warn(
- ('Attempting to set identical left==right results\n'
- 'in singular transformations; automatically expanding.\n'
- 'left=%s, right=%s') % (left, right))
- left, right = mtransforms.nonsingular(left, right, increasing=False)
- left, right = self.xaxis.limit_range_for_scale(left, right)
-
- self.viewLim.intervalx = (left, right)
- if auto is not None:
- self._autoscaleXon = bool(auto)
-
- if emit:
- self.callbacks.process('xlim_changed', self)
- # Call all of the other x-axes that are shared with this one
- for other in self._shared_x_axes.get_siblings(self):
- if other is not self:
- other.set_xlim(self.viewLim.intervalx,
- emit=False, auto=auto)
- if (other.figure != self.figure and
- other.figure.canvas is not None):
- other.figure.canvas.draw_idle()
-
- return left, right
-
- def get_xscale(self):
- return self.xaxis.get_scale()
- get_xscale.__doc__ = "Return the xaxis scale string: %s""" % (
- ", ".join(mscale.get_scale_names()))
-
- @docstring.dedent_interpd
- def set_xscale(self, value, **kwargs):
- """
- Call signature::
-
- set_xscale(value)
-
- Set the scaling of the x-axis: %(scale)s
-
- ACCEPTS: [%(scale)s]
-
- Different kwargs are accepted, depending on the scale:
- %(scale_docs)s
- """
- # If the scale is being set to log, clip nonposx to prevent headaches
- # around zero
- if value.lower() == 'log' and 'nonposx' not in kwargs.keys():
- kwargs['nonposx'] = 'clip'
- self.xaxis._set_scale(value, **kwargs)
- self.autoscale_view(scaley=False)
- self._update_transScale()
-
- def get_xticks(self, minor=False):
- """Return the x ticks as a list of locations"""
- return self.xaxis.get_ticklocs(minor=minor)
-
- def set_xticks(self, ticks, minor=False):
- """
- Set the x ticks with list of *ticks*
-
- ACCEPTS: sequence of floats
- """
- return self.xaxis.set_ticks(ticks, minor=minor)
-
- def get_xmajorticklabels(self):
- """
- Get the xtick labels as a list of :class:`~matplotlib.text.Text`
- instances.
- """
- return cbook.silent_list('Text xticklabel',
- self.xaxis.get_majorticklabels())
-
- def get_xminorticklabels(self):
- """
- Get the x minor tick labels as a list of
- :class:`matplotlib.text.Text` instances.
- """
- return cbook.silent_list('Text xticklabel',
- self.xaxis.get_minorticklabels())
-
- def get_xticklabels(self, minor=False, which=None):
- """
- Get the x tick labels as a list of :class:`~matplotlib.text.Text`
- instances.
-
- Parameters
- ----------
- minor : bool
- If True return the minor ticklabels,
- else return the major ticklabels
-
- which : None, ('minor', 'major', 'both')
- Overrides `minor`.
-
- Selects which ticklabels to return
-
- Returns
- -------
- ret : list
- List of :class:`~matplotlib.text.Text` instances.
- """
- return cbook.silent_list('Text xticklabel',
- self.xaxis.get_ticklabels(minor=minor,
- which=which))
-
- @docstring.dedent_interpd
- def set_xticklabels(self, labels, fontdict=None, minor=False, **kwargs):
- """
- Call signature::
-
- set_xticklabels(labels, fontdict=None, minor=False, **kwargs)
-
- Set the xtick labels with list of strings *labels*. Return a
- list of axis text instances.
-
- *kwargs* set the :class:`~matplotlib.text.Text` properties.
- Valid properties are
- %(Text)s
-
- ACCEPTS: sequence of strings
- """
- return self.xaxis.set_ticklabels(labels, fontdict,
- minor=minor, **kwargs)
-
- def invert_yaxis(self):
- """
- Invert the y-axis.
- """
- bottom, top = self.get_ylim()
- self.set_ylim(top, bottom, auto=None)
-
- def yaxis_inverted(self):
- """Returns *True* if the y-axis is inverted."""
- bottom, top = self.get_ylim()
- return top < bottom
-
- def get_ybound(self):
- """
- Return y-axis numerical bounds in the form of
- ``lowerBound < upperBound``
- """
- bottom, top = self.get_ylim()
- if bottom < top:
- return bottom, top
- else:
- return top, bottom
-
- def set_ybound(self, lower=None, upper=None):
- """
- Set the lower and upper numerical bounds of the y-axis.
- This method will honor axes inversion regardless of parameter order.
- It will not change the _autoscaleYon attribute.
- """
- if upper is None and iterable(lower):
- lower, upper = lower
-
- old_lower, old_upper = self.get_ybound()
-
- if lower is None:
- lower = old_lower
- if upper is None:
- upper = old_upper
-
- if self.yaxis_inverted():
- if lower < upper:
- self.set_ylim(upper, lower, auto=None)
- else:
- self.set_ylim(lower, upper, auto=None)
- else:
- if lower < upper:
- self.set_ylim(lower, upper, auto=None)
- else:
- self.set_ylim(upper, lower, auto=None)
-
- def get_ylim(self):
- """
- Get the y-axis range [*bottom*, *top*]
- """
- return tuple(self.viewLim.intervaly)
-
- def set_ylim(self, bottom=None, top=None, emit=True, auto=False, **kw):
- """
- Call signature::
-
- set_ylim(self, *args, **kwargs):
-
- Set the data limits for the yaxis
-
- Examples::
-
- set_ylim((bottom, top))
- set_ylim(bottom, top)
- set_ylim(bottom=1) # top unchanged
- set_ylim(top=1) # bottom unchanged
-
- Keyword arguments:
-
- *bottom*: scalar
- The bottom ylim; the previous name, *ymin*, may still be used
-
- *top*: scalar
- The top ylim; the previous name, *ymax*, may still be used
-
- *emit*: [ *True* | *False* ]
- Notify observers of limit change
-
- *auto*: [ *True* | *False* | *None* ]
- Turn *y* autoscaling on (*True*), off (*False*; default),
- or leave unchanged (*None*)
-
- Note, the *bottom* (formerly *ymin*) value may be greater than
- the *top* (formerly *ymax*).
- For example, suppose *y* is depth in the ocean.
- Then one might use::
-
- set_ylim(5000, 0)
-
- so 5000 m depth is at the bottom of the plot and the
- surface, 0 m, is at the top.
-
- Returns the current ylimits as a length 2 tuple
-
- ACCEPTS: length 2 sequence of floats
- """
- if 'ymin' in kw:
- bottom = kw.pop('ymin')
- if 'ymax' in kw:
- top = kw.pop('ymax')
- if kw:
- raise ValueError("unrecognized kwargs: %s" %
- list(six.iterkeys(kw)))
-
- if top is None and iterable(bottom):
- bottom, top = bottom
-
- if bottom is not None:
- bottom = self.convert_yunits(bottom)
- if top is not None:
- top = self.convert_yunits(top)
-
- old_bottom, old_top = self.get_ylim()
-
- if bottom is None:
- bottom = old_bottom
- if top is None:
- top = old_top
-
- if bottom == top:
- warnings.warn(
- ('Attempting to set identical bottom==top results\n'
- 'in singular transformations; automatically expanding.\n'
- 'bottom=%s, top=%s') % (bottom, top))
-
- bottom, top = mtransforms.nonsingular(bottom, top, increasing=False)
- bottom, top = self.yaxis.limit_range_for_scale(bottom, top)
-
- self.viewLim.intervaly = (bottom, top)
- if auto is not None:
- self._autoscaleYon = bool(auto)
-
- if emit:
- self.callbacks.process('ylim_changed', self)
- # Call all of the other y-axes that are shared with this one
- for other in self._shared_y_axes.get_siblings(self):
- if other is not self:
- other.set_ylim(self.viewLim.intervaly,
- emit=False, auto=auto)
- if (other.figure != self.figure and
- other.figure.canvas is not None):
- other.figure.canvas.draw_idle()
-
- return bottom, top
-
- def get_yscale(self):
- return self.yaxis.get_scale()
- get_yscale.__doc__ = "Return the yaxis scale string: %s""" % (
- ", ".join(mscale.get_scale_names()))
-
- @docstring.dedent_interpd
- def set_yscale(self, value, **kwargs):
- """
- Call signature::
-
- set_yscale(value)
-
- Set the scaling of the y-axis: %(scale)s
-
- ACCEPTS: [%(scale)s]
-
- Different kwargs are accepted, depending on the scale:
- %(scale_docs)s
- """
- # If the scale is being set to log, clip nonposy to prevent headaches
- # around zero
- if value.lower() == 'log' and 'nonposy' not in kwargs.keys():
- kwargs['nonposy'] = 'clip'
- self.yaxis._set_scale(value, **kwargs)
- self.autoscale_view(scalex=False)
- self._update_transScale()
-
- def get_yticks(self, minor=False):
- """Return the y ticks as a list of locations"""
- return self.yaxis.get_ticklocs(minor=minor)
-
- def set_yticks(self, ticks, minor=False):
- """
- Set the y ticks with list of *ticks*
-
- ACCEPTS: sequence of floats
-
- Keyword arguments:
-
- *minor*: [ *False* | *True* ]
- Sets the minor ticks if *True*
- """
- return self.yaxis.set_ticks(ticks, minor=minor)
-
- def get_ymajorticklabels(self):
- """
- Get the major y tick labels as a list of
- :class:`~matplotlib.text.Text` instances.
- """
- return cbook.silent_list('Text yticklabel',
- self.yaxis.get_majorticklabels())
-
- def get_yminorticklabels(self):
- """
- Get the minor y tick labels as a list of
- :class:`~matplotlib.text.Text` instances.
- """
- return cbook.silent_list('Text yticklabel',
- self.yaxis.get_minorticklabels())
-
- def get_yticklabels(self, minor=False, which=None):
- """
- Get the x tick labels as a list of :class:`~matplotlib.text.Text`
- instances.
-
- Parameters
- ----------
- minor : bool
- If True return the minor ticklabels,
- else return the major ticklabels
-
- which : None, ('minor', 'major', 'both')
- Overrides `minor`.
-
- Selects which ticklabels to return
-
- Returns
- -------
- ret : list
- List of :class:`~matplotlib.text.Text` instances.
- """
- return cbook.silent_list('Text yticklabel',
- self.yaxis.get_ticklabels(minor=minor,
- which=which))
-
- @docstring.dedent_interpd
- def set_yticklabels(self, labels, fontdict=None, minor=False, **kwargs):
- """
- Call signature::
-
- set_yticklabels(labels, fontdict=None, minor=False, **kwargs)
-
- Set the y tick labels with list of strings *labels*. Return a list of
- :class:`~matplotlib.text.Text` instances.
-
- *kwargs* set :class:`~matplotlib.text.Text` properties for the labels.
- Valid properties are
- %(Text)s
-
- ACCEPTS: sequence of strings
- """
- return self.yaxis.set_ticklabels(labels, fontdict,
- minor=minor, **kwargs)
-
- def xaxis_date(self, tz=None):
- """
- Sets up x-axis ticks and labels that treat the x data as dates.
-
- *tz* is a timezone string or :class:`tzinfo` instance.
- Defaults to rc value.
- """
- # should be enough to inform the unit conversion interface
- # dates are coming in
- self.xaxis.axis_date(tz)
-
- def yaxis_date(self, tz=None):
- """
- Sets up y-axis ticks and labels that treat the y data as dates.
-
- *tz* is a timezone string or :class:`tzinfo` instance.
- Defaults to rc value.
- """
- self.yaxis.axis_date(tz)
-
- def format_xdata(self, x):
- """
- Return *x* string formatted. This function will use the attribute
- self.fmt_xdata if it is callable, else will fall back on the xaxis
- major formatter
- """
- try:
- return self.fmt_xdata(x)
- except TypeError:
- func = self.xaxis.get_major_formatter().format_data_short
- val = func(x)
- return val
-
- def format_ydata(self, y):
- """
- Return y string formatted. This function will use the
- :attr:`fmt_ydata` attribute if it is callable, else will fall
- back on the yaxis major formatter
- """
- try:
- return self.fmt_ydata(y)
- except TypeError:
- func = self.yaxis.get_major_formatter().format_data_short
- val = func(y)
- return val
-
- def format_coord(self, x, y):
- """Return a format string formatting the *x*, *y* coord"""
- if x is None:
- xs = '???'
- else:
- xs = self.format_xdata(x)
- if y is None:
- ys = '???'
- else:
- ys = self.format_ydata(y)
- return 'x=%s y=%s' % (xs, ys)
-
- def minorticks_on(self):
- 'Add autoscaling minor ticks to the axes.'
- for ax in (self.xaxis, self.yaxis):
- if ax.get_scale() == 'log':
- s = ax._scale
- ax.set_minor_locator(mticker.LogLocator(s.base, s.subs))
- else:
- ax.set_minor_locator(mticker.AutoMinorLocator())
-
- def minorticks_off(self):
- """Remove minor ticks from the axes."""
- self.xaxis.set_minor_locator(mticker.NullLocator())
- self.yaxis.set_minor_locator(mticker.NullLocator())
-
- #### Interactive manipulation
-
- def can_zoom(self):
- """
- Return *True* if this axes supports the zoom box button functionality.
- """
- return True
-
- def can_pan(self):
- """
- Return *True* if this axes supports any pan/zoom button functionality.
- """
- return True
-
- def get_navigate(self):
- """
- Get whether the axes responds to navigation commands
- """
- return self._navigate
-
- def set_navigate(self, b):
- """
- Set whether the axes responds to navigation toolbar commands
-
- ACCEPTS: [ *True* | *False* ]
- """
- self._navigate = b
-
- def get_navigate_mode(self):
- """
- Get the navigation toolbar button status: 'PAN', 'ZOOM', or None
- """
- return self._navigate_mode
-
- def set_navigate_mode(self, b):
- """
- Set the navigation toolbar button status;
-
- .. warning::
- this is not a user-API function.
-
- """
- self._navigate_mode = b
-
- def start_pan(self, x, y, button):
- """
- Called when a pan operation has started.
-
- *x*, *y* are the mouse coordinates in display coords.
- button is the mouse button number:
-
- * 1: LEFT
- * 2: MIDDLE
- * 3: RIGHT
-
- .. note::
-
- Intended to be overridden by new projection types.
-
- """
- self._pan_start = cbook.Bunch(
- lim=self.viewLim.frozen(),
- trans=self.transData.frozen(),
- trans_inverse=self.transData.inverted().frozen(),
- bbox=self.bbox.frozen(),
- x=x,
- y=y)
-
- def end_pan(self):
- """
- Called when a pan operation completes (when the mouse button
- is up.)
-
- .. note::
-
- Intended to be overridden by new projection types.
-
- """
- del self._pan_start
-
- def drag_pan(self, button, key, x, y):
- """
- Called when the mouse moves during a pan operation.
-
- *button* is the mouse button number:
-
- * 1: LEFT
- * 2: MIDDLE
- * 3: RIGHT
-
- *key* is a "shift" key
-
- *x*, *y* are the mouse coordinates in display coords.
-
- .. note::
-
- Intended to be overridden by new projection types.
-
- """
- def format_deltas(key, dx, dy):
- if key == 'control':
- if abs(dx) > abs(dy):
- dy = dx
- else:
- dx = dy
- elif key == 'x':
- dy = 0
- elif key == 'y':
- dx = 0
- elif key == 'shift':
- if 2 * abs(dx) < abs(dy):
- dx = 0
- elif 2 * abs(dy) < abs(dx):
- dy = 0
- elif abs(dx) > abs(dy):
- dy = dy / abs(dy) * abs(dx)
- else:
- dx = dx / abs(dx) * abs(dy)
- return (dx, dy)
-
- p = self._pan_start
- dx = x - p.x
- dy = y - p.y
- if dx == 0 and dy == 0:
- return
- if button == 1:
- dx, dy = format_deltas(key, dx, dy)
- result = p.bbox.translated(-dx, -dy) \
- .transformed(p.trans_inverse)
- elif button == 3:
- try:
- dx = -dx / float(self.bbox.width)
- dy = -dy / float(self.bbox.height)
- dx, dy = format_deltas(key, dx, dy)
- if self.get_aspect() != 'auto':
- dx = 0.5 * (dx + dy)
- dy = dx
-
- alpha = np.power(10.0, (dx, dy))
- start = np.array([p.x, p.y])
- oldpoints = p.lim.transformed(p.trans)
- newpoints = start + alpha * (oldpoints - start)
- result = mtransforms.Bbox(newpoints) \
- .transformed(p.trans_inverse)
- except OverflowError:
- warnings.warn('Overflow while panning')
- return
-
- self.set_xlim(*result.intervalx)
- self.set_ylim(*result.intervaly)
-
- def get_cursor_props(self):
- """
- Return the cursor propertiess as a (*linewidth*, *color*)
- tuple, where *linewidth* is a float and *color* is an RGBA
- tuple
- """
- return self._cursorProps
-
- def set_cursor_props(self, *args):
- """
- Set the cursor property as::
-
- ax.set_cursor_props(linewidth, color)
-
- or::
-
- ax.set_cursor_props((linewidth, color))
-
- ACCEPTS: a (*float*, *color*) tuple
- """
- if len(args) == 1:
- lw, c = args[0]
- elif len(args) == 2:
- lw, c = args
- else:
- raise ValueError('args must be a (linewidth, color) tuple')
- c = mcolors.colorConverter.to_rgba(c)
- self._cursorProps = lw, c
-
- def get_children(self):
- """return a list of child artists"""
- children = []
- children.append(self.xaxis)
- children.append(self.yaxis)
- children.extend(self.lines)
- children.extend(self.patches)
- children.extend(self.texts)
- children.extend(self.tables)
- children.extend(self.artists)
- children.extend(self.images)
- if self.legend_ is not None:
- children.append(self.legend_)
- children.extend(self.collections)
- children.append(self.title)
- children.append(self._left_title)
- children.append(self._right_title)
- children.append(self.patch)
- children.extend(six.itervalues(self.spines))
- return children
-
- def contains(self, mouseevent):
- """
- Test whether the mouse event occured in the axes.
-
- Returns *True* / *False*, {}
- """
- if six.callable(self._contains):
- return self._contains(self, mouseevent)
-
- return self.patch.contains(mouseevent)
-
- def contains_point(self, point):
- """
- Returns *True* if the point (tuple of x,y) is inside the axes
- (the area defined by the its patch). A pixel coordinate is
- required.
-
- """
- return self.patch.contains_point(point, radius=1.0)
-
- def pick(self, *args):
- """
- Call signature::
-
- pick(mouseevent)
-
- each child artist will fire a pick event if mouseevent is over
- the artist and the artist has picker set
- """
- martist.Artist.pick(self, args[0])
-
- def get_default_bbox_extra_artists(self):
- return [artist for artist in self.get_children()
- if artist.get_visible()]
-
- def get_tightbbox(self, renderer, call_axes_locator=True):
- """
- Return the tight bounding box of the axes.
- The dimension of the Bbox in canvas coordinate.
-
- If *call_axes_locator* is *False*, it does not call the
- _axes_locator attribute, which is necessary to get the correct
- bounding box. ``call_axes_locator==False`` can be used if the
- caller is only intereted in the relative size of the tightbbox
- compared to the axes bbox.
- """
-
- bb = []
-
- if not self.get_visible():
- return None
-
- locator = self.get_axes_locator()
- if locator and call_axes_locator:
- pos = locator(self, renderer)
- self.apply_aspect(pos)
- else:
- self.apply_aspect()
-
- bb.append(self.get_window_extent(renderer))
-
- if self.title.get_visible():
- bb.append(self.title.get_window_extent(renderer))
- if self._left_title.get_visible():
- bb.append(self._left_title.get_window_extent(renderer))
- if self._right_title.get_visible():
- bb.append(self._right_title.get_window_extent(renderer))
-
- bb_xaxis = self.xaxis.get_tightbbox(renderer)
- if bb_xaxis:
- bb.append(bb_xaxis)
-
- bb_yaxis = self.yaxis.get_tightbbox(renderer)
- if bb_yaxis:
- bb.append(bb_yaxis)
-
- _bbox = mtransforms.Bbox.union(
- [b for b in bb if b.width != 0 or b.height != 0])
-
- return _bbox
-
- def _make_twin_axes(self, *kl, **kwargs):
- """
- make a twinx axes of self. This is used for twinx and twiny.
- """
- ax2 = self.figure.add_axes(self.get_position(True), *kl, **kwargs)
- return ax2
-
- def twinx(self):
- """
- Call signature::
-
- ax = twinx()
-
- create a twin of Axes for generating a plot with a sharex
- x-axis but independent y axis. The y-axis of self will have
- ticks on left and the returned axes will have ticks on the
- right.
-
- .. note::
- For those who are 'picking' artists while using twinx, pick
- events are only called for the artists in the top-most axes.
- """
- ax2 = self._make_twin_axes(sharex=self)
- ax2.yaxis.tick_right()
- ax2.yaxis.set_label_position('right')
- ax2.yaxis.set_offset_position('right')
- self.yaxis.tick_left()
- ax2.xaxis.set_visible(False)
- ax2.patch.set_visible(False)
- return ax2
-
- def twiny(self):
- """
- Call signature::
-
- ax = twiny()
-
- create a twin of Axes for generating a plot with a shared
- y-axis but independent x axis. The x-axis of self will have
- ticks on bottom and the returned axes will have ticks on the
- top.
-
- .. note::
- For those who are 'picking' artists while using twiny, pick
- events are only called for the artists in the top-most axes.
- """
-
- ax2 = self._make_twin_axes(sharey=self)
- ax2.xaxis.tick_top()
- ax2.xaxis.set_label_position('top')
- self.xaxis.tick_bottom()
- ax2.yaxis.set_visible(False)
- ax2.patch.set_visible(False)
- return ax2
-
- def get_shared_x_axes(self):
- 'Return a copy of the shared axes Grouper object for x axes'
- return self._shared_x_axes
-
- def get_shared_y_axes(self):
- 'Return a copy of the shared axes Grouper object for y axes'
- return self._shared_y_axes
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/axes/_subplots.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/axes/_subplots.py
deleted file mode 100644
index 892d6e9..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/axes/_subplots.py
+++ /dev/null
@@ -1,227 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import map
-
-from matplotlib.gridspec import GridSpec, SubplotSpec
-from matplotlib import docstring
-import matplotlib.artist as martist
-from matplotlib.axes._axes import Axes
-
-import warnings
-from matplotlib.cbook import mplDeprecation
-
-
-class SubplotBase(object):
- """
- Base class for subplots, which are :class:`Axes` instances with
- additional methods to facilitate generating and manipulating a set
- of :class:`Axes` within a figure.
- """
-
- def __init__(self, fig, *args, **kwargs):
- """
- *fig* is a :class:`matplotlib.figure.Figure` instance.
-
- *args* is the tuple (*numRows*, *numCols*, *plotNum*), where
- the array of subplots in the figure has dimensions *numRows*,
- *numCols*, and where *plotNum* is the number of the subplot
- being created. *plotNum* starts at 1 in the upper left
- corner and increases to the right.
-
-
- If *numRows* <= *numCols* <= *plotNum* < 10, *args* can be the
- decimal integer *numRows* * 100 + *numCols* * 10 + *plotNum*.
- """
-
- self.figure = fig
-
- if len(args) == 1:
- if isinstance(args[0], SubplotSpec):
- self._subplotspec = args[0]
- else:
- try:
- s = str(int(args[0]))
- rows, cols, num = list(map(int, s))
- except ValueError:
- raise ValueError(
- 'Single argument to subplot must be a 3-digit '
- 'integer')
- self._subplotspec = GridSpec(rows, cols)[num - 1]
- # num - 1 for converting from MATLAB to python indexing
- elif len(args) == 3:
- rows, cols, num = args
- rows = int(rows)
- cols = int(cols)
- if isinstance(num, tuple) and len(num) == 2:
- num = [int(n) for n in num]
- self._subplotspec = GridSpec(rows, cols)[num[0] - 1:num[1]]
- else:
- if num < 0 or num > rows*cols:
- raise ValueError(
- "num must be 0 <= num <= {maxn}, not {num}".format(
- maxn=rows*cols, num=num))
- if num == 0:
- warnings.warn("The use of 0 (which ends up being the "
- "_last_ sub-plot) is deprecated in 1.4 "
- "and will raise an error in 1.5",
- mplDeprecation)
- self._subplotspec = GridSpec(rows, cols)[int(num) - 1]
- # num - 1 for converting from MATLAB to python indexing
- else:
- raise ValueError('Illegal argument(s) to subplot: %s' % (args,))
-
- self.update_params()
-
- # _axes_class is set in the subplot_class_factory
- self._axes_class.__init__(self, fig, self.figbox, **kwargs)
-
- def __reduce__(self):
- # get the first axes class which does not inherit from a subplotbase
- not_subplotbase = lambda c: issubclass(c, Axes) and \
- not issubclass(c, SubplotBase)
- axes_class = [c for c in self.__class__.mro() if not_subplotbase(c)][0]
- r = [_PicklableSubplotClassConstructor(),
- (axes_class,),
- self.__getstate__()]
- return tuple(r)
-
- def get_geometry(self):
- """get the subplot geometry, e.g., 2,2,3"""
- rows, cols, num1, num2 = self.get_subplotspec().get_geometry()
- return rows, cols, num1 + 1 # for compatibility
-
- # COVERAGE NOTE: Never used internally or from examples
- def change_geometry(self, numrows, numcols, num):
- """change subplot geometry, e.g., from 1,1,1 to 2,2,3"""
- self._subplotspec = GridSpec(numrows, numcols)[num - 1]
- self.update_params()
- self.set_position(self.figbox)
-
- def get_subplotspec(self):
- """get the SubplotSpec instance associated with the subplot"""
- return self._subplotspec
-
- def set_subplotspec(self, subplotspec):
- """set the SubplotSpec instance associated with the subplot"""
- self._subplotspec = subplotspec
-
- def update_params(self):
- """update the subplot position from fig.subplotpars"""
-
- self.figbox, self.rowNum, self.colNum, self.numRows, self.numCols = \
- self.get_subplotspec().get_position(self.figure,
- return_all=True)
-
- def is_first_col(self):
- return self.colNum == 0
-
- def is_first_row(self):
- return self.rowNum == 0
-
- def is_last_row(self):
- return self.rowNum == self.numRows - 1
-
- def is_last_col(self):
- return self.colNum == self.numCols - 1
-
- # COVERAGE NOTE: Never used internally or from examples
- def label_outer(self):
- """
- set the visible property on ticklabels so xticklabels are
- visible only if the subplot is in the last row and yticklabels
- are visible only if the subplot is in the first column
- """
- lastrow = self.is_last_row()
- firstcol = self.is_first_col()
- for label in self.get_xticklabels():
- label.set_visible(lastrow)
-
- for label in self.get_yticklabels():
- label.set_visible(firstcol)
-
- def _make_twin_axes(self, *kl, **kwargs):
- """
- make a twinx axes of self. This is used for twinx and twiny.
- """
- from matplotlib.projections import process_projection_requirements
- kl = (self.get_subplotspec(),) + kl
- projection_class, kwargs, key = process_projection_requirements(
- self.figure, *kl, **kwargs)
-
- ax2 = subplot_class_factory(projection_class)(self.figure,
- *kl, **kwargs)
- self.figure.add_subplot(ax2)
- return ax2
-
-_subplot_classes = {}
-
-
-def subplot_class_factory(axes_class=None):
- # This makes a new class that inherits from SubplotBase and the
- # given axes_class (which is assumed to be a subclass of Axes).
- # This is perhaps a little bit roundabout to make a new class on
- # the fly like this, but it means that a new Subplot class does
- # not have to be created for every type of Axes.
- if axes_class is None:
- axes_class = Axes
-
- new_class = _subplot_classes.get(axes_class)
- if new_class is None:
- new_class = type(str("%sSubplot") % (axes_class.__name__),
- (SubplotBase, axes_class),
- {'_axes_class': axes_class})
- _subplot_classes[axes_class] = new_class
-
- return new_class
-
-# This is provided for backward compatibility
-Subplot = subplot_class_factory()
-
-
-class _PicklableSubplotClassConstructor(object):
- """
- This stub class exists to return the appropriate subplot
- class when __call__-ed with an axes class. This is purely to
- allow Pickling of Axes and Subplots.
- """
- def __call__(self, axes_class):
- # create a dummy object instance
- subplot_instance = _PicklableSubplotClassConstructor()
- subplot_class = subplot_class_factory(axes_class)
- # update the class to the desired subplot class
- subplot_instance.__class__ = subplot_class
- return subplot_instance
-
-
-docstring.interpd.update(Axes=martist.kwdoc(Axes))
-docstring.interpd.update(Subplot=martist.kwdoc(Axes))
-
-"""
-# this is some discarded code I was using to find the minimum positive
-# data point for some log scaling fixes. I realized there was a
-# cleaner way to do it, but am keeping this around as an example for
-# how to get the data out of the axes. Might want to make something
-# like this a method one day, or better yet make get_verts an Artist
-# method
-
- minx, maxx = self.get_xlim()
- if minx<=0 or maxx<=0:
- # find the min pos value in the data
- xs = []
- for line in self.lines:
- xs.extend(line.get_xdata(orig=False))
- for patch in self.patches:
- xs.extend([x for x,y in patch.get_verts()])
- for collection in self.collections:
- xs.extend([x for x,y in collection.get_verts()])
- posx = [x for x in xs if x>0]
- if len(posx):
-
- minx = min(posx)
- maxx = max(posx)
- # warning, probably breaks inverted axis
- self.set_xlim((0.1*minx, maxx))
-
-"""
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/axis.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/axis.py
deleted file mode 100644
index 364c34f..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/axis.py
+++ /dev/null
@@ -1,2236 +0,0 @@
-"""
-Classes for the ticks and x and y axis
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-from matplotlib import rcParams
-import matplotlib.artist as artist
-from matplotlib.artist import allow_rasterization
-import matplotlib.cbook as cbook
-import matplotlib.font_manager as font_manager
-import matplotlib.lines as mlines
-import matplotlib.patches as mpatches
-import matplotlib.scale as mscale
-import matplotlib.text as mtext
-import matplotlib.ticker as mticker
-import matplotlib.transforms as mtransforms
-import matplotlib.units as munits
-import numpy as np
-import warnings
-
-GRIDLINE_INTERPOLATION_STEPS = 180
-
-
-class Tick(artist.Artist):
- """
- Abstract base class for the axis ticks, grid lines and labels
-
- 1 refers to the bottom of the plot for xticks and the left for yticks
- 2 refers to the top of the plot for xticks and the right for yticks
-
- Publicly accessible attributes:
-
- :attr:`tick1line`
- a Line2D instance
-
- :attr:`tick2line`
- a Line2D instance
-
- :attr:`gridline`
- a Line2D instance
-
- :attr:`label1`
- a Text instance
-
- :attr:`label2`
- a Text instance
-
- :attr:`gridOn`
- a boolean which determines whether to draw the tickline
-
- :attr:`tick1On`
- a boolean which determines whether to draw the 1st tickline
-
- :attr:`tick2On`
- a boolean which determines whether to draw the 2nd tickline
-
- :attr:`label1On`
- a boolean which determines whether to draw tick label
-
- :attr:`label2On`
- a boolean which determines whether to draw tick label
-
- """
- def __init__(self, axes, loc, label,
- size=None, # points
- width=None,
- color=None,
- tickdir=None,
- pad=None,
- labelsize=None,
- labelcolor=None,
- zorder=None,
- gridOn=None, # defaults to axes.grid depending on axes.grid.which
- tick1On=True,
- tick2On=True,
- label1On=True,
- label2On=False,
- major=True,
- ):
- """
- bbox is the Bound2D bounding box in display coords of the Axes
- loc is the tick location in data coords
- size is the tick size in points
- """
- artist.Artist.__init__(self)
-
- if gridOn is None:
- if major and (rcParams['axes.grid.which'] in ('both','major')):
- gridOn = rcParams['axes.grid']
- elif (not major) and (rcParams['axes.grid.which'] in ('both','minor')):
- gridOn = rcParams['axes.grid']
- else :
- gridOn = False
-
- self.set_figure(axes.figure)
- self.axes = axes
-
- name = self.__name__.lower()
- self._name = name
-
- self._loc = loc
-
- if size is None:
- if major:
- size = rcParams['%s.major.size' % name]
- else:
- size = rcParams['%s.minor.size' % name]
- self._size = size
-
- if width is None:
- if major:
- width = rcParams['%s.major.width' % name]
- else:
- width = rcParams['%s.minor.width' % name]
- self._width = width
-
- if color is None:
- color = rcParams['%s.color' % name]
- self._color = color
-
- if pad is None:
- if major:
- pad = rcParams['%s.major.pad' % name]
- else:
- pad = rcParams['%s.minor.pad' % name]
- self._base_pad = pad
-
- if labelcolor is None:
- labelcolor = rcParams['%s.color' % name]
- self._labelcolor = labelcolor
-
- if labelsize is None:
- labelsize = rcParams['%s.labelsize' % name]
- self._labelsize = labelsize
-
- if zorder is None:
- if major:
- zorder = mlines.Line2D.zorder + 0.01
- else:
- zorder = mlines.Line2D.zorder
- self._zorder = zorder
-
- self.apply_tickdir(tickdir)
-
- self.tick1line = self._get_tick1line()
- self.tick2line = self._get_tick2line()
- self.gridline = self._get_gridline()
-
- self.label1 = self._get_text1()
- self.label = self.label1 # legacy name
- self.label2 = self._get_text2()
-
- self.gridOn = gridOn
- self.tick1On = tick1On
- self.tick2On = tick2On
- self.label1On = label1On
- self.label2On = label2On
-
- self.update_position(loc)
-
- def apply_tickdir(self, tickdir):
- """
- Calculate self._pad and self._tickmarkers
- """
- pass
-
- def get_children(self):
- children = [self.tick1line, self.tick2line,
- self.gridline, self.label1, self.label2]
- return children
-
- def set_clip_path(self, clippath, transform=None):
- artist.Artist.set_clip_path(self, clippath, transform)
- #self.tick1line.set_clip_path(clippath, transform)
- #self.tick2line.set_clip_path(clippath, transform)
- self.gridline.set_clip_path(clippath, transform)
- set_clip_path.__doc__ = artist.Artist.set_clip_path.__doc__
-
- def get_pad_pixels(self):
- return self.figure.dpi * self._base_pad / 72.0
-
- def contains(self, mouseevent):
- """
- Test whether the mouse event occurred in the Tick marks.
-
- This function always returns false. It is more useful to test if the
- axis as a whole contains the mouse rather than the set of tick marks.
- """
- if six.callable(self._contains):
- return self._contains(self, mouseevent)
- return False, {}
-
- def set_pad(self, val):
- """
- Set the tick label pad in points
-
- ACCEPTS: float
- """
- self._apply_params(pad=val)
-
- def get_pad(self):
- 'Get the value of the tick label pad in points'
- return self._base_pad
-
- def _get_text1(self):
- 'Get the default Text 1 instance'
- pass
-
- def _get_text2(self):
- 'Get the default Text 2 instance'
- pass
-
- def _get_tick1line(self):
- 'Get the default line2D instance for tick1'
- pass
-
- def _get_tick2line(self):
- 'Get the default line2D instance for tick2'
- pass
-
- def _get_gridline(self):
- 'Get the default grid Line2d instance for this tick'
- pass
-
- def get_loc(self):
- 'Return the tick location (data coords) as a scalar'
- return self._loc
-
- @allow_rasterization
- def draw(self, renderer):
- if not self.get_visible():
- return
- renderer.open_group(self.__name__)
- midPoint = mtransforms.interval_contains(self.get_view_interval(),
- self.get_loc())
-
- if midPoint:
- if self.gridOn:
- self.gridline.draw(renderer)
- if self.tick1On:
- self.tick1line.draw(renderer)
- if self.tick2On:
- self.tick2line.draw(renderer)
-
- if self.label1On:
- self.label1.draw(renderer)
- if self.label2On:
- self.label2.draw(renderer)
-
- renderer.close_group(self.__name__)
-
- def set_label1(self, s):
- """
- Set the text of ticklabel
-
- ACCEPTS: str
- """
- self.label1.set_text(s)
- set_label = set_label1
-
- def set_label2(self, s):
- """
- Set the text of ticklabel2
-
- ACCEPTS: str
- """
- self.label2.set_text(s)
-
- def _set_artist_props(self, a):
- a.set_figure(self.figure)
- #if isinstance(a, mlines.Line2D): a.set_clip_box(self.axes.bbox)
-
- def get_view_interval(self):
- 'return the view Interval instance for the axis this tick is ticking'
- raise NotImplementedError('Derived must override')
-
- def _apply_params(self, **kw):
- switchkw = ['gridOn', 'tick1On', 'tick2On', 'label1On', 'label2On']
- switches = [k for k in kw if k in switchkw]
- for k in switches:
- setattr(self, k, kw.pop(k))
- dirpad = [k for k in kw if k in ['pad', 'tickdir']]
- if dirpad:
- self._base_pad = kw.pop('pad', self._base_pad)
- self.apply_tickdir(kw.pop('tickdir', self._tickdir))
- trans = self._get_text1_transform()[0]
- self.label1.set_transform(trans)
- trans = self._get_text2_transform()[0]
- self.label2.set_transform(trans)
- self.tick1line.set_marker(self._tickmarkers[0])
- self.tick2line.set_marker(self._tickmarkers[1])
- tick_kw = dict([kv for kv in six.iteritems(kw)
- if kv[0] in ['color', 'zorder']])
- if tick_kw:
- self.tick1line.set(**tick_kw)
- self.tick2line.set(**tick_kw)
- for k, v in six.iteritems(tick_kw):
- setattr(self, '_' + k, v)
- tick_list = [kv for kv
- in six.iteritems(kw) if kv[0] in ['size', 'width']]
- for k, v in tick_list:
- setattr(self, '_' + k, v)
- if k == 'size':
- self.tick1line.set_markersize(v)
- self.tick2line.set_markersize(v)
- else:
- self.tick1line.set_markeredgewidth(v)
- self.tick2line.set_markeredgewidth(v)
- label_list = [k for k in six.iteritems(kw)
- if k[0] in ['labelsize', 'labelcolor']]
- if label_list:
- label_kw = dict([(k[5:], v) for (k, v) in label_list])
- self.label1.set(**label_kw)
- self.label2.set(**label_kw)
- for k, v in six.iteritems(label_kw):
- # for labelsize the text objects covert str ('small')
- # -> points. grab the integer from the `Text` object
- # instead of saving the string representation
- v = getattr(self.label1, 'get_' + k)()
- setattr(self, '_' + k, v)
-
-
-class XTick(Tick):
- """
- Contains all the Artists needed to make an x tick - the tick line,
- the label text and the grid line
- """
- __name__ = 'xtick'
-
- def _get_text1_transform(self):
- return self.axes.get_xaxis_text1_transform(self._pad)
-
- def _get_text2_transform(self):
- return self.axes.get_xaxis_text2_transform(self._pad)
-
- def apply_tickdir(self, tickdir):
- if tickdir is None:
- tickdir = rcParams['%s.direction' % self._name]
- self._tickdir = tickdir
-
- if self._tickdir == 'in':
- self._tickmarkers = (mlines.TICKUP, mlines.TICKDOWN)
- self._pad = self._base_pad
- elif self._tickdir == 'inout':
- self._tickmarkers = ('|', '|')
- self._pad = self._base_pad + self._size / 2.
- else:
- self._tickmarkers = (mlines.TICKDOWN, mlines.TICKUP)
- self._pad = self._base_pad + self._size
-
- def _get_text1(self):
- 'Get the default Text instance'
- # the y loc is 3 points below the min of y axis
- # get the affine as an a,b,c,d,tx,ty list
- # x in data coords, y in axes coords
- #t = mtext.Text(
- trans, vert, horiz = self._get_text1_transform()
- t = mtext.Text(
- x=0, y=0,
- fontproperties=font_manager.FontProperties(size=self._labelsize),
- color=self._labelcolor,
- verticalalignment=vert,
- horizontalalignment=horiz,
- )
- t.set_transform(trans)
- self._set_artist_props(t)
- return t
-
- def _get_text2(self):
-
- 'Get the default Text 2 instance'
- # x in data coords, y in axes coords
- #t = mtext.Text(
- trans, vert, horiz = self._get_text2_transform()
- t = mtext.Text(
- x=0, y=1,
- fontproperties=font_manager.FontProperties(size=self._labelsize),
- color=self._labelcolor,
- verticalalignment=vert,
- horizontalalignment=horiz,
- )
- t.set_transform(trans)
- self._set_artist_props(t)
- return t
-
- def _get_tick1line(self):
- 'Get the default line2D instance'
- # x in data coords, y in axes coords
- l = mlines.Line2D(xdata=(0,), ydata=(0,),
- color=self._color,
- linestyle='None',
- marker=self._tickmarkers[0],
- markersize=self._size,
- markeredgewidth=self._width,
- zorder=self._zorder,
- )
- l.set_transform(self.axes.get_xaxis_transform(which='tick1'))
- self._set_artist_props(l)
- return l
-
- def _get_tick2line(self):
- 'Get the default line2D instance'
- # x in data coords, y in axes coords
- l = mlines.Line2D(xdata=(0,), ydata=(1,),
- color=self._color,
- linestyle='None',
- marker=self._tickmarkers[1],
- markersize=self._size,
- markeredgewidth=self._width,
- zorder=self._zorder,
- )
-
- l.set_transform(self.axes.get_xaxis_transform(which='tick2'))
- self._set_artist_props(l)
- return l
-
- def _get_gridline(self):
- 'Get the default line2D instance'
- # x in data coords, y in axes coords
- l = mlines.Line2D(xdata=(0.0, 0.0), ydata=(0, 1.0),
- color=rcParams['grid.color'],
- linestyle=rcParams['grid.linestyle'],
- linewidth=rcParams['grid.linewidth'],
- alpha=rcParams['grid.alpha'],
- markersize=0
- )
- l.set_transform(self.axes.get_xaxis_transform(which='grid'))
- l.get_path()._interpolation_steps = GRIDLINE_INTERPOLATION_STEPS
- self._set_artist_props(l)
-
- return l
-
- def update_position(self, loc):
- 'Set the location of tick in data coords with scalar *loc*'
- x = loc
-
- nonlinear = (hasattr(self.axes, 'yaxis') and
- self.axes.yaxis.get_scale() != 'linear' or
- hasattr(self.axes, 'xaxis') and
- self.axes.xaxis.get_scale() != 'linear')
-
- if self.tick1On:
- self.tick1line.set_xdata((x,))
- if self.tick2On:
- self.tick2line.set_xdata((x,))
- if self.gridOn:
- self.gridline.set_xdata((x,))
- if self.label1On:
- self.label1.set_x(x)
- if self.label2On:
- self.label2.set_x(x)
-
- if nonlinear:
- self.tick1line._invalid = True
- self.tick2line._invalid = True
- self.gridline._invalid = True
-
- self._loc = loc
-
- def get_view_interval(self):
- 'return the Interval instance for this axis view limits'
- return self.axes.viewLim.intervalx
-
-
-class YTick(Tick):
- """
- Contains all the Artists needed to make a Y tick - the tick line,
- the label text and the grid line
- """
- __name__ = 'ytick'
-
- def _get_text1_transform(self):
- return self.axes.get_yaxis_text1_transform(self._pad)
-
- def _get_text2_transform(self):
- return self.axes.get_yaxis_text2_transform(self._pad)
-
- def apply_tickdir(self, tickdir):
- if tickdir is None:
- tickdir = rcParams['%s.direction' % self._name]
- self._tickdir = tickdir
-
- if self._tickdir == 'in':
- self._tickmarkers = (mlines.TICKRIGHT, mlines.TICKLEFT)
- self._pad = self._base_pad
- elif self._tickdir == 'inout':
- self._tickmarkers = ('_', '_')
- self._pad = self._base_pad + self._size / 2.
- else:
- self._tickmarkers = (mlines.TICKLEFT, mlines.TICKRIGHT)
- self._pad = self._base_pad + self._size
-
- # how far from the y axis line the right of the ticklabel are
- def _get_text1(self):
- 'Get the default Text instance'
- # x in axes coords, y in data coords
- trans, vert, horiz = self._get_text1_transform()
- t = mtext.Text(
- x=0, y=0,
- fontproperties=font_manager.FontProperties(size=self._labelsize),
- color=self._labelcolor,
- verticalalignment=vert,
- horizontalalignment=horiz,
- )
- t.set_transform(trans)
- #t.set_transform( self.axes.transData )
- self._set_artist_props(t)
- return t
-
- def _get_text2(self):
- 'Get the default Text instance'
- # x in axes coords, y in data coords
- trans, vert, horiz = self._get_text2_transform()
- t = mtext.Text(
- x=1, y=0,
- fontproperties=font_manager.FontProperties(size=self._labelsize),
- color=self._labelcolor,
- verticalalignment=vert,
- horizontalalignment=horiz,
- )
- t.set_transform(trans)
- self._set_artist_props(t)
- return t
-
- def _get_tick1line(self):
- 'Get the default line2D instance'
- # x in axes coords, y in data coords
-
- l = mlines.Line2D((0,), (0,),
- color=self._color,
- marker=self._tickmarkers[0],
- linestyle='None',
- markersize=self._size,
- markeredgewidth=self._width,
- zorder=self._zorder,
- )
- l.set_transform(self.axes.get_yaxis_transform(which='tick1'))
- self._set_artist_props(l)
- return l
-
- def _get_tick2line(self):
- 'Get the default line2D instance'
- # x in axes coords, y in data coords
- l = mlines.Line2D((1,), (0,),
- color=self._color,
- marker=self._tickmarkers[1],
- linestyle='None',
- markersize=self._size,
- markeredgewidth=self._width,
- zorder=self._zorder,
- )
- l.set_transform(self.axes.get_yaxis_transform(which='tick2'))
- self._set_artist_props(l)
- return l
-
- def _get_gridline(self):
- 'Get the default line2D instance'
- # x in axes coords, y in data coords
- l = mlines.Line2D(xdata=(0, 1), ydata=(0, 0),
- color=rcParams['grid.color'],
- linestyle=rcParams['grid.linestyle'],
- linewidth=rcParams['grid.linewidth'],
- alpha=rcParams['grid.alpha'],
- markersize=0
- )
-
- l.set_transform(self.axes.get_yaxis_transform(which='grid'))
- l.get_path()._interpolation_steps = GRIDLINE_INTERPOLATION_STEPS
- self._set_artist_props(l)
- return l
-
- def update_position(self, loc):
- 'Set the location of tick in data coords with scalar loc'
- y = loc
-
- nonlinear = (hasattr(self.axes, 'yaxis') and
- self.axes.yaxis.get_scale() != 'linear' or
- hasattr(self.axes, 'xaxis') and
- self.axes.xaxis.get_scale() != 'linear')
-
- if self.tick1On:
- self.tick1line.set_ydata((y,))
- if self.tick2On:
- self.tick2line.set_ydata((y,))
- if self.gridOn:
- self.gridline.set_ydata((y, ))
- if self.label1On:
- self.label1.set_y(y)
- if self.label2On:
- self.label2.set_y(y)
- if nonlinear:
- self.tick1line._invalid = True
- self.tick2line._invalid = True
- self.gridline._invalid = True
-
- self._loc = loc
-
- def get_view_interval(self):
- 'return the Interval instance for this axis view limits'
- return self.axes.viewLim.intervaly
-
-
-class Ticker:
- locator = None
- formatter = None
-
-
-class Axis(artist.Artist):
- """
- Public attributes
-
- * :attr:`axes.transData` - transform data coords to display coords
- * :attr:`axes.transAxes` - transform axis coords to display coords
- * :attr:`labelpad` - number of points between the axis and its label
- """
- OFFSETTEXTPAD = 3
-
- def __str__(self):
- return self.__class__.__name__ \
- + "(%f,%f)" % tuple(self.axes.transAxes.transform_point((0, 0)))
-
- def __init__(self, axes, pickradius=15):
- """
- Init the axis with the parent Axes instance
- """
- artist.Artist.__init__(self)
- self.set_figure(axes.figure)
-
- # Keep track of setting to the default value, this allows use to know
- # if any of the following values is explicitly set by the user, so as
- # to not overwrite their settings with any of our 'auto' settings.
- self.isDefault_majloc = True
- self.isDefault_minloc = True
- self.isDefault_majfmt = True
- self.isDefault_minfmt = True
- self.isDefault_label = True
-
- self.axes = axes
- self.major = Ticker()
- self.minor = Ticker()
- self.callbacks = cbook.CallbackRegistry()
-
- #class dummy:
- # locator = None
- # formatter = None
- #self.major = dummy()
- #self.minor = dummy()
-
- self._autolabelpos = True
- self._smart_bounds = False
-
- self.label = self._get_label()
- self.labelpad = 5
- self.offsetText = self._get_offset_text()
- self.majorTicks = []
- self.minorTicks = []
- self.pickradius = pickradius
-
- # Initialize here for testing; later add API
- self._major_tick_kw = dict()
- self._minor_tick_kw = dict()
-
- self.cla()
- self._set_scale('linear')
-
- def set_label_coords(self, x, y, transform=None):
- """
- Set the coordinates of the label. By default, the x
- coordinate of the y label is determined by the tick label
- bounding boxes, but this can lead to poor alignment of
- multiple ylabels if there are multiple axes. Ditto for the y
- coodinate of the x label.
-
- You can also specify the coordinate system of the label with
- the transform. If None, the default coordinate system will be
- the axes coordinate system (0,0) is (left,bottom), (0.5, 0.5)
- is middle, etc
-
- """
-
- self._autolabelpos = False
- if transform is None:
- transform = self.axes.transAxes
-
- self.label.set_transform(transform)
- self.label.set_position((x, y))
-
- def get_transform(self):
- return self._scale.get_transform()
-
- def get_scale(self):
- return self._scale.name
-
- @cbook.deprecated('1.3')
- def set_scale(self, value, **kwargs):
- """
- This should be a private function (moved to _set_scale)
- """
- self._set_scale(value, **kwargs)
-
- def _set_scale(self, value, **kwargs):
- self._scale = mscale.scale_factory(value, self, **kwargs)
- self._scale.set_default_locators_and_formatters(self)
-
- self.isDefault_majloc = True
- self.isDefault_minloc = True
- self.isDefault_majfmt = True
- self.isDefault_minfmt = True
-
- def limit_range_for_scale(self, vmin, vmax):
- return self._scale.limit_range_for_scale(vmin, vmax, self.get_minpos())
-
- def get_children(self):
- children = [self.label, self.offsetText]
- majorticks = self.get_major_ticks()
- minorticks = self.get_minor_ticks()
-
- children.extend(majorticks)
- children.extend(minorticks)
- return children
-
- def cla(self):
- 'clear the current axis'
- self.set_major_locator(mticker.AutoLocator())
- self.set_major_formatter(mticker.ScalarFormatter())
- self.set_minor_locator(mticker.NullLocator())
- self.set_minor_formatter(mticker.NullFormatter())
-
- self.set_label_text('')
- self._set_artist_props(self.label)
-
- # Keep track of setting to the default value, this allows use to know
- # if any of the following values is explicitly set by the user, so as
- # to not overwrite their settings with any of our 'auto' settings.
- self.isDefault_majloc = True
- self.isDefault_minloc = True
- self.isDefault_majfmt = True
- self.isDefault_minfmt = True
- self.isDefault_label = True
-
- # Clear the callback registry for this axis, or it may "leak"
- self.callbacks = cbook.CallbackRegistry()
-
- # whether the grids are on
- self._gridOnMajor = rcParams['axes.grid'] and (rcParams['axes.grid.which'] in ('both','major'))
- self._gridOnMinor = rcParams['axes.grid'] and (rcParams['axes.grid.which'] in ('both','minor'))
-
- self.label.set_text('')
- self._set_artist_props(self.label)
-
- self.reset_ticks()
-
- self.converter = None
- self.units = None
- self.set_units(None)
-
- def reset_ticks(self):
- # build a few default ticks; grow as necessary later; only
- # define 1 so properties set on ticks will be copied as they
- # grow
- cbook.popall(self.majorTicks)
- cbook.popall(self.minorTicks)
-
- self.majorTicks.extend([self._get_tick(major=True)])
- self.minorTicks.extend([self._get_tick(major=False)])
- self._lastNumMajorTicks = 1
- self._lastNumMinorTicks = 1
-
- def set_tick_params(self, which='major', reset=False, **kw):
- """
- Set appearance parameters for ticks and ticklabels.
-
- For documentation of keyword arguments, see
- :meth:`matplotlib.axes.Axes.tick_params`.
- """
- dicts = []
- if which == 'major' or which == 'both':
- dicts.append(self._major_tick_kw)
- if which == 'minor' or which == 'both':
- dicts.append(self._minor_tick_kw)
- kwtrans = self._translate_tick_kw(kw, to_init_kw=True)
- for d in dicts:
- if reset:
- d.clear()
- d.update(kwtrans)
- if reset:
- self.reset_ticks()
- else:
- if which == 'major' or which == 'both':
- for tick in self.majorTicks:
- tick._apply_params(**self._major_tick_kw)
- if which == 'minor' or which == 'both':
- for tick in self.minorTicks:
- tick._apply_params(**self._minor_tick_kw)
-
- @staticmethod
- def _translate_tick_kw(kw, to_init_kw=True):
- # We may want to move the following function to
- # a more visible location; or maybe there already
- # is something like this.
- def _bool(arg):
- if cbook.is_string_like(arg):
- if arg.lower() == 'on':
- return True
- if arg.lower() == 'off':
- return False
- raise ValueError('String "%s" should be "on" or "off"' % arg)
- return bool(arg)
- # The following lists may be moved to a more
- # accessible location.
- kwkeys0 = ['size', 'width', 'color', 'tickdir', 'pad',
- 'labelsize', 'labelcolor', 'zorder', 'gridOn',
- 'tick1On', 'tick2On', 'label1On', 'label2On']
- kwkeys1 = ['length', 'direction', 'left', 'bottom', 'right', 'top',
- 'labelleft', 'labelbottom', 'labelright', 'labeltop']
- kwkeys = kwkeys0 + kwkeys1
- kwtrans = dict()
- if to_init_kw:
- if 'length' in kw:
- kwtrans['size'] = kw.pop('length')
- if 'direction' in kw:
- kwtrans['tickdir'] = kw.pop('direction')
- if 'left' in kw:
- kwtrans['tick1On'] = _bool(kw.pop('left'))
- if 'bottom' in kw:
- kwtrans['tick1On'] = _bool(kw.pop('bottom'))
- if 'right' in kw:
- kwtrans['tick2On'] = _bool(kw.pop('right'))
- if 'top' in kw:
- kwtrans['tick2On'] = _bool(kw.pop('top'))
-
- if 'labelleft' in kw:
- kwtrans['label1On'] = _bool(kw.pop('labelleft'))
- if 'labelbottom' in kw:
- kwtrans['label1On'] = _bool(kw.pop('labelbottom'))
- if 'labelright' in kw:
- kwtrans['label2On'] = _bool(kw.pop('labelright'))
- if 'labeltop' in kw:
- kwtrans['label2On'] = _bool(kw.pop('labeltop'))
- if 'colors' in kw:
- c = kw.pop('colors')
- kwtrans['color'] = c
- kwtrans['labelcolor'] = c
- # Maybe move the checking up to the caller of this method.
- for key in kw:
- if key not in kwkeys:
- raise ValueError(
- "keyword %s is not recognized; valid keywords are %s"
- % (key, kwkeys))
- kwtrans.update(kw)
- else:
- raise NotImplementedError("Inverse translation is deferred")
- return kwtrans
-
- def set_clip_path(self, clippath, transform=None):
- artist.Artist.set_clip_path(self, clippath, transform)
- for child in self.majorTicks + self.minorTicks:
- child.set_clip_path(clippath, transform)
-
- def get_view_interval(self):
- 'return the Interval instance for this axis view limits'
- raise NotImplementedError('Derived must override')
-
- def set_view_interval(self, vmin, vmax, ignore=False):
- raise NotImplementedError('Derived must override')
-
- def get_data_interval(self):
- 'return the Interval instance for this axis data limits'
- raise NotImplementedError('Derived must override')
-
- def set_data_interval(self):
- '''set the axis data limits'''
- raise NotImplementedError('Derived must override')
-
- def set_default_intervals(self):
- '''set the default limits for the axis data and view interval if they
- are not mutated'''
-
- # this is mainly in support of custom object plotting. For
- # example, if someone passes in a datetime object, we do not
- # know automagically how to set the default min/max of the
- # data and view limits. The unit conversion AxisInfo
- # interface provides a hook for custom types to register
- # default limits through the AxisInfo.default_limits
- # attribute, and the derived code below will check for that
- # and use it if is available (else just use 0..1)
- pass
-
- def _set_artist_props(self, a):
- if a is None:
- return
- a.set_figure(self.figure)
-
- def iter_ticks(self):
- """
- Iterate through all of the major and minor ticks.
- """
- majorLocs = self.major.locator()
- majorTicks = self.get_major_ticks(len(majorLocs))
- self.major.formatter.set_locs(majorLocs)
- majorLabels = [self.major.formatter(val, i)
- for i, val in enumerate(majorLocs)]
-
- minorLocs = self.minor.locator()
- minorTicks = self.get_minor_ticks(len(minorLocs))
- self.minor.formatter.set_locs(minorLocs)
- minorLabels = [self.minor.formatter(val, i)
- for i, val in enumerate(minorLocs)]
-
- major_minor = [
- (majorTicks, majorLocs, majorLabels),
- (minorTicks, minorLocs, minorLabels)]
-
- for group in major_minor:
- for tick in zip(*group):
- yield tick
-
- def get_ticklabel_extents(self, renderer):
- """
- Get the extents of the tick labels on either side
- of the axes.
- """
-
- ticks_to_draw = self._update_ticks(renderer)
- ticklabelBoxes, ticklabelBoxes2 = self._get_tick_bboxes(ticks_to_draw,
- renderer)
-
- if len(ticklabelBoxes):
- bbox = mtransforms.Bbox.union(ticklabelBoxes)
- else:
- bbox = mtransforms.Bbox.from_extents(0, 0, 0, 0)
- if len(ticklabelBoxes2):
- bbox2 = mtransforms.Bbox.union(ticklabelBoxes2)
- else:
- bbox2 = mtransforms.Bbox.from_extents(0, 0, 0, 0)
- return bbox, bbox2
-
- def set_smart_bounds(self, value):
- """set the axis to have smart bounds"""
- self._smart_bounds = value
-
- def get_smart_bounds(self):
- """get whether the axis has smart bounds"""
- return self._smart_bounds
-
- def _update_ticks(self, renderer):
- """
- Update ticks (position and labels) using the current data
- interval of the axes. Returns a list of ticks that will be
- drawn.
- """
-
- interval = self.get_view_interval()
- tick_tups = [t for t in self.iter_ticks()]
- if self._smart_bounds:
- # handle inverted limits
- view_low, view_high = min(*interval), max(*interval)
- data_low, data_high = self.get_data_interval()
- if data_low > data_high:
- data_low, data_high = data_high, data_low
- locs = [ti[1] for ti in tick_tups]
- locs.sort()
- locs = np.array(locs)
- if len(locs):
- if data_low <= view_low:
- # data extends beyond view, take view as limit
- ilow = view_low
- else:
- # data stops within view, take best tick
- cond = locs <= data_low
- good_locs = locs[cond]
- if len(good_locs) > 0:
- # last tick prior or equal to first data point
- ilow = good_locs[-1]
- else:
- # No ticks (why not?), take first tick
- ilow = locs[0]
- if data_high >= view_high:
- # data extends beyond view, take view as limit
- ihigh = view_high
- else:
- # data stops within view, take best tick
- cond = locs >= data_high
- good_locs = locs[cond]
- if len(good_locs) > 0:
- # first tick after or equal to last data point
- ihigh = good_locs[0]
- else:
- # No ticks (why not?), take last tick
- ihigh = locs[-1]
- tick_tups = [ti for ti in tick_tups
- if (ti[1] >= ilow) and (ti[1] <= ihigh)]
-
- # so that we don't lose ticks on the end, expand out the interval ever so slightly. The
- # "ever so slightly" is defined to be the width of a half of a pixel. We don't want to draw
- # a tick that even one pixel outside of the defined axis interval.
- if interval[0] <= interval[1]:
- interval_expanded = interval
- else:
- interval_expanded = interval[1], interval[0]
-
- if hasattr(self, '_get_pixel_distance_along_axis'):
- # normally, one does not want to catch all exceptions that
- # could possibly happen, but it is not clear exactly what
- # exceptions might arise from a user's projection (their
- # rendition of the Axis object). So, we catch all, with
- # the idea that one would rather potentially lose a tick
- # from one side of the axis or another, rather than see a
- # stack trace.
- # We also catch users warnings here. These are the result of
- # invalid numpy calculations that may be the result of out of
- # bounds on axis with finite allowed intervals such as geo
- # projections i.e. Mollweide.
- with np.errstate(invalid='ignore'):
- try:
- ds1 = self._get_pixel_distance_along_axis(
- interval_expanded[0], -0.5)
- except:
- warnings.warn("Unable to find pixel distance along axis for\
- interval padding of ticks; assuming no interval padding\
- needed.")
- ds1 = 0.0
- if np.isnan(ds1):
- ds1 = 0.0
- try:
- ds2 = self._get_pixel_distance_along_axis(
- interval_expanded[1], +0.5)
- except:
- warnings.warn("Unable to find pixel distance along axis for\
- interval padding of ticks; assuming no interval padding\
- needed.")
- ds2 = 0.0
- if np.isnan(ds2):
- ds2 = 0.0
- interval_expanded = (interval_expanded[0] - ds1,
- interval_expanded[1] + ds2)
-
- ticks_to_draw = []
- for tick, loc, label in tick_tups:
- if tick is None:
- continue
- if not mtransforms.interval_contains(interval_expanded, loc):
- continue
- tick.update_position(loc)
- tick.set_label1(label)
- tick.set_label2(label)
- ticks_to_draw.append(tick)
-
- return ticks_to_draw
-
- def _get_tick_bboxes(self, ticks, renderer):
- """
- Given the list of ticks, return two lists of bboxes. One for
- tick lable1's and another for tick label2's.
- """
-
- ticklabelBoxes = []
- ticklabelBoxes2 = []
-
- for tick in ticks:
- if tick.label1On and tick.label1.get_visible():
- extent = tick.label1.get_window_extent(renderer)
- ticklabelBoxes.append(extent)
- if tick.label2On and tick.label2.get_visible():
- extent = tick.label2.get_window_extent(renderer)
- ticklabelBoxes2.append(extent)
- return ticklabelBoxes, ticklabelBoxes2
-
- def get_tightbbox(self, renderer):
- """
- Return a bounding box that encloses the axis. It only accounts
- tick labels, axis label, and offsetText.
- """
- if not self.get_visible():
- return
-
- ticks_to_draw = self._update_ticks(renderer)
- ticklabelBoxes, ticklabelBoxes2 = self._get_tick_bboxes(ticks_to_draw,
- renderer)
-
- self._update_label_position(ticklabelBoxes, ticklabelBoxes2)
-
- self._update_offset_text_position(ticklabelBoxes, ticklabelBoxes2)
- self.offsetText.set_text(self.major.formatter.get_offset())
-
- bb = []
-
- for a in [self.label, self.offsetText]:
- if a.get_visible():
- bb.append(a.get_window_extent(renderer))
-
- bb.extend(ticklabelBoxes)
- bb.extend(ticklabelBoxes2)
-
- #self.offsetText
- bb = [b for b in bb if b.width != 0 or b.height != 0]
- if bb:
- _bbox = mtransforms.Bbox.union(bb)
- return _bbox
- else:
- return None
-
- @allow_rasterization
- def draw(self, renderer, *args, **kwargs):
- 'Draw the axis lines, grid lines, tick lines and labels'
-
- if not self.get_visible():
- return
- renderer.open_group(__name__)
-
- ticks_to_draw = self._update_ticks(renderer)
- ticklabelBoxes, ticklabelBoxes2 = self._get_tick_bboxes(ticks_to_draw,
- renderer)
-
- for tick in ticks_to_draw:
- tick.draw(renderer)
-
- # scale up the axis label box to also find the neighbors, not
- # just the tick labels that actually overlap note we need a
- # *copy* of the axis label box because we don't wan't to scale
- # the actual bbox
-
- self._update_label_position(ticklabelBoxes, ticklabelBoxes2)
-
- self.label.draw(renderer)
-
- self._update_offset_text_position(ticklabelBoxes, ticklabelBoxes2)
- self.offsetText.set_text(self.major.formatter.get_offset())
- self.offsetText.draw(renderer)
-
- if 0: # draw the bounding boxes around the text for debug
- for tick in self.majorTicks:
- label = tick.label1
- mpatches.bbox_artist(label, renderer)
- mpatches.bbox_artist(self.label, renderer)
-
- renderer.close_group(__name__)
-
- def _get_label(self):
- raise NotImplementedError('Derived must override')
-
- def _get_offset_text(self):
- raise NotImplementedError('Derived must override')
-
- def get_gridlines(self):
- 'Return the grid lines as a list of Line2D instance'
- ticks = self.get_major_ticks()
- return cbook.silent_list('Line2D gridline',
- [tick.gridline for tick in ticks])
-
- def get_label(self):
- 'Return the axis label as a Text instance'
- return self.label
-
- def get_offset_text(self):
- 'Return the axis offsetText as a Text instance'
- return self.offsetText
-
- def get_pickradius(self):
- 'Return the depth of the axis used by the picker'
- return self.pickradius
-
- def get_majorticklabels(self):
- 'Return a list of Text instances for the major ticklabels'
- ticks = self.get_major_ticks()
- labels1 = [tick.label1 for tick in ticks if tick.label1On]
- labels2 = [tick.label2 for tick in ticks if tick.label2On]
- return cbook.silent_list('Text major ticklabel', labels1 + labels2)
-
- def get_minorticklabels(self):
- 'Return a list of Text instances for the minor ticklabels'
- ticks = self.get_minor_ticks()
- labels1 = [tick.label1 for tick in ticks if tick.label1On]
- labels2 = [tick.label2 for tick in ticks if tick.label2On]
- return cbook.silent_list('Text minor ticklabel', labels1 + labels2)
-
- def get_ticklabels(self, minor=False, which=None):
- """
- Get the x tick labels as a list of :class:`~matplotlib.text.Text`
- instances.
-
- Parameters
- ----------
- minor : bool
- If True return the minor ticklabels,
- else return the major ticklabels
-
- which : None, ('minor', 'major', 'both')
- Overrides `minor`.
-
- Selects which ticklabels to return
-
- Returns
- -------
- ret : list
- List of :class:`~matplotlib.text.Text` instances.
- """
-
- if which is not None:
- if which == 'minor':
- return self.get_minorticklabels()
- elif which == 'major':
- return self.get_majorticklabels()
- elif which =='both':
- return self.get_majorticklabels() + self.get_minorticklabels()
- else:
- raise ValueError("`which` must be one of ('minor', 'major', 'both')" +
- "not " + str(which))
- if minor:
- return self.get_minorticklabels()
- return self.get_majorticklabels()
-
- def get_majorticklines(self):
- 'Return the major tick lines as a list of Line2D instances'
- lines = []
- ticks = self.get_major_ticks()
- for tick in ticks:
- lines.append(tick.tick1line)
- lines.append(tick.tick2line)
- return cbook.silent_list('Line2D ticklines', lines)
-
- def get_minorticklines(self):
- 'Return the minor tick lines as a list of Line2D instances'
- lines = []
- ticks = self.get_minor_ticks()
- for tick in ticks:
- lines.append(tick.tick1line)
- lines.append(tick.tick2line)
- return cbook.silent_list('Line2D ticklines', lines)
-
- def get_ticklines(self, minor=False):
- 'Return the tick lines as a list of Line2D instances'
- if minor:
- return self.get_minorticklines()
- return self.get_majorticklines()
-
- def get_majorticklocs(self):
- "Get the major tick locations in data coordinates as a numpy array"
- return self.major.locator()
-
- def get_minorticklocs(self):
- "Get the minor tick locations in data coordinates as a numpy array"
- return self.minor.locator()
-
- def get_ticklocs(self, minor=False):
- "Get the tick locations in data coordinates as a numpy array"
- if minor:
- return self.minor.locator()
- return self.major.locator()
-
- def _get_tick(self, major):
- 'return the default tick instance'
- raise NotImplementedError('derived must override')
-
- def _copy_tick_props(self, src, dest):
- 'Copy the props from src tick to dest tick'
- if src is None or dest is None:
- return
- dest.label1.update_from(src.label1)
- dest.label2.update_from(src.label2)
-
- dest.tick1line.update_from(src.tick1line)
- dest.tick2line.update_from(src.tick2line)
- dest.gridline.update_from(src.gridline)
-
- dest.tick1On = src.tick1On
- dest.tick2On = src.tick2On
- dest.label1On = src.label1On
- dest.label2On = src.label2On
-
- def get_label_text(self):
- 'Get the text of the label'
- return self.label.get_text()
-
- def get_major_locator(self):
- 'Get the locator of the major ticker'
- return self.major.locator
-
- def get_minor_locator(self):
- 'Get the locator of the minor ticker'
- return self.minor.locator
-
- def get_major_formatter(self):
- 'Get the formatter of the major ticker'
- return self.major.formatter
-
- def get_minor_formatter(self):
- 'Get the formatter of the minor ticker'
- return self.minor.formatter
-
- def get_major_ticks(self, numticks=None):
- 'get the tick instances; grow as necessary'
- if numticks is None:
- numticks = len(self.get_major_locator()())
- if len(self.majorTicks) < numticks:
- # update the new tick label properties from the old
- for i in range(numticks - len(self.majorTicks)):
- tick = self._get_tick(major=True)
- self.majorTicks.append(tick)
-
- if self._lastNumMajorTicks < numticks:
- protoTick = self.majorTicks[0]
- for i in range(self._lastNumMajorTicks, len(self.majorTicks)):
- tick = self.majorTicks[i]
- if self._gridOnMajor:
- tick.gridOn = True
- self._copy_tick_props(protoTick, tick)
-
- self._lastNumMajorTicks = numticks
- ticks = self.majorTicks[:numticks]
-
- return ticks
-
- def get_minor_ticks(self, numticks=None):
- 'get the minor tick instances; grow as necessary'
- if numticks is None:
- numticks = len(self.get_minor_locator()())
-
- if len(self.minorTicks) < numticks:
- # update the new tick label properties from the old
- for i in range(numticks - len(self.minorTicks)):
- tick = self._get_tick(major=False)
- self.minorTicks.append(tick)
-
- if self._lastNumMinorTicks < numticks:
- protoTick = self.minorTicks[0]
- for i in range(self._lastNumMinorTicks, len(self.minorTicks)):
- tick = self.minorTicks[i]
- if self._gridOnMinor:
- tick.gridOn = True
- self._copy_tick_props(protoTick, tick)
-
- self._lastNumMinorTicks = numticks
- ticks = self.minorTicks[:numticks]
-
- return ticks
-
- def grid(self, b=None, which='major', **kwargs):
- """
- Set the axis grid on or off; b is a boolean. Use *which* =
- 'major' | 'minor' | 'both' to set the grid for major or minor ticks.
-
- If *b* is *None* and len(kwargs)==0, toggle the grid state. If
- *kwargs* are supplied, it is assumed you want the grid on and *b*
- will be set to True.
-
- *kwargs* are used to set the line properties of the grids, e.g.,
-
- xax.grid(color='r', linestyle='-', linewidth=2)
- """
- if len(kwargs):
- b = True
- which = which.lower()
- if which in ['minor', 'both']:
- if b is None:
- self._gridOnMinor = not self._gridOnMinor
- else:
- self._gridOnMinor = b
- for tick in self.minorTicks: # don't use get_ticks here!
- if tick is None:
- continue
- tick.gridOn = self._gridOnMinor
- if len(kwargs):
- tick.gridline.update(kwargs)
- self._minor_tick_kw['gridOn'] = self._gridOnMinor
- if which in ['major', 'both']:
- if b is None:
- self._gridOnMajor = not self._gridOnMajor
- else:
- self._gridOnMajor = b
- for tick in self.majorTicks: # don't use get_ticks here!
- if tick is None:
- continue
- tick.gridOn = self._gridOnMajor
- if len(kwargs):
- tick.gridline.update(kwargs)
- self._major_tick_kw['gridOn'] = self._gridOnMajor
-
- def update_units(self, data):
- """
- introspect *data* for units converter and update the
- axis.converter instance if necessary. Return *True*
- if *data* is registered for unit conversion.
- """
-
- converter = munits.registry.get_converter(data)
- if converter is None:
- return False
-
- neednew = self.converter != converter
- self.converter = converter
- default = self.converter.default_units(data, self)
- #print 'update units: default=%s, units=%s'%(default, self.units)
- if default is not None and self.units is None:
- self.set_units(default)
-
- if neednew:
- self._update_axisinfo()
- return True
-
- def _update_axisinfo(self):
- """
- check the axis converter for the stored units to see if the
- axis info needs to be updated
- """
-
- if self.converter is None:
- return
-
- info = self.converter.axisinfo(self.units, self)
- if info is None:
- return
- if info.majloc is not None and \
- self.major.locator != info.majloc and self.isDefault_majloc:
- self.set_major_locator(info.majloc)
- self.isDefault_majloc = True
- if info.minloc is not None and \
- self.minor.locator != info.minloc and self.isDefault_minloc:
- self.set_minor_locator(info.minloc)
- self.isDefault_minloc = True
- if info.majfmt is not None and \
- self.major.formatter != info.majfmt and self.isDefault_majfmt:
- self.set_major_formatter(info.majfmt)
- self.isDefault_majfmt = True
- if info.minfmt is not None and \
- self.minor.formatter != info.minfmt and self.isDefault_minfmt:
- self.set_minor_formatter(info.minfmt)
- self.isDefault_minfmt = True
- if info.label is not None and self.isDefault_label:
- self.set_label_text(info.label)
- self.isDefault_label = True
-
- self.set_default_intervals()
-
- def have_units(self):
- return self.converter is not None or self.units is not None
-
- def convert_units(self, x):
- if self.converter is None:
- self.converter = munits.registry.get_converter(x)
-
- if self.converter is None:
- return x
-
- ret = self.converter.convert(x, self.units, self)
- return ret
-
- def set_units(self, u):
- """
- set the units for axis
-
- ACCEPTS: a units tag
- """
- pchanged = False
- if u is None:
- self.units = None
- pchanged = True
- else:
- if u != self.units:
- self.units = u
- pchanged = True
- if pchanged:
- self._update_axisinfo()
- self.callbacks.process('units')
- self.callbacks.process('units finalize')
-
- def get_units(self):
- 'return the units for axis'
- return self.units
-
- def set_label_text(self, label, fontdict=None, **kwargs):
- """ Sets the text value of the axis label
-
- ACCEPTS: A string value for the label
- """
- self.isDefault_label = False
- self.label.set_text(label)
- if fontdict is not None:
- self.label.update(fontdict)
- self.label.update(kwargs)
- return self.label
-
- def set_major_formatter(self, formatter):
- """
- Set the formatter of the major ticker
-
- ACCEPTS: A :class:`~matplotlib.ticker.Formatter` instance
- """
- self.isDefault_majfmt = False
- self.major.formatter = formatter
- formatter.set_axis(self)
-
- def set_minor_formatter(self, formatter):
- """
- Set the formatter of the minor ticker
-
- ACCEPTS: A :class:`~matplotlib.ticker.Formatter` instance
- """
- self.isDefault_minfmt = False
- self.minor.formatter = formatter
- formatter.set_axis(self)
-
- def set_major_locator(self, locator):
- """
- Set the locator of the major ticker
-
- ACCEPTS: a :class:`~matplotlib.ticker.Locator` instance
- """
- self.isDefault_majloc = False
- self.major.locator = locator
- locator.set_axis(self)
-
- def set_minor_locator(self, locator):
- """
- Set the locator of the minor ticker
-
- ACCEPTS: a :class:`~matplotlib.ticker.Locator` instance
- """
- self.isDefault_minloc = False
- self.minor.locator = locator
- locator.set_axis(self)
-
- def set_pickradius(self, pickradius):
- """
- Set the depth of the axis used by the picker
-
- ACCEPTS: a distance in points
- """
- self.pickradius = pickradius
-
- def set_ticklabels(self, ticklabels, *args, **kwargs):
- """
- Set the text values of the tick labels. Return a list of Text
- instances. Use *kwarg* *minor=True* to select minor ticks.
- All other kwargs are used to update the text object properties.
- As for get_ticklabels, label1 (left or bottom) is
- affected for a given tick only if its label1On attribute
- is True, and similarly for label2. The list of returned
- label text objects consists of all such label1 objects followed
- by all such label2 objects.
-
- The input *ticklabels* is assumed to match the set of
- tick locations, regardless of the state of label1On and
- label2On.
-
- ACCEPTS: sequence of strings
- """
- #ticklabels = [str(l) for l in ticklabels]
- minor = kwargs.pop('minor', False)
- if minor:
- self.set_minor_formatter(mticker.FixedFormatter(ticklabels))
- ticks = self.get_minor_ticks()
- else:
- self.set_major_formatter(mticker.FixedFormatter(ticklabels))
- ticks = self.get_major_ticks()
-
- ret1 = []
- ret2 = []
- for i, tick in enumerate(ticks):
- if i < len(ticklabels):
- if tick.label1On:
- tick.label1.set_text(ticklabels[i])
- tick.label1.update(kwargs)
- ret1.append(tick.label1)
- if tick.label2On:
- tick.label2.set_text(ticklabels[i])
- ret2.append(tick.label2)
- tick.label2.update(kwargs)
- return ret1 + ret2
-
- def set_ticks(self, ticks, minor=False):
- """
- Set the locations of the tick marks from sequence ticks
-
- ACCEPTS: sequence of floats
- """
- ### XXX if the user changes units, the information will be lost here
- ticks = self.convert_units(ticks)
- if len(ticks) > 1:
- xleft, xright = self.get_view_interval()
- if xright > xleft:
- self.set_view_interval(min(ticks), max(ticks))
- else:
- self.set_view_interval(max(ticks), min(ticks))
- if minor:
- self.set_minor_locator(mticker.FixedLocator(ticks))
- return self.get_minor_ticks(len(ticks))
- else:
- self.set_major_locator(mticker.FixedLocator(ticks))
- return self.get_major_ticks(len(ticks))
-
- def _update_label_position(self, bboxes, bboxes2):
- """
- Update the label position based on the sequence of bounding
- boxes of all the ticklabels
- """
- raise NotImplementedError('Derived must override')
-
- def _update_offset_text_postion(self, bboxes, bboxes2):
- """
- Update the label position based on the sequence of bounding
- boxes of all the ticklabels
- """
- raise NotImplementedError('Derived must override')
-
- def pan(self, numsteps):
- 'Pan *numsteps* (can be positive or negative)'
- self.major.locator.pan(numsteps)
-
- def zoom(self, direction):
- "Zoom in/out on axis; if *direction* is >0 zoom in, else zoom out"
- self.major.locator.zoom(direction)
-
- def axis_date(self, tz=None):
- """
- Sets up x-axis ticks and labels that treat the x data as dates.
- *tz* is a :class:`tzinfo` instance or a timezone string.
- This timezone is used to create date labels.
- """
- # By providing a sample datetime instance with the desired
- # timezone, the registered converter can be selected,
- # and the "units" attribute, which is the timezone, can
- # be set.
- import datetime
- if isinstance(tz, six.string_types):
- import pytz
- tz = pytz.timezone(tz)
- self.update_units(datetime.datetime(2009, 1, 1, 0, 0, 0, 0, tz))
-
-
-class XAxis(Axis):
- __name__ = 'xaxis'
- axis_name = 'x'
-
- def contains(self, mouseevent):
- """Test whether the mouse event occured in the x axis.
- """
- if six.callable(self._contains):
- return self._contains(self, mouseevent)
-
- x, y = mouseevent.x, mouseevent.y
- try:
- trans = self.axes.transAxes.inverted()
- xaxes, yaxes = trans.transform_point((x, y))
- except ValueError:
- return False, {}
- l, b = self.axes.transAxes.transform_point((0, 0))
- r, t = self.axes.transAxes.transform_point((1, 1))
- inaxis = xaxes >= 0 and xaxes <= 1 and (
- (y < b and y > b - self.pickradius) or
- (y > t and y < t + self.pickradius))
- return inaxis, {}
-
- def _get_tick(self, major):
- if major:
- tick_kw = self._major_tick_kw
- else:
- tick_kw = self._minor_tick_kw
- return XTick(self.axes, 0, '', major=major, **tick_kw)
-
- def _get_label(self):
- # x in axes coords, y in display coords (to be updated at draw
- # time by _update_label_positions)
- label = mtext.Text(x=0.5, y=0,
- fontproperties=font_manager.FontProperties(
- size=rcParams['axes.labelsize'],
- weight=rcParams['axes.labelweight']),
- color=rcParams['axes.labelcolor'],
- verticalalignment='top',
- horizontalalignment='center',
- )
-
- label.set_transform(mtransforms.blended_transform_factory(
- self.axes.transAxes, mtransforms.IdentityTransform()))
-
- self._set_artist_props(label)
- self.label_position = 'bottom'
- return label
-
- def _get_offset_text(self):
- # x in axes coords, y in display coords (to be updated at draw time)
- offsetText = mtext.Text(x=1, y=0,
- fontproperties=font_manager.FontProperties(
- size=rcParams['xtick.labelsize']),
- color=rcParams['xtick.color'],
- verticalalignment='top',
- horizontalalignment='right',
- )
- offsetText.set_transform(mtransforms.blended_transform_factory(
- self.axes.transAxes, mtransforms.IdentityTransform()))
- self._set_artist_props(offsetText)
- self.offset_text_position = 'bottom'
- return offsetText
-
- def _get_pixel_distance_along_axis(self, where, perturb):
- """
- Returns the amount, in data coordinates, that a single pixel corresponds to in the
- locality given by "where", which is also given in data coordinates, and is an x coordinate.
- "perturb" is the amount to perturb the pixel. Usually +0.5 or -0.5.
-
- Implementing this routine for an axis is optional; if present, it will ensure that no
- ticks are lost due to round-off at the extreme ends of an axis.
- """
-
- # Note that this routine does not work for a polar axis, because of the 1e-10 below. To
- # do things correctly, we need to use rmax instead of 1e-10 for a polar axis. But
- # since we do not have that kind of information at this point, we just don't try to
- # pad anything for the theta axis of a polar plot.
- if self.axes.name == 'polar':
- return 0.0
-
- #
- # first figure out the pixel location of the "where" point. We use 1e-10 for the
- # y point, so that we remain compatible with log axes.
- #
- trans = self.axes.transData # transformation from data coords to display coords
- transinv = trans.inverted() # transformation from display coords to data coords
- pix = trans.transform_point((where, 1e-10))
- ptp = transinv.transform_point((pix[0] + perturb, pix[1])) # perturb the pixel.
- dx = abs(ptp[0] - where)
-
- return dx
-
- def get_label_position(self):
- """
- Return the label position (top or bottom)
- """
- return self.label_position
-
- def set_label_position(self, position):
- """
- Set the label position (top or bottom)
-
- ACCEPTS: [ 'top' | 'bottom' ]
- """
- assert position == 'top' or position == 'bottom'
- if position == 'top':
- self.label.set_verticalalignment('baseline')
- else:
- self.label.set_verticalalignment('top')
- self.label_position = position
-
- def _update_label_position(self, bboxes, bboxes2):
- """
- Update the label position based on the sequence of bounding
- boxes of all the ticklabels
- """
- if not self._autolabelpos:
- return
- x, y = self.label.get_position()
- if self.label_position == 'bottom':
- if not len(bboxes):
- bottom = self.axes.bbox.ymin
- else:
- bbox = mtransforms.Bbox.union(bboxes)
- bottom = bbox.y0
- self.label.set_position((x,
- bottom - \
- self.labelpad * self.figure.dpi / 72.0))
-
- else:
- if not len(bboxes2):
- top = self.axes.bbox.ymax
- else:
- bbox = mtransforms.Bbox.union(bboxes2)
- top = bbox.y1
- self.label.set_position((x,
- top + self.labelpad * self.figure.dpi / 72.0))
-
- def _update_offset_text_position(self, bboxes, bboxes2):
- """
- Update the offset_text position based on the sequence of bounding
- boxes of all the ticklabels
- """
- x, y = self.offsetText.get_position()
- if not len(bboxes):
- bottom = self.axes.bbox.ymin
- else:
- bbox = mtransforms.Bbox.union(bboxes)
- bottom = bbox.y0
- self.offsetText.set_position((x,
- bottom - self.OFFSETTEXTPAD * self.figure.dpi / 72.0))
-
- def get_text_heights(self, renderer):
- """
- Returns the amount of space one should reserve for text
- above and below the axes. Returns a tuple (above, below)
- """
- bbox, bbox2 = self.get_ticklabel_extents(renderer)
- # MGDTODO: Need a better way to get the pad
- padPixels = self.majorTicks[0].get_pad_pixels()
-
- above = 0.0
- if bbox2.height:
- above += bbox2.height + padPixels
- below = 0.0
- if bbox.height:
- below += bbox.height + padPixels
-
- if self.get_label_position() == 'top':
- above += self.label.get_window_extent(renderer).height + padPixels
- else:
- below += self.label.get_window_extent(renderer).height + padPixels
- return above, below
-
- def set_ticks_position(self, position):
- """
- Set the ticks position (top, bottom, both, default or none)
- both sets the ticks to appear on both positions, but does not
- change the tick labels. 'default' resets the tick positions to
- the default: ticks on both positions, labels at bottom. 'none'
- can be used if you don't want any ticks. 'none' and 'both'
- affect only the ticks, not the labels.
-
- ACCEPTS: [ 'top' | 'bottom' | 'both' | 'default' | 'none' ]
- """
- if position == 'top':
- self.set_tick_params(which='both', top=True, labeltop=True,
- bottom=False, labelbottom=False)
- elif position == 'bottom':
- self.set_tick_params(which='both', top=False, labeltop=False,
- bottom=True, labelbottom=True)
- elif position == 'both':
- self.set_tick_params(which='both', top=True,
- bottom=True)
- elif position == 'none':
- self.set_tick_params(which='both', top=False,
- bottom=False)
- elif position == 'default':
- self.set_tick_params(which='both', top=True, labeltop=False,
- bottom=True, labelbottom=True)
- else:
- raise ValueError("invalid position: %s" % position)
-
- def tick_top(self):
- 'use ticks only on top'
- self.set_ticks_position('top')
-
- def tick_bottom(self):
- 'use ticks only on bottom'
- self.set_ticks_position('bottom')
-
- def get_ticks_position(self):
- """
- Return the ticks position (top, bottom, default or unknown)
- """
- majt = self.majorTicks[0]
- mT = self.minorTicks[0]
-
- majorTop = (not majt.tick1On) and \
- majt.tick2On and (not majt.label1On) and majt.label2On
- minorTop = (not mT.tick1On) and \
- mT.tick2On and (not mT.label1On) and mT.label2On
- if majorTop and minorTop:
- return 'top'
-
- MajorBottom = majt.tick1On and (not majt.tick2On) and \
- majt.label1On and (not majt.label2On)
- MinorBottom = mT.tick1On and (not mT.tick2On) and \
- mT.label1On and (not mT.label2On)
- if MajorBottom and MinorBottom:
- return 'bottom'
-
- majorDefault = majt.tick1On and majt.tick2On and \
- majt.label1On and (not majt.label2On)
- minorDefault = mT.tick1On and mT.tick2On and \
- mT.label1On and (not mT.label2On)
- if majorDefault and minorDefault:
- return 'default'
-
- return 'unknown'
-
- def get_view_interval(self):
- 'return the Interval instance for this axis view limits'
- return self.axes.viewLim.intervalx
-
- def set_view_interval(self, vmin, vmax, ignore=False):
- """
- If *ignore* is *False*, the order of vmin, vmax
- does not matter; the original axis orientation will
- be preserved. In addition, the view limits can be
- expanded, but will not be reduced. This method is
- for mpl internal use; for normal use, see
- :meth:`~matplotlib.axes.Axes.set_xlim`.
-
- """
- if ignore:
- self.axes.viewLim.intervalx = vmin, vmax
- else:
- Vmin, Vmax = self.get_view_interval()
- if Vmin < Vmax:
- self.axes.viewLim.intervalx = (min(vmin, vmax, Vmin),
- max(vmin, vmax, Vmax))
- else:
- self.axes.viewLim.intervalx = (max(vmin, vmax, Vmin),
- min(vmin, vmax, Vmax))
-
- def get_minpos(self):
- return self.axes.dataLim.minposx
-
- def get_data_interval(self):
- 'return the Interval instance for this axis data limits'
- return self.axes.dataLim.intervalx
-
- def set_data_interval(self, vmin, vmax, ignore=False):
- 'set the axis data limits'
- if ignore:
- self.axes.dataLim.intervalx = vmin, vmax
- else:
- Vmin, Vmax = self.get_data_interval()
- self.axes.dataLim.intervalx = min(vmin, Vmin), max(vmax, Vmax)
-
- def set_default_intervals(self):
- 'set the default limits for the axis interval if they are not mutated'
- xmin, xmax = 0., 1.
- dataMutated = self.axes.dataLim.mutatedx()
- viewMutated = self.axes.viewLim.mutatedx()
- if not dataMutated or not viewMutated:
- if self.converter is not None:
- info = self.converter.axisinfo(self.units, self)
- if info.default_limits is not None:
- valmin, valmax = info.default_limits
- xmin = self.converter.convert(valmin, self.units, self)
- xmax = self.converter.convert(valmax, self.units, self)
- if not dataMutated:
- self.axes.dataLim.intervalx = xmin, xmax
- if not viewMutated:
- self.axes.viewLim.intervalx = xmin, xmax
-
-
-class YAxis(Axis):
- __name__ = 'yaxis'
- axis_name = 'y'
-
- def contains(self, mouseevent):
- """Test whether the mouse event occurred in the y axis.
-
- Returns *True* | *False*
- """
- if six.callable(self._contains):
- return self._contains(self, mouseevent)
-
- x, y = mouseevent.x, mouseevent.y
- try:
- trans = self.axes.transAxes.inverted()
- xaxes, yaxes = trans.transform_point((x, y))
- except ValueError:
- return False, {}
- l, b = self.axes.transAxes.transform_point((0, 0))
- r, t = self.axes.transAxes.transform_point((1, 1))
- inaxis = yaxes >= 0 and yaxes <= 1 and (
- (x < l and x > l - self.pickradius) or
- (x > r and x < r + self.pickradius))
- return inaxis, {}
-
- def _get_tick(self, major):
- if major:
- tick_kw = self._major_tick_kw
- else:
- tick_kw = self._minor_tick_kw
- return YTick(self.axes, 0, '', major=major, **tick_kw)
-
- def _get_label(self):
- # x in display coords (updated by _update_label_position)
- # y in axes coords
- label = mtext.Text(x=0, y=0.5,
- # todo: get the label position
- fontproperties=font_manager.FontProperties(
- size=rcParams['axes.labelsize'],
- weight=rcParams['axes.labelweight']),
- color=rcParams['axes.labelcolor'],
- verticalalignment='bottom',
- horizontalalignment='center',
- rotation='vertical',
- rotation_mode='anchor',
- )
- label.set_transform(mtransforms.blended_transform_factory(
- mtransforms.IdentityTransform(), self.axes.transAxes))
-
- self._set_artist_props(label)
- self.label_position = 'left'
- return label
-
- def _get_offset_text(self):
- # x in display coords, y in axes coords (to be updated at draw time)
- offsetText = mtext.Text(x=0, y=0.5,
- fontproperties=font_manager.FontProperties(
- size=rcParams['ytick.labelsize']),
- color=rcParams['ytick.color'],
- verticalalignment='baseline',
- horizontalalignment='left',
- )
- offsetText.set_transform(mtransforms.blended_transform_factory(
- self.axes.transAxes, mtransforms.IdentityTransform()))
- self._set_artist_props(offsetText)
- self.offset_text_position = 'left'
- return offsetText
-
- def _get_pixel_distance_along_axis(self, where, perturb):
- """
- Returns the amount, in data coordinates, that a single pixel
- corresponds to in the locality given by *where*, which is also given
- in data coordinates, and is a y coordinate.
-
- *perturb* is the amount to perturb the pixel. Usually +0.5 or -0.5.
-
- Implementing this routine for an axis is optional; if present, it will ensure that no
- ticks are lost due to round-off at the extreme ends of an axis.
- """
-
- #
- # first figure out the pixel location of the "where" point. We use 1e-10 for the
- # x point, so that we remain compatible with log axes.
- #
- trans = self.axes.transData # transformation from data coords to display coords
- transinv = trans.inverted() # transformation from display coords to data coords
- pix = trans.transform_point((1e-10, where))
- ptp = transinv.transform_point((pix[0], pix[1] + perturb)) # perturb the pixel.
- dy = abs(ptp[1] - where)
- return dy
-
- def get_label_position(self):
- """
- Return the label position (left or right)
- """
- return self.label_position
-
- def set_label_position(self, position):
- """
- Set the label position (left or right)
-
- ACCEPTS: [ 'left' | 'right' ]
- """
- assert position == 'left' or position == 'right'
- self.label.set_rotation_mode('anchor')
- self.label.set_horizontalalignment('center')
- if position == 'left':
- self.label.set_verticalalignment('bottom')
- else:
- self.label.set_verticalalignment('top')
- self.label_position = position
-
- def _update_label_position(self, bboxes, bboxes2):
- """
- Update the label position based on the sequence of bounding
- boxes of all the ticklabels
- """
- if not self._autolabelpos:
- return
- x, y = self.label.get_position()
- if self.label_position == 'left':
- if not len(bboxes):
- left = self.axes.bbox.xmin
- else:
- bbox = mtransforms.Bbox.union(bboxes)
- left = bbox.x0
-
- self.label.set_position((left - \
- self.labelpad * self.figure.dpi / 72.0, y))
-
- else:
- if not len(bboxes2):
- right = self.axes.bbox.xmax
- else:
- bbox = mtransforms.Bbox.union(bboxes2)
- right = bbox.x1
-
- self.label.set_position((right + \
- self.labelpad * self.figure.dpi / 72.0, y))
-
- def _update_offset_text_position(self, bboxes, bboxes2):
- """
- Update the offset_text position based on the sequence of bounding
- boxes of all the ticklabels
- """
- x, y = self.offsetText.get_position()
- top = self.axes.bbox.ymax
- self.offsetText.set_position((x,
- top + self.OFFSETTEXTPAD * self.figure.dpi / 72.0))
-
- def set_offset_position(self, position):
- assert position == 'left' or position == 'right'
-
- x, y = self.offsetText.get_position()
- if position == 'left':
- x = 0
- else:
- x = 1
-
- self.offsetText.set_ha(position)
- self.offsetText.set_position((x, y))
-
- def get_text_widths(self, renderer):
- bbox, bbox2 = self.get_ticklabel_extents(renderer)
- # MGDTODO: Need a better way to get the pad
- padPixels = self.majorTicks[0].get_pad_pixels()
-
- left = 0.0
- if bbox.width:
- left += bbox.width + padPixels
- right = 0.0
- if bbox2.width:
- right += bbox2.width + padPixels
-
- if self.get_label_position() == 'left':
- left += self.label.get_window_extent(renderer).width + padPixels
- else:
- right += self.label.get_window_extent(renderer).width + padPixels
- return left, right
-
- def set_ticks_position(self, position):
- """
- Set the ticks position (left, right, both, default or none)
- 'both' sets the ticks to appear on both positions, but does not
- change the tick labels. 'default' resets the tick positions to
- the default: ticks on both positions, labels at left. 'none'
- can be used if you don't want any ticks. 'none' and 'both'
- affect only the ticks, not the labels.
-
- ACCEPTS: [ 'left' | 'right' | 'both' | 'default' | 'none' ]
- """
- if position == 'right':
- self.set_tick_params(which='both', right=True, labelright=True,
- left=False, labelleft=False)
- elif position == 'left':
- self.set_tick_params(which='both', right=False, labelright=False,
- left=True, labelleft=True)
- elif position == 'both':
- self.set_tick_params(which='both', right=True,
- left=True)
- elif position == 'none':
- self.set_tick_params(which='both', right=False,
- left=False)
- elif position == 'default':
- self.set_tick_params(which='both', right=True, labelright=False,
- left=True, labelleft=True)
- else:
- raise ValueError("invalid position: %s" % position)
-
- def tick_right(self):
- 'use ticks only on right'
- self.set_ticks_position('right')
-
- def tick_left(self):
- 'use ticks only on left'
- self.set_ticks_position('left')
-
- def get_ticks_position(self):
- """
- Return the ticks position (left, right, both or unknown)
- """
- majt = self.majorTicks[0]
- mT = self.minorTicks[0]
-
- majorRight = (not majt.tick1On) and majt.tick2On \
- and (not majt.label1On) and majt.label2On
- minorRight = (not mT.tick1On) and mT.tick2On and \
- (not mT.label1On) and mT.label2On
- if majorRight and minorRight:
- return 'right'
-
- majorLeft = majt.tick1On and (not majt.tick2On) and \
- majt.label1On and (not majt.label2On)
- minorLeft = mT.tick1On and (not mT.tick2On) and \
- mT.label1On and (not mT.label2On)
- if majorLeft and minorLeft:
- return 'left'
-
- majorDefault = majt.tick1On and majt.tick2On and \
- majt.label1On and (not majt.label2On)
- minorDefault = mT.tick1On and mT.tick2On and \
- mT.label1On and (not mT.label2On)
- if majorDefault and minorDefault:
- return 'default'
-
- return 'unknown'
-
- def get_view_interval(self):
- 'return the Interval instance for this axis view limits'
- return self.axes.viewLim.intervaly
-
- def set_view_interval(self, vmin, vmax, ignore=False):
- """
- If *ignore* is *False*, the order of vmin, vmax
- does not matter; the original axis orientation will
- be preserved. In addition, the view limits can be
- expanded, but will not be reduced. This method is
- for mpl internal use; for normal use, see
- :meth:`~matplotlib.axes.Axes.set_ylim`.
-
- """
- if ignore:
- self.axes.viewLim.intervaly = vmin, vmax
- else:
- Vmin, Vmax = self.get_view_interval()
- if Vmin < Vmax:
- self.axes.viewLim.intervaly = (min(vmin, vmax, Vmin),
- max(vmin, vmax, Vmax))
- else:
- self.axes.viewLim.intervaly = (max(vmin, vmax, Vmin),
- min(vmin, vmax, Vmax))
-
- def get_minpos(self):
- return self.axes.dataLim.minposy
-
- def get_data_interval(self):
- 'return the Interval instance for this axis data limits'
- return self.axes.dataLim.intervaly
-
- def set_data_interval(self, vmin, vmax, ignore=False):
- 'set the axis data limits'
- if ignore:
- self.axes.dataLim.intervaly = vmin, vmax
- else:
- Vmin, Vmax = self.get_data_interval()
- self.axes.dataLim.intervaly = min(vmin, Vmin), max(vmax, Vmax)
-
- def set_default_intervals(self):
- 'set the default limits for the axis interval if they are not mutated'
- ymin, ymax = 0., 1.
- dataMutated = self.axes.dataLim.mutatedy()
- viewMutated = self.axes.viewLim.mutatedy()
- if not dataMutated or not viewMutated:
- if self.converter is not None:
- info = self.converter.axisinfo(self.units, self)
- if info.default_limits is not None:
- valmin, valmax = info.default_limits
- ymin = self.converter.convert(valmin, self.units, self)
- ymax = self.converter.convert(valmax, self.units, self)
- if not dataMutated:
- self.axes.dataLim.intervaly = ymin, ymax
- if not viewMutated:
- self.axes.viewLim.intervaly = ymin, ymax
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backend_bases.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backend_bases.py
deleted file mode 100644
index 7b983eb..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backend_bases.py
+++ /dev/null
@@ -1,3197 +0,0 @@
-"""
-Abstract base classes define the primitives that renderers and
-graphics contexts must implement to serve as a matplotlib backend
-
-:class:`RendererBase`
- An abstract base class to handle drawing/rendering operations.
-
-:class:`FigureCanvasBase`
- The abstraction layer that separates the
- :class:`matplotlib.figure.Figure` from the backend specific
- details like a user interface drawing area
-
-:class:`GraphicsContextBase`
- An abstract base class that provides color, line styles, etc...
-
-:class:`Event`
- The base class for all of the matplotlib event
- handling. Derived classes suh as :class:`KeyEvent` and
- :class:`MouseEvent` store the meta data like keys and buttons
- pressed, x and y locations in pixel and
- :class:`~matplotlib.axes.Axes` coordinates.
-
-:class:`ShowBase`
- The base class for the Show class of each interactive backend;
- the 'show' callable is then set to Show.__call__, inherited from
- ShowBase.
-
-"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import xrange
-
-import os
-import sys
-import warnings
-import time
-import io
-
-import numpy as np
-import matplotlib.cbook as cbook
-import matplotlib.colors as colors
-import matplotlib.transforms as transforms
-import matplotlib.widgets as widgets
-#import matplotlib.path as path
-from matplotlib import rcParams
-from matplotlib import is_interactive
-from matplotlib import get_backend
-from matplotlib._pylab_helpers import Gcf
-
-from matplotlib.transforms import Bbox, TransformedBbox, Affine2D
-
-import matplotlib.tight_bbox as tight_bbox
-import matplotlib.textpath as textpath
-from matplotlib.path import Path
-from matplotlib.cbook import mplDeprecation
-
-try:
- from importlib import import_module
-except:
- # simple python 2.6 implementation (no relative imports)
- def import_module(name):
- __import__(name)
- return sys.modules[name]
-
-try:
- from PIL import Image
- _has_pil = True
-except ImportError:
- _has_pil = False
-
-
-_default_filetypes = {
- 'ps': 'Postscript',
- 'eps': 'Encapsulated Postscript',
- 'pdf': 'Portable Document Format',
- 'pgf': 'PGF code for LaTeX',
- 'png': 'Portable Network Graphics',
- 'raw': 'Raw RGBA bitmap',
- 'rgba': 'Raw RGBA bitmap',
- 'svg': 'Scalable Vector Graphics',
- 'svgz': 'Scalable Vector Graphics'
-}
-
-
-_default_backends = {
- 'ps': 'matplotlib.backends.backend_ps',
- 'eps': 'matplotlib.backends.backend_ps',
- 'pdf': 'matplotlib.backends.backend_pdf',
- 'pgf': 'matplotlib.backends.backend_pgf',
- 'png': 'matplotlib.backends.backend_agg',
- 'raw': 'matplotlib.backends.backend_agg',
- 'rgba': 'matplotlib.backends.backend_agg',
- 'svg': 'matplotlib.backends.backend_svg',
- 'svgz': 'matplotlib.backends.backend_svg',
-}
-
-
-def register_backend(format, backend, description=None):
- """
- Register a backend for saving to a given file format.
-
- format : str
- File extention
-
- backend : module string or canvas class
- Backend for handling file output
-
- description : str, optional
- Description of the file type. Defaults to an empty string
- """
- if description is None:
- description = ''
- _default_backends[format] = backend
- _default_filetypes[format] = description
-
-
-def get_registered_canvas_class(format):
- """
- Return the registered default canvas for given file format.
- Handles deferred import of required backend.
- """
- if format not in _default_backends:
- return None
- backend_class = _default_backends[format]
- if cbook.is_string_like(backend_class):
- backend_class = import_module(backend_class).FigureCanvas
- _default_backends[format] = backend_class
- return backend_class
-
-
-class ShowBase(object):
- """
- Simple base class to generate a show() callable in backends.
-
- Subclass must override mainloop() method.
- """
- def __call__(self, block=None):
- """
- Show all figures. If *block* is not None, then
- it is a boolean that overrides all other factors
- determining whether show blocks by calling mainloop().
- The other factors are:
- it does not block if run inside ipython's "%pylab" mode
- it does not block in interactive mode.
- """
- managers = Gcf.get_all_fig_managers()
- if not managers:
- return
-
- for manager in managers:
- manager.show()
-
- if block is not None:
- if block:
- self.mainloop()
- return
- else:
- return
-
- # Hack: determine at runtime whether we are
- # inside ipython in pylab mode.
- from matplotlib import pyplot
- try:
- ipython_pylab = not pyplot.show._needmain
- # IPython versions >= 0.10 tack the _needmain
- # attribute onto pyplot.show, and always set
- # it to False, when in %pylab mode.
- ipython_pylab = ipython_pylab and get_backend() != 'WebAgg'
- # TODO: The above is a hack to get the WebAgg backend
- # working with ipython's `%pylab` mode until proper
- # integration is implemented.
- except AttributeError:
- ipython_pylab = False
-
- # Leave the following as a separate step in case we
- # want to control this behavior with an rcParam.
- if ipython_pylab:
- return
-
- if not is_interactive() or get_backend() == 'WebAgg':
- self.mainloop()
-
- def mainloop(self):
- pass
-
-
-class RendererBase(object):
- """An abstract base class to handle drawing/rendering operations.
-
- The following methods must be implemented in the backend for full
- functionality (though just implementing :meth:`draw_path` alone would
- give a highly capable backend):
-
- * :meth:`draw_path`
- * :meth:`draw_image`
- * :meth:`draw_gouraud_triangle`
-
- The following methods *should* be implemented in the backend for
- optimization reasons:
-
- * :meth:`draw_text`
- * :meth:`draw_markers`
- * :meth:`draw_path_collection`
- * :meth:`draw_quad_mesh`
-
- """
- def __init__(self):
- self._texmanager = None
-
- self._text2path = textpath.TextToPath()
-
- def open_group(self, s, gid=None):
- """
- Open a grouping element with label *s*. If *gid* is given, use
- *gid* as the id of the group. Is only currently used by
- :mod:`~matplotlib.backends.backend_svg`.
- """
- pass
-
- def close_group(self, s):
- """
- Close a grouping element with label *s*
- Is only currently used by :mod:`~matplotlib.backends.backend_svg`
- """
- pass
-
- def draw_path(self, gc, path, transform, rgbFace=None):
- """
- Draws a :class:`~matplotlib.path.Path` instance using the
- given affine transform.
- """
- raise NotImplementedError
-
- def draw_markers(self, gc, marker_path, marker_trans, path,
- trans, rgbFace=None):
- """
- Draws a marker at each of the vertices in path. This includes
- all vertices, including control points on curves. To avoid
- that behavior, those vertices should be removed before calling
- this function.
-
- *gc*
- the :class:`GraphicsContextBase` instance
-
- *marker_trans*
- is an affine transform applied to the marker.
-
- *trans*
- is an affine transform applied to the path.
-
- This provides a fallback implementation of draw_markers that
- makes multiple calls to :meth:`draw_path`. Some backends may
- want to override this method in order to draw the marker only
- once and reuse it multiple times.
- """
- for vertices, codes in path.iter_segments(trans, simplify=False):
- if len(vertices):
- x, y = vertices[-2:]
- self.draw_path(gc, marker_path,
- marker_trans +
- transforms.Affine2D().translate(x, y),
- rgbFace)
-
- def draw_path_collection(self, gc, master_transform, paths, all_transforms,
- offsets, offsetTrans, facecolors, edgecolors,
- linewidths, linestyles, antialiaseds, urls,
- offset_position):
- """
- Draws a collection of paths selecting drawing properties from
- the lists *facecolors*, *edgecolors*, *linewidths*,
- *linestyles* and *antialiaseds*. *offsets* is a list of
- offsets to apply to each of the paths. The offsets in
- *offsets* are first transformed by *offsetTrans* before being
- applied. *offset_position* may be either "screen" or "data"
- depending on the space that the offsets are in.
-
- This provides a fallback implementation of
- :meth:`draw_path_collection` that makes multiple calls to
- :meth:`draw_path`. Some backends may want to override this in
- order to render each set of path data only once, and then
- reference that path multiple times with the different offsets,
- colors, styles etc. The generator methods
- :meth:`_iter_collection_raw_paths` and
- :meth:`_iter_collection` are provided to help with (and
- standardize) the implementation across backends. It is highly
- recommended to use those generators, so that changes to the
- behavior of :meth:`draw_path_collection` can be made globally.
- """
- path_ids = []
- for path, transform in self._iter_collection_raw_paths(
- master_transform, paths, all_transforms):
- path_ids.append((path, transforms.Affine2D(transform)))
-
- for xo, yo, path_id, gc0, rgbFace in self._iter_collection(
- gc, master_transform, all_transforms, path_ids, offsets,
- offsetTrans, facecolors, edgecolors, linewidths, linestyles,
- antialiaseds, urls, offset_position):
- path, transform = path_id
- transform = transforms.Affine2D(
- transform.get_matrix()).translate(xo, yo)
- self.draw_path(gc0, path, transform, rgbFace)
-
- def draw_quad_mesh(self, gc, master_transform, meshWidth, meshHeight,
- coordinates, offsets, offsetTrans, facecolors,
- antialiased, edgecolors):
- """
- This provides a fallback implementation of
- :meth:`draw_quad_mesh` that generates paths and then calls
- :meth:`draw_path_collection`.
- """
-
- from matplotlib.collections import QuadMesh
- paths = QuadMesh.convert_mesh_to_paths(
- meshWidth, meshHeight, coordinates)
-
- if edgecolors is None:
- edgecolors = facecolors
- linewidths = np.array([gc.get_linewidth()], np.float_)
-
- return self.draw_path_collection(
- gc, master_transform, paths, [], offsets, offsetTrans, facecolors,
- edgecolors, linewidths, [], [antialiased], [None], 'screen')
-
- def draw_gouraud_triangle(self, gc, points, colors, transform):
- """
- Draw a Gouraud-shaded triangle.
-
- *points* is a 3x2 array of (x, y) points for the triangle.
-
- *colors* is a 3x4 array of RGBA colors for each point of the
- triangle.
-
- *transform* is an affine transform to apply to the points.
- """
- raise NotImplementedError
-
- def draw_gouraud_triangles(self, gc, triangles_array, colors_array,
- transform):
- """
- Draws a series of Gouraud triangles.
-
- *points* is a Nx3x2 array of (x, y) points for the trianglex.
-
- *colors* is a Nx3x4 array of RGBA colors for each point of the
- triangles.
-
- *transform* is an affine transform to apply to the points.
- """
- transform = transform.frozen()
- for tri, col in zip(triangles_array, colors_array):
- self.draw_gouraud_triangle(gc, tri, col, transform)
-
- def _iter_collection_raw_paths(self, master_transform, paths,
- all_transforms):
- """
- This is a helper method (along with :meth:`_iter_collection`) to make
- it easier to write a space-efficent :meth:`draw_path_collection`
- implementation in a backend.
-
- This method yields all of the base path/transform
- combinations, given a master transform, a list of paths and
- list of transforms.
-
- The arguments should be exactly what is passed in to
- :meth:`draw_path_collection`.
-
- The backend should take each yielded path and transform and
- create an object that can be referenced (reused) later.
- """
- Npaths = len(paths)
- Ntransforms = len(all_transforms)
- N = max(Npaths, Ntransforms)
-
- if Npaths == 0:
- return
-
- transform = transforms.IdentityTransform()
- for i in xrange(N):
- path = paths[i % Npaths]
- if Ntransforms:
- transform = Affine2D(all_transforms[i % Ntransforms])
- yield path, transform + master_transform
-
- def _iter_collection_uses_per_path(self, paths, all_transforms,
- offsets, facecolors, edgecolors):
- """
- Compute how many times each raw path object returned by
- _iter_collection_raw_paths would be used when calling
- _iter_collection. This is intended for the backend to decide
- on the tradeoff between using the paths in-line and storing
- them once and reusing. Rounds up in case the number of uses
- is not the same for every path.
- """
- Npaths = len(paths)
- if Npaths == 0 or (len(facecolors) == 0 and len(edgecolors) == 0):
- return 0
- Npath_ids = max(Npaths, len(all_transforms))
- N = max(Npath_ids, len(offsets))
- return (N + Npath_ids - 1) // Npath_ids
-
- def _iter_collection(self, gc, master_transform, all_transforms,
- path_ids, offsets, offsetTrans, facecolors,
- edgecolors, linewidths, linestyles,
- antialiaseds, urls, offset_position):
- """
- This is a helper method (along with
- :meth:`_iter_collection_raw_paths`) to make it easier to write
- a space-efficent :meth:`draw_path_collection` implementation in a
- backend.
-
- This method yields all of the path, offset and graphics
- context combinations to draw the path collection. The caller
- should already have looped over the results of
- :meth:`_iter_collection_raw_paths` to draw this collection.
-
- The arguments should be the same as that passed into
- :meth:`draw_path_collection`, with the exception of
- *path_ids*, which is a list of arbitrary objects that the
- backend will use to reference one of the paths created in the
- :meth:`_iter_collection_raw_paths` stage.
-
- Each yielded result is of the form::
-
- xo, yo, path_id, gc, rgbFace
-
- where *xo*, *yo* is an offset; *path_id* is one of the elements of
- *path_ids*; *gc* is a graphics context and *rgbFace* is a color to
- use for filling the path.
- """
- Ntransforms = len(all_transforms)
- Npaths = len(path_ids)
- Noffsets = len(offsets)
- N = max(Npaths, Noffsets)
- Nfacecolors = len(facecolors)
- Nedgecolors = len(edgecolors)
- Nlinewidths = len(linewidths)
- Nlinestyles = len(linestyles)
- Naa = len(antialiaseds)
- Nurls = len(urls)
-
- if (Nfacecolors == 0 and Nedgecolors == 0) or Npaths == 0:
- return
- if Noffsets:
- toffsets = offsetTrans.transform(offsets)
-
- gc0 = self.new_gc()
- gc0.copy_properties(gc)
-
- if Nfacecolors == 0:
- rgbFace = None
-
- if Nedgecolors == 0:
- gc0.set_linewidth(0.0)
-
- xo, yo = 0, 0
- for i in xrange(N):
- path_id = path_ids[i % Npaths]
- if Noffsets:
- xo, yo = toffsets[i % Noffsets]
- if offset_position == 'data':
- if Ntransforms:
- transform = (
- Affine2D(all_transforms[i % Ntransforms]) +
- master_transform)
- else:
- transform = master_transform
- xo, yo = transform.transform_point((xo, yo))
- xp, yp = transform.transform_point((0, 0))
- xo = -(xp - xo)
- yo = -(yp - yo)
- if not (np.isfinite(xo) and np.isfinite(yo)):
- continue
- if Nfacecolors:
- rgbFace = facecolors[i % Nfacecolors]
- if Nedgecolors:
- if Nlinewidths:
- gc0.set_linewidth(linewidths[i % Nlinewidths])
- if Nlinestyles:
- gc0.set_dashes(*linestyles[i % Nlinestyles])
- fg = edgecolors[i % Nedgecolors]
- if len(fg) == 4:
- if fg[3] == 0.0:
- gc0.set_linewidth(0)
- else:
- gc0.set_foreground(fg)
- else:
- gc0.set_foreground(fg)
- if rgbFace is not None and len(rgbFace) == 4:
- if rgbFace[3] == 0:
- rgbFace = None
- gc0.set_antialiased(antialiaseds[i % Naa])
- if Nurls:
- gc0.set_url(urls[i % Nurls])
-
- yield xo, yo, path_id, gc0, rgbFace
- gc0.restore()
-
- def get_image_magnification(self):
- """
- Get the factor by which to magnify images passed to :meth:`draw_image`.
- Allows a backend to have images at a different resolution to other
- artists.
- """
- return 1.0
-
- def draw_image(self, gc, x, y, im):
- """
- Draw the image instance into the current axes;
-
- *gc*
- a GraphicsContext containing clipping information
-
- *x*
- is the distance in pixels from the left hand side of the canvas.
-
- *y*
- the distance from the origin. That is, if origin is
- upper, y is the distance from top. If origin is lower, y
- is the distance from bottom
-
- *im*
- the :class:`matplotlib._image.Image` instance
- """
- raise NotImplementedError
-
- def option_image_nocomposite(self):
- """
- override this method for renderers that do not necessarily
- want to rescale and composite raster images. (like SVG)
- """
- return False
-
- def option_scale_image(self):
- """
- override this method for renderers that support arbitrary
- scaling of image (most of the vector backend).
- """
- return False
-
- def draw_tex(self, gc, x, y, s, prop, angle, ismath='TeX!', mtext=None):
- """
- """
- self._draw_text_as_path(gc, x, y, s, prop, angle, ismath="TeX")
-
- def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
- """
- Draw the text instance
-
- *gc*
- the :class:`GraphicsContextBase` instance
-
- *x*
- the x location of the text in display coords
-
- *y*
- the y location of the text baseline in display coords
-
- *s*
- the text string
-
- *prop*
- a :class:`matplotlib.font_manager.FontProperties` instance
-
- *angle*
- the rotation angle in degrees
-
- *mtext*
- a :class:`matplotlib.text.Text` instance
-
- **backend implementers note**
-
- When you are trying to determine if you have gotten your bounding box
- right (which is what enables the text layout/alignment to work
- properly), it helps to change the line in text.py::
-
- if 0: bbox_artist(self, renderer)
-
- to if 1, and then the actual bounding box will be plotted along with
- your text.
- """
-
- self._draw_text_as_path(gc, x, y, s, prop, angle, ismath)
-
- def _get_text_path_transform(self, x, y, s, prop, angle, ismath):
- """
- return the text path and transform
-
- *prop*
- font property
-
- *s*
- text to be converted
-
- *usetex*
- If True, use matplotlib usetex mode.
-
- *ismath*
- If True, use mathtext parser. If "TeX", use *usetex* mode.
- """
-
- text2path = self._text2path
- fontsize = self.points_to_pixels(prop.get_size_in_points())
-
- if ismath == "TeX":
- verts, codes = text2path.get_text_path(prop, s, ismath=False,
- usetex=True)
- else:
- verts, codes = text2path.get_text_path(prop, s, ismath=ismath,
- usetex=False)
-
- path = Path(verts, codes)
- angle = angle / 180. * 3.141592
- if self.flipy():
- transform = Affine2D().scale(fontsize / text2path.FONT_SCALE,
- fontsize / text2path.FONT_SCALE)
- transform = transform.rotate(angle).translate(x, self.height - y)
- else:
- transform = Affine2D().scale(fontsize / text2path.FONT_SCALE,
- fontsize / text2path.FONT_SCALE)
- transform = transform.rotate(angle).translate(x, y)
-
- return path, transform
-
- def _draw_text_as_path(self, gc, x, y, s, prop, angle, ismath):
- """
- draw the text by converting them to paths using textpath module.
-
- *prop*
- font property
-
- *s*
- text to be converted
-
- *usetex*
- If True, use matplotlib usetex mode.
-
- *ismath*
- If True, use mathtext parser. If "TeX", use *usetex* mode.
- """
- path, transform = self._get_text_path_transform(
- x, y, s, prop, angle, ismath)
- color = gc.get_rgb()
-
- gc.set_linewidth(0.0)
- self.draw_path(gc, path, transform, rgbFace=color)
-
- def get_text_width_height_descent(self, s, prop, ismath):
- """
- get the width and height, and the offset from the bottom to the
- baseline (descent), in display coords of the string s with
- :class:`~matplotlib.font_manager.FontProperties` prop
- """
- if ismath == 'TeX':
- # todo: handle props
- size = prop.get_size_in_points()
- texmanager = self._text2path.get_texmanager()
- fontsize = prop.get_size_in_points()
- w, h, d = texmanager.get_text_width_height_descent(s, fontsize,
- renderer=self)
- return w, h, d
-
- dpi = self.points_to_pixels(72)
- if ismath:
- dims = self._text2path.mathtext_parser.parse(s, dpi, prop)
- return dims[0:3] # return width, height, descent
-
- flags = self._text2path._get_hinting_flag()
- font = self._text2path._get_font(prop)
- size = prop.get_size_in_points()
- font.set_size(size, dpi)
- # the width and height of unrotated string
- font.set_text(s, 0.0, flags=flags)
- w, h = font.get_width_height()
- d = font.get_descent()
- w /= 64.0 # convert from subpixels
- h /= 64.0
- d /= 64.0
- return w, h, d
-
- def flipy(self):
- """
- Return true if y small numbers are top for renderer Is used
- for drawing text (:mod:`matplotlib.text`) and images
- (:mod:`matplotlib.image`) only
- """
- return True
-
- def get_canvas_width_height(self):
- 'return the canvas width and height in display coords'
- return 1, 1
-
- def get_texmanager(self):
- """
- return the :class:`matplotlib.texmanager.TexManager` instance
- """
- if self._texmanager is None:
- from matplotlib.texmanager import TexManager
- self._texmanager = TexManager()
- return self._texmanager
-
- def new_gc(self):
- """
- Return an instance of a :class:`GraphicsContextBase`
- """
- return GraphicsContextBase()
-
- def points_to_pixels(self, points):
- """
- Convert points to display units
-
- *points*
- a float or a numpy array of float
-
- return points converted to pixels
-
- You need to override this function (unless your backend
- doesn't have a dpi, e.g., postscript or svg). Some imaging
- systems assume some value for pixels per inch::
-
- points to pixels = points * pixels_per_inch/72.0 * dpi/72.0
- """
- return points
-
- def strip_math(self, s):
- return cbook.strip_math(s)
-
- def start_rasterizing(self):
- """
- Used in MixedModeRenderer. Switch to the raster renderer.
- """
- pass
-
- def stop_rasterizing(self):
- """
- Used in MixedModeRenderer. Switch back to the vector renderer
- and draw the contents of the raster renderer as an image on
- the vector renderer.
- """
- pass
-
- def start_filter(self):
- """
- Used in AggRenderer. Switch to a temporary renderer for image
- filtering effects.
- """
- pass
-
- def stop_filter(self, filter_func):
- """
- Used in AggRenderer. Switch back to the original renderer.
- The contents of the temporary renderer is processed with the
- *filter_func* and is drawn on the original renderer as an
- image.
- """
- pass
-
-
-class GraphicsContextBase:
- """
- An abstract base class that provides color, line styles, etc...
- """
-
- # a mapping from dash styles to suggested offset, dash pairs
- dashd = {
- 'solid': (None, None),
- 'dashed': (0, (6.0, 6.0)),
- 'dashdot': (0, (3.0, 5.0, 1.0, 5.0)),
- 'dotted': (0, (1.0, 3.0)),
- }
-
- def __init__(self):
- self._alpha = 1.0
- self._forced_alpha = False # if True, _alpha overrides A from RGBA
- self._antialiased = 1 # use 0,1 not True, False for extension code
- self._capstyle = 'butt'
- self._cliprect = None
- self._clippath = None
- self._dashes = None, None
- self._joinstyle = 'round'
- self._linestyle = 'solid'
- self._linewidth = 1
- self._rgb = (0.0, 0.0, 0.0, 1.0)
- self._orig_color = (0.0, 0.0, 0.0, 1.0)
- self._hatch = None
- self._url = None
- self._gid = None
- self._snap = None
- self._sketch = None
-
- def copy_properties(self, gc):
- 'Copy properties from gc to self'
- self._alpha = gc._alpha
- self._forced_alpha = gc._forced_alpha
- self._antialiased = gc._antialiased
- self._capstyle = gc._capstyle
- self._cliprect = gc._cliprect
- self._clippath = gc._clippath
- self._dashes = gc._dashes
- self._joinstyle = gc._joinstyle
- self._linestyle = gc._linestyle
- self._linewidth = gc._linewidth
- self._rgb = gc._rgb
- self._orig_color = gc._orig_color
- self._hatch = gc._hatch
- self._url = gc._url
- self._gid = gc._gid
- self._snap = gc._snap
- self._sketch = gc._sketch
-
- def restore(self):
- """
- Restore the graphics context from the stack - needed only
- for backends that save graphics contexts on a stack
- """
- pass
-
- def get_alpha(self):
- """
- Return the alpha value used for blending - not supported on
- all backends
- """
- return self._alpha
-
- def get_antialiased(self):
- "Return true if the object should try to do antialiased rendering"
- return self._antialiased
-
- def get_capstyle(self):
- """
- Return the capstyle as a string in ('butt', 'round', 'projecting')
- """
- return self._capstyle
-
- def get_clip_rectangle(self):
- """
- Return the clip rectangle as a :class:`~matplotlib.transforms.Bbox`
- instance
- """
- return self._cliprect
-
- def get_clip_path(self):
- """
- Return the clip path in the form (path, transform), where path
- is a :class:`~matplotlib.path.Path` instance, and transform is
- an affine transform to apply to the path before clipping.
- """
- if self._clippath is not None:
- return self._clippath.get_transformed_path_and_affine()
- return None, None
-
- def get_dashes(self):
- """
- Return the dash information as an offset dashlist tuple.
-
- The dash list is a even size list that gives the ink on, ink
- off in pixels.
-
- See p107 of to PostScript `BLUEBOOK
- `_
- for more info.
-
- Default value is None
- """
- return self._dashes
-
- def get_forced_alpha(self):
- """
- Return whether the value given by get_alpha() should be used to
- override any other alpha-channel values.
- """
- return self._forced_alpha
-
- def get_joinstyle(self):
- """
- Return the line join style as one of ('miter', 'round', 'bevel')
- """
- return self._joinstyle
-
- def get_linestyle(self, style):
- """
- Return the linestyle: one of ('solid', 'dashed', 'dashdot',
- 'dotted').
- """
- return self._linestyle
-
- def get_linewidth(self):
- """
- Return the line width in points as a scalar
- """
- return self._linewidth
-
- def get_rgb(self):
- """
- returns a tuple of three or four floats from 0-1.
- """
- return self._rgb
-
- def get_url(self):
- """
- returns a url if one is set, None otherwise
- """
- return self._url
-
- def get_gid(self):
- """
- Return the object identifier if one is set, None otherwise.
- """
- return self._gid
-
- def get_snap(self):
- """
- returns the snap setting which may be:
-
- * True: snap vertices to the nearest pixel center
-
- * False: leave vertices as-is
-
- * None: (auto) If the path contains only rectilinear line
- segments, round to the nearest pixel center
- """
- return self._snap
-
- def set_alpha(self, alpha):
- """
- Set the alpha value used for blending - not supported on all backends.
- If ``alpha=None`` (the default), the alpha components of the
- foreground and fill colors will be used to set their respective
- transparencies (where applicable); otherwise, ``alpha`` will override
- them.
- """
- if alpha is not None:
- self._alpha = alpha
- self._forced_alpha = True
- else:
- self._alpha = 1.0
- self._forced_alpha = False
- self.set_foreground(self._orig_color)
-
- def set_antialiased(self, b):
- """
- True if object should be drawn with antialiased rendering
- """
-
- # use 0, 1 to make life easier on extension code trying to read the gc
- if b:
- self._antialiased = 1
- else:
- self._antialiased = 0
-
- def set_capstyle(self, cs):
- """
- Set the capstyle as a string in ('butt', 'round', 'projecting')
- """
- if cs in ('butt', 'round', 'projecting'):
- self._capstyle = cs
- else:
- raise ValueError('Unrecognized cap style. Found %s' % cs)
-
- def set_clip_rectangle(self, rectangle):
- """
- Set the clip rectangle with sequence (left, bottom, width, height)
- """
- self._cliprect = rectangle
-
- def set_clip_path(self, path):
- """
- Set the clip path and transformation. Path should be a
- :class:`~matplotlib.transforms.TransformedPath` instance.
- """
- assert path is None or isinstance(path, transforms.TransformedPath)
- self._clippath = path
-
- def set_dashes(self, dash_offset, dash_list):
- """
- Set the dash style for the gc.
-
- *dash_offset*
- is the offset (usually 0).
-
- *dash_list*
- specifies the on-off sequence as points.
- ``(None, None)`` specifies a solid line
-
- """
- if dash_list is not None:
- dl = np.asarray(dash_list)
- if np.any(dl <= 0.0):
- raise ValueError("All values in the dash list must be positive")
- self._dashes = dash_offset, dash_list
-
- def set_foreground(self, fg, isRGBA=False):
- """
- Set the foreground color. fg can be a MATLAB format string, a
- html hex color string, an rgb or rgba unit tuple, or a float between 0
- and 1. In the latter case, grayscale is used.
-
- If you know fg is rgba, set ``isRGBA=True`` for efficiency.
- """
- self._orig_color = fg
- if self._forced_alpha:
- self._rgb = colors.colorConverter.to_rgba(fg, self._alpha)
- elif isRGBA:
- self._rgb = fg
- else:
- self._rgb = colors.colorConverter.to_rgba(fg)
-
- def set_graylevel(self, frac):
- """
- Set the foreground color to be a gray level with *frac*
- """
- self._orig_color = frac
- self._rgb = (frac, frac, frac, self._alpha)
-
- def set_joinstyle(self, js):
- """
- Set the join style to be one of ('miter', 'round', 'bevel')
- """
- if js in ('miter', 'round', 'bevel'):
- self._joinstyle = js
- else:
- raise ValueError('Unrecognized join style. Found %s' % js)
-
- def set_linewidth(self, w):
- """
- Set the linewidth in points
- """
- self._linewidth = w
-
- def set_linestyle(self, style):
- """
- Set the linestyle to be one of ('solid', 'dashed', 'dashdot',
- 'dotted'). One may specify customized dash styles by providing
- a tuple of (offset, dash pairs). For example, the predefiend
- linestyles have following values.:
-
- 'dashed' : (0, (6.0, 6.0)),
- 'dashdot' : (0, (3.0, 5.0, 1.0, 5.0)),
- 'dotted' : (0, (1.0, 3.0)),
- """
-
- if style in self.dashd:
- offset, dashes = self.dashd[style]
- elif isinstance(style, tuple):
- offset, dashes = style
- else:
- raise ValueError('Unrecognized linestyle: %s' % str(style))
-
- self._linestyle = style
- self.set_dashes(offset, dashes)
-
- def set_url(self, url):
- """
- Sets the url for links in compatible backends
- """
- self._url = url
-
- def set_gid(self, id):
- """
- Sets the id.
- """
- self._gid = id
-
- def set_snap(self, snap):
- """
- Sets the snap setting which may be:
-
- * True: snap vertices to the nearest pixel center
-
- * False: leave vertices as-is
-
- * None: (auto) If the path contains only rectilinear line
- segments, round to the nearest pixel center
- """
- self._snap = snap
-
- def set_hatch(self, hatch):
- """
- Sets the hatch style for filling
- """
- self._hatch = hatch
-
- def get_hatch(self):
- """
- Gets the current hatch style
- """
- return self._hatch
-
- def get_hatch_path(self, density=6.0):
- """
- Returns a Path for the current hatch.
- """
- if self._hatch is None:
- return None
- return Path.hatch(self._hatch, density)
-
- def get_sketch_params(self):
- """
- Returns the sketch parameters for the artist.
-
- Returns
- -------
- sketch_params : tuple or `None`
-
- A 3-tuple with the following elements:
-
- * `scale`: The amplitude of the wiggle perpendicular to the
- source line.
-
- * `length`: The length of the wiggle along the line.
-
- * `randomness`: The scale factor by which the length is
- shrunken or expanded.
-
- May return `None` if no sketch parameters were set.
- """
- return self._sketch
-
- def set_sketch_params(self, scale=None, length=None, randomness=None):
- """
- Sets the the sketch parameters.
-
- Parameters
- ----------
-
- scale : float, optional
- The amplitude of the wiggle perpendicular to the source
- line, in pixels. If scale is `None`, or not provided, no
- sketch filter will be provided.
-
- length : float, optional
- The length of the wiggle along the line, in pixels
- (default 128.0)
-
- randomness : float, optional
- The scale factor by which the length is shrunken or
- expanded (default 16.0)
- """
- if scale is None:
- self._sketch = None
- else:
- self._sketch = (scale, length or 128.0, randomness or 16.0)
-
-
-class TimerBase(object):
- '''
- A base class for providing timer events, useful for things animations.
- Backends need to implement a few specific methods in order to use their
- own timing mechanisms so that the timer events are integrated into their
- event loops.
-
- Mandatory functions that must be implemented:
-
- * `_timer_start`: Contains backend-specific code for starting
- the timer
-
- * `_timer_stop`: Contains backend-specific code for stopping
- the timer
-
- Optional overrides:
-
- * `_timer_set_single_shot`: Code for setting the timer to
- single shot operating mode, if supported by the timer
- object. If not, the `Timer` class itself will store the flag
- and the `_on_timer` method should be overridden to support
- such behavior.
-
- * `_timer_set_interval`: Code for setting the interval on the
- timer, if there is a method for doing so on the timer
- object.
-
- * `_on_timer`: This is the internal function that any timer
- object should call, which will handle the task of running
- all callbacks that have been set.
-
- Attributes:
-
- * `interval`: The time between timer events in
- milliseconds. Default is 1000 ms.
-
- * `single_shot`: Boolean flag indicating whether this timer
- should operate as single shot (run once and then
- stop). Defaults to `False`.
-
- * `callbacks`: Stores list of (func, args) tuples that will be
- called upon timer events. This list can be manipulated
- directly, or the functions `add_callback` and
- `remove_callback` can be used.
- '''
- def __init__(self, interval=None, callbacks=None):
- #Initialize empty callbacks list and setup default settings if necssary
- if callbacks is None:
- self.callbacks = []
- else:
- self.callbacks = callbacks[:] # Create a copy
-
- if interval is None:
- self._interval = 1000
- else:
- self._interval = interval
-
- self._single = False
-
- # Default attribute for holding the GUI-specific timer object
- self._timer = None
-
- def __del__(self):
- 'Need to stop timer and possibly disconnect timer.'
- self._timer_stop()
-
- def start(self, interval=None):
- '''
- Start the timer object. `interval` is optional and will be used
- to reset the timer interval first if provided.
- '''
- if interval is not None:
- self._set_interval(interval)
- self._timer_start()
-
- def stop(self):
- '''
- Stop the timer.
- '''
- self._timer_stop()
-
- def _timer_start(self):
- pass
-
- def _timer_stop(self):
- pass
-
- def _get_interval(self):
- return self._interval
-
- def _set_interval(self, interval):
- # Force to int since none of the backends actually support fractional
- # milliseconds, and some error or give warnings.
- interval = int(interval)
- self._interval = interval
- self._timer_set_interval()
-
- interval = property(_get_interval, _set_interval)
-
- def _get_single_shot(self):
- return self._single
-
- def _set_single_shot(self, ss=True):
- self._single = ss
- self._timer_set_single_shot()
-
- single_shot = property(_get_single_shot, _set_single_shot)
-
- def add_callback(self, func, *args, **kwargs):
- '''
- Register `func` to be called by timer when the event fires. Any
- additional arguments provided will be passed to `func`.
- '''
- self.callbacks.append((func, args, kwargs))
-
- def remove_callback(self, func, *args, **kwargs):
- '''
- Remove `func` from list of callbacks. `args` and `kwargs` are optional
- and used to distinguish between copies of the same function registered
- to be called with different arguments.
- '''
- if args or kwargs:
- self.callbacks.remove((func, args, kwargs))
- else:
- funcs = [c[0] for c in self.callbacks]
- if func in funcs:
- self.callbacks.pop(funcs.index(func))
-
- def _timer_set_interval(self):
- 'Used to set interval on underlying timer object.'
- pass
-
- def _timer_set_single_shot(self):
- 'Used to set single shot on underlying timer object.'
- pass
-
- def _on_timer(self):
- '''
- Runs all function that have been registered as callbacks. Functions
- can return False (or 0) if they should not be called any more. If there
- are no callbacks, the timer is automatically stopped.
- '''
- for func, args, kwargs in self.callbacks:
- ret = func(*args, **kwargs)
- # docstring above explains why we use `if ret == False` here,
- # instead of `if not ret`.
- if ret == False:
- self.callbacks.remove((func, args, kwargs))
-
- if len(self.callbacks) == 0:
- self.stop()
-
-
-class Event:
- """
- A matplotlib event. Attach additional attributes as defined in
- :meth:`FigureCanvasBase.mpl_connect`. The following attributes
- are defined and shown with their default values
-
- *name*
- the event name
-
- *canvas*
- the FigureCanvas instance generating the event
-
- *guiEvent*
- the GUI event that triggered the matplotlib event
-
-
- """
- def __init__(self, name, canvas, guiEvent=None):
- self.name = name
- self.canvas = canvas
- self.guiEvent = guiEvent
-
-
-class IdleEvent(Event):
- """
- An event triggered by the GUI backend when it is idle -- useful
- for passive animation
- """
- pass
-
-
-class DrawEvent(Event):
- """
- An event triggered by a draw operation on the canvas
-
- In addition to the :class:`Event` attributes, the following event
- attributes are defined:
-
- *renderer*
- the :class:`RendererBase` instance for the draw event
-
- """
- def __init__(self, name, canvas, renderer):
- Event.__init__(self, name, canvas)
- self.renderer = renderer
-
-
-class ResizeEvent(Event):
- """
- An event triggered by a canvas resize
-
- In addition to the :class:`Event` attributes, the following event
- attributes are defined:
-
- *width*
- width of the canvas in pixels
-
- *height*
- height of the canvas in pixels
-
- """
- def __init__(self, name, canvas):
- Event.__init__(self, name, canvas)
- self.width, self.height = canvas.get_width_height()
-
-
-class CloseEvent(Event):
- """
- An event triggered by a figure being closed
-
- In addition to the :class:`Event` attributes, the following event
- attributes are defined:
- """
- def __init__(self, name, canvas, guiEvent=None):
- Event.__init__(self, name, canvas, guiEvent)
-
-
-class LocationEvent(Event):
- """
- An event that has a screen location
-
- The following additional attributes are defined and shown with
- their default values.
-
- In addition to the :class:`Event` attributes, the following
- event attributes are defined:
-
- *x*
- x position - pixels from left of canvas
-
- *y*
- y position - pixels from bottom of canvas
-
- *inaxes*
- the :class:`~matplotlib.axes.Axes` instance if mouse is over axes
-
- *xdata*
- x coord of mouse in data coords
-
- *ydata*
- y coord of mouse in data coords
-
- """
- x = None # x position - pixels from left of canvas
- y = None # y position - pixels from right of canvas
- inaxes = None # the Axes instance if mouse us over axes
- xdata = None # x coord of mouse in data coords
- ydata = None # y coord of mouse in data coords
-
- # the last event that was triggered before this one
- lastevent = None
-
- def __init__(self, name, canvas, x, y, guiEvent=None):
- """
- *x*, *y* in figure coords, 0,0 = bottom, left
- """
- Event.__init__(self, name, canvas, guiEvent=guiEvent)
- self.x = x
- self.y = y
-
- if x is None or y is None:
- # cannot check if event was in axes if no x,y info
- self.inaxes = None
- self._update_enter_leave()
- return
-
- # Find all axes containing the mouse
- if self.canvas.mouse_grabber is None:
- axes_list = [a for a in self.canvas.figure.get_axes()
- if a.in_axes(self)]
- else:
- axes_list = [self.canvas.mouse_grabber]
-
- if len(axes_list) == 0: # None found
- self.inaxes = None
- self._update_enter_leave()
- return
- elif (len(axes_list) > 1): # Overlap, get the highest zorder
- axes_list.sort(key=lambda x: x.zorder)
- self.inaxes = axes_list[-1] # Use the highest zorder
- else: # Just found one hit
- self.inaxes = axes_list[0]
-
- try:
- trans = self.inaxes.transData.inverted()
- xdata, ydata = trans.transform_point((x, y))
- except ValueError:
- self.xdata = None
- self.ydata = None
- else:
- self.xdata = xdata
- self.ydata = ydata
-
- self._update_enter_leave()
-
- def _update_enter_leave(self):
- 'process the figure/axes enter leave events'
- if LocationEvent.lastevent is not None:
- last = LocationEvent.lastevent
- if last.inaxes != self.inaxes:
- # process axes enter/leave events
- try:
- if last.inaxes is not None:
- last.canvas.callbacks.process('axes_leave_event', last)
- except:
- pass
- # See ticket 2901582.
- # I think this is a valid exception to the rule
- # against catching all exceptions; if anything goes
- # wrong, we simply want to move on and process the
- # current event.
- if self.inaxes is not None:
- self.canvas.callbacks.process('axes_enter_event', self)
-
- else:
- # process a figure enter event
- if self.inaxes is not None:
- self.canvas.callbacks.process('axes_enter_event', self)
-
- LocationEvent.lastevent = self
-
-
-class MouseEvent(LocationEvent):
- """
- A mouse event ('button_press_event',
- 'button_release_event',
- 'scroll_event',
- 'motion_notify_event').
-
- In addition to the :class:`Event` and :class:`LocationEvent`
- attributes, the following attributes are defined:
-
- *button*
- button pressed None, 1, 2, 3, 'up', 'down' (up and down are used
- for scroll events)
-
- *key*
- the key depressed when the mouse event triggered (see
- :class:`KeyEvent`)
-
- *step*
- number of scroll steps (positive for 'up', negative for 'down')
-
-
- Example usage::
-
- def on_press(event):
- print('you pressed', event.button, event.xdata, event.ydata)
-
- cid = fig.canvas.mpl_connect('button_press_event', on_press)
-
- """
- x = None # x position - pixels from left of canvas
- y = None # y position - pixels from right of canvas
- button = None # button pressed None, 1, 2, 3
- dblclick = None # whether or not the event is the result of a double click
- inaxes = None # the Axes instance if mouse us over axes
- xdata = None # x coord of mouse in data coords
- ydata = None # y coord of mouse in data coords
- step = None # scroll steps for scroll events
-
- def __init__(self, name, canvas, x, y, button=None, key=None,
- step=0, dblclick=False, guiEvent=None):
- """
- x, y in figure coords, 0,0 = bottom, left
- button pressed None, 1, 2, 3, 'up', 'down'
- """
- LocationEvent.__init__(self, name, canvas, x, y, guiEvent=guiEvent)
- self.button = button
- self.key = key
- self.step = step
- self.dblclick = dblclick
-
- def __str__(self):
- return ("MPL MouseEvent: xy=(%d,%d) xydata=(%s,%s) button=%s " +
- "dblclick=%s inaxes=%s") % (self.x, self.y, self.xdata,
- self.ydata, self.button,
- self.dblclick, self.inaxes)
-
-
-class PickEvent(Event):
- """
- a pick event, fired when the user picks a location on the canvas
- sufficiently close to an artist.
-
- Attrs: all the :class:`Event` attributes plus
-
- *mouseevent*
- the :class:`MouseEvent` that generated the pick
-
- *artist*
- the :class:`~matplotlib.artist.Artist` picked
-
- other
- extra class dependent attrs -- e.g., a
- :class:`~matplotlib.lines.Line2D` pick may define different
- extra attributes than a
- :class:`~matplotlib.collections.PatchCollection` pick event
-
-
- Example usage::
-
- line, = ax.plot(rand(100), 'o', picker=5) # 5 points tolerance
-
- def on_pick(event):
- thisline = event.artist
- xdata, ydata = thisline.get_data()
- ind = event.ind
- print('on pick line:', zip(xdata[ind], ydata[ind]))
-
- cid = fig.canvas.mpl_connect('pick_event', on_pick)
-
- """
- def __init__(self, name, canvas, mouseevent, artist,
- guiEvent=None, **kwargs):
- Event.__init__(self, name, canvas, guiEvent)
- self.mouseevent = mouseevent
- self.artist = artist
- self.__dict__.update(kwargs)
-
-
-class KeyEvent(LocationEvent):
- """
- A key event (key press, key release).
-
- Attach additional attributes as defined in
- :meth:`FigureCanvasBase.mpl_connect`.
-
- In addition to the :class:`Event` and :class:`LocationEvent`
- attributes, the following attributes are defined:
-
- *key*
- the key(s) pressed. Could be **None**, a single case sensitive ascii
- character ("g", "G", "#", etc.), a special key
- ("control", "shift", "f1", "up", etc.) or a
- combination of the above (e.g., "ctrl+alt+g", "ctrl+alt+G").
-
- .. note::
-
- Modifier keys will be prefixed to the pressed key and will be in the
- order "ctrl", "alt", "super". The exception to this rule is when the
- pressed key is itself a modifier key, therefore "ctrl+alt" and
- "alt+control" can both be valid key values.
-
-
- Example usage::
-
- def on_key(event):
- print('you pressed', event.key, event.xdata, event.ydata)
-
- cid = fig.canvas.mpl_connect('key_press_event', on_key)
-
- """
- def __init__(self, name, canvas, key, x=0, y=0, guiEvent=None):
- LocationEvent.__init__(self, name, canvas, x, y, guiEvent=guiEvent)
- self.key = key
-
-
-class FigureCanvasBase(object):
- """
- The canvas the figure renders into.
-
- Public attributes
-
- *figure*
- A :class:`matplotlib.figure.Figure` instance
-
- """
- events = [
- 'resize_event',
- 'draw_event',
- 'key_press_event',
- 'key_release_event',
- 'button_press_event',
- 'button_release_event',
- 'scroll_event',
- 'motion_notify_event',
- 'pick_event',
- 'idle_event',
- 'figure_enter_event',
- 'figure_leave_event',
- 'axes_enter_event',
- 'axes_leave_event',
- 'close_event'
- ]
-
- supports_blit = True
- fixed_dpi = None
-
- filetypes = _default_filetypes
- if _has_pil:
- # JPEG support
- register_backend('jpg', 'matplotlib.backends.backend_agg',
- 'Joint Photographic Experts Group')
- register_backend('jpeg', 'matplotlib.backends.backend_agg',
- 'Joint Photographic Experts Group')
-
- # TIFF support
- register_backend('tif', 'matplotlib.backends.backend_agg',
- 'Tagged Image File Format')
- register_backend('tiff', 'matplotlib.backends.backend_agg',
- 'Tagged Image File Format')
-
- def __init__(self, figure):
- figure.set_canvas(self)
- self.figure = figure
- # a dictionary from event name to a dictionary that maps cid->func
- self.callbacks = cbook.CallbackRegistry()
- self.widgetlock = widgets.LockDraw()
- self._button = None # the button pressed
- self._key = None # the key pressed
- self._lastx, self._lasty = None, None
- self.button_pick_id = self.mpl_connect('button_press_event', self.pick)
- self.scroll_pick_id = self.mpl_connect('scroll_event', self.pick)
- self.mouse_grabber = None # the axes currently grabbing mouse
- self.toolbar = None # NavigationToolbar2 will set me
- self._is_saving = False
- if False:
- ## highlight the artists that are hit
- self.mpl_connect('motion_notify_event', self.onHilite)
- ## delete the artists that are clicked on
- #self.mpl_disconnect(self.button_pick_id)
- #self.mpl_connect('button_press_event',self.onRemove)
-
- def is_saving(self):
- """
- Returns `True` when the renderer is in the process of saving
- to a file, rather than rendering for an on-screen buffer.
- """
- return self._is_saving
-
- def onRemove(self, ev):
- """
- Mouse event processor which removes the top artist
- under the cursor. Connect this to the 'mouse_press_event'
- using::
-
- canvas.mpl_connect('mouse_press_event',canvas.onRemove)
- """
- def sort_artists(artists):
- # This depends on stable sort and artists returned
- # from get_children in z order.
- L = [(h.zorder, h) for h in artists]
- L.sort()
- return [h for zorder, h in L]
-
- # Find the top artist under the cursor
- under = sort_artists(self.figure.hitlist(ev))
- h = None
- if under:
- h = under[-1]
-
- # Try deleting that artist, or its parent if you
- # can't delete the artist
- while h:
- if h.remove():
- self.draw_idle()
- break
- parent = None
- for p in under:
- if h in p.get_children():
- parent = p
- break
- h = parent
-
- def onHilite(self, ev):
- """
- Mouse event processor which highlights the artists
- under the cursor. Connect this to the 'motion_notify_event'
- using::
-
- canvas.mpl_connect('motion_notify_event',canvas.onHilite)
- """
- if not hasattr(self, '_active'):
- self._active = dict()
-
- under = self.figure.hitlist(ev)
- enter = [a for a in under if a not in self._active]
- leave = [a for a in self._active if a not in under]
- #print "within:"," ".join([str(x) for x in under])
- #print "entering:",[str(a) for a in enter]
- #print "leaving:",[str(a) for a in leave]
- # On leave restore the captured colour
- for a in leave:
- if hasattr(a, 'get_color'):
- a.set_color(self._active[a])
- elif hasattr(a, 'get_edgecolor'):
- a.set_edgecolor(self._active[a][0])
- a.set_facecolor(self._active[a][1])
- del self._active[a]
- # On enter, capture the color and repaint the artist
- # with the highlight colour. Capturing colour has to
- # be done first in case the parent recolouring affects
- # the child.
- for a in enter:
- if hasattr(a, 'get_color'):
- self._active[a] = a.get_color()
- elif hasattr(a, 'get_edgecolor'):
- self._active[a] = (a.get_edgecolor(), a.get_facecolor())
- else:
- self._active[a] = None
- for a in enter:
- if hasattr(a, 'get_color'):
- a.set_color('red')
- elif hasattr(a, 'get_edgecolor'):
- a.set_edgecolor('red')
- a.set_facecolor('lightblue')
- else:
- self._active[a] = None
- self.draw_idle()
-
- def pick(self, mouseevent):
- if not self.widgetlock.locked():
- self.figure.pick(mouseevent)
-
- def blit(self, bbox=None):
- """
- blit the canvas in bbox (default entire canvas)
- """
- pass
-
- def resize(self, w, h):
- """
- set the canvas size in pixels
- """
- pass
-
- def draw_event(self, renderer):
- """
- This method will be call all functions connected to the
- 'draw_event' with a :class:`DrawEvent`
- """
-
- s = 'draw_event'
- event = DrawEvent(s, self, renderer)
- self.callbacks.process(s, event)
-
- def resize_event(self):
- """
- This method will be call all functions connected to the
- 'resize_event' with a :class:`ResizeEvent`
- """
-
- s = 'resize_event'
- event = ResizeEvent(s, self)
- self.callbacks.process(s, event)
-
- def close_event(self, guiEvent=None):
- """
- This method will be called by all functions connected to the
- 'close_event' with a :class:`CloseEvent`
- """
- s = 'close_event'
- try:
- event = CloseEvent(s, self, guiEvent=guiEvent)
- self.callbacks.process(s, event)
- except (TypeError, AttributeError):
- pass
- # Suppress the TypeError when the python session is being killed.
- # It may be that a better solution would be a mechanism to
- # disconnect all callbacks upon shutdown.
- # AttributeError occurs on OSX with qt4agg upon exiting
- # with an open window; 'callbacks' attribute no longer exists.
-
- def key_press_event(self, key, guiEvent=None):
- """
- This method will be call all functions connected to the
- 'key_press_event' with a :class:`KeyEvent`
- """
- self._key = key
- s = 'key_press_event'
- event = KeyEvent(
- s, self, key, self._lastx, self._lasty, guiEvent=guiEvent)
- self.callbacks.process(s, event)
-
- def key_release_event(self, key, guiEvent=None):
- """
- This method will be call all functions connected to the
- 'key_release_event' with a :class:`KeyEvent`
- """
- s = 'key_release_event'
- event = KeyEvent(
- s, self, key, self._lastx, self._lasty, guiEvent=guiEvent)
- self.callbacks.process(s, event)
- self._key = None
-
- def pick_event(self, mouseevent, artist, **kwargs):
- """
- This method will be called by artists who are picked and will
- fire off :class:`PickEvent` callbacks registered listeners
- """
- s = 'pick_event'
- event = PickEvent(s, self, mouseevent, artist, **kwargs)
- self.callbacks.process(s, event)
-
- def scroll_event(self, x, y, step, guiEvent=None):
- """
- Backend derived classes should call this function on any
- scroll wheel event. x,y are the canvas coords: 0,0 is lower,
- left. button and key are as defined in MouseEvent.
-
- This method will be call all functions connected to the
- 'scroll_event' with a :class:`MouseEvent` instance.
- """
- if step >= 0:
- self._button = 'up'
- else:
- self._button = 'down'
- s = 'scroll_event'
- mouseevent = MouseEvent(s, self, x, y, self._button, self._key,
- step=step, guiEvent=guiEvent)
- self.callbacks.process(s, mouseevent)
-
- def button_press_event(self, x, y, button, dblclick=False, guiEvent=None):
- """
- Backend derived classes should call this function on any mouse
- button press. x,y are the canvas coords: 0,0 is lower, left.
- button and key are as defined in :class:`MouseEvent`.
-
- This method will be call all functions connected to the
- 'button_press_event' with a :class:`MouseEvent` instance.
-
- """
- self._button = button
- s = 'button_press_event'
- mouseevent = MouseEvent(s, self, x, y, button, self._key,
- dblclick=dblclick, guiEvent=guiEvent)
- self.callbacks.process(s, mouseevent)
-
- def button_release_event(self, x, y, button, guiEvent=None):
- """
- Backend derived classes should call this function on any mouse
- button release.
-
- *x*
- the canvas coordinates where 0=left
-
- *y*
- the canvas coordinates where 0=bottom
-
- *guiEvent*
- the native UI event that generated the mpl event
-
-
- This method will be call all functions connected to the
- 'button_release_event' with a :class:`MouseEvent` instance.
-
- """
- s = 'button_release_event'
- event = MouseEvent(s, self, x, y, button, self._key, guiEvent=guiEvent)
- self.callbacks.process(s, event)
- self._button = None
-
- def motion_notify_event(self, x, y, guiEvent=None):
- """
- Backend derived classes should call this function on any
- motion-notify-event.
-
- *x*
- the canvas coordinates where 0=left
-
- *y*
- the canvas coordinates where 0=bottom
-
- *guiEvent*
- the native UI event that generated the mpl event
-
-
- This method will be call all functions connected to the
- 'motion_notify_event' with a :class:`MouseEvent` instance.
-
- """
- self._lastx, self._lasty = x, y
- s = 'motion_notify_event'
- event = MouseEvent(s, self, x, y, self._button, self._key,
- guiEvent=guiEvent)
- self.callbacks.process(s, event)
-
- def leave_notify_event(self, guiEvent=None):
- """
- Backend derived classes should call this function when leaving
- canvas
-
- *guiEvent*
- the native UI event that generated the mpl event
-
- """
-
- self.callbacks.process('figure_leave_event', LocationEvent.lastevent)
- LocationEvent.lastevent = None
- self._lastx, self._lasty = None, None
-
- def enter_notify_event(self, guiEvent=None, xy=None):
- """
- Backend derived classes should call this function when entering
- canvas
-
- *guiEvent*
- the native UI event that generated the mpl event
- *xy*
- the coordinate location of the pointer when the canvas is
- entered
-
- """
- if xy is not None:
- x, y = xy
- self._lastx, self._lasty = x, y
-
- event = Event('figure_enter_event', self, guiEvent)
- self.callbacks.process('figure_enter_event', event)
-
- def idle_event(self, guiEvent=None):
- """Called when GUI is idle."""
- s = 'idle_event'
- event = IdleEvent(s, self, guiEvent=guiEvent)
- self.callbacks.process(s, event)
-
- def grab_mouse(self, ax):
- """
- Set the child axes which are currently grabbing the mouse events.
- Usually called by the widgets themselves.
- It is an error to call this if the mouse is already grabbed by
- another axes.
- """
- if self.mouse_grabber not in (None, ax):
- raise RuntimeError('two different attempted to grab mouse input')
- self.mouse_grabber = ax
-
- def release_mouse(self, ax):
- """
- Release the mouse grab held by the axes, ax.
- Usually called by the widgets.
- It is ok to call this even if you ax doesn't have the mouse
- grab currently.
- """
- if self.mouse_grabber is ax:
- self.mouse_grabber = None
-
- def draw(self, *args, **kwargs):
- """
- Render the :class:`~matplotlib.figure.Figure`
- """
- pass
-
- def draw_idle(self, *args, **kwargs):
- """
- :meth:`draw` only if idle; defaults to draw but backends can overrride
- """
- self.draw(*args, **kwargs)
-
- def draw_cursor(self, event):
- """
- Draw a cursor in the event.axes if inaxes is not None. Use
- native GUI drawing for efficiency if possible
- """
- pass
-
- def get_width_height(self):
- """
- Return the figure width and height in points or pixels
- (depending on the backend), truncated to integers
- """
- return int(self.figure.bbox.width), int(self.figure.bbox.height)
-
- @classmethod
- def get_supported_filetypes(cls):
- """Return dict of savefig file formats supported by this backend"""
- return cls.filetypes
-
- @classmethod
- def get_supported_filetypes_grouped(cls):
- """Return a dict of savefig file formats supported by this backend,
- where the keys are a file type name, such as 'Joint Photographic
- Experts Group', and the values are a list of filename extensions used
- for that filetype, such as ['jpg', 'jpeg']."""
- groupings = {}
- for ext, name in six.iteritems(cls.filetypes):
- groupings.setdefault(name, []).append(ext)
- groupings[name].sort()
- return groupings
-
- def _get_output_canvas(self, format):
- """Return a canvas that is suitable for saving figures to a specified
- file format. If necessary, this function will switch to a registered
- backend that supports the format.
- """
- method_name = 'print_%s' % format
-
- # check if this canvas supports the requested format
- if hasattr(self, method_name):
- return self
-
- # check if there is a default canvas for the requested format
- canvas_class = get_registered_canvas_class(format)
- if canvas_class:
- return self.switch_backends(canvas_class)
-
- # else report error for unsupported format
- formats = sorted(self.get_supported_filetypes())
- raise ValueError('Format "%s" is not supported.\n'
- 'Supported formats: '
- '%s.' % (format, ', '.join(formats)))
-
- def print_figure(self, filename, dpi=None, facecolor='w', edgecolor='w',
- orientation='portrait', format=None, **kwargs):
- """
- Render the figure to hardcopy. Set the figure patch face and edge
- colors. This is useful because some of the GUIs have a gray figure
- face color background and you'll probably want to override this on
- hardcopy.
-
- Arguments are:
-
- *filename*
- can also be a file object on image backends
-
- *orientation*
- only currently applies to PostScript printing.
-
- *dpi*
- the dots per inch to save the figure in; if None, use savefig.dpi
-
- *facecolor*
- the facecolor of the figure
-
- *edgecolor*
- the edgecolor of the figure
-
- *orientation*
- landscape' | 'portrait' (not supported on all backends)
-
- *format*
- when set, forcibly set the file format to save to
-
- *bbox_inches*
- Bbox in inches. Only the given portion of the figure is
- saved. If 'tight', try to figure out the tight bbox of
- the figure. If None, use savefig.bbox
-
- *pad_inches*
- Amount of padding around the figure when bbox_inches is
- 'tight'. If None, use savefig.pad_inches
-
- *bbox_extra_artists*
- A list of extra artists that will be considered when the
- tight bbox is calculated.
-
- """
- if format is None:
- # get format from filename, or from backend's default filetype
- if cbook.is_string_like(filename):
- format = os.path.splitext(filename)[1][1:]
- if format is None or format == '':
- format = self.get_default_filetype()
- if cbook.is_string_like(filename):
- filename = filename.rstrip('.') + '.' + format
- format = format.lower()
-
- # get canvas object and print method for format
- canvas = self._get_output_canvas(format)
- print_method = getattr(canvas, 'print_%s' % format)
-
- if dpi is None:
- dpi = rcParams['savefig.dpi']
-
- origDPI = self.figure.dpi
- origfacecolor = self.figure.get_facecolor()
- origedgecolor = self.figure.get_edgecolor()
-
- self.figure.dpi = dpi
- self.figure.set_facecolor(facecolor)
- self.figure.set_edgecolor(edgecolor)
-
- bbox_inches = kwargs.pop("bbox_inches", None)
- if bbox_inches is None:
- bbox_inches = rcParams['savefig.bbox']
-
- if bbox_inches:
- # call adjust_bbox to save only the given area
- if bbox_inches == "tight":
- # when bbox_inches == "tight", it saves the figure
- # twice. The first save command is just to estimate
- # the bounding box of the figure. A stringIO object is
- # used as a temporary file object, but it causes a
- # problem for some backends (ps backend with
- # usetex=True) if they expect a filename, not a
- # file-like object. As I think it is best to change
- # the backend to support file-like object, i'm going
- # to leave it as it is. However, a better solution
- # than stringIO seems to be needed. -JJL
- #result = getattr(self, method_name)
- result = print_method(
- io.BytesIO(),
- dpi=dpi,
- facecolor=facecolor,
- edgecolor=edgecolor,
- orientation=orientation,
- dryrun=True,
- **kwargs)
- renderer = self.figure._cachedRenderer
- bbox_inches = self.figure.get_tightbbox(renderer)
-
- bbox_artists = kwargs.pop("bbox_extra_artists", None)
- if bbox_artists is None:
- bbox_artists = self.figure.get_default_bbox_extra_artists()
-
- bbox_filtered = []
- for a in bbox_artists:
- bbox = a.get_window_extent(renderer)
- if a.get_clip_on():
- clip_box = a.get_clip_box()
- if clip_box is not None:
- bbox = Bbox.intersection(bbox, clip_box)
- clip_path = a.get_clip_path()
- if clip_path is not None and bbox is not None:
- clip_path = clip_path.get_fully_transformed_path()
- bbox = Bbox.intersection(bbox,
- clip_path.get_extents())
- if bbox is not None and (bbox.width != 0 or
- bbox.height != 0):
- bbox_filtered.append(bbox)
-
- if bbox_filtered:
- _bbox = Bbox.union(bbox_filtered)
- trans = Affine2D().scale(1.0 / self.figure.dpi)
- bbox_extra = TransformedBbox(_bbox, trans)
- bbox_inches = Bbox.union([bbox_inches, bbox_extra])
-
- pad = kwargs.pop("pad_inches", None)
- if pad is None:
- pad = rcParams['savefig.pad_inches']
-
- bbox_inches = bbox_inches.padded(pad)
-
- restore_bbox = tight_bbox.adjust_bbox(self.figure, bbox_inches,
- canvas.fixed_dpi)
-
- _bbox_inches_restore = (bbox_inches, restore_bbox)
- else:
- _bbox_inches_restore = None
-
- self._is_saving = True
- try:
- #result = getattr(self, method_name)(
- result = print_method(
- filename,
- dpi=dpi,
- facecolor=facecolor,
- edgecolor=edgecolor,
- orientation=orientation,
- bbox_inches_restore=_bbox_inches_restore,
- **kwargs)
- finally:
- if bbox_inches and restore_bbox:
- restore_bbox()
-
- self.figure.dpi = origDPI
- self.figure.set_facecolor(origfacecolor)
- self.figure.set_edgecolor(origedgecolor)
- self.figure.set_canvas(self)
- self._is_saving = False
- #self.figure.canvas.draw() ## seems superfluous
- return result
-
- @classmethod
- def get_default_filetype(cls):
- """
- Get the default savefig file format as specified in rcParam
- ``savefig.format``. Returned string excludes period. Overridden
- in backends that only support a single file type.
- """
- return rcParams['savefig.format']
-
- def get_window_title(self):
- """
- Get the title text of the window containing the figure.
- Return None if there is no window (e.g., a PS backend).
- """
- if hasattr(self, "manager"):
- return self.manager.get_window_title()
-
- def set_window_title(self, title):
- """
- Set the title text of the window containing the figure. Note that
- this has no effect if there is no window (e.g., a PS backend).
- """
- if hasattr(self, "manager"):
- self.manager.set_window_title(title)
-
- def get_default_filename(self):
- """
- Return a string, which includes extension, suitable for use as
- a default filename.
- """
- default_filename = self.get_window_title() or 'image'
- default_filename = default_filename.lower().replace(' ', '_')
- return default_filename + '.' + self.get_default_filetype()
-
- def switch_backends(self, FigureCanvasClass):
- """
- Instantiate an instance of FigureCanvasClass
-
- This is used for backend switching, e.g., to instantiate a
- FigureCanvasPS from a FigureCanvasGTK. Note, deep copying is
- not done, so any changes to one of the instances (e.g., setting
- figure size or line props), will be reflected in the other
- """
- newCanvas = FigureCanvasClass(self.figure)
- newCanvas._is_saving = self._is_saving
- return newCanvas
-
- def mpl_connect(self, s, func):
- """
- Connect event with string *s* to *func*. The signature of *func* is::
-
- def func(event)
-
- where event is a :class:`matplotlib.backend_bases.Event`. The
- following events are recognized
-
- - 'button_press_event'
- - 'button_release_event'
- - 'draw_event'
- - 'key_press_event'
- - 'key_release_event'
- - 'motion_notify_event'
- - 'pick_event'
- - 'resize_event'
- - 'scroll_event'
- - 'figure_enter_event',
- - 'figure_leave_event',
- - 'axes_enter_event',
- - 'axes_leave_event'
- - 'close_event'
-
- For the location events (button and key press/release), if the
- mouse is over the axes, the variable ``event.inaxes`` will be
- set to the :class:`~matplotlib.axes.Axes` the event occurs is
- over, and additionally, the variables ``event.xdata`` and
- ``event.ydata`` will be defined. This is the mouse location
- in data coords. See
- :class:`~matplotlib.backend_bases.KeyEvent` and
- :class:`~matplotlib.backend_bases.MouseEvent` for more info.
-
- Return value is a connection id that can be used with
- :meth:`~matplotlib.backend_bases.Event.mpl_disconnect`.
-
- Example usage::
-
- def on_press(event):
- print('you pressed', event.button, event.xdata, event.ydata)
-
- cid = canvas.mpl_connect('button_press_event', on_press)
-
- """
-
- return self.callbacks.connect(s, func)
-
- def mpl_disconnect(self, cid):
- """
- Disconnect callback id cid
-
- Example usage::
-
- cid = canvas.mpl_connect('button_press_event', on_press)
- #...later
- canvas.mpl_disconnect(cid)
- """
- return self.callbacks.disconnect(cid)
-
- def new_timer(self, *args, **kwargs):
- """
- Creates a new backend-specific subclass of
- :class:`backend_bases.Timer`. This is useful for getting periodic
- events through the backend's native event loop. Implemented only for
- backends with GUIs.
-
- optional arguments:
-
- *interval*
- Timer interval in milliseconds
- *callbacks*
- Sequence of (func, args, kwargs) where func(*args, **kwargs) will
- be executed by the timer every *interval*.
- """
- return TimerBase(*args, **kwargs)
-
- def flush_events(self):
- """
- Flush the GUI events for the figure. Implemented only for
- backends with GUIs.
- """
- raise NotImplementedError
-
- def start_event_loop(self, timeout):
- """
- Start an event loop. This is used to start a blocking event
- loop so that interactive functions, such as ginput and
- waitforbuttonpress, can wait for events. This should not be
- confused with the main GUI event loop, which is always running
- and has nothing to do with this.
-
- This is implemented only for backends with GUIs.
- """
- raise NotImplementedError
-
- def stop_event_loop(self):
- """
- Stop an event loop. This is used to stop a blocking event
- loop so that interactive functions, such as ginput and
- waitforbuttonpress, can wait for events.
-
- This is implemented only for backends with GUIs.
- """
- raise NotImplementedError
-
- def start_event_loop_default(self, timeout=0):
- """
- Start an event loop. This is used to start a blocking event
- loop so that interactive functions, such as ginput and
- waitforbuttonpress, can wait for events. This should not be
- confused with the main GUI event loop, which is always running
- and has nothing to do with this.
-
- This function provides default event loop functionality based
- on time.sleep that is meant to be used until event loop
- functions for each of the GUI backends can be written. As
- such, it throws a deprecated warning.
-
- Call signature::
-
- start_event_loop_default(self,timeout=0)
-
- This call blocks until a callback function triggers
- stop_event_loop() or *timeout* is reached. If *timeout* is
- <=0, never timeout.
- """
- str = "Using default event loop until function specific"
- str += " to this GUI is implemented"
- warnings.warn(str, mplDeprecation)
-
- if timeout <= 0:
- timeout = np.inf
- timestep = 0.01
- counter = 0
- self._looping = True
- while self._looping and counter * timestep < timeout:
- self.flush_events()
- time.sleep(timestep)
- counter += 1
-
- def stop_event_loop_default(self):
- """
- Stop an event loop. This is used to stop a blocking event
- loop so that interactive functions, such as ginput and
- waitforbuttonpress, can wait for events.
-
- Call signature::
-
- stop_event_loop_default(self)
- """
- self._looping = False
-
-
-def key_press_handler(event, canvas, toolbar=None):
- """
- Implement the default mpl key bindings for the canvas and toolbar
- described at :ref:`key-event-handling`
-
- *event*
- a :class:`KeyEvent` instance
- *canvas*
- a :class:`FigureCanvasBase` instance
- *toolbar*
- a :class:`NavigationToolbar2` instance
-
- """
- # these bindings happen whether you are over an axes or not
-
- if event.key is None:
- return
-
- # Load key-mappings from your matplotlibrc file.
- fullscreen_keys = rcParams['keymap.fullscreen']
- home_keys = rcParams['keymap.home']
- back_keys = rcParams['keymap.back']
- forward_keys = rcParams['keymap.forward']
- pan_keys = rcParams['keymap.pan']
- zoom_keys = rcParams['keymap.zoom']
- save_keys = rcParams['keymap.save']
- quit_keys = rcParams['keymap.quit']
- grid_keys = rcParams['keymap.grid']
- toggle_yscale_keys = rcParams['keymap.yscale']
- toggle_xscale_keys = rcParams['keymap.xscale']
- all = rcParams['keymap.all_axes']
-
- # toggle fullscreen mode (default key 'f')
- if event.key in fullscreen_keys:
- canvas.manager.full_screen_toggle()
-
- # quit the figure (defaut key 'ctrl+w')
- if event.key in quit_keys:
- Gcf.destroy_fig(canvas.figure)
-
- if toolbar is not None:
- # home or reset mnemonic (default key 'h', 'home' and 'r')
- if event.key in home_keys:
- toolbar.home()
- # forward / backward keys to enable left handed quick navigation
- # (default key for backward: 'left', 'backspace' and 'c')
- elif event.key in back_keys:
- toolbar.back()
- # (default key for forward: 'right' and 'v')
- elif event.key in forward_keys:
- toolbar.forward()
- # pan mnemonic (default key 'p')
- elif event.key in pan_keys:
- toolbar.pan()
- toolbar._set_cursor(event)
- # zoom mnemonic (default key 'o')
- elif event.key in zoom_keys:
- toolbar.zoom()
- toolbar._set_cursor(event)
- # saving current figure (default key 's')
- elif event.key in save_keys:
- toolbar.save_figure()
-
- if event.inaxes is None:
- return
-
- # these bindings require the mouse to be over an axes to trigger
-
- # switching on/off a grid in current axes (default key 'g')
- if event.key in grid_keys:
- event.inaxes.grid()
- canvas.draw()
- # toggle scaling of y-axes between 'log and 'linear' (default key 'l')
- elif event.key in toggle_yscale_keys:
- ax = event.inaxes
- scale = ax.get_yscale()
- if scale == 'log':
- ax.set_yscale('linear')
- ax.figure.canvas.draw()
- elif scale == 'linear':
- ax.set_yscale('log')
- ax.figure.canvas.draw()
- # toggle scaling of x-axes between 'log and 'linear' (default key 'k')
- elif event.key in toggle_xscale_keys:
- ax = event.inaxes
- scalex = ax.get_xscale()
- if scalex == 'log':
- ax.set_xscale('linear')
- ax.figure.canvas.draw()
- elif scalex == 'linear':
- ax.set_xscale('log')
- ax.figure.canvas.draw()
-
- elif (event.key.isdigit() and event.key != '0') or event.key in all:
- # keys in list 'all' enables all axes (default key 'a'),
- # otherwise if key is a number only enable this particular axes
- # if it was the axes, where the event was raised
- if not (event.key in all):
- n = int(event.key) - 1
- for i, a in enumerate(canvas.figure.get_axes()):
- # consider axes, in which the event was raised
- # FIXME: Why only this axes?
- if event.x is not None and event.y is not None \
- and a.in_axes(event):
- if event.key in all:
- a.set_navigate(True)
- else:
- a.set_navigate(i == n)
-
-
-class NonGuiException(Exception):
- pass
-
-
-class FigureManagerBase(object):
- """
- Helper class for pyplot mode, wraps everything up into a neat bundle
-
- Public attibutes:
-
- *canvas*
- A :class:`FigureCanvasBase` instance
-
- *num*
- The figure number
- """
- def __init__(self, canvas, num):
- self.canvas = canvas
- canvas.manager = self # store a pointer to parent
- self.num = num
-
- self.key_press_handler_id = self.canvas.mpl_connect('key_press_event',
- self.key_press)
- """
- The returned id from connecting the default key handler via
- :meth:`FigureCanvasBase.mpl_connnect`.
-
- To disable default key press handling::
-
- manager, canvas = figure.canvas.manager, figure.canvas
- canvas.mpl_disconnect(manager.key_press_handler_id)
-
- """
-
- def show(self):
- """
- For GUI backends, show the figure window and redraw.
- For non-GUI backends, raise an exception to be caught
- by :meth:`~matplotlib.figure.Figure.show`, for an
- optional warning.
- """
- raise NonGuiException()
-
- def destroy(self):
- pass
-
- def full_screen_toggle(self):
- pass
-
- def resize(self, w, h):
- """"For gui backends, resize the window (in pixels)."""
- pass
-
- def key_press(self, event):
- """
- Implement the default mpl key bindings defined at
- :ref:`key-event-handling`
- """
- key_press_handler(event, self.canvas, self.canvas.toolbar)
-
- def show_popup(self, msg):
- """
- Display message in a popup -- GUI only
- """
- pass
-
- def get_window_title(self):
- """
- Get the title text of the window containing the figure.
- Return None for non-GUI backends (e.g., a PS backend).
- """
- return 'image'
-
- def set_window_title(self, title):
- """
- Set the title text of the window containing the figure. Note that
- this has no effect for non-GUI backends (e.g., a PS backend).
- """
- pass
-
-
-class Cursors:
- # this class is only used as a simple namespace
- HAND, POINTER, SELECT_REGION, MOVE = list(range(4))
-cursors = Cursors()
-
-
-class NavigationToolbar2(object):
- """
- Base class for the navigation cursor, version 2
-
- backends must implement a canvas that handles connections for
- 'button_press_event' and 'button_release_event'. See
- :meth:`FigureCanvasBase.mpl_connect` for more information
-
-
- They must also define
-
- :meth:`save_figure`
- save the current figure
-
- :meth:`set_cursor`
- if you want the pointer icon to change
-
- :meth:`_init_toolbar`
- create your toolbar widget
-
- :meth:`draw_rubberband` (optional)
- draw the zoom to rect "rubberband" rectangle
-
- :meth:`press` (optional)
- whenever a mouse button is pressed, you'll be notified with
- the event
-
- :meth:`release` (optional)
- whenever a mouse button is released, you'll be notified with
- the event
-
- :meth:`dynamic_update` (optional)
- dynamically update the window while navigating
-
- :meth:`set_message` (optional)
- display message
-
- :meth:`set_history_buttons` (optional)
- you can change the history back / forward buttons to
- indicate disabled / enabled state.
-
- That's it, we'll do the rest!
- """
-
- # list of toolitems to add to the toolbar, format is:
- # (
- # text, # the text of the button (often not visible to users)
- # tooltip_text, # the tooltip shown on hover (where possible)
- # image_file, # name of the image for the button (without the extension)
- # name_of_method, # name of the method in NavigationToolbar2 to call
- # )
- toolitems = (
- ('Home', 'Reset original view', 'home', 'home'),
- ('Back', 'Back to previous view', 'back', 'back'),
- ('Forward', 'Forward to next view', 'forward', 'forward'),
- (None, None, None, None),
- ('Pan', 'Pan axes with left mouse, zoom with right', 'move', 'pan'),
- ('Zoom', 'Zoom to rectangle', 'zoom_to_rect', 'zoom'),
- (None, None, None, None),
- ('Subplots', 'Configure subplots', 'subplots', 'configure_subplots'),
- ('Save', 'Save the figure', 'filesave', 'save_figure'),
- )
-
- def __init__(self, canvas):
- self.canvas = canvas
- canvas.toolbar = self
- # a dict from axes index to a list of view limits
- self._views = cbook.Stack()
- self._positions = cbook.Stack() # stack of subplot positions
- self._xypress = None # the location and axis info at the time
- # of the press
- self._idPress = None
- self._idRelease = None
- self._active = None
- self._lastCursor = None
- self._init_toolbar()
- self._idDrag = self.canvas.mpl_connect(
- 'motion_notify_event', self.mouse_move)
-
- self._ids_zoom = []
- self._zoom_mode = None
-
- self._button_pressed = None # determined by the button pressed
- # at start
-
- self.mode = '' # a mode string for the status bar
- self.set_history_buttons()
-
- def set_message(self, s):
- """Display a message on toolbar or in status bar"""
- pass
-
- def back(self, *args):
- """move back up the view lim stack"""
- self._views.back()
- self._positions.back()
- self.set_history_buttons()
- self._update_view()
-
- def dynamic_update(self):
- pass
-
- def draw_rubberband(self, event, x0, y0, x1, y1):
- """Draw a rectangle rubberband to indicate zoom limits"""
- pass
-
- def forward(self, *args):
- """Move forward in the view lim stack"""
- self._views.forward()
- self._positions.forward()
- self.set_history_buttons()
- self._update_view()
-
- def home(self, *args):
- """Restore the original view"""
- self._views.home()
- self._positions.home()
- self.set_history_buttons()
- self._update_view()
-
- def _init_toolbar(self):
- """
- This is where you actually build the GUI widgets (called by
- __init__). The icons ``home.xpm``, ``back.xpm``, ``forward.xpm``,
- ``hand.xpm``, ``zoom_to_rect.xpm`` and ``filesave.xpm`` are standard
- across backends (there are ppm versions in CVS also).
-
- You just need to set the callbacks
-
- home : self.home
- back : self.back
- forward : self.forward
- hand : self.pan
- zoom_to_rect : self.zoom
- filesave : self.save_figure
-
- You only need to define the last one - the others are in the base
- class implementation.
-
- """
- raise NotImplementedError
-
- def _set_cursor(self, event):
- if not event.inaxes or not self._active:
- if self._lastCursor != cursors.POINTER:
- self.set_cursor(cursors.POINTER)
- self._lastCursor = cursors.POINTER
- else:
- if self._active == 'ZOOM':
- if self._lastCursor != cursors.SELECT_REGION:
- self.set_cursor(cursors.SELECT_REGION)
- self._lastCursor = cursors.SELECT_REGION
- elif (self._active == 'PAN' and
- self._lastCursor != cursors.MOVE):
- self.set_cursor(cursors.MOVE)
-
- self._lastCursor = cursors.MOVE
-
- def mouse_move(self, event):
- self._set_cursor(event)
-
- if event.inaxes and event.inaxes.get_navigate():
-
- try:
- s = event.inaxes.format_coord(event.xdata, event.ydata)
- except (ValueError, OverflowError):
- pass
- else:
- if len(self.mode):
- self.set_message('%s, %s' % (self.mode, s))
- else:
- self.set_message(s)
- else:
- self.set_message(self.mode)
-
- def pan(self, *args):
- """Activate the pan/zoom tool. pan with left button, zoom with right"""
- # set the pointer icon and button press funcs to the
- # appropriate callbacks
-
- if self._active == 'PAN':
- self._active = None
- else:
- self._active = 'PAN'
- if self._idPress is not None:
- self._idPress = self.canvas.mpl_disconnect(self._idPress)
- self.mode = ''
-
- if self._idRelease is not None:
- self._idRelease = self.canvas.mpl_disconnect(self._idRelease)
- self.mode = ''
-
- if self._active:
- self._idPress = self.canvas.mpl_connect(
- 'button_press_event', self.press_pan)
- self._idRelease = self.canvas.mpl_connect(
- 'button_release_event', self.release_pan)
- self.mode = 'pan/zoom'
- self.canvas.widgetlock(self)
- else:
- self.canvas.widgetlock.release(self)
-
- for a in self.canvas.figure.get_axes():
- a.set_navigate_mode(self._active)
-
- self.set_message(self.mode)
-
- def press(self, event):
- """Called whenver a mouse button is pressed."""
- pass
-
- def press_pan(self, event):
- """the press mouse button in pan/zoom mode callback"""
-
- if event.button == 1:
- self._button_pressed = 1
- elif event.button == 3:
- self._button_pressed = 3
- else:
- self._button_pressed = None
- return
-
- x, y = event.x, event.y
-
- # push the current view to define home if stack is empty
- if self._views.empty():
- self.push_current()
-
- self._xypress = []
- for i, a in enumerate(self.canvas.figure.get_axes()):
- if (x is not None and y is not None and a.in_axes(event) and
- a.get_navigate() and a.can_pan()):
- a.start_pan(x, y, event.button)
- self._xypress.append((a, i))
- self.canvas.mpl_disconnect(self._idDrag)
- self._idDrag = self.canvas.mpl_connect('motion_notify_event',
- self.drag_pan)
-
- self.press(event)
-
- def press_zoom(self, event):
- """the press mouse button in zoom to rect mode callback"""
- # If we're already in the middle of a zoom, pressing another
- # button works to "cancel"
- if self._ids_zoom != []:
- for zoom_id in self._ids_zoom:
- self.canvas.mpl_disconnect(zoom_id)
- self.release(event)
- self.draw()
- self._xypress = None
- self._button_pressed = None
- self._ids_zoom = []
- return
-
- if event.button == 1:
- self._button_pressed = 1
- elif event.button == 3:
- self._button_pressed = 3
- else:
- self._button_pressed = None
- return
-
- x, y = event.x, event.y
-
- # push the current view to define home if stack is empty
- if self._views.empty():
- self.push_current()
-
- self._xypress = []
- for i, a in enumerate(self.canvas.figure.get_axes()):
- if (x is not None and y is not None and a.in_axes(event) and
- a.get_navigate() and a.can_zoom()):
- self._xypress.append((x, y, a, i, a.viewLim.frozen(),
- a.transData.frozen()))
-
- id1 = self.canvas.mpl_connect('motion_notify_event', self.drag_zoom)
- id2 = self.canvas.mpl_connect('key_press_event',
- self._switch_on_zoom_mode)
- id3 = self.canvas.mpl_connect('key_release_event',
- self._switch_off_zoom_mode)
-
- self._ids_zoom = id1, id2, id3
- self._zoom_mode = event.key
-
- self.press(event)
-
- def _switch_on_zoom_mode(self, event):
- self._zoom_mode = event.key
- self.mouse_move(event)
-
- def _switch_off_zoom_mode(self, event):
- self._zoom_mode = None
- self.mouse_move(event)
-
- def push_current(self):
- """push the current view limits and position onto the stack"""
- lims = []
- pos = []
- for a in self.canvas.figure.get_axes():
- xmin, xmax = a.get_xlim()
- ymin, ymax = a.get_ylim()
- lims.append((xmin, xmax, ymin, ymax))
- # Store both the original and modified positions
- pos.append((
- a.get_position(True).frozen(),
- a.get_position().frozen()))
- self._views.push(lims)
- self._positions.push(pos)
- self.set_history_buttons()
-
- def release(self, event):
- """this will be called whenever mouse button is released"""
- pass
-
- def release_pan(self, event):
- """the release mouse button callback in pan/zoom mode"""
-
- if self._button_pressed is None:
- return
- self.canvas.mpl_disconnect(self._idDrag)
- self._idDrag = self.canvas.mpl_connect(
- 'motion_notify_event', self.mouse_move)
- for a, ind in self._xypress:
- a.end_pan()
- if not self._xypress:
- return
- self._xypress = []
- self._button_pressed = None
- self.push_current()
- self.release(event)
- self.draw()
-
- def drag_pan(self, event):
- """the drag callback in pan/zoom mode"""
-
- for a, ind in self._xypress:
- #safer to use the recorded button at the press than current button:
- #multiple button can get pressed during motion...
- a.drag_pan(self._button_pressed, event.key, event.x, event.y)
- self.dynamic_update()
-
- def drag_zoom(self, event):
- """the drag callback in zoom mode"""
-
- if self._xypress:
- x, y = event.x, event.y
- lastx, lasty, a, ind, lim, trans = self._xypress[0]
-
- # adjust x, last, y, last
- x1, y1, x2, y2 = a.bbox.extents
- x, lastx = max(min(x, lastx), x1), min(max(x, lastx), x2)
- y, lasty = max(min(y, lasty), y1), min(max(y, lasty), y2)
-
- if self._zoom_mode == "x":
- x1, y1, x2, y2 = a.bbox.extents
- y, lasty = y1, y2
- elif self._zoom_mode == "y":
- x1, y1, x2, y2 = a.bbox.extents
- x, lastx = x1, x2
-
- self.draw_rubberband(event, x, y, lastx, lasty)
-
- def release_zoom(self, event):
- """the release mouse button callback in zoom to rect mode"""
- for zoom_id in self._ids_zoom:
- self.canvas.mpl_disconnect(zoom_id)
- self._ids_zoom = []
-
- if not self._xypress:
- return
-
- last_a = []
-
- for cur_xypress in self._xypress:
- x, y = event.x, event.y
- lastx, lasty, a, ind, lim, trans = cur_xypress
- # ignore singular clicks - 5 pixels is a threshold
- if abs(x - lastx) < 5 or abs(y - lasty) < 5:
- self._xypress = None
- self.release(event)
- self.draw()
- return
-
- x0, y0, x1, y1 = lim.extents
-
- # zoom to rect
- inverse = a.transData.inverted()
- lastx, lasty = inverse.transform_point((lastx, lasty))
- x, y = inverse.transform_point((x, y))
- Xmin, Xmax = a.get_xlim()
- Ymin, Ymax = a.get_ylim()
-
- # detect twinx,y axes and avoid double zooming
- twinx, twiny = False, False
- if last_a:
- for la in last_a:
- if a.get_shared_x_axes().joined(a, la):
- twinx = True
- if a.get_shared_y_axes().joined(a, la):
- twiny = True
- last_a.append(a)
-
- if twinx:
- x0, x1 = Xmin, Xmax
- else:
- if Xmin < Xmax:
- if x < lastx:
- x0, x1 = x, lastx
- else:
- x0, x1 = lastx, x
- if x0 < Xmin:
- x0 = Xmin
- if x1 > Xmax:
- x1 = Xmax
- else:
- if x > lastx:
- x0, x1 = x, lastx
- else:
- x0, x1 = lastx, x
- if x0 > Xmin:
- x0 = Xmin
- if x1 < Xmax:
- x1 = Xmax
-
- if twiny:
- y0, y1 = Ymin, Ymax
- else:
- if Ymin < Ymax:
- if y < lasty:
- y0, y1 = y, lasty
- else:
- y0, y1 = lasty, y
- if y0 < Ymin:
- y0 = Ymin
- if y1 > Ymax:
- y1 = Ymax
- else:
- if y > lasty:
- y0, y1 = y, lasty
- else:
- y0, y1 = lasty, y
- if y0 > Ymin:
- y0 = Ymin
- if y1 < Ymax:
- y1 = Ymax
-
- if self._button_pressed == 1:
- if self._zoom_mode == "x":
- a.set_xlim((x0, x1))
- elif self._zoom_mode == "y":
- a.set_ylim((y0, y1))
- else:
- a.set_xlim((x0, x1))
- a.set_ylim((y0, y1))
- elif self._button_pressed == 3:
- if a.get_xscale() == 'log':
- alpha = np.log(Xmax / Xmin) / np.log(x1 / x0)
- rx1 = pow(Xmin / x0, alpha) * Xmin
- rx2 = pow(Xmax / x0, alpha) * Xmin
- else:
- alpha = (Xmax - Xmin) / (x1 - x0)
- rx1 = alpha * (Xmin - x0) + Xmin
- rx2 = alpha * (Xmax - x0) + Xmin
- if a.get_yscale() == 'log':
- alpha = np.log(Ymax / Ymin) / np.log(y1 / y0)
- ry1 = pow(Ymin / y0, alpha) * Ymin
- ry2 = pow(Ymax / y0, alpha) * Ymin
- else:
- alpha = (Ymax - Ymin) / (y1 - y0)
- ry1 = alpha * (Ymin - y0) + Ymin
- ry2 = alpha * (Ymax - y0) + Ymin
-
- if self._zoom_mode == "x":
- a.set_xlim((rx1, rx2))
- elif self._zoom_mode == "y":
- a.set_ylim((ry1, ry2))
- else:
- a.set_xlim((rx1, rx2))
- a.set_ylim((ry1, ry2))
-
- self.draw()
- self._xypress = None
- self._button_pressed = None
-
- self._zoom_mode = None
-
- self.push_current()
- self.release(event)
-
- def draw(self):
- """Redraw the canvases, update the locators"""
- for a in self.canvas.figure.get_axes():
- xaxis = getattr(a, 'xaxis', None)
- yaxis = getattr(a, 'yaxis', None)
- locators = []
- if xaxis is not None:
- locators.append(xaxis.get_major_locator())
- locators.append(xaxis.get_minor_locator())
- if yaxis is not None:
- locators.append(yaxis.get_major_locator())
- locators.append(yaxis.get_minor_locator())
-
- for loc in locators:
- loc.refresh()
- self.canvas.draw_idle()
-
- def _update_view(self):
- """Update the viewlim and position from the view and
- position stack for each axes
- """
-
- lims = self._views()
- if lims is None:
- return
- pos = self._positions()
- if pos is None:
- return
- for i, a in enumerate(self.canvas.figure.get_axes()):
- xmin, xmax, ymin, ymax = lims[i]
- a.set_xlim((xmin, xmax))
- a.set_ylim((ymin, ymax))
- # Restore both the original and modified positions
- a.set_position(pos[i][0], 'original')
- a.set_position(pos[i][1], 'active')
-
- self.canvas.draw_idle()
-
- def save_figure(self, *args):
- """Save the current figure"""
- raise NotImplementedError
-
- def set_cursor(self, cursor):
- """
- Set the current cursor to one of the :class:`Cursors`
- enums values
- """
- pass
-
- def update(self):
- """Reset the axes stack"""
- self._views.clear()
- self._positions.clear()
- self.set_history_buttons()
-
- def zoom(self, *args):
- """Activate zoom to rect mode"""
- if self._active == 'ZOOM':
- self._active = None
- else:
- self._active = 'ZOOM'
-
- if self._idPress is not None:
- self._idPress = self.canvas.mpl_disconnect(self._idPress)
- self.mode = ''
-
- if self._idRelease is not None:
- self._idRelease = self.canvas.mpl_disconnect(self._idRelease)
- self.mode = ''
-
- if self._active:
- self._idPress = self.canvas.mpl_connect('button_press_event',
- self.press_zoom)
- self._idRelease = self.canvas.mpl_connect('button_release_event',
- self.release_zoom)
- self.mode = 'zoom rect'
- self.canvas.widgetlock(self)
- else:
- self.canvas.widgetlock.release(self)
-
- for a in self.canvas.figure.get_axes():
- a.set_navigate_mode(self._active)
-
- self.set_message(self.mode)
-
- def set_history_buttons(self):
- """Enable or disable back/forward button"""
- pass
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/Matplotlib.nib/classes.nib b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/Matplotlib.nib/classes.nib
deleted file mode 100644
index 5f296f1..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/Matplotlib.nib/classes.nib
+++ /dev/null
@@ -1,59 +0,0 @@
-
-
-
-
- IBClasses
-
-
- CLASS
- FirstResponder
- LANGUAGE
- ObjC
- SUPERCLASS
- NSObject
-
-
- ACTIONS
-
- printFigure
- id
- quit
- id
- saveFigure
- id
-
- CLASS
- MatplotlibController
- LANGUAGE
- ObjC
- OUTLETS
-
- plotView
- PlotView
- plotWindow
- NSWindow
-
- SUPERCLASS
- NSObject
-
-
- CLASS
- PlotView
- LANGUAGE
- ObjC
- SUPERCLASS
- NSImageView
-
-
- CLASS
- PlotWindow
- LANGUAGE
- ObjC
- SUPERCLASS
- NSWindow
-
-
- IBVersion
- 1
-
-
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/Matplotlib.nib/info.nib b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/Matplotlib.nib/info.nib
deleted file mode 100644
index 1019096..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/Matplotlib.nib/info.nib
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
- IBDocumentLocation
- 42 396 439 411 0 0 1280 832
- IBFramework Version
- 446.1
- IBOpenObjects
-
- 21
-
- IBSystem Version
- 8L127
-
-
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/Matplotlib.nib/keyedobjects.nib b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/Matplotlib.nib/keyedobjects.nib
deleted file mode 100644
index 9d6c306..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/Matplotlib.nib/keyedobjects.nib
+++ /dev/null
@@ -1,1225 +0,0 @@
-
-
-
-
- $archiver
- NSKeyedArchiver
- $objects
-
- $null
-
- $class
-
- CF$UID
- 97
-
- NSAccessibilityConnectors
-
- CF$UID
- 94
-
- NSAccessibilityOidsKeys
-
- CF$UID
- 95
-
- NSAccessibilityOidsValues
-
- CF$UID
- 96
-
- NSClassesKeys
-
- CF$UID
- 77
-
- NSClassesValues
-
- CF$UID
- 78
-
- NSConnections
-
- CF$UID
- 52
-
- NSFontManager
-
- CF$UID
- 0
-
- NSFramework
-
- CF$UID
- 6
-
- NSNamesKeys
-
- CF$UID
- 72
-
- NSNamesValues
-
- CF$UID
- 73
-
- NSNextOid
- 262
- NSObjectsKeys
-
- CF$UID
- 69
-
- NSObjectsValues
-
- CF$UID
- 71
-
- NSOidsKeys
-
- CF$UID
- 79
-
- NSOidsValues
-
- CF$UID
- 80
-
- NSRoot
-
- CF$UID
- 2
-
- NSVisibleWindows
-
- CF$UID
- 7
-
-
-
- $class
-
- CF$UID
- 5
-
- NSClassName
-
- CF$UID
- 3
-
-
-
- $class
-
- CF$UID
- 4
-
- NS.string
- NSApplication
-
-
- $classes
-
- NSMutableString
- NSString
- NSObject
-
- $classname
- NSMutableString
-
-
- $classes
-
- NSCustomObject
- NSObject
-
- $classname
- NSCustomObject
-
-
- $class
-
- CF$UID
- 4
-
- NS.string
- IBCocoaFramework
-
-
- $class
-
- CF$UID
- 25
-
- NS.objects
-
-
- CF$UID
- 8
-
-
-
-
- $class
-
- CF$UID
- 51
-
- NSMaxSize
-
- CF$UID
- 50
-
- NSMinSize
-
- CF$UID
- 49
-
- NSScreenRect
-
- CF$UID
- 48
-
- NSViewClass
-
- CF$UID
- 12
-
- NSWTFlags
- 807927808
- NSWindowBacking
- 2
- NSWindowClass
-
- CF$UID
- 11
-
- NSWindowRect
-
- CF$UID
- 9
-
- NSWindowStyleMask
- 270
- NSWindowTitle
-
- CF$UID
- 10
-
- NSWindowView
-
- CF$UID
- 13
-
-
- {{50, 189}, {600, 500}}
- Matplotlib
- PlotWindow
-
- $class
-
- CF$UID
- 4
-
- NS.string
- View
-
-
- $class
-
- CF$UID
- 47
-
- NSFrame
-
- CF$UID
- 46
-
- NSNextResponder
-
- CF$UID
- 0
-
- NSSubviews
-
- CF$UID
- 14
-
-
-
- $class
-
- CF$UID
- 45
-
- NS.objects
-
-
- CF$UID
- 15
-
-
- CF$UID
- 30
-
-
- CF$UID
- 41
-
-
-
-
- $class
-
- CF$UID
- 29
-
- NSCell
-
- CF$UID
- 27
-
- NSClassName
-
- CF$UID
- 16
-
- NSDragTypes
-
- CF$UID
- 18
-
- NSEditable
-
- NSEnabled
-
- NSFrame
-
- CF$UID
- 26
-
- NSNextResponder
-
- CF$UID
- 13
-
- NSOriginalClassName
-
- CF$UID
- 17
-
- NSSuperview
-
- CF$UID
- 13
-
- NSvFlags
- 274
-
- PlotView
- NSImageView
-
- $class
-
- CF$UID
- 25
-
- NS.objects
-
-
- CF$UID
- 19
-
-
- CF$UID
- 20
-
-
- CF$UID
- 21
-
-
- CF$UID
- 22
-
-
- CF$UID
- 23
-
-
- CF$UID
- 24
-
-
-
- Apple PDF pasteboard type
- NeXT Encapsulated PostScript v1.2 pasteboard type
- NeXT TIFF v4.0 pasteboard type
- NSFilenamesPboardType
- Apple PICT pasteboard type
- Apple PNG pasteboard type
-
- $classes
-
- NSMutableSet
- NSSet
- NSObject
-
- $classname
- NSMutableSet
-
- {{7, 52}, {586, 441}}
-
- $class
-
- CF$UID
- 28
-
- NSAlign
- 0
- NSAnimates
-
- NSCellFlags
- 130560
- NSCellFlags2
- 33554432
- NSScale
- 2
- NSStyle
- 2
-
-
- $classes
-
- NSImageCell
- %NSImageCell
- NSCell
- NSObject
-
- $classname
- NSImageCell
-
-
- $classes
-
- NSClassSwapper
- NSObject
-
- $classname
- NSClassSwapper
-
-
- $class
-
- CF$UID
- 40
-
- NSCell
-
- CF$UID
- 32
-
- NSEnabled
-
- NSFrame
-
- CF$UID
- 31
-
- NSNextResponder
-
- CF$UID
- 13
-
- NSSuperview
-
- CF$UID
- 13
-
- NSvFlags
- 289
-
- {{486, 20}, {94, 20}}
-
- $class
-
- CF$UID
- 39
-
- NSAlternateContents
-
- CF$UID
- 38
-
- NSAlternateImage
-
- CF$UID
- 37
-
- NSButtonFlags
- -2038021889
- NSButtonFlags2
- 32
- NSCellFlags
- 67239424
- NSCellFlags2
- 134348800
- NSContents
-
- CF$UID
- 33
-
- NSControlView
-
- CF$UID
- 30
-
- NSKeyEquivalent
-
- CF$UID
- 38
-
- NSPeriodicDelay
- 400
- NSPeriodicInterval
- 75
- NSSupport
-
- CF$UID
- 34
-
-
- Save Figure
-
- $class
-
- CF$UID
- 36
-
- NSName
-
- CF$UID
- 35
-
- NSSize
- 11
- NSfFlags
- 3100
-
- LucidaGrande
-
- $classes
-
- NSFont
- NSObject
-
- $classname
- NSFont
-
-
- $class
-
- CF$UID
- 36
-
- NSName
-
- CF$UID
- 35
-
- NSSize
- 11
- NSfFlags
- 16
-
-
-
- $classes
-
- NSButtonCell
- %NSButtonCell
- NSActionCell
- NSCell
- NSObject
-
- $classname
- NSButtonCell
-
-
- $classes
-
- NSButton
- NSControl
- NSView
- NSResponder
- NSObject
-
- $classname
- NSButton
-
-
- $class
-
- CF$UID
- 40
-
- NSCell
-
- CF$UID
- 43
-
- NSEnabled
-
- NSFrame
-
- CF$UID
- 42
-
- NSNextResponder
-
- CF$UID
- 13
-
- NSSuperview
-
- CF$UID
- 13
-
- NSvFlags
- 292
-
- {{20, 20}, {94, 20}}
-
- $class
-
- CF$UID
- 39
-
- NSAlternateContents
-
- CF$UID
- 38
-
- NSAlternateImage
-
- CF$UID
- 37
-
- NSButtonFlags
- -2038021889
- NSButtonFlags2
- 32
- NSCellFlags
- 67239424
- NSCellFlags2
- 134348800
- NSContents
-
- CF$UID
- 44
-
- NSControlView
-
- CF$UID
- 41
-
- NSKeyEquivalent
-
- CF$UID
- 38
-
- NSPeriodicDelay
- 400
- NSPeriodicInterval
- 75
- NSSupport
-
- CF$UID
- 34
-
-
- Print
-
- $classes
-
- NSMutableArray
- NSArray
- NSObject
-
- $classname
- NSMutableArray
-
- {{1, 9}, {600, 500}}
-
- $classes
-
- NSView
- NSResponder
- NSObject
-
- $classname
- NSView
-
- {{0, 0}, {1024, 746}}
- {213, 129}
- {3.40282e+38, 3.40282e+38}
-
- $classes
-
- NSWindowTemplate
- NSObject
-
- $classname
- NSWindowTemplate
-
-
- $class
-
- CF$UID
- 45
-
- NS.objects
-
-
- CF$UID
- 53
-
-
- CF$UID
- 58
-
-
- CF$UID
- 60
-
-
- CF$UID
- 63
-
-
- CF$UID
- 65
-
-
- CF$UID
- 67
-
-
-
-
- $class
-
- CF$UID
- 57
-
- NSDestination
-
- CF$UID
- 15
-
- NSLabel
-
- CF$UID
- 56
-
- NSSource
-
- CF$UID
- 54
-
-
-
- $class
-
- CF$UID
- 5
-
- NSClassName
-
- CF$UID
- 55
-
-
- MatplotlibController
- plotView
-
- $classes
-
- NSNibOutletConnector
- NSNibConnector
- NSObject
-
- $classname
- NSNibOutletConnector
-
-
- $class
-
- CF$UID
- 57
-
- NSDestination
-
- CF$UID
- 8
-
- NSLabel
-
- CF$UID
- 59
-
- NSSource
-
- CF$UID
- 54
-
-
- plotWindow
-
- $class
-
- CF$UID
- 62
-
- NSDestination
-
- CF$UID
- 54
-
- NSLabel
-
- CF$UID
- 61
-
- NSSource
-
- CF$UID
- 30
-
-
- saveFigure:
-
- $classes
-
- NSNibControlConnector
- NSNibConnector
- NSObject
-
- $classname
- NSNibControlConnector
-
-
- $class
-
- CF$UID
- 57
-
- NSDestination
-
- CF$UID
- 54
-
- NSLabel
-
- CF$UID
- 64
-
- NSSource
-
- CF$UID
- 8
-
-
- delegate
-
- $class
-
- CF$UID
- 57
-
- NSDestination
-
- CF$UID
- 54
-
- NSLabel
-
- CF$UID
- 66
-
- NSSource
-
- CF$UID
- 2
-
-
- delegate
-
- $class
-
- CF$UID
- 62
-
- NSDestination
-
- CF$UID
- 54
-
- NSLabel
-
- CF$UID
- 68
-
- NSSource
-
- CF$UID
- 41
-
-
- printFigure:
-
- $class
-
- CF$UID
- 70
-
- NS.objects
-
-
- CF$UID
- 41
-
-
- CF$UID
- 54
-
-
- CF$UID
- 13
-
-
- CF$UID
- 30
-
-
- CF$UID
- 8
-
-
- CF$UID
- 15
-
-
-
-
- $classes
-
- NSArray
- NSObject
-
- $classname
- NSArray
-
-
- $class
-
- CF$UID
- 70
-
- NS.objects
-
-
- CF$UID
- 13
-
-
- CF$UID
- 2
-
-
- CF$UID
- 8
-
-
- CF$UID
- 13
-
-
- CF$UID
- 2
-
-
- CF$UID
- 13
-
-
-
-
- $class
-
- CF$UID
- 70
-
- NS.objects
-
-
- CF$UID
- 54
-
-
- CF$UID
- 8
-
-
- CF$UID
- 2
-
-
-
-
- $class
-
- CF$UID
- 70
-
- NS.objects
-
-
- CF$UID
- 74
-
-
- CF$UID
- 75
-
-
- CF$UID
- 76
-
-
-
- MatplotlibController
- Window
-
- $class
-
- CF$UID
- 4
-
- NS.string
- File's Owner
-
-
- $class
-
- CF$UID
- 70
-
- NS.objects
-
-
- CF$UID
- 15
-
-
-
-
- $class
-
- CF$UID
- 70
-
- NS.objects
-
-
- CF$UID
- 16
-
-
-
-
- $class
-
- CF$UID
- 70
-
- NS.objects
-
-
- CF$UID
- 63
-
-
- CF$UID
- 54
-
-
- CF$UID
- 60
-
-
- CF$UID
- 30
-
-
- CF$UID
- 67
-
-
- CF$UID
- 8
-
-
- CF$UID
- 53
-
-
- CF$UID
- 41
-
-
- CF$UID
- 13
-
-
- CF$UID
- 65
-
-
- CF$UID
- 15
-
-
- CF$UID
- 58
-
-
- CF$UID
- 2
-
-
-
-
- $class
-
- CF$UID
- 70
-
- NS.objects
-
-
- CF$UID
- 81
-
-
- CF$UID
- 82
-
-
- CF$UID
- 83
-
-
- CF$UID
- 84
-
-
- CF$UID
- 85
-
-
- CF$UID
- 86
-
-
- CF$UID
- 87
-
-
- CF$UID
- 88
-
-
- CF$UID
- 89
-
-
- CF$UID
- 90
-
-
- CF$UID
- 91
-
-
- CF$UID
- 92
-
-
- CF$UID
- 93
-
-
-
- 258
- 248
- 251
- 247
- 261
- 21
- 249
- 260
- 2
- 259
- 246
- 250
- 1
-
- $class
-
- CF$UID
- 45
-
- NS.objects
-
-
-
- $class
-
- CF$UID
- 70
-
- NS.objects
-
-
-
- $class
-
- CF$UID
- 70
-
- NS.objects
-
-
-
- $classes
-
- NSIBObjectData
- NSObject
-
- $classname
- NSIBObjectData
-
-
- $top
-
- IB.objectdata
-
- CF$UID
- 1
-
-
- $version
- 100000
-
-
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/__init__.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/__init__.py
deleted file mode 100644
index cf80dc0..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/__init__.py
+++ /dev/null
@@ -1,62 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import matplotlib
-import inspect
-import warnings
-
-# ipython relies on interactive_bk being defined here
-from matplotlib.rcsetup import interactive_bk
-
-__all__ = ['backend','show','draw_if_interactive',
- 'new_figure_manager', 'backend_version']
-
-backend = matplotlib.get_backend() # validates, to match all_backends
-
-def pylab_setup():
- 'return new_figure_manager, draw_if_interactive and show for pylab'
- # Import the requested backend into a generic module object
-
- if backend.startswith('module://'):
- backend_name = backend[9:]
- else:
- backend_name = 'backend_'+backend
- backend_name = backend_name.lower() # until we banish mixed case
- backend_name = 'matplotlib.backends.%s'%backend_name.lower()
-
- # the last argument is specifies whether to use absolute or relative
- # imports. 0 means only perform absolute imports.
- backend_mod = __import__(backend_name,
- globals(),locals(),[backend_name],0)
-
- # Things we pull in from all backends
- new_figure_manager = backend_mod.new_figure_manager
-
- # image backends like pdf, agg or svg do not need to do anything
- # for "show" or "draw_if_interactive", so if they are not defined
- # by the backend, just do nothing
- def do_nothing_show(*args, **kwargs):
- frame = inspect.currentframe()
- fname = frame.f_back.f_code.co_filename
- if fname in ('', ''):
- warnings.warn("""
-Your currently selected backend, '%s' does not support show().
-Please select a GUI backend in your matplotlibrc file ('%s')
-or with matplotlib.use()""" %
- (backend, matplotlib.matplotlib_fname()))
- def do_nothing(*args, **kwargs): pass
- backend_version = getattr(backend_mod,'backend_version', 'unknown')
- show = getattr(backend_mod, 'show', do_nothing_show)
- draw_if_interactive = getattr(backend_mod, 'draw_if_interactive', do_nothing)
-
- # Additional imports which only happen for certain backends. This section
- # should probably disappear once all backends are uniform.
- if backend.lower() in ['wx','wxagg']:
- Toolbar = backend_mod.Toolbar
- __all__.append('Toolbar')
-
- matplotlib.verbose.report('backend %s version %s' % (backend,backend_version))
-
- return backend_mod, new_figure_manager, draw_if_interactive, show
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/_backend_agg.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/_backend_agg.so
deleted file mode 100755
index c212be4..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/_backend_agg.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/_macosx.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/_macosx.so
deleted file mode 100755
index 0805f6f..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/_macosx.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/_tkagg.so b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/_tkagg.so
deleted file mode 100755
index bf721e7..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/_tkagg.so and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_agg.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_agg.py
deleted file mode 100644
index 4cb14a6..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_agg.py
+++ /dev/null
@@ -1,594 +0,0 @@
-"""
-An agg http://antigrain.com/ backend
-
-Features that are implemented
-
- * capstyles and join styles
- * dashes
- * linewidth
- * lines, rectangles, ellipses
- * clipping to a rectangle
- * output to RGBA and PNG, optionally JPEG and TIFF
- * alpha blending
- * DPI scaling properly - everything scales properly (dashes, linewidths, etc)
- * draw polygon
- * freetype2 w/ ft2font
-
-TODO:
-
- * integrate screen dpi w/ ppi and text
-
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import threading
-import numpy as np
-
-from matplotlib import verbose, rcParams
-from matplotlib.backend_bases import RendererBase,\
- FigureManagerBase, FigureCanvasBase
-from matplotlib.cbook import is_string_like, maxdict, restrict_dict
-from matplotlib.figure import Figure
-from matplotlib.font_manager import findfont
-from matplotlib.ft2font import FT2Font, LOAD_FORCE_AUTOHINT, LOAD_NO_HINTING, \
- LOAD_DEFAULT, LOAD_NO_AUTOHINT
-from matplotlib.mathtext import MathTextParser
-from matplotlib.path import Path
-from matplotlib.transforms import Bbox, BboxBase
-
-from matplotlib.backends._backend_agg import RendererAgg as _RendererAgg
-from matplotlib import _png
-
-try:
- from PIL import Image
- _has_pil = True
-except ImportError:
- _has_pil = False
-
-backend_version = 'v2.2'
-
-def get_hinting_flag():
- mapping = {
- True: LOAD_FORCE_AUTOHINT,
- False: LOAD_NO_HINTING,
- 'either': LOAD_DEFAULT,
- 'native': LOAD_NO_AUTOHINT,
- 'auto': LOAD_FORCE_AUTOHINT,
- 'none': LOAD_NO_HINTING
- }
- return mapping[rcParams['text.hinting']]
-
-
-class RendererAgg(RendererBase):
- """
- The renderer handles all the drawing primitives using a graphics
- context instance that controls the colors/styles
- """
- debug=1
-
- # we want to cache the fonts at the class level so that when
- # multiple figures are created we can reuse them. This helps with
- # a bug on windows where the creation of too many figures leads to
- # too many open file handles. However, storing them at the class
- # level is not thread safe. The solution here is to let the
- # FigureCanvas acquire a lock on the fontd at the start of the
- # draw, and release it when it is done. This allows multiple
- # renderers to share the cached fonts, but only one figure can
- # draw at at time and so the font cache is used by only one
- # renderer at a time
-
- lock = threading.RLock()
- _fontd = maxdict(50)
- def __init__(self, width, height, dpi):
- if __debug__: verbose.report('RendererAgg.__init__', 'debug-annoying')
- RendererBase.__init__(self)
- self.texd = maxdict(50) # a cache of tex image rasters
-
- self.dpi = dpi
- self.width = width
- self.height = height
- if __debug__: verbose.report('RendererAgg.__init__ width=%s, height=%s'%(width, height), 'debug-annoying')
- self._renderer = _RendererAgg(int(width), int(height), dpi, debug=False)
- self._filter_renderers = []
-
- if __debug__: verbose.report('RendererAgg.__init__ _RendererAgg done',
- 'debug-annoying')
-
- self._update_methods()
- self.mathtext_parser = MathTextParser('Agg')
-
- self.bbox = Bbox.from_bounds(0, 0, self.width, self.height)
- if __debug__: verbose.report('RendererAgg.__init__ done',
- 'debug-annoying')
-
- def __getstate__(self):
- # We only want to preserve the init keywords of the Renderer.
- # Anything else can be re-created.
- return {'width': self.width, 'height': self.height, 'dpi': self.dpi}
-
- def __setstate__(self, state):
- self.__init__(state['width'], state['height'], state['dpi'])
-
- def _get_hinting_flag(self):
- if rcParams['text.hinting']:
- return LOAD_FORCE_AUTOHINT
- else:
- return LOAD_NO_HINTING
-
- # for filtering to work with rasterization, methods needs to be wrapped.
- # maybe there is better way to do it.
- def draw_markers(self, *kl, **kw):
- return self._renderer.draw_markers(*kl, **kw)
-
- def draw_path_collection(self, *kl, **kw):
- return self._renderer.draw_path_collection(*kl, **kw)
-
- def _update_methods(self):
- #self.draw_path = self._renderer.draw_path # see below
- #self.draw_markers = self._renderer.draw_markers
- #self.draw_path_collection = self._renderer.draw_path_collection
- self.draw_quad_mesh = self._renderer.draw_quad_mesh
- self.draw_gouraud_triangle = self._renderer.draw_gouraud_triangle
- self.draw_gouraud_triangles = self._renderer.draw_gouraud_triangles
- self.draw_image = self._renderer.draw_image
- self.copy_from_bbox = self._renderer.copy_from_bbox
- self.tostring_rgba_minimized = self._renderer.tostring_rgba_minimized
-
- def draw_path(self, gc, path, transform, rgbFace=None):
- """
- Draw the path
- """
- nmax = rcParams['agg.path.chunksize'] # here at least for testing
- npts = path.vertices.shape[0]
- if (nmax > 100 and npts > nmax and path.should_simplify and
- rgbFace is None and gc.get_hatch() is None):
- nch = np.ceil(npts/float(nmax))
- chsize = int(np.ceil(npts/nch))
- i0 = np.arange(0, npts, chsize)
- i1 = np.zeros_like(i0)
- i1[:-1] = i0[1:] - 1
- i1[-1] = npts
- for ii0, ii1 in zip(i0, i1):
- v = path.vertices[ii0:ii1,:]
- c = path.codes
- if c is not None:
- c = c[ii0:ii1]
- c[0] = Path.MOVETO # move to end of last chunk
- p = Path(v, c)
- self._renderer.draw_path(gc, p, transform, rgbFace)
- else:
- self._renderer.draw_path(gc, path, transform, rgbFace)
-
- def draw_mathtext(self, gc, x, y, s, prop, angle):
- """
- Draw the math text using matplotlib.mathtext
- """
- if __debug__: verbose.report('RendererAgg.draw_mathtext',
- 'debug-annoying')
- ox, oy, width, height, descent, font_image, used_characters = \
- self.mathtext_parser.parse(s, self.dpi, prop)
-
- xd = descent * np.sin(np.deg2rad(angle))
- yd = descent * np.cos(np.deg2rad(angle))
- x = np.round(x + ox + xd)
- y = np.round(y - oy + yd)
- self._renderer.draw_text_image(font_image, x, y + 1, angle, gc)
-
- def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
- """
- Render the text
- """
- if __debug__: verbose.report('RendererAgg.draw_text', 'debug-annoying')
-
- if ismath:
- return self.draw_mathtext(gc, x, y, s, prop, angle)
-
- flags = get_hinting_flag()
- font = self._get_agg_font(prop)
- if font is None: return None
- if len(s) == 1 and ord(s) > 127:
- font.load_char(ord(s), flags=flags)
- else:
- # We pass '0' for angle here, since it will be rotated (in raster
- # space) in the following call to draw_text_image).
- font.set_text(s, 0, flags=flags)
- font.draw_glyphs_to_bitmap(antialiased=rcParams['text.antialiased'])
- d = font.get_descent() / 64.0
- # The descent needs to be adjusted for the angle
- xd = -d * np.sin(np.deg2rad(angle))
- yd = d * np.cos(np.deg2rad(angle))
-
- #print x, y, int(x), int(y), s
- self._renderer.draw_text_image(
- font.get_image(), np.round(x - xd), np.round(y + yd) + 1, angle, gc)
-
- def get_text_width_height_descent(self, s, prop, ismath):
- """
- get the width and height in display coords of the string s
- with FontPropertry prop
-
- # passing rgb is a little hack to make caching in the
- # texmanager more efficient. It is not meant to be used
- # outside the backend
- """
- if rcParams['text.usetex']:
- # todo: handle props
- size = prop.get_size_in_points()
- texmanager = self.get_texmanager()
- fontsize = prop.get_size_in_points()
- w, h, d = texmanager.get_text_width_height_descent(s, fontsize,
- renderer=self)
- return w, h, d
-
- if ismath:
- ox, oy, width, height, descent, fonts, used_characters = \
- self.mathtext_parser.parse(s, self.dpi, prop)
- return width, height, descent
-
- flags = get_hinting_flag()
- font = self._get_agg_font(prop)
- font.set_text(s, 0.0, flags=flags) # the width and height of unrotated string
- w, h = font.get_width_height()
- d = font.get_descent()
- w /= 64.0 # convert from subpixels
- h /= 64.0
- d /= 64.0
- return w, h, d
-
-
- def draw_tex(self, gc, x, y, s, prop, angle, ismath='TeX!', mtext=None):
- # todo, handle props, angle, origins
- size = prop.get_size_in_points()
-
- texmanager = self.get_texmanager()
- key = s, size, self.dpi, angle, texmanager.get_font_config()
- im = self.texd.get(key)
- if im is None:
- Z = texmanager.get_grey(s, size, self.dpi)
- Z = np.array(Z * 255.0, np.uint8)
-
- w, h, d = self.get_text_width_height_descent(s, prop, ismath)
- xd = d * np.sin(np.deg2rad(angle))
- yd = d * np.cos(np.deg2rad(angle))
- x = np.round(x + xd)
- y = np.round(y + yd)
-
- self._renderer.draw_text_image(Z, x, y, angle, gc)
-
- def get_canvas_width_height(self):
- 'return the canvas width and height in display coords'
- return self.width, self.height
-
- def _get_agg_font(self, prop):
- """
- Get the font for text instance t, cacheing for efficiency
- """
- if __debug__: verbose.report('RendererAgg._get_agg_font',
- 'debug-annoying')
-
- key = hash(prop)
- font = RendererAgg._fontd.get(key)
-
- if font is None:
- fname = findfont(prop)
- font = RendererAgg._fontd.get(fname)
- if font is None:
- font = FT2Font(
- fname,
- hinting_factor=rcParams['text.hinting_factor'])
- RendererAgg._fontd[fname] = font
- RendererAgg._fontd[key] = font
-
- font.clear()
- size = prop.get_size_in_points()
- font.set_size(size, self.dpi)
-
- return font
-
- def points_to_pixels(self, points):
- """
- convert point measures to pixes using dpi and the pixels per
- inch of the display
- """
- if __debug__: verbose.report('RendererAgg.points_to_pixels',
- 'debug-annoying')
- return points*self.dpi/72.0
-
- def tostring_rgb(self):
- if __debug__: verbose.report('RendererAgg.tostring_rgb',
- 'debug-annoying')
- return self._renderer.tostring_rgb()
-
- def tostring_argb(self):
- if __debug__: verbose.report('RendererAgg.tostring_argb',
- 'debug-annoying')
- return self._renderer.tostring_argb()
-
- def buffer_rgba(self):
- if __debug__: verbose.report('RendererAgg.buffer_rgba',
- 'debug-annoying')
- return self._renderer.buffer_rgba()
-
- def clear(self):
- self._renderer.clear()
-
- def option_image_nocomposite(self):
- # It is generally faster to composite each image directly to
- # the Figure, and there's no file size benefit to compositing
- # with the Agg backend
- return True
-
- def option_scale_image(self):
- """
- agg backend support arbitrary scaling of image.
- """
- return True
-
- def restore_region(self, region, bbox=None, xy=None):
- """
- Restore the saved region. If bbox (instance of BboxBase, or
- its extents) is given, only the region specified by the bbox
- will be restored. *xy* (a tuple of two floasts) optionally
- specifies the new position (the LLC of the original region,
- not the LLC of the bbox) where the region will be restored.
-
- >>> region = renderer.copy_from_bbox()
- >>> x1, y1, x2, y2 = region.get_extents()
- >>> renderer.restore_region(region, bbox=(x1+dx, y1, x2, y2),
- ... xy=(x1-dx, y1))
-
- """
- if bbox is not None or xy is not None:
- if bbox is None:
- x1, y1, x2, y2 = region.get_extents()
- elif isinstance(bbox, BboxBase):
- x1, y1, x2, y2 = bbox.extents
- else:
- x1, y1, x2, y2 = bbox
-
- if xy is None:
- ox, oy = x1, y1
- else:
- ox, oy = xy
-
- self._renderer.restore_region2(region, x1, y1, x2, y2, ox, oy)
-
- else:
- self._renderer.restore_region(region)
-
- def start_filter(self):
- """
- Start filtering. It simply create a new canvas (the old one is saved).
- """
- self._filter_renderers.append(self._renderer)
- self._renderer = _RendererAgg(int(self.width), int(self.height),
- self.dpi)
- self._update_methods()
-
- def stop_filter(self, post_processing):
- """
- Save the plot in the current canvas as a image and apply
- the *post_processing* function.
-
- def post_processing(image, dpi):
- # ny, nx, depth = image.shape
- # image (numpy array) has RGBA channels and has a depth of 4.
- ...
- # create a new_image (numpy array of 4 channels, size can be
- # different). The resulting image may have offsets from
- # lower-left corner of the original image
- return new_image, offset_x, offset_y
-
- The saved renderer is restored and the returned image from
- post_processing is plotted (using draw_image) on it.
- """
-
- # WARNING.
- # For agg_filter to work, the rendere's method need
- # to overridden in the class. See draw_markers, and draw_path_collections
-
- from matplotlib._image import fromarray
-
- width, height = int(self.width), int(self.height)
-
- buffer, bounds = self._renderer.tostring_rgba_minimized()
-
- l, b, w, h = bounds
-
-
- self._renderer = self._filter_renderers.pop()
- self._update_methods()
-
- if w > 0 and h > 0:
- img = np.fromstring(buffer, np.uint8)
- img, ox, oy = post_processing(img.reshape((h, w, 4)) / 255.,
- self.dpi)
- image = fromarray(img, 1)
- image.flipud_out()
-
- gc = self.new_gc()
- self._renderer.draw_image(gc,
- l+ox, height - b - h +oy,
- image)
-
-
-def new_figure_manager(num, *args, **kwargs):
- """
- Create a new figure manager instance
- """
- if __debug__: verbose.report('backend_agg.new_figure_manager',
- 'debug-annoying')
-
-
- FigureClass = kwargs.pop('FigureClass', Figure)
- thisFig = FigureClass(*args, **kwargs)
- return new_figure_manager_given_figure(num, thisFig)
-
-
-def new_figure_manager_given_figure(num, figure):
- """
- Create a new figure manager instance for the given figure.
- """
- canvas = FigureCanvasAgg(figure)
- manager = FigureManagerBase(canvas, num)
- return manager
-
-
-class FigureCanvasAgg(FigureCanvasBase):
- """
- The canvas the figure renders into. Calls the draw and print fig
- methods, creates the renderers, etc...
-
- Public attribute
-
- figure - A Figure instance
- """
-
- def copy_from_bbox(self, bbox):
- renderer = self.get_renderer()
- return renderer.copy_from_bbox(bbox)
-
- def restore_region(self, region, bbox=None, xy=None):
- renderer = self.get_renderer()
- return renderer.restore_region(region, bbox, xy)
-
- def draw(self):
- """
- Draw the figure using the renderer
- """
- if __debug__: verbose.report('FigureCanvasAgg.draw', 'debug-annoying')
-
- self.renderer = self.get_renderer(cleared=True)
- # acquire a lock on the shared font cache
- RendererAgg.lock.acquire()
-
- try:
- self.figure.draw(self.renderer)
- finally:
- RendererAgg.lock.release()
-
- def get_renderer(self, cleared=False):
- l, b, w, h = self.figure.bbox.bounds
- key = w, h, self.figure.dpi
- try: self._lastKey, self.renderer
- except AttributeError: need_new_renderer = True
- else: need_new_renderer = (self._lastKey != key)
-
- if need_new_renderer:
- self.renderer = RendererAgg(w, h, self.figure.dpi)
- self._lastKey = key
- elif cleared:
- self.renderer.clear()
- return self.renderer
-
- def tostring_rgb(self):
- if __debug__: verbose.report('FigureCanvasAgg.tostring_rgb',
- 'debug-annoying')
- return self.renderer.tostring_rgb()
-
- def tostring_argb(self):
- if __debug__: verbose.report('FigureCanvasAgg.tostring_argb',
- 'debug-annoying')
- return self.renderer.tostring_argb()
-
- def buffer_rgba(self):
- if __debug__: verbose.report('FigureCanvasAgg.buffer_rgba',
- 'debug-annoying')
- return self.renderer.buffer_rgba()
-
- def print_raw(self, filename_or_obj, *args, **kwargs):
- FigureCanvasAgg.draw(self)
- renderer = self.get_renderer()
- original_dpi = renderer.dpi
- renderer.dpi = self.figure.dpi
- if is_string_like(filename_or_obj):
- filename_or_obj = open(filename_or_obj, 'wb')
- close = True
- else:
- close = False
- try:
- renderer._renderer.write_rgba(filename_or_obj)
- finally:
- if close:
- filename_or_obj.close()
- renderer.dpi = original_dpi
- print_rgba = print_raw
-
- def print_png(self, filename_or_obj, *args, **kwargs):
- FigureCanvasAgg.draw(self)
- renderer = self.get_renderer()
- original_dpi = renderer.dpi
- renderer.dpi = self.figure.dpi
- if is_string_like(filename_or_obj):
- filename_or_obj = open(filename_or_obj, 'wb')
- close = True
- else:
- close = False
- try:
- _png.write_png(renderer._renderer.buffer_rgba(),
- renderer.width, renderer.height,
- filename_or_obj, self.figure.dpi)
- finally:
- if close:
- filename_or_obj.close()
- renderer.dpi = original_dpi
-
- def print_to_buffer(self):
- FigureCanvasAgg.draw(self)
- renderer = self.get_renderer()
- original_dpi = renderer.dpi
- renderer.dpi = self.figure.dpi
- result = (renderer._renderer.buffer_rgba(),
- (int(renderer.width), int(renderer.height)))
- renderer.dpi = original_dpi
- return result
-
- if _has_pil:
-
- # add JPEG support
- def print_jpg(self, filename_or_obj, *args, **kwargs):
- """
- Supported kwargs:
-
- *quality*: The image quality, on a scale from 1 (worst) to
- 95 (best). The default is 95, if not given in the
- matplotlibrc file in the savefig.jpeg_quality parameter.
- Values above 95 should be avoided; 100 completely
- disables the JPEG quantization stage.
-
- *optimize*: If present, indicates that the encoder should
- make an extra pass over the image in order to select
- optimal encoder settings.
-
- *progressive*: If present, indicates that this image
- should be stored as a progressive JPEG file.
- """
- buf, size = self.print_to_buffer()
- if kwargs.pop("dryrun", False):
- return
- image = Image.frombuffer('RGBA', size, buf, 'raw', 'RGBA', 0, 1)
- options = restrict_dict(kwargs, ['quality', 'optimize',
- 'progressive'])
-
- if 'quality' not in options:
- options['quality'] = rcParams['savefig.jpeg_quality']
-
- return image.save(filename_or_obj, format='jpeg', **options)
- print_jpeg = print_jpg
-
- # add TIFF support
- def print_tif(self, filename_or_obj, *args, **kwargs):
- buf, size = self.print_to_buffer()
- if kwargs.pop("dryrun", False):
- return
- image = Image.frombuffer('RGBA', size, buf, 'raw', 'RGBA', 0, 1)
- dpi = (self.figure.dpi, self.figure.dpi)
- return image.save(filename_or_obj, format='tiff',
- dpi=dpi)
- print_tiff = print_tif
-
-
-FigureCanvas = FigureCanvasAgg
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_cairo.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_cairo.py
deleted file mode 100644
index d71c73f..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_cairo.py
+++ /dev/null
@@ -1,530 +0,0 @@
-"""
-A Cairo backend for matplotlib
-Author: Steve Chaplin
-
-Cairo is a vector graphics library with cross-device output support.
-Features of Cairo:
- * anti-aliasing
- * alpha channel
- * saves image files as PNG, PostScript, PDF
-
-http://cairographics.org
-Requires (in order, all available from Cairo website):
- cairo, pycairo
-
-Naming Conventions
- * classes MixedUpperCase
- * varables lowerUpper
- * functions underscore_separated
-"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import os, sys, warnings, gzip
-
-import numpy as np
-
-def _fn_name(): return sys._getframe(1).f_code.co_name
-
-try:
- import cairocffi as cairo
-except ImportError:
- try:
- import cairo
- except ImportError:
- raise ImportError("Cairo backend requires that cairocffi or pycairo is installed.")
- else:
- HAS_CAIRO_CFFI = False
-else:
- HAS_CAIRO_CFFI = True
-
-_version_required = (1,2,0)
-if cairo.version_info < _version_required:
- raise ImportError ("Pycairo %d.%d.%d is installed\n"
- "Pycairo %d.%d.%d or later is required"
- % (cairo.version_info + _version_required))
-backend_version = cairo.version
-del _version_required
-
-from matplotlib.backend_bases import RendererBase, GraphicsContextBase,\
- FigureManagerBase, FigureCanvasBase
-from matplotlib.cbook import is_string_like
-from matplotlib.figure import Figure
-from matplotlib.mathtext import MathTextParser
-from matplotlib.path import Path
-from matplotlib.transforms import Bbox, Affine2D
-from matplotlib.font_manager import ttfFontProperty
-
-_debug = False
-#_debug = True
-
-# Image::color_conv(format) for draw_image()
-if sys.byteorder == 'little':
- BYTE_FORMAT = 0 # BGRA
-else:
- BYTE_FORMAT = 1 # ARGB
-
-
-class RendererCairo(RendererBase):
- fontweights = {
- 100 : cairo.FONT_WEIGHT_NORMAL,
- 200 : cairo.FONT_WEIGHT_NORMAL,
- 300 : cairo.FONT_WEIGHT_NORMAL,
- 400 : cairo.FONT_WEIGHT_NORMAL,
- 500 : cairo.FONT_WEIGHT_NORMAL,
- 600 : cairo.FONT_WEIGHT_BOLD,
- 700 : cairo.FONT_WEIGHT_BOLD,
- 800 : cairo.FONT_WEIGHT_BOLD,
- 900 : cairo.FONT_WEIGHT_BOLD,
- 'ultralight' : cairo.FONT_WEIGHT_NORMAL,
- 'light' : cairo.FONT_WEIGHT_NORMAL,
- 'normal' : cairo.FONT_WEIGHT_NORMAL,
- 'medium' : cairo.FONT_WEIGHT_NORMAL,
- 'semibold' : cairo.FONT_WEIGHT_BOLD,
- 'bold' : cairo.FONT_WEIGHT_BOLD,
- 'heavy' : cairo.FONT_WEIGHT_BOLD,
- 'ultrabold' : cairo.FONT_WEIGHT_BOLD,
- 'black' : cairo.FONT_WEIGHT_BOLD,
- }
- fontangles = {
- 'italic' : cairo.FONT_SLANT_ITALIC,
- 'normal' : cairo.FONT_SLANT_NORMAL,
- 'oblique' : cairo.FONT_SLANT_OBLIQUE,
- }
-
-
- def __init__(self, dpi):
- """
- """
- if _debug: print('%s.%s()' % (self.__class__.__name__, _fn_name()))
- self.dpi = dpi
- self.gc = GraphicsContextCairo (renderer=self)
- self.text_ctx = cairo.Context (
- cairo.ImageSurface (cairo.FORMAT_ARGB32,1,1))
- self.mathtext_parser = MathTextParser('Cairo')
-
- RendererBase.__init__(self)
-
- def set_ctx_from_surface (self, surface):
- self.gc.ctx = cairo.Context (surface)
-
-
- def set_width_height(self, width, height):
- self.width = width
- self.height = height
- self.matrix_flipy = cairo.Matrix (yy=-1, y0=self.height)
- # use matrix_flipy for ALL rendering?
- # - problem with text? - will need to switch matrix_flipy off, or do a
- # font transform?
-
-
- def _fill_and_stroke (self, ctx, fill_c, alpha, alpha_overrides):
- if fill_c is not None:
- ctx.save()
- if len(fill_c) == 3 or alpha_overrides:
- ctx.set_source_rgba (fill_c[0], fill_c[1], fill_c[2], alpha)
- else:
- ctx.set_source_rgba (fill_c[0], fill_c[1], fill_c[2], fill_c[3])
- ctx.fill_preserve()
- ctx.restore()
- ctx.stroke()
-
- @staticmethod
- def convert_path(ctx, path, transform):
- for points, code in path.iter_segments(transform):
- if code == Path.MOVETO:
- ctx.move_to(*points)
- elif code == Path.CLOSEPOLY:
- ctx.close_path()
- elif code == Path.LINETO:
- ctx.line_to(*points)
- elif code == Path.CURVE3:
- ctx.curve_to(points[0], points[1],
- points[0], points[1],
- points[2], points[3])
- elif code == Path.CURVE4:
- ctx.curve_to(*points)
-
-
- def draw_path(self, gc, path, transform, rgbFace=None):
- if len(path.vertices) > 18980:
- raise ValueError("The Cairo backend can not draw paths longer than 18980 points.")
-
- ctx = gc.ctx
-
- transform = transform + \
- Affine2D().scale(1.0, -1.0).translate(0, self.height)
-
- ctx.new_path()
- self.convert_path(ctx, path, transform)
-
- self._fill_and_stroke(ctx, rgbFace, gc.get_alpha(), gc.get_forced_alpha())
-
- def draw_image(self, gc, x, y, im):
- # bbox - not currently used
- if _debug: print('%s.%s()' % (self.__class__.__name__, _fn_name()))
-
- im.flipud_out()
-
- rows, cols, buf = im.color_conv (BYTE_FORMAT)
- surface = cairo.ImageSurface.create_for_data (
- buf, cairo.FORMAT_ARGB32, cols, rows, cols*4)
- ctx = gc.ctx
- y = self.height - y - rows
-
- ctx.save()
- ctx.set_source_surface (surface, x, y)
- if gc.get_alpha() != 1.0:
- ctx.paint_with_alpha(gc.get_alpha())
- else:
- ctx.paint()
- ctx.restore()
-
- im.flipud_out()
-
- def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
- # Note: x,y are device/display coords, not user-coords, unlike other
- # draw_* methods
- if _debug: print('%s.%s()' % (self.__class__.__name__, _fn_name()))
-
- if ismath:
- self._draw_mathtext(gc, x, y, s, prop, angle)
-
- else:
- ctx = gc.ctx
- ctx.new_path()
- ctx.move_to (x, y)
- ctx.select_font_face (prop.get_name(),
- self.fontangles [prop.get_style()],
- self.fontweights[prop.get_weight()])
-
- size = prop.get_size_in_points() * self.dpi / 72.0
-
- ctx.save()
- if angle:
- ctx.rotate (-angle * np.pi / 180)
- ctx.set_font_size (size)
-
- if HAS_CAIRO_CFFI:
- if not isinstance(s, six.text_type):
- s = six.text_type(s)
- else:
- if not six.PY3 and isinstance(s, six.text_type):
- s = s.encode("utf-8")
-
- ctx.show_text(s)
- ctx.restore()
-
- def _draw_mathtext(self, gc, x, y, s, prop, angle):
- if _debug: print('%s.%s()' % (self.__class__.__name__, _fn_name()))
-
- ctx = gc.ctx
- width, height, descent, glyphs, rects = self.mathtext_parser.parse(
- s, self.dpi, prop)
-
- ctx.save()
- ctx.translate(x, y)
- if angle:
- ctx.rotate (-angle * np.pi / 180)
-
- for font, fontsize, s, ox, oy in glyphs:
- ctx.new_path()
- ctx.move_to(ox, oy)
-
- fontProp = ttfFontProperty(font)
- ctx.save()
- ctx.select_font_face (fontProp.name,
- self.fontangles [fontProp.style],
- self.fontweights[fontProp.weight])
-
- size = fontsize * self.dpi / 72.0
- ctx.set_font_size(size)
- if isinstance(s, six.text_type):
- s = s.encode("utf-8")
- ctx.show_text(s)
- ctx.restore()
-
- for ox, oy, w, h in rects:
- ctx.new_path()
- ctx.rectangle (ox, oy, w, h)
- ctx.set_source_rgb (0, 0, 0)
- ctx.fill_preserve()
-
- ctx.restore()
-
-
- def flipy(self):
- if _debug: print('%s.%s()' % (self.__class__.__name__, _fn_name()))
- return True
- #return False # tried - all draw objects ok except text (and images?)
- # which comes out mirrored!
-
-
- def get_canvas_width_height(self):
- if _debug: print('%s.%s()' % (self.__class__.__name__, _fn_name()))
- return self.width, self.height
-
-
- def get_text_width_height_descent(self, s, prop, ismath):
- if _debug: print('%s.%s()' % (self.__class__.__name__, _fn_name()))
- if ismath:
- width, height, descent, fonts, used_characters = self.mathtext_parser.parse(
- s, self.dpi, prop)
- return width, height, descent
-
- ctx = self.text_ctx
- ctx.save()
- ctx.select_font_face (prop.get_name(),
- self.fontangles [prop.get_style()],
- self.fontweights[prop.get_weight()])
-
- # Cairo (says it) uses 1/96 inch user space units, ref: cairo_gstate.c
- # but if /96.0 is used the font is too small
-
- size = prop.get_size_in_points() * self.dpi / 72.0
-
- # problem - scale remembers last setting and font can become
- # enormous causing program to crash
- # save/restore prevents the problem
- ctx.set_font_size (size)
-
- y_bearing, w, h = ctx.text_extents (s)[1:4]
- ctx.restore()
-
- return w, h, h + y_bearing
-
-
- def new_gc(self):
- if _debug: print('%s.%s()' % (self.__class__.__name__, _fn_name()))
- self.gc.ctx.save()
- self.gc._alpha = 1.0
- self.gc._forced_alpha = False # if True, _alpha overrides A from RGBA
- return self.gc
-
-
- def points_to_pixels(self, points):
- if _debug: print('%s.%s()' % (self.__class__.__name__, _fn_name()))
- return points/72.0 * self.dpi
-
-
-class GraphicsContextCairo(GraphicsContextBase):
- _joind = {
- 'bevel' : cairo.LINE_JOIN_BEVEL,
- 'miter' : cairo.LINE_JOIN_MITER,
- 'round' : cairo.LINE_JOIN_ROUND,
- }
-
- _capd = {
- 'butt' : cairo.LINE_CAP_BUTT,
- 'projecting' : cairo.LINE_CAP_SQUARE,
- 'round' : cairo.LINE_CAP_ROUND,
- }
-
-
- def __init__(self, renderer):
- GraphicsContextBase.__init__(self)
- self.renderer = renderer
-
-
- def restore(self):
- self.ctx.restore()
-
-
- def set_alpha(self, alpha):
- GraphicsContextBase.set_alpha(self, alpha)
- _alpha = self.get_alpha()
- rgb = self._rgb
- if self.get_forced_alpha():
- self.ctx.set_source_rgba (rgb[0], rgb[1], rgb[2], _alpha)
- else:
- self.ctx.set_source_rgba (rgb[0], rgb[1], rgb[2], rgb[3])
-
-
- #def set_antialiased(self, b):
- # enable/disable anti-aliasing is not (yet) supported by Cairo
-
-
- def set_capstyle(self, cs):
- if cs in ('butt', 'round', 'projecting'):
- self._capstyle = cs
- self.ctx.set_line_cap (self._capd[cs])
- else:
- raise ValueError('Unrecognized cap style. Found %s' % cs)
-
-
- def set_clip_rectangle(self, rectangle):
- if not rectangle: return
- x,y,w,h = rectangle.bounds
- # pixel-aligned clip-regions are faster
- x,y,w,h = round(x), round(y), round(w), round(h)
- ctx = self.ctx
- ctx.new_path()
- ctx.rectangle (x, self.renderer.height - h - y, w, h)
- ctx.clip ()
-
- def set_clip_path(self, path):
- if not path: return
- tpath, affine = path.get_transformed_path_and_affine()
- ctx = self.ctx
- ctx.new_path()
- affine = affine + Affine2D().scale(1.0, -1.0).translate(0.0, self.renderer.height)
- RendererCairo.convert_path(ctx, tpath, affine)
- ctx.clip()
-
- def set_dashes(self, offset, dashes):
- self._dashes = offset, dashes
- if dashes == None:
- self.ctx.set_dash([], 0) # switch dashes off
- else:
- self.ctx.set_dash(
- list(self.renderer.points_to_pixels(np.asarray(dashes))), offset)
-
-
- def set_foreground(self, fg, isRGBA=None):
- GraphicsContextBase.set_foreground(self, fg, isRGBA)
- if len(self._rgb) == 3:
- self.ctx.set_source_rgb(*self._rgb)
- else:
- self.ctx.set_source_rgba(*self._rgb)
-
- def set_graylevel(self, frac):
- GraphicsContextBase.set_graylevel(self, frac)
- if len(self._rgb) == 3:
- self.ctx.set_source_rgb(*self._rgb)
- else:
- self.ctx.set_source_rgba(*self._rgb)
-
-
- def set_joinstyle(self, js):
- if js in ('miter', 'round', 'bevel'):
- self._joinstyle = js
- self.ctx.set_line_join(self._joind[js])
- else:
- raise ValueError('Unrecognized join style. Found %s' % js)
-
-
- def set_linewidth(self, w):
- self._linewidth = w
- self.ctx.set_line_width (self.renderer.points_to_pixels(w))
-
-
-def new_figure_manager(num, *args, **kwargs): # called by backends/__init__.py
- """
- Create a new figure manager instance
- """
- if _debug: print('%s()' % (_fn_name()))
- FigureClass = kwargs.pop('FigureClass', Figure)
- thisFig = FigureClass(*args, **kwargs)
- return new_figure_manager_given_figure(num, thisFig)
-
-
-def new_figure_manager_given_figure(num, figure):
- """
- Create a new figure manager instance for the given figure.
- """
- canvas = FigureCanvasCairo(figure)
- manager = FigureManagerBase(canvas, num)
- return manager
-
-
-class FigureCanvasCairo (FigureCanvasBase):
- def print_png(self, fobj, *args, **kwargs):
- width, height = self.get_width_height()
-
- renderer = RendererCairo (self.figure.dpi)
- renderer.set_width_height (width, height)
- surface = cairo.ImageSurface (cairo.FORMAT_ARGB32, width, height)
- renderer.set_ctx_from_surface (surface)
-
- self.figure.draw (renderer)
- surface.write_to_png (fobj)
-
- def print_pdf(self, fobj, *args, **kwargs):
- return self._save(fobj, 'pdf', *args, **kwargs)
-
- def print_ps(self, fobj, *args, **kwargs):
- return self._save(fobj, 'ps', *args, **kwargs)
-
- def print_svg(self, fobj, *args, **kwargs):
- return self._save(fobj, 'svg', *args, **kwargs)
-
- def print_svgz(self, fobj, *args, **kwargs):
- return self._save(fobj, 'svgz', *args, **kwargs)
-
- def _save (self, fo, format, **kwargs):
- # save PDF/PS/SVG
- orientation = kwargs.get('orientation', 'portrait')
-
- dpi = 72
- self.figure.dpi = dpi
- w_in, h_in = self.figure.get_size_inches()
- width_in_points, height_in_points = w_in * dpi, h_in * dpi
-
- if orientation == 'landscape':
- width_in_points, height_in_points = (height_in_points,
- width_in_points)
-
- if format == 'ps':
- if not hasattr(cairo, 'PSSurface'):
- raise RuntimeError ('cairo has not been compiled with PS '
- 'support enabled')
- surface = cairo.PSSurface (fo, width_in_points, height_in_points)
- elif format == 'pdf':
- if not hasattr(cairo, 'PDFSurface'):
- raise RuntimeError ('cairo has not been compiled with PDF '
- 'support enabled')
- surface = cairo.PDFSurface (fo, width_in_points, height_in_points)
- elif format in ('svg', 'svgz'):
- if not hasattr(cairo, 'SVGSurface'):
- raise RuntimeError ('cairo has not been compiled with SVG '
- 'support enabled')
- if format == 'svgz':
- if is_string_like(fo):
- fo = gzip.GzipFile(fo, 'wb')
- else:
- fo = gzip.GzipFile(None, 'wb', fileobj=fo)
- surface = cairo.SVGSurface (fo, width_in_points, height_in_points)
- else:
- warnings.warn ("unknown format: %s" % format)
- return
-
- # surface.set_dpi() can be used
- renderer = RendererCairo (self.figure.dpi)
- renderer.set_width_height (width_in_points, height_in_points)
- renderer.set_ctx_from_surface (surface)
- ctx = renderer.gc.ctx
-
- if orientation == 'landscape':
- ctx.rotate (np.pi/2)
- ctx.translate (0, -height_in_points)
- # cairo/src/cairo_ps_surface.c
- # '%%Orientation: Portrait' is always written to the file header
- # '%%Orientation: Landscape' would possibly cause problems
- # since some printers would rotate again ?
- # TODO:
- # add portrait/landscape checkbox to FileChooser
-
- self.figure.draw (renderer)
-
- show_fig_border = False # for testing figure orientation and scaling
- if show_fig_border:
- ctx.new_path()
- ctx.rectangle(0, 0, width_in_points, height_in_points)
- ctx.set_line_width(4.0)
- ctx.set_source_rgb(1,0,0)
- ctx.stroke()
- ctx.move_to(30,30)
- ctx.select_font_face ('sans-serif')
- ctx.set_font_size(20)
- ctx.show_text('Origin corner')
-
- ctx.show_page()
- surface.finish()
- if format == 'svgz':
- fo.close()
-
-
-FigureCanvas = FigureCanvasCairo
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_cocoaagg.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_cocoaagg.py
deleted file mode 100644
index 2a9fb6b..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_cocoaagg.py
+++ /dev/null
@@ -1,306 +0,0 @@
-"""
- backend_cocoaagg.py
-
- A native Cocoa backend via PyObjC in OSX.
-
- Author: Charles Moad (cmoad@users.sourceforge.net)
-
- Notes:
- - Requires PyObjC (currently testing v1.3.7)
- - The Tk backend works nicely on OSX. This code
- primarily serves as an example of embedding a
- matplotlib rendering context into a cocoa app
- using a NSImageView.
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import xrange
-
-import os, sys
-
-try:
- import objc
-except ImportError:
- raise ImportError('The CococaAgg backend required PyObjC to be installed!')
-
-from Foundation import *
-from AppKit import *
-from PyObjCTools import NibClassBuilder, AppHelper
-
-from matplotlib import cbook
-cbook.warn_deprecated(
- '1.3',
- message="The CocoaAgg backend is not a fully-functioning backend. "
- "It may be removed in matplotlib 1.4.")
-
-import matplotlib
-from matplotlib.figure import Figure
-from matplotlib.backend_bases import FigureManagerBase, FigureCanvasBase
-from matplotlib.backend_bases import ShowBase
-
-from .backend_agg import FigureCanvasAgg
-from matplotlib._pylab_helpers import Gcf
-
-mplBundle = NSBundle.bundleWithPath_(os.path.dirname(__file__))
-
-
-def new_figure_manager(num, *args, **kwargs):
- FigureClass = kwargs.pop('FigureClass', Figure)
- thisFig = FigureClass( *args, **kwargs )
- return new_figure_manager_given_figure(num, thisFig)
-
-
-def new_figure_manager_given_figure(num, figure):
- """
- Create a new figure manager instance for the given figure.
- """
- canvas = FigureCanvasCocoaAgg(figure)
- return FigureManagerCocoaAgg(canvas, num)
-
-
-## Below is the original show() function:
-#def show():
-# for manager in Gcf.get_all_fig_managers():
-# manager.show()
-#
-## It appears that this backend is unusual in having a separate
-## run function invoked for each figure, instead of a single
-## mainloop. Presumably there is no blocking at all.
-##
-## Using the Show class below should cause no difference in
-## behavior.
-
-class Show(ShowBase):
- def mainloop(self):
- pass
-
-show = Show()
-
-def draw_if_interactive():
- if matplotlib.is_interactive():
- figManager = Gcf.get_active()
- if figManager is not None:
- figManager.show()
-
-class FigureCanvasCocoaAgg(FigureCanvasAgg):
- def draw(self):
- FigureCanvasAgg.draw(self)
-
- def blit(self, bbox):
- pass
-
- def start_event_loop(self,timeout):
- FigureCanvasBase.start_event_loop_default(self,timeout)
- start_event_loop.__doc__=FigureCanvasBase.start_event_loop_default.__doc__
-
- def stop_event_loop(self):
- FigureCanvasBase.stop_event_loop_default(self)
- stop_event_loop.__doc__=FigureCanvasBase.stop_event_loop_default.__doc__
-
-
-
-NibClassBuilder.extractClasses('Matplotlib.nib', mplBundle)
-
-class MatplotlibController(NibClassBuilder.AutoBaseClass):
- # available outlets:
- # NSWindow plotWindow
- # PlotView plotView
-
- def awakeFromNib(self):
- # Get a reference to the active canvas
- NSApp().setDelegate_(self)
- self.app = NSApp()
- self.canvas = Gcf.get_active().canvas
- self.plotView.canvas = self.canvas
- self.canvas.plotView = self.plotView
-
- self.plotWindow.setAcceptsMouseMovedEvents_(True)
- self.plotWindow.makeKeyAndOrderFront_(self)
- self.plotWindow.setDelegate_(self)#.plotView)
-
- self.plotView.setImageFrameStyle_(NSImageFrameGroove)
- self.plotView.image_ = NSImage.alloc().initWithSize_((0,0))
- self.plotView.setImage_(self.plotView.image_)
-
- # Make imageview first responder for key events
- self.plotWindow.makeFirstResponder_(self.plotView)
-
- # Force the first update
- self.plotView.windowDidResize_(self)
-
- def windowDidResize_(self, sender):
- self.plotView.windowDidResize_(sender)
-
- def windowShouldClose_(self, sender):
- #NSApplication.sharedApplication().stop_(self)
- self.app.stop_(self)
- return objc.YES
-
- def saveFigure_(self, sender):
- p = NSSavePanel.savePanel()
- if(p.runModal() == NSFileHandlingPanelOKButton):
- self.canvas.print_figure(p.filename())
-
- def printFigure_(self, sender):
- op = NSPrintOperation.printOperationWithView_(self.plotView)
- op.runOperation()
-
-class PlotWindow(NibClassBuilder.AutoBaseClass):
- pass
-
-class PlotView(NibClassBuilder.AutoBaseClass):
- def updatePlot(self):
- w,h = self.canvas.get_width_height()
-
- # Remove all previous images
- for i in xrange(self.image_.representations().count()):
- self.image_.removeRepresentation_(self.image_.representations().objectAtIndex_(i))
-
- self.image_.setSize_((w,h))
-
- brep = NSBitmapImageRep.alloc().initWithBitmapDataPlanes_pixelsWide_pixelsHigh_bitsPerSample_samplesPerPixel_hasAlpha_isPlanar_colorSpaceName_bytesPerRow_bitsPerPixel_(
- (self.canvas.buffer_rgba(),'','','',''), # Image data
- w, # width
- h, # height
- 8, # bits per pixel
- 4, # components per pixel
- True, # has alpha?
- False, # is planar?
- NSCalibratedRGBColorSpace, # color space
- w*4, # row bytes
- 32) # bits per pixel
-
- self.image_.addRepresentation_(brep)
- self.setNeedsDisplay_(True)
-
- def windowDidResize_(self, sender):
- w,h = self.bounds().size
- dpi = self.canvas.figure.dpi
- self.canvas.figure.set_size_inches(w / dpi, h / dpi)
- self.canvas.draw()
- self.updatePlot()
-
- def mouseDown_(self, event):
- dblclick = (event.clickCount() == 2)
- loc = self.convertPoint_fromView_(event.locationInWindow(), None)
- type = event.type()
- if (type == NSLeftMouseDown):
- button = 1
- else:
- print('Unknown mouse event type:', type, file=sys.stderr)
- button = -1
- self.canvas.button_press_event(loc.x, loc.y, button, dblclick=dblclick)
- self.updatePlot()
-
- def mouseDragged_(self, event):
- loc = self.convertPoint_fromView_(event.locationInWindow(), None)
- self.canvas.motion_notify_event(loc.x, loc.y)
- self.updatePlot()
-
- def mouseUp_(self, event):
- loc = self.convertPoint_fromView_(event.locationInWindow(), None)
- type = event.type()
- if (type == NSLeftMouseUp):
- button = 1
- else:
- print('Unknown mouse event type:', type, file=sys.stderr)
- button = -1
- self.canvas.button_release_event(loc.x, loc.y, button)
- self.updatePlot()
-
- def keyDown_(self, event):
- self.canvas.key_press_event(event.characters())
- self.updatePlot()
-
- def keyUp_(self, event):
- self.canvas.key_release_event(event.characters())
- self.updatePlot()
-
-class MPLBootstrap(NSObject):
- # Loads the nib containing the PlotWindow and PlotView
- def startWithBundle_(self, bundle):
- #NSApplicationLoad()
- if not bundle.loadNibFile_externalNameTable_withZone_('Matplotlib.nib', {}, None):
- print('Unable to load Matplotlib Cocoa UI!', file=sys.stderr)
- sys.exit()
-
-class FigureManagerCocoaAgg(FigureManagerBase):
- def __init__(self, canvas, num):
- FigureManagerBase.__init__(self, canvas, num)
-
- try:
- WMEnable('Matplotlib')
- except:
- # MULTIPLE FIGURES ARE BUGGY!
- pass # If there are multiple figures we only need to enable once
- #self.bootstrap = MPLBootstrap.alloc().init().performSelectorOnMainThread_withObject_waitUntilDone_(
- # 'startWithBundle:',
- # mplBundle,
- # False)
-
- def show(self):
- # Load a new PlotWindow
- self.bootstrap = MPLBootstrap.alloc().init().performSelectorOnMainThread_withObject_waitUntilDone_(
- 'startWithBundle:',
- mplBundle,
- False)
- NSApplication.sharedApplication().run()
-
-
-#### Everything below taken from PyObjC examples
-#### This is a hack to allow python scripts to access
-#### the window manager without running pythonw.
-def S(*args):
- return ''.join(args)
-
-OSErr = objc._C_SHT
-OUTPSN = 'o^{ProcessSerialNumber=LL}'
-INPSN = 'n^{ProcessSerialNumber=LL}'
-FUNCTIONS=[
- # These two are public API
- ( 'GetCurrentProcess', S(OSErr, OUTPSN) ),
- ( 'SetFrontProcess', S(OSErr, INPSN) ),
- # This is undocumented SPI
- ( 'CPSSetProcessName', S(OSErr, INPSN, objc._C_CHARPTR) ),
- ( 'CPSEnableForegroundOperation', S(OSErr, INPSN) ),
-]
-def WMEnable(name='Python'):
- if isinstance(name, six.text_type):
- name = name.encode('utf8')
- mainBundle = NSBundle.mainBundle()
- bPath = os.path.split(os.path.split(os.path.split(sys.executable)[0])[0])[0]
- if mainBundle.bundlePath() == bPath:
- return True
- bndl = NSBundle.bundleWithPath_(objc.pathForFramework('/System/Library/Frameworks/ApplicationServices.framework'))
- if bndl is None:
- print('ApplicationServices missing', file=sys.stderr)
- return False
- d = {}
- objc.loadBundleFunctions(bndl, d, FUNCTIONS)
- for (fn, sig) in FUNCTIONS:
- if fn not in d:
- print('Missing', fn, file=sys.stderr)
- return False
- err, psn = d['GetCurrentProcess']()
- if err:
- print('GetCurrentProcess', (err, psn), file=sys.stderr)
- return False
- err = d['CPSSetProcessName'](psn, name)
- if err:
- print('CPSSetProcessName', (err, psn), file=sys.stderr)
- return False
- err = d['CPSEnableForegroundOperation'](psn)
- if err:
- #print >>sys.stderr, 'CPSEnableForegroundOperation', (err, psn)
- return False
- err = d['SetFrontProcess'](psn)
- if err:
- print('SetFrontProcess', (err, psn), file=sys.stderr)
- return False
- return True
-
-
-FigureCanvas = FigureCanvasCocoaAgg
-FigureManager = FigureManagerCocoaAgg
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_gdk.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_gdk.py
deleted file mode 100644
index fc705fe..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_gdk.py
+++ /dev/null
@@ -1,486 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import math
-import os
-import sys
-import warnings
-def fn_name(): return sys._getframe(1).f_code.co_name
-
-import gobject
-import gtk; gdk = gtk.gdk
-import pango
-pygtk_version_required = (2,2,0)
-if gtk.pygtk_version < pygtk_version_required:
- raise ImportError ("PyGTK %d.%d.%d is installed\n"
- "PyGTK %d.%d.%d or later is required"
- % (gtk.pygtk_version + pygtk_version_required))
-del pygtk_version_required
-
-import numpy as np
-
-import matplotlib
-from matplotlib import rcParams
-from matplotlib._pylab_helpers import Gcf
-from matplotlib.backend_bases import RendererBase, GraphicsContextBase, \
- FigureManagerBase, FigureCanvasBase
-from matplotlib.cbook import is_string_like
-from matplotlib.figure import Figure
-from matplotlib.mathtext import MathTextParser
-from matplotlib.transforms import Affine2D
-from matplotlib.backends._backend_gdk import pixbuf_get_pixels_array
-
-backend_version = "%d.%d.%d" % gtk.pygtk_version
-_debug = False
-
-# Image formats that this backend supports - for FileChooser and print_figure()
-IMAGE_FORMAT = ['eps', 'jpg', 'png', 'ps', 'svg'] + ['bmp'] # , 'raw', 'rgb']
-IMAGE_FORMAT.sort()
-IMAGE_FORMAT_DEFAULT = 'png'
-
-
-class RendererGDK(RendererBase):
- fontweights = {
- 100 : pango.WEIGHT_ULTRALIGHT,
- 200 : pango.WEIGHT_LIGHT,
- 300 : pango.WEIGHT_LIGHT,
- 400 : pango.WEIGHT_NORMAL,
- 500 : pango.WEIGHT_NORMAL,
- 600 : pango.WEIGHT_BOLD,
- 700 : pango.WEIGHT_BOLD,
- 800 : pango.WEIGHT_HEAVY,
- 900 : pango.WEIGHT_ULTRABOLD,
- 'ultralight' : pango.WEIGHT_ULTRALIGHT,
- 'light' : pango.WEIGHT_LIGHT,
- 'normal' : pango.WEIGHT_NORMAL,
- 'medium' : pango.WEIGHT_NORMAL,
- 'semibold' : pango.WEIGHT_BOLD,
- 'bold' : pango.WEIGHT_BOLD,
- 'heavy' : pango.WEIGHT_HEAVY,
- 'ultrabold' : pango.WEIGHT_ULTRABOLD,
- 'black' : pango.WEIGHT_ULTRABOLD,
- }
-
- # cache for efficiency, these must be at class, not instance level
- layoutd = {} # a map from text prop tups to pango layouts
- rotated = {} # a map from text prop tups to rotated text pixbufs
-
- def __init__(self, gtkDA, dpi):
- # widget gtkDA is used for:
- # '.create_pango_layout(s)'
- # cmap line below)
- self.gtkDA = gtkDA
- self.dpi = dpi
- self._cmap = gtkDA.get_colormap()
- self.mathtext_parser = MathTextParser("Agg")
-
- def set_pixmap (self, pixmap):
- self.gdkDrawable = pixmap
-
- def set_width_height (self, width, height):
- """w,h is the figure w,h not the pixmap w,h
- """
- self.width, self.height = width, height
-
- def draw_path(self, gc, path, transform, rgbFace=None):
- transform = transform + Affine2D(). \
- scale(1.0, -1.0).translate(0, self.height)
- polygons = path.to_polygons(transform, self.width, self.height)
- for polygon in polygons:
- # draw_polygon won't take an arbitrary sequence -- it must be a list
- # of tuples
- polygon = [(int(round(x)), int(round(y))) for x, y in polygon]
- if rgbFace is not None:
- saveColor = gc.gdkGC.foreground
- gc.gdkGC.foreground = gc.rgb_to_gdk_color(rgbFace)
- self.gdkDrawable.draw_polygon(gc.gdkGC, True, polygon)
- gc.gdkGC.foreground = saveColor
- if gc.gdkGC.line_width > 0:
- self.gdkDrawable.draw_lines(gc.gdkGC, polygon)
-
- def draw_image(self, gc, x, y, im):
- bbox = gc.get_clip_rectangle()
-
- if bbox != None:
- l,b,w,h = bbox.bounds
- #rectangle = (int(l), self.height-int(b+h),
- # int(w), int(h))
- # set clip rect?
-
- im.flipud_out()
- rows, cols, image_str = im.as_rgba_str()
-
- image_array = np.fromstring(image_str, np.uint8)
- image_array.shape = rows, cols, 4
-
- pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB,
- has_alpha=True, bits_per_sample=8,
- width=cols, height=rows)
-
- array = pixbuf_get_pixels_array(pixbuf)
- array[:,:,:] = image_array
-
- gc = self.new_gc()
-
-
- y = self.height-y-rows
-
- try: # new in 2.2
- # can use None instead of gc.gdkGC, if don't need clipping
- self.gdkDrawable.draw_pixbuf (gc.gdkGC, pixbuf, 0, 0,
- int(x), int(y), cols, rows,
- gdk.RGB_DITHER_NONE, 0, 0)
- except AttributeError:
- # deprecated in 2.2
- pixbuf.render_to_drawable(self.gdkDrawable, gc.gdkGC, 0, 0,
- int(x), int(y), cols, rows,
- gdk.RGB_DITHER_NONE, 0, 0)
-
- # unflip
- im.flipud_out()
-
-
- def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
- x, y = int(x), int(y)
-
- if x < 0 or y < 0: # window has shrunk and text is off the edge
- return
-
- if angle not in (0,90):
- warnings.warn('backend_gdk: unable to draw text at angles ' +
- 'other than 0 or 90')
- elif ismath:
- self._draw_mathtext(gc, x, y, s, prop, angle)
-
- elif angle==90:
- self._draw_rotated_text(gc, x, y, s, prop, angle)
-
- else:
- layout, inkRect, logicalRect = self._get_pango_layout(s, prop)
- l, b, w, h = inkRect
- if (x + w > self.width or y + h > self.height):
- return
-
- self.gdkDrawable.draw_layout(gc.gdkGC, x, y-h-b, layout)
-
-
- def _draw_mathtext(self, gc, x, y, s, prop, angle):
- ox, oy, width, height, descent, font_image, used_characters = \
- self.mathtext_parser.parse(s, self.dpi, prop)
-
- if angle==90:
- width, height = height, width
- x -= width
- y -= height
-
- imw = font_image.get_width()
- imh = font_image.get_height()
- N = imw * imh
-
- # a numpixels by num fonts array
- Xall = np.zeros((N,1), np.uint8)
-
- image_str = font_image.as_str()
- Xall[:,0] = np.fromstring(image_str, np.uint8)
-
- # get the max alpha at each pixel
- Xs = np.amax(Xall,axis=1)
-
- # convert it to it's proper shape
- Xs.shape = imh, imw
-
- pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, has_alpha=True,
- bits_per_sample=8, width=imw, height=imh)
-
- array = pixbuf_get_pixels_array(pixbuf)
-
- rgb = gc.get_rgb()
- array[:,:,0]=int(rgb[0]*255)
- array[:,:,1]=int(rgb[1]*255)
- array[:,:,2]=int(rgb[2]*255)
- array[:,:,3]=Xs
-
- try: # new in 2.2
- # can use None instead of gc.gdkGC, if don't need clipping
- self.gdkDrawable.draw_pixbuf (gc.gdkGC, pixbuf, 0, 0,
- int(x), int(y), imw, imh,
- gdk.RGB_DITHER_NONE, 0, 0)
- except AttributeError:
- # deprecated in 2.2
- pixbuf.render_to_drawable(self.gdkDrawable, gc.gdkGC, 0, 0,
- int(x), int(y), imw, imh,
- gdk.RGB_DITHER_NONE, 0, 0)
-
-
- def _draw_rotated_text(self, gc, x, y, s, prop, angle):
- """
- Draw the text rotated 90 degrees, other angles are not supported
- """
- # this function (and its called functions) is a bottleneck
- # Pango 1.6 supports rotated text, but pygtk 2.4.0 does not yet have
- # wrapper functions
- # GTK+ 2.6 pixbufs support rotation
-
- gdrawable = self.gdkDrawable
- ggc = gc.gdkGC
-
- layout, inkRect, logicalRect = self._get_pango_layout(s, prop)
- l, b, w, h = inkRect
- x = int(x-h)
- y = int(y-w)
-
- if (x < 0 or y < 0 or # window has shrunk and text is off the edge
- x + w > self.width or y + h > self.height):
- return
-
- key = (x,y,s,angle,hash(prop))
- imageVert = self.rotated.get(key)
- if imageVert != None:
- gdrawable.draw_image(ggc, imageVert, 0, 0, x, y, h, w)
- return
-
- imageBack = gdrawable.get_image(x, y, w, h)
- imageVert = gdrawable.get_image(x, y, h, w)
- imageFlip = gtk.gdk.Image(type=gdk.IMAGE_FASTEST,
- visual=gdrawable.get_visual(),
- width=w, height=h)
- if imageFlip == None or imageBack == None or imageVert == None:
- warnings.warn("Could not renderer vertical text")
- return
- imageFlip.set_colormap(self._cmap)
- for i in range(w):
- for j in range(h):
- imageFlip.put_pixel(i, j, imageVert.get_pixel(j,w-i-1) )
-
- gdrawable.draw_image(ggc, imageFlip, 0, 0, x, y, w, h)
- gdrawable.draw_layout(ggc, x, y-b, layout)
-
- imageIn = gdrawable.get_image(x, y, w, h)
- for i in range(w):
- for j in range(h):
- imageVert.put_pixel(j, i, imageIn.get_pixel(w-i-1,j) )
-
- gdrawable.draw_image(ggc, imageBack, 0, 0, x, y, w, h)
- gdrawable.draw_image(ggc, imageVert, 0, 0, x, y, h, w)
- self.rotated[key] = imageVert
-
-
- def _get_pango_layout(self, s, prop):
- """
- Create a pango layout instance for Text 's' with properties 'prop'.
- Return - pango layout (from cache if already exists)
-
- Note that pango assumes a logical DPI of 96
- Ref: pango/fonts.c/pango_font_description_set_size() manual page
- """
- # problem? - cache gets bigger and bigger, is never cleared out
- # two (not one) layouts are created for every text item s (then they
- # are cached) - why?
-
- key = self.dpi, s, hash(prop)
- value = self.layoutd.get(key)
- if value != None:
- return value
-
- size = prop.get_size_in_points() * self.dpi / 96.0
- size = round(size)
-
- font_str = '%s, %s %i' % (prop.get_name(), prop.get_style(), size,)
- font = pango.FontDescription(font_str)
-
- # later - add fontweight to font_str
- font.set_weight(self.fontweights[prop.get_weight()])
-
- layout = self.gtkDA.create_pango_layout(s)
- layout.set_font_description(font)
- inkRect, logicalRect = layout.get_pixel_extents()
-
- self.layoutd[key] = layout, inkRect, logicalRect
- return layout, inkRect, logicalRect
-
-
- def flipy(self):
- return True
-
- def get_canvas_width_height(self):
- return self.width, self.height
-
- def get_text_width_height_descent(self, s, prop, ismath):
- if ismath:
- ox, oy, width, height, descent, font_image, used_characters = \
- self.mathtext_parser.parse(s, self.dpi, prop)
- return width, height, descent
-
- layout, inkRect, logicalRect = self._get_pango_layout(s, prop)
- l, b, w, h = inkRect
- ll, lb, lw, lh = logicalRect
-
- return w, h + 1, h - lh
-
- def new_gc(self):
- return GraphicsContextGDK(renderer=self)
-
-
- def points_to_pixels(self, points):
- return points/72.0 * self.dpi
-
-
-class GraphicsContextGDK(GraphicsContextBase):
- # a cache shared by all class instances
- _cached = {} # map: rgb color -> gdk.Color
-
- _joind = {
- 'bevel' : gdk.JOIN_BEVEL,
- 'miter' : gdk.JOIN_MITER,
- 'round' : gdk.JOIN_ROUND,
- }
-
- _capd = {
- 'butt' : gdk.CAP_BUTT,
- 'projecting' : gdk.CAP_PROJECTING,
- 'round' : gdk.CAP_ROUND,
- }
-
-
- def __init__(self, renderer):
- GraphicsContextBase.__init__(self)
- self.renderer = renderer
- self.gdkGC = gtk.gdk.GC(renderer.gdkDrawable)
- self._cmap = renderer._cmap
-
-
- def rgb_to_gdk_color(self, rgb):
- """
- rgb - an RGB tuple (three 0.0-1.0 values)
- return an allocated gtk.gdk.Color
- """
- try:
- return self._cached[tuple(rgb)]
- except KeyError:
- color = self._cached[tuple(rgb)] = \
- self._cmap.alloc_color(
- int(rgb[0]*65535),int(rgb[1]*65535),int(rgb[2]*65535))
- return color
-
-
- #def set_antialiased(self, b):
- # anti-aliasing is not supported by GDK
-
- def set_capstyle(self, cs):
- GraphicsContextBase.set_capstyle(self, cs)
- self.gdkGC.cap_style = self._capd[self._capstyle]
-
-
- def set_clip_rectangle(self, rectangle):
- GraphicsContextBase.set_clip_rectangle(self, rectangle)
- if rectangle is None:
- return
- l,b,w,h = rectangle.bounds
- rectangle = (int(l), self.renderer.height-int(b+h)+1,
- int(w), int(h))
- #rectangle = (int(l), self.renderer.height-int(b+h),
- # int(w+1), int(h+2))
- self.gdkGC.set_clip_rectangle(rectangle)
-
- def set_dashes(self, dash_offset, dash_list):
- GraphicsContextBase.set_dashes(self, dash_offset, dash_list)
-
- if dash_list == None:
- self.gdkGC.line_style = gdk.LINE_SOLID
- else:
- pixels = self.renderer.points_to_pixels(np.asarray(dash_list))
- dl = [max(1, int(round(val))) for val in pixels]
- self.gdkGC.set_dashes(dash_offset, dl)
- self.gdkGC.line_style = gdk.LINE_ON_OFF_DASH
-
-
- def set_foreground(self, fg, isRGBA=False):
- GraphicsContextBase.set_foreground(self, fg, isRGBA)
- self.gdkGC.foreground = self.rgb_to_gdk_color(self.get_rgb())
-
-
- def set_graylevel(self, frac):
- GraphicsContextBase.set_graylevel(self, frac)
- self.gdkGC.foreground = self.rgb_to_gdk_color(self.get_rgb())
-
-
- def set_joinstyle(self, js):
- GraphicsContextBase.set_joinstyle(self, js)
- self.gdkGC.join_style = self._joind[self._joinstyle]
-
-
- def set_linewidth(self, w):
- GraphicsContextBase.set_linewidth(self, w)
- if w == 0:
- self.gdkGC.line_width = 0
- else:
- pixels = self.renderer.points_to_pixels(w)
- self.gdkGC.line_width = max(1, int(round(pixels)))
-
-
-def new_figure_manager(num, *args, **kwargs):
- """
- Create a new figure manager instance
- """
- FigureClass = kwargs.pop('FigureClass', Figure)
- thisFig = FigureClass(*args, **kwargs)
- return new_figure_manager_given_figure(num, thisFig)
-
-
-def new_figure_manager_given_figure(num, figure):
- """
- Create a new figure manager instance for the given figure.
- """
- canvas = FigureCanvasGDK(figure)
- manager = FigureManagerBase(canvas, num)
- return manager
-
-
-class FigureCanvasGDK (FigureCanvasBase):
- def __init__(self, figure):
- FigureCanvasBase.__init__(self, figure)
-
- self._renderer_init()
-
- def _renderer_init(self):
- self._renderer = RendererGDK (gtk.DrawingArea(), self.figure.dpi)
-
- def _render_figure(self, pixmap, width, height):
- self._renderer.set_pixmap (pixmap)
- self._renderer.set_width_height (width, height)
- self.figure.draw (self._renderer)
-
- filetypes = FigureCanvasBase.filetypes.copy()
- filetypes['jpg'] = 'JPEG'
- filetypes['jpeg'] = 'JPEG'
-
- def print_jpeg(self, filename, *args, **kwargs):
- return self._print_image(filename, 'jpeg')
- print_jpg = print_jpeg
-
- def print_png(self, filename, *args, **kwargs):
- return self._print_image(filename, 'png')
-
- def _print_image(self, filename, format, *args, **kwargs):
- width, height = self.get_width_height()
- pixmap = gtk.gdk.Pixmap (None, width, height, depth=24)
- self._render_figure(pixmap, width, height)
-
- # jpg colors don't match the display very well, png colors match
- # better
- pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, 0, 8,
- width, height)
- pixbuf.get_from_drawable(pixmap, pixmap.get_colormap(),
- 0, 0, 0, 0, width, height)
-
- # set the default quality, if we are writing a JPEG.
- # http://www.pygtk.org/docs/pygtk/class-gdkpixbuf.html#method-gdkpixbuf--save
- options = cbook.restrict_dict(kwargs, ['quality'])
- if format in ['jpg','jpeg']:
- if 'quality' not in options:
- options['quality'] = rcParams['savefig.jpeg_quality']
- options['quality'] = str(options['quality'])
-
- pixbuf.save(filename, format, options=options)
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_gtk.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_gtk.py
deleted file mode 100644
index 4135c8b..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_gtk.py
+++ /dev/null
@@ -1,1071 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import os, sys, warnings
-def fn_name(): return sys._getframe(1).f_code.co_name
-
-if six.PY3:
- warnings.warn(
- "The gtk* backends have not been tested with Python 3.x",
- ImportWarning)
-
-try:
- import gobject
- import gtk; gdk = gtk.gdk
- import pango
-except ImportError:
- raise ImportError("Gtk* backend requires pygtk to be installed.")
-
-pygtk_version_required = (2,4,0)
-if gtk.pygtk_version < pygtk_version_required:
- raise ImportError ("PyGTK %d.%d.%d is installed\n"
- "PyGTK %d.%d.%d or later is required"
- % (gtk.pygtk_version + pygtk_version_required))
-del pygtk_version_required
-
-_new_tooltip_api = (gtk.pygtk_version[1] >= 12)
-
-import matplotlib
-from matplotlib._pylab_helpers import Gcf
-from matplotlib.backend_bases import RendererBase, GraphicsContextBase, \
- FigureManagerBase, FigureCanvasBase, NavigationToolbar2, cursors, TimerBase
-from matplotlib.backend_bases import ShowBase
-
-from matplotlib.backends.backend_gdk import RendererGDK, FigureCanvasGDK
-from matplotlib.cbook import is_string_like, is_writable_file_like
-from matplotlib.colors import colorConverter
-from matplotlib.figure import Figure
-from matplotlib.widgets import SubplotTool
-
-from matplotlib import lines
-from matplotlib import markers
-from matplotlib import cbook
-from matplotlib import verbose
-from matplotlib import rcParams
-
-backend_version = "%d.%d.%d" % gtk.pygtk_version
-
-_debug = False
-#_debug = True
-
-# the true dots per inch on the screen; should be display dependent
-# see http://groups.google.com/groups?q=screen+dpi+x11&hl=en&lr=&ie=UTF-8&oe=UTF-8&safe=off&selm=7077.26e81ad5%40swift.cs.tcd.ie&rnum=5 for some info about screen dpi
-PIXELS_PER_INCH = 96
-
-# Hide the benign warning that it can't stat a file that doesn't
-warnings.filterwarnings('ignore', '.*Unable to retrieve the file info for.*', gtk.Warning)
-
-cursord = {
- cursors.MOVE : gdk.Cursor(gdk.FLEUR),
- cursors.HAND : gdk.Cursor(gdk.HAND2),
- cursors.POINTER : gdk.Cursor(gdk.LEFT_PTR),
- cursors.SELECT_REGION : gdk.Cursor(gdk.TCROSS),
- }
-
-# ref gtk+/gtk/gtkwidget.h
-def GTK_WIDGET_DRAWABLE(w):
- flags = w.flags();
- return flags & gtk.VISIBLE != 0 and flags & gtk.MAPPED != 0
-
-
-def draw_if_interactive():
- """
- Is called after every pylab drawing command
- """
- if matplotlib.is_interactive():
- figManager = Gcf.get_active()
- if figManager is not None:
- figManager.canvas.draw_idle()
-
-
-class Show(ShowBase):
- def mainloop(self):
- if gtk.main_level() == 0:
- gtk.main()
-
-show = Show()
-
-def new_figure_manager(num, *args, **kwargs):
- """
- Create a new figure manager instance
- """
- FigureClass = kwargs.pop('FigureClass', Figure)
- thisFig = FigureClass(*args, **kwargs)
- return new_figure_manager_given_figure(num, thisFig)
-
-
-def new_figure_manager_given_figure(num, figure):
- """
- Create a new figure manager instance for the given figure.
- """
- canvas = FigureCanvasGTK(figure)
- manager = FigureManagerGTK(canvas, num)
- return manager
-
-
-class TimerGTK(TimerBase):
- '''
- Subclass of :class:`backend_bases.TimerBase` that uses GTK for timer events.
-
- Attributes:
- * interval: The time between timer events in milliseconds. Default
- is 1000 ms.
- * single_shot: Boolean flag indicating whether this timer should
- operate as single shot (run once and then stop). Defaults to False.
- * callbacks: Stores list of (func, args) tuples that will be called
- upon timer events. This list can be manipulated directly, or the
- functions add_callback and remove_callback can be used.
- '''
- def _timer_start(self):
- # Need to stop it, otherwise we potentially leak a timer id that will
- # never be stopped.
- self._timer_stop()
- self._timer = gobject.timeout_add(self._interval, self._on_timer)
-
- def _timer_stop(self):
- if self._timer is not None:
- gobject.source_remove(self._timer)
- self._timer = None
-
- def _timer_set_interval(self):
- # Only stop and restart it if the timer has already been started
- if self._timer is not None:
- self._timer_stop()
- self._timer_start()
-
- def _on_timer(self):
- TimerBase._on_timer(self)
-
- # Gtk timeout_add() requires that the callback returns True if it
- # is to be called again.
- if len(self.callbacks) > 0 and not self._single:
- return True
- else:
- self._timer = None
- return False
-
-
-class FigureCanvasGTK (gtk.DrawingArea, FigureCanvasBase):
- keyvald = {65507 : 'control',
- 65505 : 'shift',
- 65513 : 'alt',
- 65508 : 'control',
- 65506 : 'shift',
- 65514 : 'alt',
- 65361 : 'left',
- 65362 : 'up',
- 65363 : 'right',
- 65364 : 'down',
- 65307 : 'escape',
- 65470 : 'f1',
- 65471 : 'f2',
- 65472 : 'f3',
- 65473 : 'f4',
- 65474 : 'f5',
- 65475 : 'f6',
- 65476 : 'f7',
- 65477 : 'f8',
- 65478 : 'f9',
- 65479 : 'f10',
- 65480 : 'f11',
- 65481 : 'f12',
- 65300 : 'scroll_lock',
- 65299 : 'break',
- 65288 : 'backspace',
- 65293 : 'enter',
- 65379 : 'insert',
- 65535 : 'delete',
- 65360 : 'home',
- 65367 : 'end',
- 65365 : 'pageup',
- 65366 : 'pagedown',
- 65438 : '0',
- 65436 : '1',
- 65433 : '2',
- 65435 : '3',
- 65430 : '4',
- 65437 : '5',
- 65432 : '6',
- 65429 : '7',
- 65431 : '8',
- 65434 : '9',
- 65451 : '+',
- 65453 : '-',
- 65450 : '*',
- 65455 : '/',
- 65439 : 'dec',
- 65421 : 'enter',
- 65511 : 'super',
- 65512 : 'super',
- 65406 : 'alt',
- 65289 : 'tab',
- }
-
- # Setting this as a static constant prevents
- # this resulting expression from leaking
- event_mask = (gdk.BUTTON_PRESS_MASK |
- gdk.BUTTON_RELEASE_MASK |
- gdk.EXPOSURE_MASK |
- gdk.KEY_PRESS_MASK |
- gdk.KEY_RELEASE_MASK |
- gdk.ENTER_NOTIFY_MASK |
- gdk.LEAVE_NOTIFY_MASK |
- gdk.POINTER_MOTION_MASK |
- gdk.POINTER_MOTION_HINT_MASK)
-
- def __init__(self, figure):
- if _debug: print('FigureCanvasGTK.%s' % fn_name())
- FigureCanvasBase.__init__(self, figure)
- gtk.DrawingArea.__init__(self)
-
- self._idle_draw_id = 0
- self._need_redraw = True
- self._pixmap_width = -1
- self._pixmap_height = -1
- self._lastCursor = None
-
- self.connect('scroll_event', self.scroll_event)
- self.connect('button_press_event', self.button_press_event)
- self.connect('button_release_event', self.button_release_event)
- self.connect('configure_event', self.configure_event)
- self.connect('expose_event', self.expose_event)
- self.connect('key_press_event', self.key_press_event)
- self.connect('key_release_event', self.key_release_event)
- self.connect('motion_notify_event', self.motion_notify_event)
- self.connect('leave_notify_event', self.leave_notify_event)
- self.connect('enter_notify_event', self.enter_notify_event)
-
- self.set_events(self.__class__.event_mask)
-
- self.set_double_buffered(False)
- self.set_flags(gtk.CAN_FOCUS)
- self._renderer_init()
-
- self._idle_event_id = gobject.idle_add(self.idle_event)
-
- self.last_downclick = {}
-
- def destroy(self):
- #gtk.DrawingArea.destroy(self)
- self.close_event()
- gobject.source_remove(self._idle_event_id)
- if self._idle_draw_id != 0:
- gobject.source_remove(self._idle_draw_id)
-
- def scroll_event(self, widget, event):
- if _debug: print('FigureCanvasGTK.%s' % fn_name())
- x = event.x
- # flipy so y=0 is bottom of canvas
- y = self.allocation.height - event.y
- if event.direction==gdk.SCROLL_UP:
- step = 1
- else:
- step = -1
- FigureCanvasBase.scroll_event(self, x, y, step, guiEvent=event)
- return False # finish event propagation?
-
- def button_press_event(self, widget, event):
- if _debug: print('FigureCanvasGTK.%s' % fn_name())
- x = event.x
- # flipy so y=0 is bottom of canvas
- y = self.allocation.height - event.y
- dblclick = (event.type == gdk._2BUTTON_PRESS)
- if not dblclick:
- # GTK is the only backend that generates a DOWN-UP-DOWN-DBLCLICK-UP event
- # sequence for a double click. All other backends have a DOWN-UP-DBLCLICK-UP
- # sequence. In order to provide consistency to matplotlib users, we will
- # eat the extra DOWN event in the case that we detect it is part of a double
- # click.
- # first, get the double click time in milliseconds.
- current_time = event.get_time()
- last_time = self.last_downclick.get(event.button,0)
- dblclick_time = gtk.settings_get_for_screen(gdk.screen_get_default()).get_property('gtk-double-click-time')
- delta_time = current_time-last_time
- if delta_time < dblclick_time:
- del self.last_downclick[event.button] # we do not want to eat more than one event.
- return False # eat.
- self.last_downclick[event.button] = current_time
- FigureCanvasBase.button_press_event(self, x, y, event.button, dblclick=dblclick, guiEvent=event)
- return False # finish event propagation?
-
- def button_release_event(self, widget, event):
- if _debug: print('FigureCanvasGTK.%s' % fn_name())
- x = event.x
- # flipy so y=0 is bottom of canvas
- y = self.allocation.height - event.y
- FigureCanvasBase.button_release_event(self, x, y, event.button, guiEvent=event)
- return False # finish event propagation?
-
- def key_press_event(self, widget, event):
- if _debug: print('FigureCanvasGTK.%s' % fn_name())
- key = self._get_key(event)
- if _debug: print("hit", key)
- FigureCanvasBase.key_press_event(self, key, guiEvent=event)
- return False # finish event propagation?
-
- def key_release_event(self, widget, event):
- if _debug: print('FigureCanvasGTK.%s' % fn_name())
- key = self._get_key(event)
- if _debug: print("release", key)
- FigureCanvasBase.key_release_event(self, key, guiEvent=event)
- return False # finish event propagation?
-
- def motion_notify_event(self, widget, event):
- if _debug: print('FigureCanvasGTK.%s' % fn_name())
- if event.is_hint:
- x, y, state = event.window.get_pointer()
- else:
- x, y, state = event.x, event.y, event.state
-
- # flipy so y=0 is bottom of canvas
- y = self.allocation.height - y
- FigureCanvasBase.motion_notify_event(self, x, y, guiEvent=event)
- return False # finish event propagation?
-
- def leave_notify_event(self, widget, event):
- FigureCanvasBase.leave_notify_event(self, event)
-
- def enter_notify_event(self, widget, event):
- x, y, state = event.window.get_pointer()
- FigureCanvasBase.enter_notify_event(self, event, xy=(x, y))
-
- def _get_key(self, event):
- if event.keyval in self.keyvald:
- key = self.keyvald[event.keyval]
- elif event.keyval < 256:
- key = chr(event.keyval)
- else:
- key = None
-
- for key_mask, prefix in (
- [gdk.MOD4_MASK, 'super'],
- [gdk.MOD1_MASK, 'alt'],
- [gdk.CONTROL_MASK, 'ctrl'], ):
- if event.state & key_mask:
- key = '{0}+{1}'.format(prefix, key)
-
- return key
-
- def configure_event(self, widget, event):
- if _debug: print('FigureCanvasGTK.%s' % fn_name())
- if widget.window is None:
- return
- w, h = event.width, event.height
- if w < 3 or h < 3:
- return # empty fig
-
- # resize the figure (in inches)
- dpi = self.figure.dpi
- self.figure.set_size_inches (w/dpi, h/dpi)
- self._need_redraw = True
-
- return False # finish event propagation?
-
- def draw(self):
- # Note: FigureCanvasBase.draw() is inconveniently named as it clashes
- # with the deprecated gtk.Widget.draw()
-
- self._need_redraw = True
- if GTK_WIDGET_DRAWABLE(self):
- self.queue_draw()
- # do a synchronous draw (its less efficient than an async draw,
- # but is required if/when animation is used)
- self.window.process_updates (False)
-
- def draw_idle(self):
- def idle_draw(*args):
- try:
- self.draw()
- finally:
- self._idle_draw_id = 0
- return False
- if self._idle_draw_id == 0:
- self._idle_draw_id = gobject.idle_add(idle_draw)
-
-
- def _renderer_init(self):
- """Override by GTK backends to select a different renderer
- Renderer should provide the methods:
- set_pixmap ()
- set_width_height ()
- that are used by
- _render_figure() / _pixmap_prepare()
- """
- self._renderer = RendererGDK (self, self.figure.dpi)
-
-
- def _pixmap_prepare(self, width, height):
- """
- Make sure _._pixmap is at least width, height,
- create new pixmap if necessary
- """
- if _debug: print('FigureCanvasGTK.%s' % fn_name())
-
- create_pixmap = False
- if width > self._pixmap_width:
- # increase the pixmap in 10%+ (rather than 1 pixel) steps
- self._pixmap_width = max (int (self._pixmap_width * 1.1),
- width)
- create_pixmap = True
-
- if height > self._pixmap_height:
- self._pixmap_height = max (int (self._pixmap_height * 1.1),
- height)
- create_pixmap = True
-
- if create_pixmap:
- self._pixmap = gdk.Pixmap (self.window, self._pixmap_width,
- self._pixmap_height)
- self._renderer.set_pixmap (self._pixmap)
-
-
- def _render_figure(self, pixmap, width, height):
- """used by GTK and GTKcairo. GTKAgg overrides
- """
- self._renderer.set_width_height (width, height)
- self.figure.draw (self._renderer)
-
-
- def expose_event(self, widget, event):
- """Expose_event for all GTK backends. Should not be overridden.
- """
- if _debug: print('FigureCanvasGTK.%s' % fn_name())
-
- if GTK_WIDGET_DRAWABLE(self):
- if self._need_redraw:
- x, y, w, h = self.allocation
- self._pixmap_prepare (w, h)
- self._render_figure(self._pixmap, w, h)
- self._need_redraw = False
-
- x, y, w, h = event.area
- self.window.draw_drawable (self.style.fg_gc[self.state],
- self._pixmap, x, y, x, y, w, h)
- return False # finish event propagation?
-
- filetypes = FigureCanvasBase.filetypes.copy()
- filetypes['jpg'] = 'JPEG'
- filetypes['jpeg'] = 'JPEG'
- filetypes['png'] = 'Portable Network Graphics'
-
- def print_jpeg(self, filename, *args, **kwargs):
- return self._print_image(filename, 'jpeg')
- print_jpg = print_jpeg
-
- def print_png(self, filename, *args, **kwargs):
- return self._print_image(filename, 'png')
-
- def _print_image(self, filename, format, *args, **kwargs):
- if self.flags() & gtk.REALIZED == 0:
- # for self.window(for pixmap) and has a side effect of altering
- # figure width,height (via configure-event?)
- gtk.DrawingArea.realize(self)
-
- width, height = self.get_width_height()
- pixmap = gdk.Pixmap (self.window, width, height)
- self._renderer.set_pixmap (pixmap)
- self._render_figure(pixmap, width, height)
-
- # jpg colors don't match the display very well, png colors match
- # better
- pixbuf = gdk.Pixbuf(gdk.COLORSPACE_RGB, 0, 8, width, height)
- pixbuf.get_from_drawable(pixmap, pixmap.get_colormap(),
- 0, 0, 0, 0, width, height)
-
- # set the default quality, if we are writing a JPEG.
- # http://www.pygtk.org/docs/pygtk/class-gdkpixbuf.html#method-gdkpixbuf--save
- options = cbook.restrict_dict(kwargs, ['quality'])
- if format in ['jpg','jpeg']:
- if 'quality' not in options:
- options['quality'] = rcParams['savefig.jpeg_quality']
-
- options['quality'] = str(options['quality'])
-
- if is_string_like(filename):
- try:
- pixbuf.save(filename, format, options=options)
- except gobject.GError as exc:
- error_msg_gtk('Save figure failure:\n%s' % (exc,), parent=self)
- elif is_writable_file_like(filename):
- if hasattr(pixbuf, 'save_to_callback'):
- def save_callback(buf, data=None):
- data.write(buf)
- try:
- pixbuf.save_to_callback(save_callback, format, user_data=filename, options=options)
- except gobject.GError as exc:
- error_msg_gtk('Save figure failure:\n%s' % (exc,), parent=self)
- else:
- raise ValueError("Saving to a Python file-like object is only supported by PyGTK >= 2.8")
- else:
- raise ValueError("filename must be a path or a file-like object")
-
- def new_timer(self, *args, **kwargs):
- """
- Creates a new backend-specific subclass of :class:`backend_bases.Timer`.
- This is useful for getting periodic events through the backend's native
- event loop. Implemented only for backends with GUIs.
-
- optional arguments:
-
- *interval*
- Timer interval in milliseconds
- *callbacks*
- Sequence of (func, args, kwargs) where func(*args, **kwargs) will
- be executed by the timer every *interval*.
- """
- return TimerGTK(*args, **kwargs)
-
- def flush_events(self):
- gtk.gdk.threads_enter()
- while gtk.events_pending():
- gtk.main_iteration(True)
- gtk.gdk.flush()
- gtk.gdk.threads_leave()
-
- def start_event_loop(self,timeout):
- FigureCanvasBase.start_event_loop_default(self,timeout)
- start_event_loop.__doc__=FigureCanvasBase.start_event_loop_default.__doc__
-
- def stop_event_loop(self):
- FigureCanvasBase.stop_event_loop_default(self)
- stop_event_loop.__doc__=FigureCanvasBase.stop_event_loop_default.__doc__
-
-class FigureManagerGTK(FigureManagerBase):
- """
- Public attributes
-
- canvas : The FigureCanvas instance
- num : The Figure number
- toolbar : The gtk.Toolbar (gtk only)
- vbox : The gtk.VBox containing the canvas and toolbar (gtk only)
- window : The gtk.Window (gtk only)
- """
- def __init__(self, canvas, num):
- if _debug: print('FigureManagerGTK.%s' % fn_name())
- FigureManagerBase.__init__(self, canvas, num)
-
- self.window = gtk.Window()
- self.set_window_title("Figure %d" % num)
- if (window_icon):
- try:
- self.window.set_icon_from_file(window_icon)
- except:
- # some versions of gtk throw a glib.GError but not
- # all, so I am not sure how to catch it. I am unhappy
- # diong a blanket catch here, but an not sure what a
- # better way is - JDH
- verbose.report('Could not load matplotlib icon: %s' % sys.exc_info()[1])
-
- self.vbox = gtk.VBox()
- self.window.add(self.vbox)
- self.vbox.show()
-
- self.canvas.show()
-
- self.vbox.pack_start(self.canvas, True, True)
-
- self.toolbar = self._get_toolbar(canvas)
-
- # calculate size for window
- w = int (self.canvas.figure.bbox.width)
- h = int (self.canvas.figure.bbox.height)
-
- if self.toolbar is not None:
- self.toolbar.show()
- self.vbox.pack_end(self.toolbar, False, False)
-
- tb_w, tb_h = self.toolbar.size_request()
- h += tb_h
- self.window.set_default_size (w, h)
-
- def destroy(*args):
- Gcf.destroy(num)
- self.window.connect("destroy", destroy)
- self.window.connect("delete_event", destroy)
- if matplotlib.is_interactive():
- self.window.show()
-
- def notify_axes_change(fig):
- 'this will be called whenever the current axes is changed'
- if self.toolbar is not None: self.toolbar.update()
- self.canvas.figure.add_axobserver(notify_axes_change)
-
- self.canvas.grab_focus()
-
- def destroy(self, *args):
- if _debug: print('FigureManagerGTK.%s' % fn_name())
- if hasattr(self, 'toolbar') and self.toolbar is not None:
- self.toolbar.destroy()
- if hasattr(self, 'vbox'):
- self.vbox.destroy()
- if hasattr(self, 'window'):
- self.window.destroy()
- if hasattr(self, 'canvas'):
- self.canvas.destroy()
- self.__dict__.clear() #Is this needed? Other backends don't have it.
-
- if Gcf.get_num_fig_managers()==0 and \
- not matplotlib.is_interactive() and \
- gtk.main_level() >= 1:
- gtk.main_quit()
-
- def show(self):
- # show the figure window
- self.window.show()
-
- def full_screen_toggle(self):
- self._full_screen_flag = not self._full_screen_flag
- if self._full_screen_flag:
- self.window.fullscreen()
- else:
- self.window.unfullscreen()
- _full_screen_flag = False
-
-
- def _get_toolbar(self, canvas):
- # must be inited after the window, drawingArea and figure
- # attrs are set
- if rcParams['toolbar'] == 'toolbar2':
- toolbar = NavigationToolbar2GTK (canvas, self.window)
- else:
- toolbar = None
- return toolbar
-
- def get_window_title(self):
- return self.window.get_title()
-
- def set_window_title(self, title):
- self.window.set_title(title)
-
- def resize(self, width, height):
- 'set the canvas size in pixels'
- #_, _, cw, ch = self.canvas.allocation
- #_, _, ww, wh = self.window.allocation
- #self.window.resize (width-cw+ww, height-ch+wh)
- self.window.resize(width, height)
-
-
-class NavigationToolbar2GTK(NavigationToolbar2, gtk.Toolbar):
- def __init__(self, canvas, window):
- self.win = window
- gtk.Toolbar.__init__(self)
- NavigationToolbar2.__init__(self, canvas)
-
- def set_message(self, s):
- self.message.set_label(s)
-
- def set_cursor(self, cursor):
- self.canvas.window.set_cursor(cursord[cursor])
-
- def release(self, event):
- try: del self._pixmapBack
- except AttributeError: pass
-
- def dynamic_update(self):
- # legacy method; new method is canvas.draw_idle
- self.canvas.draw_idle()
-
- def draw_rubberband(self, event, x0, y0, x1, y1):
- 'adapted from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/189744'
- drawable = self.canvas.window
- if drawable is None:
- return
-
- gc = drawable.new_gc()
-
- height = self.canvas.figure.bbox.height
- y1 = height - y1
- y0 = height - y0
-
- w = abs(x1 - x0)
- h = abs(y1 - y0)
-
- rect = [int(val)for val in (min(x0,x1), min(y0, y1), w, h)]
- try:
- lastrect, pixmapBack = self._pixmapBack
- except AttributeError:
- #snap image back
- if event.inaxes is None:
- return
-
- ax = event.inaxes
- l,b,w,h = [int(val) for val in ax.bbox.bounds]
- b = int(height)-(b+h)
- axrect = l,b,w,h
- self._pixmapBack = axrect, gtk.gdk.Pixmap(drawable, w, h)
- self._pixmapBack[1].draw_drawable(gc, drawable, l, b, 0, 0, w, h)
- else:
- drawable.draw_drawable(gc, pixmapBack, 0, 0, *lastrect)
- drawable.draw_rectangle(gc, False, *rect)
-
-
- def _init_toolbar(self):
- self.set_style(gtk.TOOLBAR_ICONS)
- self._init_toolbar2_4()
-
-
- def _init_toolbar2_4(self):
- basedir = os.path.join(rcParams['datapath'],'images')
- if not _new_tooltip_api:
- self.tooltips = gtk.Tooltips()
-
- for text, tooltip_text, image_file, callback in self.toolitems:
- if text is None:
- self.insert( gtk.SeparatorToolItem(), -1 )
- continue
- fname = os.path.join(basedir, image_file + '.png')
- image = gtk.Image()
- image.set_from_file(fname)
- tbutton = gtk.ToolButton(image, text)
- self.insert(tbutton, -1)
- tbutton.connect('clicked', getattr(self, callback))
- if _new_tooltip_api:
- tbutton.set_tooltip_text(tooltip_text)
- else:
- tbutton.set_tooltip(self.tooltips, tooltip_text, 'Private')
-
- toolitem = gtk.SeparatorToolItem()
- self.insert(toolitem, -1)
- # set_draw() not making separator invisible,
- # bug #143692 fixed Jun 06 2004, will be in GTK+ 2.6
- toolitem.set_draw(False)
- toolitem.set_expand(True)
-
- toolitem = gtk.ToolItem()
- self.insert(toolitem, -1)
- self.message = gtk.Label()
- toolitem.add(self.message)
-
- self.show_all()
-
- def get_filechooser(self):
- fc = FileChooserDialog(
- title='Save the figure',
- parent=self.win,
- path=os.path.expanduser(rcParams.get('savefig.directory', '')),
- filetypes=self.canvas.get_supported_filetypes(),
- default_filetype=self.canvas.get_default_filetype())
- fc.set_current_name(self.canvas.get_default_filename())
- return fc
-
- def save_figure(self, *args):
- chooser = self.get_filechooser()
- fname, format = chooser.get_filename_from_user()
- chooser.destroy()
- if fname:
- startpath = os.path.expanduser(rcParams.get('savefig.directory', ''))
- if startpath == '':
- # explicitly missing key or empty str signals to use cwd
- rcParams['savefig.directory'] = startpath
- else:
- # save dir for next time
- rcParams['savefig.directory'] = os.path.dirname(six.text_type(fname))
- try:
- self.canvas.print_figure(fname, format=format)
- except Exception as e:
- error_msg_gtk(str(e), parent=self)
-
- def configure_subplots(self, button):
- toolfig = Figure(figsize=(6,3))
- canvas = self._get_canvas(toolfig)
- toolfig.subplots_adjust(top=0.9)
- tool = SubplotTool(self.canvas.figure, toolfig)
-
- w = int (toolfig.bbox.width)
- h = int (toolfig.bbox.height)
-
-
- window = gtk.Window()
- if (window_icon):
- try: window.set_icon_from_file(window_icon)
- except:
- # we presumably already logged a message on the
- # failure of the main plot, don't keep reporting
- pass
- window.set_title("Subplot Configuration Tool")
- window.set_default_size(w, h)
- vbox = gtk.VBox()
- window.add(vbox)
- vbox.show()
-
- canvas.show()
- vbox.pack_start(canvas, True, True)
- window.show()
-
- def _get_canvas(self, fig):
- return FigureCanvasGTK(fig)
-
-
-class FileChooserDialog(gtk.FileChooserDialog):
- """GTK+ 2.4 file selector which presents the user with a menu
- of supported image formats
- """
- def __init__ (self,
- title = 'Save file',
- parent = None,
- action = gtk.FILE_CHOOSER_ACTION_SAVE,
- buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
- gtk.STOCK_SAVE, gtk.RESPONSE_OK),
- path = None,
- filetypes = [],
- default_filetype = None
- ):
- super(FileChooserDialog, self).__init__ (title, parent, action,
- buttons)
- super(FileChooserDialog, self).set_do_overwrite_confirmation(True)
- self.set_default_response (gtk.RESPONSE_OK)
-
- if not path: path = os.getcwd() + os.sep
-
- # create an extra widget to list supported image formats
- self.set_current_folder (path)
- self.set_current_name ('image.' + default_filetype)
-
- hbox = gtk.HBox (spacing=10)
- hbox.pack_start (gtk.Label ("File Format:"), expand=False)
-
- liststore = gtk.ListStore(gobject.TYPE_STRING)
- cbox = gtk.ComboBox(liststore)
- cell = gtk.CellRendererText()
- cbox.pack_start(cell, True)
- cbox.add_attribute(cell, 'text', 0)
- hbox.pack_start (cbox)
-
- self.filetypes = filetypes
- self.sorted_filetypes = list(six.iteritems(filetypes))
- self.sorted_filetypes.sort()
- default = 0
- for i, (ext, name) in enumerate(self.sorted_filetypes):
- cbox.append_text ("%s (*.%s)" % (name, ext))
- if ext == default_filetype:
- default = i
- cbox.set_active(default)
- self.ext = default_filetype
-
- def cb_cbox_changed (cbox, data=None):
- """File extension changed"""
- head, filename = os.path.split(self.get_filename())
- root, ext = os.path.splitext(filename)
- ext = ext[1:]
- new_ext = self.sorted_filetypes[cbox.get_active()][0]
- self.ext = new_ext
-
- if ext in self.filetypes:
- filename = root + '.' + new_ext
- elif ext == '':
- filename = filename.rstrip('.') + '.' + new_ext
-
- self.set_current_name (filename)
- cbox.connect ("changed", cb_cbox_changed)
-
- hbox.show_all()
- self.set_extra_widget(hbox)
-
- def get_filename_from_user (self):
- while True:
- filename = None
- if self.run() != int(gtk.RESPONSE_OK):
- break
- filename = self.get_filename()
- break
-
- return filename, self.ext
-
-class DialogLineprops:
- """
- A GUI dialog for controlling lineprops
- """
- signals = (
- 'on_combobox_lineprops_changed',
- 'on_combobox_linestyle_changed',
- 'on_combobox_marker_changed',
- 'on_colorbutton_linestyle_color_set',
- 'on_colorbutton_markerface_color_set',
- 'on_dialog_lineprops_okbutton_clicked',
- 'on_dialog_lineprops_cancelbutton_clicked',
- )
-
- linestyles = [ls for ls in lines.Line2D.lineStyles if ls.strip()]
- linestyled = dict([ (s,i) for i,s in enumerate(linestyles)])
-
-
- markers = [m for m in markers.MarkerStyle.markers if cbook.is_string_like(m)]
-
- markerd = dict([(s,i) for i,s in enumerate(markers)])
-
- def __init__(self, lines):
- import gtk.glade
-
- datadir = matplotlib.get_data_path()
- gladefile = os.path.join(datadir, 'lineprops.glade')
- if not os.path.exists(gladefile):
- raise IOError('Could not find gladefile lineprops.glade in %s'%datadir)
-
- self._inited = False
- self._updateson = True # suppress updates when setting widgets manually
- self.wtree = gtk.glade.XML(gladefile, 'dialog_lineprops')
- self.wtree.signal_autoconnect(dict([(s, getattr(self, s)) for s in self.signals]))
-
- self.dlg = self.wtree.get_widget('dialog_lineprops')
-
- self.lines = lines
-
- cbox = self.wtree.get_widget('combobox_lineprops')
- cbox.set_active(0)
- self.cbox_lineprops = cbox
-
- cbox = self.wtree.get_widget('combobox_linestyles')
- for ls in self.linestyles:
- cbox.append_text(ls)
- cbox.set_active(0)
- self.cbox_linestyles = cbox
-
- cbox = self.wtree.get_widget('combobox_markers')
- for m in self.markers:
- cbox.append_text(m)
- cbox.set_active(0)
- self.cbox_markers = cbox
- self._lastcnt = 0
- self._inited = True
-
-
- def show(self):
- 'populate the combo box'
- self._updateson = False
- # flush the old
- cbox = self.cbox_lineprops
- for i in range(self._lastcnt-1,-1,-1):
- cbox.remove_text(i)
-
- # add the new
- for line in self.lines:
- cbox.append_text(line.get_label())
- cbox.set_active(0)
-
- self._updateson = True
- self._lastcnt = len(self.lines)
- self.dlg.show()
-
- def get_active_line(self):
- 'get the active line'
- ind = self.cbox_lineprops.get_active()
- line = self.lines[ind]
- return line
-
-
- def get_active_linestyle(self):
- 'get the active lineinestyle'
- ind = self.cbox_linestyles.get_active()
- ls = self.linestyles[ind]
- return ls
-
- def get_active_marker(self):
- 'get the active lineinestyle'
- ind = self.cbox_markers.get_active()
- m = self.markers[ind]
- return m
-
- def _update(self):
- 'update the active line props from the widgets'
- if not self._inited or not self._updateson: return
- line = self.get_active_line()
- ls = self.get_active_linestyle()
- marker = self.get_active_marker()
- line.set_linestyle(ls)
- line.set_marker(marker)
-
- button = self.wtree.get_widget('colorbutton_linestyle')
- color = button.get_color()
- r, g, b = [val/65535. for val in (color.red, color.green, color.blue)]
- line.set_color((r,g,b))
-
- button = self.wtree.get_widget('colorbutton_markerface')
- color = button.get_color()
- r, g, b = [val/65535. for val in (color.red, color.green, color.blue)]
- line.set_markerfacecolor((r,g,b))
-
- line.figure.canvas.draw()
-
-
-
- def on_combobox_lineprops_changed(self, item):
- 'update the widgets from the active line'
- if not self._inited: return
- self._updateson = False
- line = self.get_active_line()
-
- ls = line.get_linestyle()
- if ls is None: ls = 'None'
- self.cbox_linestyles.set_active(self.linestyled[ls])
-
- marker = line.get_marker()
- if marker is None: marker = 'None'
- self.cbox_markers.set_active(self.markerd[marker])
-
- r,g,b = colorConverter.to_rgb(line.get_color())
- color = gtk.gdk.Color(*[int(val*65535) for val in (r,g,b)])
- button = self.wtree.get_widget('colorbutton_linestyle')
- button.set_color(color)
-
- r,g,b = colorConverter.to_rgb(line.get_markerfacecolor())
- color = gtk.gdk.Color(*[int(val*65535) for val in (r,g,b)])
- button = self.wtree.get_widget('colorbutton_markerface')
- button.set_color(color)
- self._updateson = True
-
- def on_combobox_linestyle_changed(self, item):
- self._update()
-
- def on_combobox_marker_changed(self, item):
- self._update()
-
- def on_colorbutton_linestyle_color_set(self, button):
- self._update()
-
- def on_colorbutton_markerface_color_set(self, button):
- 'called colorbutton marker clicked'
- self._update()
-
- def on_dialog_lineprops_okbutton_clicked(self, button):
- self._update()
- self.dlg.hide()
-
- def on_dialog_lineprops_cancelbutton_clicked(self, button):
- self.dlg.hide()
-
-# set icon used when windows are minimized
-# Unfortunately, the SVG renderer (rsvg) leaks memory under earlier
-# versions of pygtk, so we have to use a PNG file instead.
-try:
-
- if gtk.pygtk_version < (2, 8, 0) or sys.platform == 'win32':
- icon_filename = 'matplotlib.png'
- else:
- icon_filename = 'matplotlib.svg'
- window_icon = os.path.join(rcParams['datapath'], 'images', icon_filename)
-except:
- window_icon = None
- verbose.report('Could not load matplotlib icon: %s' % sys.exc_info()[1])
-
-def error_msg_gtk(msg, parent=None):
- if parent is not None: # find the toplevel gtk.Window
- parent = parent.get_toplevel()
- if parent.flags() & gtk.TOPLEVEL == 0:
- parent = None
-
- if not is_string_like(msg):
- msg = ','.join(map(str,msg))
-
- dialog = gtk.MessageDialog(
- parent = parent,
- type = gtk.MESSAGE_ERROR,
- buttons = gtk.BUTTONS_OK,
- message_format = msg)
- dialog.run()
- dialog.destroy()
-
-
-FigureCanvas = FigureCanvasGTK
-FigureManager = FigureManagerGTK
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_gtk3.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_gtk3.py
deleted file mode 100644
index eab6564..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_gtk3.py
+++ /dev/null
@@ -1,889 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import os, sys
-def fn_name(): return sys._getframe(1).f_code.co_name
-
-try:
- import gi
-except ImportError:
- raise ImportError("Gtk3 backend requires pygobject to be installed.")
-
-try:
- gi.require_version("Gtk", "3.0")
-except AttributeError:
- raise ImportError(
- "pygobject version too old -- it must have require_version")
-except ValueError:
- raise ImportError(
- "Gtk3 backend requires the GObject introspection bindings for Gtk 3 "
- "to be installed.")
-
-try:
- from gi.repository import Gtk, Gdk, GObject, GLib
-except ImportError:
- raise ImportError("Gtk3 backend requires pygobject to be installed.")
-
-import matplotlib
-from matplotlib._pylab_helpers import Gcf
-from matplotlib.backend_bases import RendererBase, GraphicsContextBase, \
- FigureManagerBase, FigureCanvasBase, NavigationToolbar2, cursors, TimerBase
-from matplotlib.backend_bases import ShowBase
-
-from matplotlib.cbook import is_string_like, is_writable_file_like
-from matplotlib.colors import colorConverter
-from matplotlib.figure import Figure
-from matplotlib.widgets import SubplotTool
-
-from matplotlib import lines
-from matplotlib import cbook
-from matplotlib import verbose
-from matplotlib import rcParams
-
-backend_version = "%s.%s.%s" % (Gtk.get_major_version(), Gtk.get_micro_version(), Gtk.get_minor_version())
-
-_debug = False
-#_debug = True
-
-# the true dots per inch on the screen; should be display dependent
-# see http://groups.google.com/groups?q=screen+dpi+x11&hl=en&lr=&ie=UTF-8&oe=UTF-8&safe=off&selm=7077.26e81ad5%40swift.cs.tcd.ie&rnum=5 for some info about screen dpi
-PIXELS_PER_INCH = 96
-
-cursord = {
- cursors.MOVE : Gdk.Cursor.new(Gdk.CursorType.FLEUR),
- cursors.HAND : Gdk.Cursor.new(Gdk.CursorType.HAND2),
- cursors.POINTER : Gdk.Cursor.new(Gdk.CursorType.LEFT_PTR),
- cursors.SELECT_REGION : Gdk.Cursor.new(Gdk.CursorType.TCROSS),
- }
-
-def draw_if_interactive():
- """
- Is called after every pylab drawing command
- """
- if matplotlib.is_interactive():
- figManager = Gcf.get_active()
- if figManager is not None:
- figManager.canvas.draw_idle()
-
-class Show(ShowBase):
- def mainloop(self):
- if Gtk.main_level() == 0:
- Gtk.main()
-
-show = Show()
-
-
-class TimerGTK3(TimerBase):
- '''
- Subclass of :class:`backend_bases.TimerBase` that uses GTK3 for timer events.
-
- Attributes:
- * interval: The time between timer events in milliseconds. Default
- is 1000 ms.
- * single_shot: Boolean flag indicating whether this timer should
- operate as single shot (run once and then stop). Defaults to False.
- * callbacks: Stores list of (func, args) tuples that will be called
- upon timer events. This list can be manipulated directly, or the
- functions add_callback and remove_callback can be used.
- '''
- def _timer_start(self):
- # Need to stop it, otherwise we potentially leak a timer id that will
- # never be stopped.
- self._timer_stop()
- self._timer = GLib.timeout_add(self._interval, self._on_timer)
-
- def _timer_stop(self):
- if self._timer is not None:
- GLib.source_remove(self._timer)
- self._timer = None
-
- def _timer_set_interval(self):
- # Only stop and restart it if the timer has already been started
- if self._timer is not None:
- self._timer_stop()
- self._timer_start()
-
- def _on_timer(self):
- TimerBase._on_timer(self)
-
- # Gtk timeout_add() requires that the callback returns True if it
- # is to be called again.
- if len(self.callbacks) > 0 and not self._single:
- return True
- else:
- self._timer = None
- return False
-
-class FigureCanvasGTK3 (Gtk.DrawingArea, FigureCanvasBase):
- keyvald = {65507 : 'control',
- 65505 : 'shift',
- 65513 : 'alt',
- 65508 : 'control',
- 65506 : 'shift',
- 65514 : 'alt',
- 65361 : 'left',
- 65362 : 'up',
- 65363 : 'right',
- 65364 : 'down',
- 65307 : 'escape',
- 65470 : 'f1',
- 65471 : 'f2',
- 65472 : 'f3',
- 65473 : 'f4',
- 65474 : 'f5',
- 65475 : 'f6',
- 65476 : 'f7',
- 65477 : 'f8',
- 65478 : 'f9',
- 65479 : 'f10',
- 65480 : 'f11',
- 65481 : 'f12',
- 65300 : 'scroll_lock',
- 65299 : 'break',
- 65288 : 'backspace',
- 65293 : 'enter',
- 65379 : 'insert',
- 65535 : 'delete',
- 65360 : 'home',
- 65367 : 'end',
- 65365 : 'pageup',
- 65366 : 'pagedown',
- 65438 : '0',
- 65436 : '1',
- 65433 : '2',
- 65435 : '3',
- 65430 : '4',
- 65437 : '5',
- 65432 : '6',
- 65429 : '7',
- 65431 : '8',
- 65434 : '9',
- 65451 : '+',
- 65453 : '-',
- 65450 : '*',
- 65455 : '/',
- 65439 : 'dec',
- 65421 : 'enter',
- }
-
- # Setting this as a static constant prevents
- # this resulting expression from leaking
- event_mask = (Gdk.EventMask.BUTTON_PRESS_MASK |
- Gdk.EventMask.BUTTON_RELEASE_MASK |
- Gdk.EventMask.EXPOSURE_MASK |
- Gdk.EventMask.KEY_PRESS_MASK |
- Gdk.EventMask.KEY_RELEASE_MASK |
- Gdk.EventMask.ENTER_NOTIFY_MASK |
- Gdk.EventMask.LEAVE_NOTIFY_MASK |
- Gdk.EventMask.POINTER_MOTION_MASK |
- Gdk.EventMask.POINTER_MOTION_HINT_MASK|
- Gdk.EventMask.SCROLL_MASK)
-
- def __init__(self, figure):
- if _debug: print('FigureCanvasGTK3.%s' % fn_name())
- FigureCanvasBase.__init__(self, figure)
- GObject.GObject.__init__(self)
-
- self._idle_draw_id = 0
- self._need_redraw = True
- self._lastCursor = None
-
- self.connect('scroll_event', self.scroll_event)
- self.connect('button_press_event', self.button_press_event)
- self.connect('button_release_event', self.button_release_event)
- self.connect('configure_event', self.configure_event)
- self.connect('draw', self.on_draw_event)
- self.connect('key_press_event', self.key_press_event)
- self.connect('key_release_event', self.key_release_event)
- self.connect('motion_notify_event', self.motion_notify_event)
- self.connect('leave_notify_event', self.leave_notify_event)
- self.connect('enter_notify_event', self.enter_notify_event)
- self.connect('size_allocate', self.size_allocate)
-
- self.set_events(self.__class__.event_mask)
-
- self.set_double_buffered(True)
- self.set_can_focus(True)
- self._renderer_init()
- self._idle_event_id = GLib.idle_add(self.idle_event)
-
- def destroy(self):
- #Gtk.DrawingArea.destroy(self)
- self.close_event()
- GLib.source_remove(self._idle_event_id)
- if self._idle_draw_id != 0:
- GLib.source_remove(self._idle_draw_id)
-
- def scroll_event(self, widget, event):
- if _debug: print('FigureCanvasGTK3.%s' % fn_name())
- x = event.x
- # flipy so y=0 is bottom of canvas
- y = self.get_allocation().height - event.y
- if event.direction==Gdk.ScrollDirection.UP:
- step = 1
- else:
- step = -1
- FigureCanvasBase.scroll_event(self, x, y, step, guiEvent=event)
- return False # finish event propagation?
-
- def button_press_event(self, widget, event):
- if _debug: print('FigureCanvasGTK3.%s' % fn_name())
- x = event.x
- # flipy so y=0 is bottom of canvas
- y = self.get_allocation().height - event.y
- FigureCanvasBase.button_press_event(self, x, y, event.button, guiEvent=event)
- return False # finish event propagation?
-
- def button_release_event(self, widget, event):
- if _debug: print('FigureCanvasGTK3.%s' % fn_name())
- x = event.x
- # flipy so y=0 is bottom of canvas
- y = self.get_allocation().height - event.y
- FigureCanvasBase.button_release_event(self, x, y, event.button, guiEvent=event)
- return False # finish event propagation?
-
- def key_press_event(self, widget, event):
- if _debug: print('FigureCanvasGTK3.%s' % fn_name())
- key = self._get_key(event)
- if _debug: print("hit", key)
- FigureCanvasBase.key_press_event(self, key, guiEvent=event)
- return False # finish event propagation?
-
- def key_release_event(self, widget, event):
- if _debug: print('FigureCanvasGTK3.%s' % fn_name())
- key = self._get_key(event)
- if _debug: print("release", key)
- FigureCanvasBase.key_release_event(self, key, guiEvent=event)
- return False # finish event propagation?
-
- def motion_notify_event(self, widget, event):
- if _debug: print('FigureCanvasGTK3.%s' % fn_name())
- if event.is_hint:
- t, x, y, state = event.window.get_pointer()
- else:
- x, y, state = event.x, event.y, event.get_state()
-
- # flipy so y=0 is bottom of canvas
- y = self.get_allocation().height - y
- FigureCanvasBase.motion_notify_event(self, x, y, guiEvent=event)
- return False # finish event propagation?
-
- def leave_notify_event(self, widget, event):
- FigureCanvasBase.leave_notify_event(self, event)
-
- def enter_notify_event(self, widget, event):
- FigureCanvasBase.enter_notify_event(self, event)
-
- def size_allocate(self, widget, allocation):
- if _debug:
- print("FigureCanvasGTK3.%s" % fn_name())
- print("size_allocate (%d x %d)" % (allocation.width, allocation.height))
- dpival = self.figure.dpi
- winch = allocation.width / dpival
- hinch = allocation.height / dpival
- self.figure.set_size_inches(winch, hinch)
- FigureCanvasBase.resize_event(self)
- self.draw_idle()
-
- def _get_key(self, event):
- if event.keyval in self.keyvald:
- key = self.keyvald[event.keyval]
- elif event.keyval < 256:
- key = chr(event.keyval)
- else:
- key = None
-
- modifiers = [
- (Gdk.ModifierType.MOD4_MASK, 'super'),
- (Gdk.ModifierType.MOD1_MASK, 'alt'),
- (Gdk.ModifierType.CONTROL_MASK, 'ctrl'),
- ]
- for key_mask, prefix in modifiers:
- if event.state & key_mask:
- key = '{0}+{1}'.format(prefix, key)
-
- return key
-
- def configure_event(self, widget, event):
- if _debug: print('FigureCanvasGTK3.%s' % fn_name())
- if widget.get_property("window") is None:
- return
- w, h = event.width, event.height
- if w < 3 or h < 3:
- return # empty fig
-
- # resize the figure (in inches)
- dpi = self.figure.dpi
- self.figure.set_size_inches (w/dpi, h/dpi)
- self._need_redraw = True
-
- return False # finish event propagation?
-
- def on_draw_event(self, widget, ctx):
- # to be overwritten by GTK3Agg or GTK3Cairo
- pass
-
- def draw(self):
- self._need_redraw = True
- if self.get_visible() and self.get_mapped():
- self.queue_draw()
- # do a synchronous draw (its less efficient than an async draw,
- # but is required if/when animation is used)
- self.get_property("window").process_updates (False)
-
- def draw_idle(self):
- def idle_draw(*args):
- try:
- self.draw()
- finally:
- self._idle_draw_id = 0
- return False
- if self._idle_draw_id == 0:
- self._idle_draw_id = GLib.idle_add(idle_draw)
-
- def new_timer(self, *args, **kwargs):
- """
- Creates a new backend-specific subclass of :class:`backend_bases.Timer`.
- This is useful for getting periodic events through the backend's native
- event loop. Implemented only for backends with GUIs.
-
- optional arguments:
-
- *interval*
- Timer interval in milliseconds
- *callbacks*
- Sequence of (func, args, kwargs) where func(*args, **kwargs) will
- be executed by the timer every *interval*.
- """
- return TimerGTK3(*args, **kwargs)
-
- def flush_events(self):
- Gdk.threads_enter()
- while Gtk.events_pending():
- Gtk.main_iteration(True)
- Gdk.flush()
- Gdk.threads_leave()
-
- def start_event_loop(self,timeout):
- FigureCanvasBase.start_event_loop_default(self,timeout)
- start_event_loop.__doc__=FigureCanvasBase.start_event_loop_default.__doc__
-
- def stop_event_loop(self):
- FigureCanvasBase.stop_event_loop_default(self)
- stop_event_loop.__doc__=FigureCanvasBase.stop_event_loop_default.__doc__
-
-
-class FigureManagerGTK3(FigureManagerBase):
- """
- Public attributes
-
- canvas : The FigureCanvas instance
- num : The Figure number
- toolbar : The Gtk.Toolbar (gtk only)
- vbox : The Gtk.VBox containing the canvas and toolbar (gtk only)
- window : The Gtk.Window (gtk only)
- """
- def __init__(self, canvas, num):
- if _debug: print('FigureManagerGTK3.%s' % fn_name())
- FigureManagerBase.__init__(self, canvas, num)
-
- self.window = Gtk.Window()
- self.set_window_title("Figure %d" % num)
- try:
- self.window.set_icon_from_file(window_icon)
- except (SystemExit, KeyboardInterrupt):
- # re-raise exit type Exceptions
- raise
- except:
- # some versions of gtk throw a glib.GError but not
- # all, so I am not sure how to catch it. I am unhappy
- # doing a blanket catch here, but am not sure what a
- # better way is - JDH
- verbose.report('Could not load matplotlib icon: %s' % sys.exc_info()[1])
-
- self.vbox = Gtk.Box()
- self.vbox.set_property("orientation", Gtk.Orientation.VERTICAL)
- self.window.add(self.vbox)
- self.vbox.show()
-
- self.canvas.show()
-
- self.vbox.pack_start(self.canvas, True, True, 0)
-
- self.toolbar = self._get_toolbar(canvas)
-
- # calculate size for window
- w = int (self.canvas.figure.bbox.width)
- h = int (self.canvas.figure.bbox.height)
-
- if self.toolbar is not None:
- self.toolbar.show()
- self.vbox.pack_end(self.toolbar, False, False, 0)
- size_request = self.toolbar.size_request()
- h += size_request.height
-
- self.window.set_default_size (w, h)
-
- def destroy(*args):
- Gcf.destroy(num)
- self.window.connect("destroy", destroy)
- self.window.connect("delete_event", destroy)
- if matplotlib.is_interactive():
- self.window.show()
-
- def notify_axes_change(fig):
- 'this will be called whenever the current axes is changed'
- if self.toolbar is not None: self.toolbar.update()
- self.canvas.figure.add_axobserver(notify_axes_change)
-
- self.canvas.grab_focus()
-
- def destroy(self, *args):
- if _debug: print('FigureManagerGTK3.%s' % fn_name())
- self.vbox.destroy()
- self.window.destroy()
- self.canvas.destroy()
- if self.toolbar:
- self.toolbar.destroy()
-
- if Gcf.get_num_fig_managers()==0 and \
- not matplotlib.is_interactive() and \
- Gtk.main_level() >= 1:
- Gtk.main_quit()
-
- def show(self):
- # show the figure window
- self.window.show()
-
- def full_screen_toggle (self):
- self._full_screen_flag = not self._full_screen_flag
- if self._full_screen_flag:
- self.window.fullscreen()
- else:
- self.window.unfullscreen()
- _full_screen_flag = False
-
-
- def _get_toolbar(self, canvas):
- # must be inited after the window, drawingArea and figure
- # attrs are set
- if rcParams['toolbar'] == 'toolbar2':
- toolbar = NavigationToolbar2GTK3 (canvas, self.window)
- else:
- toolbar = None
- return toolbar
-
- def get_window_title(self):
- return self.window.get_title()
-
- def set_window_title(self, title):
- self.window.set_title(title)
-
- def resize(self, width, height):
- 'set the canvas size in pixels'
- #_, _, cw, ch = self.canvas.allocation
- #_, _, ww, wh = self.window.allocation
- #self.window.resize (width-cw+ww, height-ch+wh)
- self.window.resize(width, height)
-
-
-class NavigationToolbar2GTK3(NavigationToolbar2, Gtk.Toolbar):
- def __init__(self, canvas, window):
- self.win = window
- GObject.GObject.__init__(self)
- NavigationToolbar2.__init__(self, canvas)
- self.ctx = None
-
- def set_message(self, s):
- self.message.set_label(s)
-
- def set_cursor(self, cursor):
- self.canvas.get_property("window").set_cursor(cursord[cursor])
- #self.canvas.set_cursor(cursord[cursor])
-
- def release(self, event):
- try: del self._pixmapBack
- except AttributeError: pass
-
- def dynamic_update(self):
- # legacy method; new method is canvas.draw_idle
- self.canvas.draw_idle()
-
- def draw_rubberband(self, event, x0, y0, x1, y1):
- 'adapted from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/189744'
- self.ctx = self.canvas.get_property("window").cairo_create()
-
- # todo: instead of redrawing the entire figure, copy the part of
- # the figure that was covered by the previous rubberband rectangle
- self.canvas.draw()
-
- height = self.canvas.figure.bbox.height
- y1 = height - y1
- y0 = height - y0
- w = abs(x1 - x0)
- h = abs(y1 - y0)
- rect = [int(val) for val in (min(x0,x1), min(y0, y1), w, h)]
-
- self.ctx.new_path()
- self.ctx.set_line_width(0.5)
- self.ctx.rectangle(rect[0], rect[1], rect[2], rect[3])
- self.ctx.set_source_rgb(0, 0, 0)
- self.ctx.stroke()
-
- def _init_toolbar(self):
- self.set_style(Gtk.ToolbarStyle.ICONS)
- basedir = os.path.join(rcParams['datapath'],'images')
-
- for text, tooltip_text, image_file, callback in self.toolitems:
- if text is None:
- self.insert( Gtk.SeparatorToolItem(), -1 )
- continue
- fname = os.path.join(basedir, image_file + '.png')
- image = Gtk.Image()
- image.set_from_file(fname)
- tbutton = Gtk.ToolButton()
- tbutton.set_label(text)
- tbutton.set_icon_widget(image)
- self.insert(tbutton, -1)
- tbutton.connect('clicked', getattr(self, callback))
- tbutton.set_tooltip_text(tooltip_text)
-
- toolitem = Gtk.SeparatorToolItem()
- self.insert(toolitem, -1)
- toolitem.set_draw(False)
- toolitem.set_expand(True)
-
- toolitem = Gtk.ToolItem()
- self.insert(toolitem, -1)
- self.message = Gtk.Label()
- toolitem.add(self.message)
-
- self.show_all()
-
- def get_filechooser(self):
- fc = FileChooserDialog(
- title='Save the figure',
- parent=self.win,
- path=os.path.expanduser(rcParams.get('savefig.directory', '')),
- filetypes=self.canvas.get_supported_filetypes(),
- default_filetype=self.canvas.get_default_filetype())
- fc.set_current_name(self.canvas.get_default_filename())
- return fc
-
- def save_figure(self, *args):
- chooser = self.get_filechooser()
- fname, format = chooser.get_filename_from_user()
- chooser.destroy()
- if fname:
- startpath = os.path.expanduser(rcParams.get('savefig.directory', ''))
- if startpath == '':
- # explicitly missing key or empty str signals to use cwd
- rcParams['savefig.directory'] = startpath
- else:
- # save dir for next time
- rcParams['savefig.directory'] = os.path.dirname(six.text_type(fname))
- try:
- self.canvas.print_figure(fname, format=format)
- except Exception as e:
- error_msg_gtk(str(e), parent=self)
-
- def configure_subplots(self, button):
- toolfig = Figure(figsize=(6,3))
- canvas = self._get_canvas(toolfig)
- toolfig.subplots_adjust(top=0.9)
- tool = SubplotTool(self.canvas.figure, toolfig)
-
- w = int (toolfig.bbox.width)
- h = int (toolfig.bbox.height)
-
-
- window = Gtk.Window()
- try:
- window.set_icon_from_file(window_icon)
- except (SystemExit, KeyboardInterrupt):
- # re-raise exit type Exceptions
- raise
- except:
- # we presumably already logged a message on the
- # failure of the main plot, don't keep reporting
- pass
- window.set_title("Subplot Configuration Tool")
- window.set_default_size(w, h)
- vbox = Gtk.Box()
- vbox.set_property("orientation", Gtk.Orientation.VERTICAL)
- window.add(vbox)
- vbox.show()
-
- canvas.show()
- vbox.pack_start(canvas, True, True, 0)
- window.show()
-
- def _get_canvas(self, fig):
- return self.canvas.__class__(fig)
-
-
-class FileChooserDialog(Gtk.FileChooserDialog):
- """GTK+ file selector which remembers the last file/directory
- selected and presents the user with a menu of supported image formats
- """
- def __init__ (self,
- title = 'Save file',
- parent = None,
- action = Gtk.FileChooserAction.SAVE,
- buttons = (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
- Gtk.STOCK_SAVE, Gtk.ResponseType.OK),
- path = None,
- filetypes = [],
- default_filetype = None
- ):
- super (FileChooserDialog, self).__init__ (title, parent, action,
- buttons)
- self.set_default_response (Gtk.ResponseType.OK)
-
- if not path: path = os.getcwd() + os.sep
-
- # create an extra widget to list supported image formats
- self.set_current_folder (path)
- self.set_current_name ('image.' + default_filetype)
-
- hbox = Gtk.Box(spacing=10)
- hbox.pack_start(Gtk.Label(label="File Format:"), False, False, 0)
-
- liststore = Gtk.ListStore(GObject.TYPE_STRING)
- cbox = Gtk.ComboBox() #liststore)
- cbox.set_model(liststore)
- cell = Gtk.CellRendererText()
- cbox.pack_start(cell, True)
- cbox.add_attribute(cell, 'text', 0)
- hbox.pack_start(cbox, False, False, 0)
-
- self.filetypes = filetypes
- self.sorted_filetypes = list(six.iteritems(filetypes))
- self.sorted_filetypes.sort()
- default = 0
- for i, (ext, name) in enumerate(self.sorted_filetypes):
- liststore.append(["%s (*.%s)" % (name, ext)])
- if ext == default_filetype:
- default = i
- cbox.set_active(default)
- self.ext = default_filetype
-
- def cb_cbox_changed (cbox, data=None):
- """File extension changed"""
- head, filename = os.path.split(self.get_filename())
- root, ext = os.path.splitext(filename)
- ext = ext[1:]
- new_ext = self.sorted_filetypes[cbox.get_active()][0]
- self.ext = new_ext
-
- if ext in self.filetypes:
- filename = root + '.' + new_ext
- elif ext == '':
- filename = filename.rstrip('.') + '.' + new_ext
-
- self.set_current_name (filename)
- cbox.connect ("changed", cb_cbox_changed)
-
- hbox.show_all()
- self.set_extra_widget(hbox)
-
- def get_filename_from_user (self):
- while True:
- filename = None
- if self.run() != int(Gtk.ResponseType.OK):
- break
- filename = self.get_filename()
- break
-
- return filename, self.ext
-
-class DialogLineprops:
- """
- A GUI dialog for controlling lineprops
- """
- signals = (
- 'on_combobox_lineprops_changed',
- 'on_combobox_linestyle_changed',
- 'on_combobox_marker_changed',
- 'on_colorbutton_linestyle_color_set',
- 'on_colorbutton_markerface_color_set',
- 'on_dialog_lineprops_okbutton_clicked',
- 'on_dialog_lineprops_cancelbutton_clicked',
- )
-
- linestyles = [ls for ls in lines.Line2D.lineStyles if ls.strip()]
- linestyled = dict([ (s,i) for i,s in enumerate(linestyles)])
-
-
- markers = [m for m in lines.Line2D.markers if cbook.is_string_like(m)]
-
- markerd = dict([(s,i) for i,s in enumerate(markers)])
-
- def __init__(self, lines):
- import Gtk.glade
-
- datadir = matplotlib.get_data_path()
- gladefile = os.path.join(datadir, 'lineprops.glade')
- if not os.path.exists(gladefile):
- raise IOError('Could not find gladefile lineprops.glade in %s'%datadir)
-
- self._inited = False
- self._updateson = True # suppress updates when setting widgets manually
- self.wtree = Gtk.glade.XML(gladefile, 'dialog_lineprops')
- self.wtree.signal_autoconnect(dict([(s, getattr(self, s)) for s in self.signals]))
-
- self.dlg = self.wtree.get_widget('dialog_lineprops')
-
- self.lines = lines
-
- cbox = self.wtree.get_widget('combobox_lineprops')
- cbox.set_active(0)
- self.cbox_lineprops = cbox
-
- cbox = self.wtree.get_widget('combobox_linestyles')
- for ls in self.linestyles:
- cbox.append_text(ls)
- cbox.set_active(0)
- self.cbox_linestyles = cbox
-
- cbox = self.wtree.get_widget('combobox_markers')
- for m in self.markers:
- cbox.append_text(m)
- cbox.set_active(0)
- self.cbox_markers = cbox
- self._lastcnt = 0
- self._inited = True
-
-
- def show(self):
- 'populate the combo box'
- self._updateson = False
- # flush the old
- cbox = self.cbox_lineprops
- for i in range(self._lastcnt-1,-1,-1):
- cbox.remove_text(i)
-
- # add the new
- for line in self.lines:
- cbox.append_text(line.get_label())
- cbox.set_active(0)
-
- self._updateson = True
- self._lastcnt = len(self.lines)
- self.dlg.show()
-
- def get_active_line(self):
- 'get the active line'
- ind = self.cbox_lineprops.get_active()
- line = self.lines[ind]
- return line
-
- def get_active_linestyle(self):
- 'get the active lineinestyle'
- ind = self.cbox_linestyles.get_active()
- ls = self.linestyles[ind]
- return ls
-
- def get_active_marker(self):
- 'get the active lineinestyle'
- ind = self.cbox_markers.get_active()
- m = self.markers[ind]
- return m
-
- def _update(self):
- 'update the active line props from the widgets'
- if not self._inited or not self._updateson: return
- line = self.get_active_line()
- ls = self.get_active_linestyle()
- marker = self.get_active_marker()
- line.set_linestyle(ls)
- line.set_marker(marker)
-
- button = self.wtree.get_widget('colorbutton_linestyle')
- color = button.get_color()
- r, g, b = [val/65535. for val in (color.red, color.green, color.blue)]
- line.set_color((r,g,b))
-
- button = self.wtree.get_widget('colorbutton_markerface')
- color = button.get_color()
- r, g, b = [val/65535. for val in (color.red, color.green, color.blue)]
- line.set_markerfacecolor((r,g,b))
-
- line.figure.canvas.draw()
-
- def on_combobox_lineprops_changed(self, item):
- 'update the widgets from the active line'
- if not self._inited: return
- self._updateson = False
- line = self.get_active_line()
-
- ls = line.get_linestyle()
- if ls is None: ls = 'None'
- self.cbox_linestyles.set_active(self.linestyled[ls])
-
- marker = line.get_marker()
- if marker is None: marker = 'None'
- self.cbox_markers.set_active(self.markerd[marker])
-
- r,g,b = colorConverter.to_rgb(line.get_color())
- color = Gdk.Color(*[int(val*65535) for val in (r,g,b)])
- button = self.wtree.get_widget('colorbutton_linestyle')
- button.set_color(color)
-
- r,g,b = colorConverter.to_rgb(line.get_markerfacecolor())
- color = Gdk.Color(*[int(val*65535) for val in (r,g,b)])
- button = self.wtree.get_widget('colorbutton_markerface')
- button.set_color(color)
- self._updateson = True
-
- def on_combobox_linestyle_changed(self, item):
- self._update()
-
- def on_combobox_marker_changed(self, item):
- self._update()
-
- def on_colorbutton_linestyle_color_set(self, button):
- self._update()
-
- def on_colorbutton_markerface_color_set(self, button):
- 'called colorbutton marker clicked'
- self._update()
-
- def on_dialog_lineprops_okbutton_clicked(self, button):
- self._update()
- self.dlg.hide()
-
- def on_dialog_lineprops_cancelbutton_clicked(self, button):
- self.dlg.hide()
-
-
-# Define the file to use as the GTk icon
-if sys.platform == 'win32':
- icon_filename = 'matplotlib.png'
-else:
- icon_filename = 'matplotlib.svg'
-window_icon = os.path.join(matplotlib.rcParams['datapath'], 'images', icon_filename)
-
-
-def error_msg_gtk(msg, parent=None):
- if parent is not None: # find the toplevel Gtk.Window
- parent = parent.get_toplevel()
- if not parent.is_toplevel():
- parent = None
-
- if not is_string_like(msg):
- msg = ','.join(map(str,msg))
-
- dialog = Gtk.MessageDialog(
- parent = parent,
- type = Gtk.MessageType.ERROR,
- buttons = Gtk.ButtonsType.OK,
- message_format = msg)
- dialog.run()
- dialog.destroy()
-
-
-FigureCanvas = FigureCanvasGTK3
-FigureManager = FigureManagerGTK3
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_gtk3agg.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_gtk3agg.py
deleted file mode 100644
index c3eb1da..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_gtk3agg.py
+++ /dev/null
@@ -1,124 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import numpy as np
-import sys
-import warnings
-
-from . import backend_agg
-from . import backend_gtk3
-from .backend_cairo import cairo, HAS_CAIRO_CFFI
-from matplotlib.figure import Figure
-from matplotlib import transforms
-
-if six.PY3 and not HAS_CAIRO_CFFI:
- warnings.warn(
- "The Gtk3Agg backend is known to not work on Python 3.x with pycairo. "
- "Try installing cairocffi.")
-
-
-class FigureCanvasGTK3Agg(backend_gtk3.FigureCanvasGTK3,
- backend_agg.FigureCanvasAgg):
- def __init__(self, figure):
- backend_gtk3.FigureCanvasGTK3.__init__(self, figure)
- self._bbox_queue = []
-
- def _renderer_init(self):
- pass
-
- def _render_figure(self, width, height):
- backend_agg.FigureCanvasAgg.draw(self)
-
- def on_draw_event(self, widget, ctx):
- """ GtkDrawable draw event, like expose_event in GTK 2.X
- """
- allocation = self.get_allocation()
- w, h = allocation.width, allocation.height
-
- if not len(self._bbox_queue):
- if self._need_redraw:
- self._render_figure(w, h)
- bbox_queue = [transforms.Bbox([[0, 0], [w, h]])]
- else:
- return
- else:
- bbox_queue = self._bbox_queue
-
- if HAS_CAIRO_CFFI:
- ctx = cairo.Context._from_pointer(
- cairo.ffi.cast('cairo_t **',
- id(ctx) + object.__basicsize__)[0],
- incref=True)
-
- for bbox in bbox_queue:
- area = self.copy_from_bbox(bbox)
- buf = np.fromstring(area.to_string_argb(), dtype='uint8')
-
- x = int(bbox.x0)
- y = h - int(bbox.y1)
- width = int(bbox.x1) - int(bbox.x0)
- height = int(bbox.y1) - int(bbox.y0)
-
- if HAS_CAIRO_CFFI:
- image = cairo.ImageSurface.create_for_data(
- buf.data, cairo.FORMAT_ARGB32, width, height)
- else:
- image = cairo.ImageSurface.create_for_data(
- buf, cairo.FORMAT_ARGB32, width, height)
- ctx.set_source_surface(image, x, y)
- ctx.paint()
-
- if len(self._bbox_queue):
- self._bbox_queue = []
-
- return False
-
- def blit(self, bbox=None):
- # If bbox is None, blit the entire canvas to gtk. Otherwise
- # blit only the area defined by the bbox.
- if bbox is None:
- bbox = self.figure.bbox
-
- allocation = self.get_allocation()
- w, h = allocation.width, allocation.height
- x = int(bbox.x0)
- y = h - int(bbox.y1)
- width = int(bbox.x1) - int(bbox.x0)
- height = int(bbox.y1) - int(bbox.y0)
-
- self._bbox_queue.append(bbox)
- self.queue_draw_area(x, y, width, height)
-
- def print_png(self, filename, *args, **kwargs):
- # Do this so we can save the resolution of figure in the PNG file
- agg = self.switch_backends(backend_agg.FigureCanvasAgg)
- return agg.print_png(filename, *args, **kwargs)
-
-
-class FigureManagerGTK3Agg(backend_gtk3.FigureManagerGTK3):
- pass
-
-
-def new_figure_manager(num, *args, **kwargs):
- """
- Create a new figure manager instance
- """
- FigureClass = kwargs.pop('FigureClass', Figure)
- thisFig = FigureClass(*args, **kwargs)
- return new_figure_manager_given_figure(num, thisFig)
-
-
-def new_figure_manager_given_figure(num, figure):
- """
- Create a new figure manager instance for the given figure.
- """
- canvas = FigureCanvasGTK3Agg(figure)
- manager = FigureManagerGTK3Agg(canvas, num)
- return manager
-
-
-FigureCanvas = FigureCanvasGTK3Agg
-FigureManager = FigureManagerGTK3Agg
-show = backend_gtk3.show
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_gtk3cairo.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_gtk3cairo.py
deleted file mode 100644
index da8f099..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_gtk3cairo.py
+++ /dev/null
@@ -1,75 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-from . import backend_gtk3
-from . import backend_cairo
-from .backend_cairo import cairo, HAS_CAIRO_CFFI
-from matplotlib.figure import Figure
-
-class RendererGTK3Cairo(backend_cairo.RendererCairo):
- def set_context(self, ctx):
- if HAS_CAIRO_CFFI:
- ctx = cairo.Context._from_pointer(
- cairo.ffi.cast(
- 'cairo_t **',
- id(ctx) + object.__basicsize__)[0],
- incref=True)
-
- self.gc.ctx = ctx
-
-
-class FigureCanvasGTK3Cairo(backend_gtk3.FigureCanvasGTK3,
- backend_cairo.FigureCanvasCairo):
- def __init__(self, figure):
- backend_gtk3.FigureCanvasGTK3.__init__(self, figure)
-
- def _renderer_init(self):
- """use cairo renderer"""
- self._renderer = RendererGTK3Cairo(self.figure.dpi)
-
- def _render_figure(self, width, height):
- self._renderer.set_width_height (width, height)
- self.figure.draw (self._renderer)
-
- def on_draw_event(self, widget, ctx):
- """ GtkDrawable draw event, like expose_event in GTK 2.X
- """
- # the _need_redraw flag doesnt work. it sometimes prevents
- # the rendering and leaving the canvas blank
- #if self._need_redraw:
- self._renderer.set_context(ctx)
- allocation = self.get_allocation()
- x, y, w, h = allocation.x, allocation.y, allocation.width, allocation.height
- self._render_figure(w, h)
- #self._need_redraw = False
-
- return False # finish event propagation?
-
-
-class FigureManagerGTK3Cairo(backend_gtk3.FigureManagerGTK3):
- pass
-
-
-def new_figure_manager(num, *args, **kwargs):
- """
- Create a new figure manager instance
- """
- FigureClass = kwargs.pop('FigureClass', Figure)
- thisFig = FigureClass(*args, **kwargs)
- return new_figure_manager_given_figure(num, thisFig)
-
-
-def new_figure_manager_given_figure(num, figure):
- """
- Create a new figure manager instance for the given figure.
- """
- canvas = FigureCanvasGTK3Cairo(figure)
- manager = FigureManagerGTK3Cairo(canvas, num)
- return manager
-
-
-FigureCanvas = FigureCanvasGTK3Cairo
-FigureManager = FigureManagerGTK3Cairo
-show = backend_gtk3.show
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_gtkagg.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_gtkagg.py
deleted file mode 100644
index 3e10841..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_gtkagg.py
+++ /dev/null
@@ -1,127 +0,0 @@
-"""
-Render to gtk from agg
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import os
-
-import matplotlib
-from matplotlib.figure import Figure
-from matplotlib.backends.backend_agg import FigureCanvasAgg
-from matplotlib.backends.backend_gtk import gtk, FigureManagerGTK, FigureCanvasGTK,\
- show, draw_if_interactive,\
- error_msg_gtk, PIXELS_PER_INCH, backend_version, \
- NavigationToolbar2GTK
-from matplotlib.backends._gtkagg import agg_to_gtk_drawable
-
-
-DEBUG = False
-
-class NavigationToolbar2GTKAgg(NavigationToolbar2GTK):
- def _get_canvas(self, fig):
- return FigureCanvasGTKAgg(fig)
-
-
-class FigureManagerGTKAgg(FigureManagerGTK):
- def _get_toolbar(self, canvas):
- # must be inited after the window, drawingArea and figure
- # attrs are set
- if matplotlib.rcParams['toolbar']=='toolbar2':
- toolbar = NavigationToolbar2GTKAgg (canvas, self.window)
- else:
- toolbar = None
- return toolbar
-
-
-def new_figure_manager(num, *args, **kwargs):
- """
- Create a new figure manager instance
- """
- if DEBUG: print('backend_gtkagg.new_figure_manager')
- FigureClass = kwargs.pop('FigureClass', Figure)
- thisFig = FigureClass(*args, **kwargs)
- return new_figure_manager_given_figure(num, thisFig)
-
-
-def new_figure_manager_given_figure(num, figure):
- """
- Create a new figure manager instance for the given figure.
- """
- canvas = FigureCanvasGTKAgg(figure)
- return FigureManagerGTKAgg(canvas, num)
- if DEBUG: print('backend_gtkagg.new_figure_manager done')
-
-
-class FigureCanvasGTKAgg(FigureCanvasGTK, FigureCanvasAgg):
- filetypes = FigureCanvasGTK.filetypes.copy()
- filetypes.update(FigureCanvasAgg.filetypes)
-
- def configure_event(self, widget, event=None):
-
- if DEBUG: print('FigureCanvasGTKAgg.configure_event')
- if widget.window is None:
- return
- try:
- del self.renderer
- except AttributeError:
- pass
- w,h = widget.window.get_size()
- if w==1 or h==1: return # empty fig
-
- # compute desired figure size in inches
- dpival = self.figure.dpi
- winch = w/dpival
- hinch = h/dpival
- self.figure.set_size_inches(winch, hinch)
- self._need_redraw = True
- self.resize_event()
- if DEBUG: print('FigureCanvasGTKAgg.configure_event end')
- return True
-
- def _render_figure(self, pixmap, width, height):
- if DEBUG: print('FigureCanvasGTKAgg.render_figure')
- FigureCanvasAgg.draw(self)
- if DEBUG: print('FigureCanvasGTKAgg.render_figure pixmap', pixmap)
- #agg_to_gtk_drawable(pixmap, self.renderer._renderer, None)
-
- buf = self.buffer_rgba()
- ren = self.get_renderer()
- w = int(ren.width)
- h = int(ren.height)
-
- pixbuf = gtk.gdk.pixbuf_new_from_data(
- buf, gtk.gdk.COLORSPACE_RGB, True, 8, w, h, w*4)
- pixmap.draw_pixbuf(pixmap.new_gc(), pixbuf, 0, 0, 0, 0, w, h,
- gtk.gdk.RGB_DITHER_NONE, 0, 0)
- if DEBUG: print('FigureCanvasGTKAgg.render_figure done')
-
- def blit(self, bbox=None):
- if DEBUG: print('FigureCanvasGTKAgg.blit', self._pixmap)
- agg_to_gtk_drawable(self._pixmap, self.renderer._renderer, bbox)
-
- x, y, w, h = self.allocation
-
- self.window.draw_drawable (self.style.fg_gc[self.state], self._pixmap,
- 0, 0, 0, 0, w, h)
- if DEBUG: print('FigureCanvasGTKAgg.done')
-
- def print_png(self, filename, *args, **kwargs):
- # Do this so we can save the resolution of figure in the PNG file
- agg = self.switch_backends(FigureCanvasAgg)
- return agg.print_png(filename, *args, **kwargs)
-
-
-"""\
-Traceback (most recent call last):
- File "/home/titan/johnh/local/lib/python2.3/site-packages/matplotlib/backends/backend_gtk.py", line 304, in expose_event
- self._render_figure(self._pixmap, w, h)
- File "/home/titan/johnh/local/lib/python2.3/site-packages/matplotlib/backends/backend_gtkagg.py", line 77, in _render_figure
- pixbuf = gtk.gdk.pixbuf_new_from_data(
-ValueError: data length (3156672) is less then required by the other parameters (3160608)
-"""
-
-FigureCanvas = FigureCanvasGTKAgg
-FigureManager = FigureManagerGTKAgg
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_gtkcairo.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_gtkcairo.py
deleted file mode 100644
index 93bb698..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_gtkcairo.py
+++ /dev/null
@@ -1,79 +0,0 @@
-"""
-GTK+ Matplotlib interface using cairo (not GDK) drawing operations.
-Author: Steve Chaplin
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import gtk
-if gtk.pygtk_version < (2,7,0):
- import cairo.gtk
-
-from matplotlib.backends import backend_cairo
-from matplotlib.backends.backend_gtk import *
-
-backend_version = 'PyGTK(%d.%d.%d) ' % gtk.pygtk_version + \
- 'Pycairo(%s)' % backend_cairo.backend_version
-
-
-_debug = False
-#_debug = True
-
-
-def new_figure_manager(num, *args, **kwargs):
- """
- Create a new figure manager instance
- """
- if _debug: print('backend_gtkcairo.%s()' % fn_name())
- FigureClass = kwargs.pop('FigureClass', Figure)
- thisFig = FigureClass(*args, **kwargs)
- return new_figure_manager_given_figure(num, thisFig)
-
-
-def new_figure_manager_given_figure(num, figure):
- """
- Create a new figure manager instance for the given figure.
- """
- canvas = FigureCanvasGTKCairo(figure)
- return FigureManagerGTK(canvas, num)
-
-
-class RendererGTKCairo (backend_cairo.RendererCairo):
- if gtk.pygtk_version >= (2,7,0):
- def set_pixmap (self, pixmap):
- self.gc.ctx = pixmap.cairo_create()
- else:
- def set_pixmap (self, pixmap):
- self.gc.ctx = cairo.gtk.gdk_cairo_create (pixmap)
-
-
-class FigureCanvasGTKCairo(backend_cairo.FigureCanvasCairo, FigureCanvasGTK):
- filetypes = FigureCanvasGTK.filetypes.copy()
- filetypes.update(backend_cairo.FigureCanvasCairo.filetypes)
-
- def _renderer_init(self):
- """Override to use cairo (rather than GDK) renderer"""
- if _debug: print('%s.%s()' % (self.__class__.__name__, _fn_name()))
- self._renderer = RendererGTKCairo (self.figure.dpi)
-
-
-class FigureManagerGTKCairo(FigureManagerGTK):
- def _get_toolbar(self, canvas):
- # must be inited after the window, drawingArea and figure
- # attrs are set
- if matplotlib.rcParams['toolbar']=='toolbar2':
- toolbar = NavigationToolbar2GTKCairo (canvas, self.window)
- else:
- toolbar = None
- return toolbar
-
-
-class NavigationToolbar2Cairo(NavigationToolbar2GTK):
- def _get_canvas(self, fig):
- return FigureCanvasGTKCairo(fig)
-
-
-FigureCanvas = FigureCanvasGTKCairo
-FigureManager = FigureManagerGTKCairo
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_macosx.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_macosx.py
deleted file mode 100644
index 371f687..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_macosx.py
+++ /dev/null
@@ -1,431 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import os
-import numpy
-
-from matplotlib._pylab_helpers import Gcf
-from matplotlib.backend_bases import RendererBase, GraphicsContextBase,\
- FigureManagerBase, FigureCanvasBase, NavigationToolbar2, TimerBase
-from matplotlib.backend_bases import ShowBase
-
-from matplotlib.cbook import maxdict
-from matplotlib.figure import Figure
-from matplotlib.path import Path
-from matplotlib.mathtext import MathTextParser
-from matplotlib.colors import colorConverter
-from matplotlib import rcParams
-
-from matplotlib.widgets import SubplotTool
-
-import matplotlib
-from matplotlib.backends import _macosx
-
-
-class Show(ShowBase):
- def mainloop(self):
- _macosx.show()
-show = Show()
-
-
-class RendererMac(RendererBase):
- """
- The renderer handles drawing/rendering operations. Most of the renderer's
- methods forward the command to the renderer's graphics context. The
- renderer does not wrap a C object and is written in pure Python.
- """
-
- texd = maxdict(50) # a cache of tex image rasters
-
- def __init__(self, dpi, width, height):
- RendererBase.__init__(self)
- self.dpi = dpi
- self.width = width
- self.height = height
- self.gc = GraphicsContextMac()
- self.gc.set_dpi(self.dpi)
- self.mathtext_parser = MathTextParser('MacOSX')
-
- def set_width_height (self, width, height):
- self.width, self.height = width, height
-
- def draw_path(self, gc, path, transform, rgbFace=None):
- if rgbFace is not None:
- rgbFace = tuple(rgbFace)
- linewidth = gc.get_linewidth()
- gc.draw_path(path, transform, linewidth, rgbFace)
-
- def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None):
- if rgbFace is not None:
- rgbFace = tuple(rgbFace)
- linewidth = gc.get_linewidth()
- gc.draw_markers(marker_path, marker_trans, path, trans, linewidth, rgbFace)
-
- def draw_path_collection(self, gc, master_transform, paths, all_transforms,
- offsets, offsetTrans, facecolors, edgecolors,
- linewidths, linestyles, antialiaseds, urls,
- offset_position):
- if offset_position=='data':
- offset_position = True
- else:
- offset_position = False
- path_ids = []
- for path, transform in self._iter_collection_raw_paths(
- master_transform, paths, all_transforms):
- path_ids.append((path, transform))
- master_transform = master_transform.get_matrix()
- offsetTrans = offsetTrans.get_matrix()
- gc.draw_path_collection(master_transform, path_ids, all_transforms,
- offsets, offsetTrans, facecolors, edgecolors,
- linewidths, linestyles, antialiaseds,
- offset_position)
-
- def draw_quad_mesh(self, gc, master_transform, meshWidth, meshHeight,
- coordinates, offsets, offsetTrans, facecolors,
- antialiased, edgecolors):
- gc.draw_quad_mesh(master_transform.get_matrix(),
- meshWidth,
- meshHeight,
- coordinates,
- offsets,
- offsetTrans.get_matrix(),
- facecolors,
- antialiased,
- edgecolors)
-
- def new_gc(self):
- self.gc.save()
- self.gc.set_hatch(None)
- self.gc._alpha = 1.0
- self.gc._forced_alpha = False # if True, _alpha overrides A from RGBA
- return self.gc
-
- def draw_gouraud_triangle(self, gc, points, colors, transform):
- points = transform.transform(points)
- gc.draw_gouraud_triangle(points, colors)
-
- def get_image_magnification(self):
- return self.gc.get_image_magnification()
-
- def draw_image(self, gc, x, y, im):
- im.flipud_out()
- nrows, ncols, data = im.as_rgba_str()
- gc.draw_image(x, y, nrows, ncols, data)
- im.flipud_out()
-
- def draw_tex(self, gc, x, y, s, prop, angle, ismath='TeX!', mtext=None):
- # todo, handle props, angle, origins
- scale = self.gc.get_image_magnification()
- size = prop.get_size_in_points()
- texmanager = self.get_texmanager()
- key = s, size, self.dpi, angle, texmanager.get_font_config()
- im = self.texd.get(key) # Not sure what this does; just copied from backend_agg.py
- if im is None:
- Z = texmanager.get_grey(s, size, self.dpi*scale)
- Z = numpy.array(255.0 - Z * 255.0, numpy.uint8)
-
- gc.draw_mathtext(x, y, angle, Z)
-
- def _draw_mathtext(self, gc, x, y, s, prop, angle):
- scale = self.gc.get_image_magnification()
- ox, oy, width, height, descent, image, used_characters = \
- self.mathtext_parser.parse(s, self.dpi*scale, prop)
- gc.draw_mathtext(x, y, angle, 255 - image.as_array())
-
- def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
- if ismath:
- self._draw_mathtext(gc, x, y, s, prop, angle)
- else:
- family = prop.get_family()
- weight = prop.get_weight()
- style = prop.get_style()
- points = prop.get_size_in_points()
- size = self.points_to_pixels(points)
- gc.draw_text(x, y, six.text_type(s), family, size, weight, style, angle)
-
- def get_text_width_height_descent(self, s, prop, ismath):
- if ismath=='TeX':
- # todo: handle props
- texmanager = self.get_texmanager()
- fontsize = prop.get_size_in_points()
- w, h, d = texmanager.get_text_width_height_descent(s, fontsize,
- renderer=self)
- return w, h, d
- if ismath:
- ox, oy, width, height, descent, fonts, used_characters = \
- self.mathtext_parser.parse(s, self.dpi, prop)
- return width, height, descent
- family = prop.get_family()
- weight = prop.get_weight()
- style = prop.get_style()
- points = prop.get_size_in_points()
- size = self.points_to_pixels(points)
- width, height, descent = self.gc.get_text_width_height_descent(
- six.text_type(s), family, size, weight, style)
- return width, height, 0.0*descent
-
- def flipy(self):
- return False
-
- def points_to_pixels(self, points):
- return points/72.0 * self.dpi
-
- def option_image_nocomposite(self):
- return True
-
-
-class GraphicsContextMac(_macosx.GraphicsContext, GraphicsContextBase):
- """
- The GraphicsContext wraps a Quartz graphics context. All methods
- are implemented at the C-level in macosx.GraphicsContext. These
- methods set drawing properties such as the line style, fill color,
- etc. The actual drawing is done by the Renderer, which draws into
- the GraphicsContext.
- """
- def __init__(self):
- GraphicsContextBase.__init__(self)
- _macosx.GraphicsContext.__init__(self)
-
- def set_alpha(self, alpha):
- GraphicsContextBase.set_alpha(self, alpha)
- _alpha = self.get_alpha()
- _macosx.GraphicsContext.set_alpha(self, _alpha, self.get_forced_alpha())
- rgb = self.get_rgb()
- _macosx.GraphicsContext.set_foreground(self, rgb)
-
- def set_foreground(self, fg, isRGBA=False):
- GraphicsContextBase.set_foreground(self, fg, isRGBA)
- rgb = self.get_rgb()
- _macosx.GraphicsContext.set_foreground(self, rgb)
-
- def set_graylevel(self, fg):
- GraphicsContextBase.set_graylevel(self, fg)
- _macosx.GraphicsContext.set_graylevel(self, fg)
-
- def set_clip_rectangle(self, box):
- GraphicsContextBase.set_clip_rectangle(self, box)
- if not box: return
- _macosx.GraphicsContext.set_clip_rectangle(self, box.bounds)
-
- def set_clip_path(self, path):
- GraphicsContextBase.set_clip_path(self, path)
- if not path: return
- path = path.get_fully_transformed_path()
- _macosx.GraphicsContext.set_clip_path(self, path)
-
-
-########################################################################
-#
-# The following functions and classes are for pylab and implement
-# window/figure managers, etc...
-#
-########################################################################
-
-def draw_if_interactive():
- """
- For performance reasons, we don't want to redraw the figure after
- each draw command. Instead, we mark the figure as invalid, so that
- it will be redrawn as soon as the event loop resumes via PyOS_InputHook.
- This function should be called after each draw event, even if
- matplotlib is not running interactively.
- """
- if matplotlib.is_interactive():
- figManager = Gcf.get_active()
- if figManager is not None:
- figManager.canvas.invalidate()
-
-
-def new_figure_manager(num, *args, **kwargs):
- """
- Create a new figure manager instance
- """
- FigureClass = kwargs.pop('FigureClass', Figure)
- figure = FigureClass(*args, **kwargs)
- return new_figure_manager_given_figure(num, figure)
-
-
-def new_figure_manager_given_figure(num, figure):
- """
- Create a new figure manager instance for the given figure.
- """
- canvas = FigureCanvasMac(figure)
- manager = FigureManagerMac(canvas, num)
- return manager
-
-
-class TimerMac(_macosx.Timer, TimerBase):
- '''
- Subclass of :class:`backend_bases.TimerBase` that uses CoreFoundation
- run loops for timer events.
-
- Attributes:
- * interval: The time between timer events in milliseconds. Default
- is 1000 ms.
- * single_shot: Boolean flag indicating whether this timer should
- operate as single shot (run once and then stop). Defaults to False.
- * callbacks: Stores list of (func, args) tuples that will be called
- upon timer events. This list can be manipulated directly, or the
- functions add_callback and remove_callback can be used.
- '''
- # completely implemented at the C-level (in _macosx.Timer)
-
-
-class FigureCanvasMac(_macosx.FigureCanvas, FigureCanvasBase):
- """
- The canvas the figure renders into. Calls the draw and print fig
- methods, creates the renderers, etc...
-
- Public attribute
-
- figure - A Figure instance
-
- Events such as button presses, mouse movements, and key presses
- are handled in the C code and the base class methods
- button_press_event, button_release_event, motion_notify_event,
- key_press_event, and key_release_event are called from there.
- """
-
- filetypes = FigureCanvasBase.filetypes.copy()
- filetypes['bmp'] = 'Windows bitmap'
- filetypes['jpeg'] = 'JPEG'
- filetypes['jpg'] = 'JPEG'
- filetypes['gif'] = 'Graphics Interchange Format'
- filetypes['tif'] = 'Tagged Image Format File'
- filetypes['tiff'] = 'Tagged Image Format File'
-
- def __init__(self, figure):
- FigureCanvasBase.__init__(self, figure)
- width, height = self.get_width_height()
- self.renderer = RendererMac(figure.dpi, width, height)
- _macosx.FigureCanvas.__init__(self, width, height)
-
- def resize(self, width, height):
- self.renderer.set_width_height(width, height)
- dpi = self.figure.dpi
- width /= dpi
- height /= dpi
- self.figure.set_size_inches(width, height)
-
- def _print_bitmap(self, filename, *args, **kwargs):
- # In backend_bases.py, print_figure changes the dpi of the figure.
- # But since we are essentially redrawing the picture, we need the
- # original dpi. Pick it up from the renderer.
- dpi = kwargs['dpi']
- old_dpi = self.figure.dpi
- self.figure.dpi = self.renderer.dpi
- width, height = self.figure.get_size_inches()
- width, height = width*dpi, height*dpi
- filename = six.text_type(filename)
- self.write_bitmap(filename, width, height, dpi)
- self.figure.dpi = old_dpi
-
- def print_bmp(self, filename, *args, **kwargs):
- self._print_bitmap(filename, *args, **kwargs)
-
- def print_jpg(self, filename, *args, **kwargs):
- self._print_bitmap(filename, *args, **kwargs)
-
- def print_jpeg(self, filename, *args, **kwargs):
- self._print_bitmap(filename, *args, **kwargs)
-
- def print_tif(self, filename, *args, **kwargs):
- self._print_bitmap(filename, *args, **kwargs)
-
- def print_tiff(self, filename, *args, **kwargs):
- self._print_bitmap(filename, *args, **kwargs)
-
- def print_gif(self, filename, *args, **kwargs):
- self._print_bitmap(filename, *args, **kwargs)
-
- def new_timer(self, *args, **kwargs):
- """
- Creates a new backend-specific subclass of :class:`backend_bases.Timer`.
- This is useful for getting periodic events through the backend's native
- event loop. Implemented only for backends with GUIs.
-
- optional arguments:
-
- *interval*
- Timer interval in milliseconds
- *callbacks*
- Sequence of (func, args, kwargs) where func(*args, **kwargs) will
- be executed by the timer every *interval*.
- """
- return TimerMac(*args, **kwargs)
-
-
-class FigureManagerMac(_macosx.FigureManager, FigureManagerBase):
- """
- Wrap everything up into a window for the pylab interface
- """
- def __init__(self, canvas, num):
- FigureManagerBase.__init__(self, canvas, num)
- title = "Figure %d" % num
- _macosx.FigureManager.__init__(self, canvas, title)
- if rcParams['toolbar']=='toolbar2':
- self.toolbar = NavigationToolbar2Mac(canvas)
- else:
- self.toolbar = None
- if self.toolbar is not None:
- self.toolbar.update()
-
- def notify_axes_change(fig):
- 'this will be called whenever the current axes is changed'
- if self.toolbar != None: self.toolbar.update()
- self.canvas.figure.add_axobserver(notify_axes_change)
-
- if matplotlib.is_interactive():
- self.show()
-
- def close(self):
- Gcf.destroy(self.num)
-
-
-class NavigationToolbar2Mac(_macosx.NavigationToolbar2, NavigationToolbar2):
-
- def __init__(self, canvas):
- NavigationToolbar2.__init__(self, canvas)
-
- def _init_toolbar(self):
- basedir = os.path.join(rcParams['datapath'], "images")
- _macosx.NavigationToolbar2.__init__(self, basedir)
-
- def draw_rubberband(self, event, x0, y0, x1, y1):
- self.canvas.set_rubberband(int(x0), int(y0), int(x1), int(y1))
-
- def release(self, event):
- self.canvas.remove_rubberband()
-
- def set_cursor(self, cursor):
- _macosx.set_cursor(cursor)
-
- def save_figure(self, *args):
- filename = _macosx.choose_save_file('Save the figure',
- self.canvas.get_default_filename())
- if filename is None: # Cancel
- return
- self.canvas.print_figure(filename)
-
- def prepare_configure_subplots(self):
- toolfig = Figure(figsize=(6,3))
- canvas = FigureCanvasMac(toolfig)
- toolfig.subplots_adjust(top=0.9)
- tool = SubplotTool(self.canvas.figure, toolfig)
- return canvas
-
- def set_message(self, message):
- _macosx.NavigationToolbar2.set_message(self, message.encode('utf-8'))
-
- def dynamic_update(self):
- self.canvas.draw_idle()
-
-########################################################################
-#
-# Now just provide the standard names that backend.__init__ is expecting
-#
-########################################################################
-
-FigureCanvas = FigureCanvasMac
-FigureManager = FigureManagerMac
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_mixed.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_mixed.py
deleted file mode 100644
index 85b3c42..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_mixed.py
+++ /dev/null
@@ -1,144 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-from matplotlib._image import frombuffer
-from matplotlib.backends.backend_agg import RendererAgg
-from matplotlib.tight_bbox import process_figure_for_rasterizing
-
-
-class MixedModeRenderer(object):
- """
- A helper class to implement a renderer that switches between
- vector and raster drawing. An example may be a PDF writer, where
- most things are drawn with PDF vector commands, but some very
- complex objects, such as quad meshes, are rasterised and then
- output as images.
- """
- def __init__(self, figure, width, height, dpi, vector_renderer,
- raster_renderer_class=None,
- bbox_inches_restore=None):
- """
- figure: The figure instance.
-
- width: The width of the canvas in logical units
-
- height: The height of the canvas in logical units
-
- dpi: The dpi of the canvas
-
- vector_renderer: An instance of a subclass of RendererBase
- that will be used for the vector drawing.
-
- raster_renderer_class: The renderer class to use for the
- raster drawing. If not provided, this will use the Agg
- backend (which is currently the only viable option anyway.)
- """
- if raster_renderer_class is None:
- raster_renderer_class = RendererAgg
-
- self._raster_renderer_class = raster_renderer_class
- self._width = width
- self._height = height
- self.dpi = dpi
-
- assert not vector_renderer.option_image_nocomposite()
- self._vector_renderer = vector_renderer
-
- self._raster_renderer = None
- self._rasterizing = 0
-
- # A reference to the figure is needed as we need to change
- # the figure dpi before and after the rasterization. Although
- # this looks ugly, I couldn't find a better solution. -JJL
- self.figure=figure
- self._figdpi = figure.get_dpi()
-
- self._bbox_inches_restore = bbox_inches_restore
-
- self._set_current_renderer(vector_renderer)
-
- _methods = """
- close_group draw_image draw_markers draw_path
- draw_path_collection draw_quad_mesh draw_tex draw_text
- finalize flipy get_canvas_width_height get_image_magnification
- get_texmanager get_text_width_height_descent new_gc open_group
- option_image_nocomposite points_to_pixels strip_math
- start_filter stop_filter draw_gouraud_triangle
- draw_gouraud_triangles option_scale_image
- _text2path _get_text_path_transform height width
- """.split()
- def _set_current_renderer(self, renderer):
- self._renderer = renderer
-
- for method in self._methods:
- if hasattr(renderer, method):
- setattr(self, method, getattr(renderer, method))
- renderer.start_rasterizing = self.start_rasterizing
- renderer.stop_rasterizing = self.stop_rasterizing
-
- def start_rasterizing(self):
- """
- Enter "raster" mode. All subsequent drawing commands (until
- stop_rasterizing is called) will be drawn with the raster
- backend.
-
- If start_rasterizing is called multiple times before
- stop_rasterizing is called, this method has no effect.
- """
-
- # change the dpi of the figure temporarily.
- self.figure.set_dpi(self.dpi)
-
- if self._bbox_inches_restore: # when tight bbox is used
- r = process_figure_for_rasterizing(self.figure,
- self._bbox_inches_restore)
- self._bbox_inches_restore = r
-
- if self._rasterizing == 0:
- self._raster_renderer = self._raster_renderer_class(
- self._width*self.dpi, self._height*self.dpi, self.dpi)
- self._set_current_renderer(self._raster_renderer)
- self._rasterizing += 1
-
- def stop_rasterizing(self):
- """
- Exit "raster" mode. All of the drawing that was done since
- the last start_rasterizing command will be copied to the
- vector backend by calling draw_image.
-
- If stop_rasterizing is called multiple times before
- start_rasterizing is called, this method has no effect.
- """
- self._rasterizing -= 1
- if self._rasterizing == 0:
- self._set_current_renderer(self._vector_renderer)
-
- width, height = self._width * self.dpi, self._height * self.dpi
- buffer, bounds = self._raster_renderer.tostring_rgba_minimized()
- l, b, w, h = bounds
- if w > 0 and h > 0:
- image = frombuffer(buffer, w, h, True)
- image.is_grayscale = False
- image.flipud_out()
- gc = self._renderer.new_gc()
- # TODO: If the mixedmode resolution differs from the figure's
- # dpi, the image must be scaled (dpi->_figdpi). Not all
- # backends support this.
- self._renderer.draw_image(
- gc,
- float(l) / self.dpi * self._figdpi,
- (float(height)-b-h) / self.dpi * self._figdpi,
- image)
- self._raster_renderer = None
- self._rasterizing = False
-
- # restore the figure dpi.
- self.figure.set_dpi(self._figdpi)
-
- if self._bbox_inches_restore: # when tight bbox is used
- r = process_figure_for_rasterizing(self.figure,
- self._bbox_inches_restore,
- self._figdpi)
- self._bbox_inches_restore = r
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_nbagg.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_nbagg.py
deleted file mode 100644
index 4950f87..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_nbagg.py
+++ /dev/null
@@ -1,293 +0,0 @@
-"""Interactive figures in the IPython notebook"""
-# Note: There is a notebook in
-# lib/matplotlib/backends/web_backend/nbagg_uat.ipynb to help verify
-# that changes made maintain expected behaviour.
-
-from base64 import b64encode
-from contextlib import contextmanager
-import json
-import io
-import os
-import six
-from uuid import uuid4 as uuid
-
-import tornado.ioloop
-
-from IPython.display import display, Javascript, HTML
-from IPython.kernel.comm import Comm
-
-from matplotlib import rcParams
-from matplotlib.figure import Figure
-from matplotlib.backends import backend_agg
-from matplotlib.backends.backend_webagg_core import (FigureManagerWebAgg,
- FigureCanvasWebAggCore,
- NavigationToolbar2WebAgg)
-from matplotlib.backend_bases import (ShowBase, NavigationToolbar2,
- TimerBase, FigureCanvasBase)
-
-
-class Show(ShowBase):
- def __call__(self, block=None):
- from matplotlib._pylab_helpers import Gcf
- from matplotlib import is_interactive
-
- managers = Gcf.get_all_fig_managers()
- if not managers:
- return
-
- interactive = is_interactive()
-
- for manager in managers:
- manager.show()
-
- # plt.figure adds an event which puts the figure in focus
- # in the activeQue. Disable this behaviour, as it results in
- # figures being put as the active figure after they have been
- # shown, even in non-interactive mode.
- if hasattr(manager, '_cidgcf'):
- manager.canvas.mpl_disconnect(manager._cidgcf)
-
- if not interactive and manager in Gcf._activeQue:
- Gcf._activeQue.remove(manager)
-
-show = Show()
-
-
-def draw_if_interactive():
- from matplotlib import is_interactive
- import matplotlib._pylab_helpers as pylab_helpers
-
- if is_interactive():
- manager = pylab_helpers.Gcf.get_active()
- if manager is not None:
- manager.show()
-
-
-def connection_info():
- """
- Return a string showing the figure and connection status for
- the backend. This is intended as a diagnostic tool, and not for general
- use.
-
- """
- from matplotlib._pylab_helpers import Gcf
- result = []
- for manager in Gcf.get_all_fig_managers():
- fig = manager.canvas.figure
- result.append('{} - {}'.format((fig.get_label() or
- "Figure {0}".format(manager.num)),
- manager.web_sockets))
- result.append('Figures pending show: {}'.format(len(Gcf._activeQue)))
- return '\n'.join(result)
-
-
-# Note: Version 3.2 and 4.x icons
-# http://fontawesome.io/3.2.1/icons/
-# http://fontawesome.io/
-# the `fa fa-xxx` part targets font-awesome 4, (IPython 3.x)
-# the icon-xxx targets font awesome 3.21 (IPython 2.x)
-_FONT_AWESOME_CLASSES = {
- 'home': 'fa fa-home icon-home',
- 'back': 'fa fa-arrow-left icon-arrow-left',
- 'forward': 'fa fa-arrow-right icon-arrow-right',
- 'zoom_to_rect': 'fa fa-square-o icon-check-empty',
- 'move': 'fa fa-arrows icon-move',
- 'download': 'fa fa-floppy-o icon-save',
- None: None
-}
-
-
-class NavigationIPy(NavigationToolbar2WebAgg):
-
- # Use the standard toolbar items + download button
- toolitems = [(text, tooltip_text,
- _FONT_AWESOME_CLASSES[image_file], name_of_method)
- for text, tooltip_text, image_file, name_of_method
- in (NavigationToolbar2.toolitems +
- (('Download', 'Download plot', 'download', 'download'),))
- if image_file in _FONT_AWESOME_CLASSES]
-
-
-class FigureManagerNbAgg(FigureManagerWebAgg):
- ToolbarCls = NavigationIPy
-
- def __init__(self, canvas, num):
- self._shown = False
- FigureManagerWebAgg.__init__(self, canvas, num)
-
- def display_js(self):
- # XXX How to do this just once? It has to deal with multiple
- # browser instances using the same kernel (require.js - but the
- # file isn't static?).
- display(Javascript(FigureManagerNbAgg.get_javascript()))
-
- def show(self):
- if not self._shown:
- self.display_js()
- self._create_comm()
- else:
- self.canvas.draw_idle()
- self._shown = True
-
- def reshow(self):
- """
- A special method to re-show the figure in the notebook.
-
- """
- self._shown = False
- self.show()
-
- @property
- def connected(self):
- return bool(self.web_sockets)
-
- @classmethod
- def get_javascript(cls, stream=None):
- if stream is None:
- output = io.StringIO()
- else:
- output = stream
- super(FigureManagerNbAgg, cls).get_javascript(stream=output)
- with io.open(os.path.join(
- os.path.dirname(__file__),
- "web_backend",
- "nbagg_mpl.js"), encoding='utf8') as fd:
- output.write(fd.read())
- if stream is None:
- return output.getvalue()
-
- def _create_comm(self):
- comm = CommSocket(self)
- self.add_web_socket(comm)
- return comm
-
- def destroy(self):
- self._send_event('close')
- for comm in self.web_sockets.copy():
- comm.on_close()
-
- def clearup_closed(self):
- """Clear up any closed Comms."""
- self.web_sockets = set([socket for socket in self.web_sockets
- if not socket.is_open()])
-
-
-class TimerTornado(TimerBase):
- def _timer_start(self):
- import datetime
- self._timer_stop()
- if self._single:
- ioloop = tornado.ioloop.IOLoop.instance()
- self._timer = ioloop.add_timeout(
- datetime.timedelta(milliseconds=self.interval),
- self._on_timer)
- else:
- self._timer = tornado.ioloop.PeriodicCallback(
- self._on_timer,
- self.interval)
- self._timer.start()
-
- def _timer_stop(self):
- if self._timer is not None:
- self._timer.stop()
- self._timer = None
-
- def _timer_set_interval(self):
- # Only stop and restart it if the timer has already been started
- if self._timer is not None:
- self._timer_stop()
- self._timer_start()
-
-
-class FigureCanvasNbAgg(FigureCanvasWebAggCore):
- def new_timer(self, *args, **kwargs):
- return TimerTornado(*args, **kwargs)
-
- def start_event_loop(self, timeout):
- FigureCanvasBase.start_event_loop_default(self, timeout)
-
- def stop_event_loop(self):
- FigureCanvasBase.stop_event_loop_default(self)
-
-
-def new_figure_manager(num, *args, **kwargs):
- """
- Create a new figure manager instance
- """
- FigureClass = kwargs.pop('FigureClass', Figure)
- thisFig = FigureClass(*args, **kwargs)
- return new_figure_manager_given_figure(num, thisFig)
-
-
-def new_figure_manager_given_figure(num, figure):
- """
- Create a new figure manager instance for the given figure.
- """
- canvas = FigureCanvasNbAgg(figure)
- if rcParams['nbagg.transparent']:
- figure.patch.set_alpha(0)
- manager = FigureManagerNbAgg(canvas, num)
- return manager
-
-
-class CommSocket(object):
- """
- Manages the Comm connection between IPython and the browser (client).
-
- Comms are 2 way, with the CommSocket being able to publish a message
- via the send_json method, and handle a message with on_message. On the
- JS side figure.send_message and figure.ws.onmessage do the sending and
- receiving respectively.
-
- """
- def __init__(self, manager):
- self.supports_binary = None
- self.manager = manager
- self.uuid = str(uuid())
- # Publish an output area with a unique ID. The javascript can then
- # hook into this area.
- display(HTML("" % self.uuid))
- try:
- self.comm = Comm('matplotlib', data={'id': self.uuid})
- except AttributeError:
- raise RuntimeError('Unable to create an IPython notebook Comm '
- 'instance. Are you in the IPython notebook?')
- self.comm.on_msg(self.on_message)
-
- manager = self.manager
- self.comm.on_close(lambda close_message: manager.clearup_closed())
-
- def is_open(self):
- return not self.comm._closed
-
- def on_close(self):
- # When the socket is closed, deregister the websocket with
- # the FigureManager.
- self.comm.close()
- self.manager.clearup_closed()
-
- def send_json(self, content):
- self.comm.send({'data': json.dumps(content)})
-
- def send_binary(self, blob):
- # The comm is ascii, so we always send the image in base64
- # encoded data URL form.
- data = b64encode(blob)
- if six.PY3:
- data = data.decode('ascii')
- data_uri = "data:image/png;base64,{0}".format(data)
- self.comm.send({'data': data_uri})
-
- def on_message(self, message):
- # The 'supports_binary' message is relevant to the
- # websocket itself. The other messages get passed along
- # to matplotlib as-is.
-
- # Every message has a "type" and a "figure_id".
- message = json.loads(message['content']['data'])
- if message['type'] == 'closing':
- self.on_close()
- elif message['type'] == 'supports_binary':
- self.supports_binary = message['value']
- else:
- self.manager.handle_json(message)
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_pdf.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_pdf.py
deleted file mode 100644
index 0f229a2..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_pdf.py
+++ /dev/null
@@ -1,2499 +0,0 @@
-# -*- coding: iso-8859-1 -*-
-
-"""
-A PDF matplotlib backend
-Author: Jouni K Sepp�nen
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import map
-
-import codecs
-import os
-import re
-import sys
-import time
-import warnings
-import zlib
-
-import numpy as np
-from six import unichr
-from six import BytesIO
-
-from datetime import datetime
-from math import ceil, cos, floor, pi, sin
-try:
- set
-except NameError:
- from sets import Set as set
-
-import matplotlib
-from matplotlib import __version__, rcParams
-from matplotlib._pylab_helpers import Gcf
-from matplotlib.backend_bases import RendererBase, GraphicsContextBase,\
- FigureManagerBase, FigureCanvasBase
-from matplotlib.backends.backend_mixed import MixedModeRenderer
-from matplotlib.cbook import Bunch, is_string_like, \
- get_realpath_and_stat, is_writable_file_like, maxdict
-from matplotlib.mlab import quad2cubic
-from matplotlib.figure import Figure
-from matplotlib.font_manager import findfont, is_opentype_cff_font
-from matplotlib.afm import AFM
-import matplotlib.type1font as type1font
-import matplotlib.dviread as dviread
-from matplotlib.ft2font import FT2Font, FIXED_WIDTH, ITALIC, LOAD_NO_SCALE, \
- LOAD_NO_HINTING, KERNING_UNFITTED
-from matplotlib.mathtext import MathTextParser
-from matplotlib.transforms import Affine2D, BboxBase
-from matplotlib.path import Path
-from matplotlib import ttconv
-
-# Overview
-#
-# The low-level knowledge about pdf syntax lies mainly in the pdfRepr
-# function and the classes Reference, Name, Operator, and Stream. The
-# PdfFile class knows about the overall structure of pdf documents.
-# It provides a "write" method for writing arbitrary strings in the
-# file, and an "output" method that passes objects through the pdfRepr
-# function before writing them in the file. The output method is
-# called by the RendererPdf class, which contains the various draw_foo
-# methods. RendererPdf contains a GraphicsContextPdf instance, and
-# each draw_foo calls self.check_gc before outputting commands. This
-# method checks whether the pdf graphics state needs to be modified
-# and outputs the necessary commands. GraphicsContextPdf represents
-# the graphics state, and its "delta" method returns the commands that
-# modify the state.
-
-# Add "pdf.use14corefonts: True" in your configuration file to use only
-# the 14 PDF core fonts. These fonts do not need to be embedded; every
-# PDF viewing application is required to have them. This results in very
-# light PDF files you can use directly in LaTeX or ConTeXt documents
-# generated with pdfTeX, without any conversion.
-
-# These fonts are: Helvetica, Helvetica-Bold, Helvetica-Oblique,
-# Helvetica-BoldOblique, Courier, Courier-Bold, Courier-Oblique,
-# Courier-BoldOblique, Times-Roman, Times-Bold, Times-Italic,
-# Times-BoldItalic, Symbol, ZapfDingbats.
-#
-# Some tricky points:
-#
-# 1. The clip path can only be widened by popping from the state
-# stack. Thus the state must be pushed onto the stack before narrowing
-# the clip path. This is taken care of by GraphicsContextPdf.
-#
-# 2. Sometimes it is necessary to refer to something (e.g., font,
-# image, or extended graphics state, which contains the alpha value)
-# in the page stream by a name that needs to be defined outside the
-# stream. PdfFile provides the methods fontName, imageObject, and
-# alphaState for this purpose. The implementations of these methods
-# should perhaps be generalized.
-
-# TODOs:
-#
-# * the alpha channel of images
-# * image compression could be improved (PDF supports png-like compression)
-# * encoding of fonts, including mathtext fonts and unicode support
-# * TTF support has lots of small TODOs, e.g., how do you know if a font
-# is serif/sans-serif, or symbolic/non-symbolic?
-# * draw_markers, draw_line_collection, etc.
-
-
-def fill(strings, linelen=75):
- """Make one string from sequence of strings, with whitespace
- in between. The whitespace is chosen to form lines of at most
- linelen characters, if possible."""
- currpos = 0
- lasti = 0
- result = []
- for i, s in enumerate(strings):
- length = len(s)
- if currpos + length < linelen:
- currpos += length + 1
- else:
- result.append(b' '.join(strings[lasti:i]))
- lasti = i
- currpos = length
- result.append(b' '.join(strings[lasti:]))
- return b'\n'.join(result)
-
-# PDF strings are supposed to be able to include any eight-bit data,
-# except that unbalanced parens and backslashes must be escaped by a
-# backslash. However, sf bug #2708559 shows that the carriage return
-# character may get read as a newline; these characters correspond to
-# \gamma and \Omega in TeX's math font encoding. Escaping them fixes
-# the bug.
-_string_escape_regex = re.compile(br'([\\()\r\n])')
-
-
-def _string_escape(match):
- m = match.group(0)
- if m in br'\()':
- return b'\\' + m
- elif m == b'\n':
- return br'\n'
- elif m == b'\r':
- return br'\r'
- assert False
-
-
-def pdfRepr(obj):
- """Map Python objects to PDF syntax."""
-
- # Some objects defined later have their own pdfRepr method.
- if hasattr(obj, 'pdfRepr'):
- return obj.pdfRepr()
-
- # Floats. PDF does not have exponential notation (1.0e-10) so we
- # need to use %f with some precision. Perhaps the precision
- # should adapt to the magnitude of the number?
- elif isinstance(obj, (float, np.floating)):
- if not np.isfinite(obj):
- raise ValueError("Can only output finite numbers in PDF")
- r = ("%.10f" % obj).encode('ascii')
- return r.rstrip(b'0').rstrip(b'.')
-
- # Booleans. Needs to be tested before integers since
- # isinstance(True, int) is true.
- elif isinstance(obj, bool):
- return [b'false', b'true'][obj]
-
- # Integers are written as such.
- elif isinstance(obj, (six.integer_types, np.integer)):
- return ("%d" % obj).encode('ascii')
-
- # Unicode strings are encoded in UTF-16BE with byte-order mark.
- elif isinstance(obj, six.text_type):
- try:
- # But maybe it's really ASCII?
- s = obj.encode('ASCII')
- return pdfRepr(s)
- except UnicodeEncodeError:
- s = codecs.BOM_UTF16_BE + obj.encode('UTF-16BE')
- return pdfRepr(s)
-
- # Strings are written in parentheses, with backslashes and parens
- # escaped. Actually balanced parens are allowed, but it is
- # simpler to escape them all. TODO: cut long strings into lines;
- # I believe there is some maximum line length in PDF.
- elif isinstance(obj, bytes):
- return b'(' + _string_escape_regex.sub(_string_escape, obj) + b')'
-
- # Dictionaries. The keys must be PDF names, so if we find strings
- # there, we make Name objects from them. The values may be
- # anything, so the caller must ensure that PDF names are
- # represented as Name objects.
- elif isinstance(obj, dict):
- r = [b"<<"]
- r.extend([Name(key).pdfRepr() + b" " + pdfRepr(val)
- for key, val in six.iteritems(obj)])
- r.append(b">>")
- return fill(r)
-
- # Lists.
- elif isinstance(obj, (list, tuple)):
- r = [b"["]
- r.extend([pdfRepr(val) for val in obj])
- r.append(b"]")
- return fill(r)
-
- # The null keyword.
- elif obj is None:
- return b'null'
-
- # A date.
- elif isinstance(obj, datetime):
- r = obj.strftime('D:%Y%m%d%H%M%S')
- if time.daylight:
- z = time.altzone
- else:
- z = time.timezone
- if z == 0:
- r += 'Z'
- elif z < 0:
- r += "+%02d'%02d'" % ((-z) // 3600, (-z) % 3600)
- else:
- r += "-%02d'%02d'" % (z // 3600, z % 3600)
- return pdfRepr(r)
-
- # A bounding box
- elif isinstance(obj, BboxBase):
- return fill([pdfRepr(val) for val in obj.bounds])
-
- else:
- msg = "Don't know a PDF representation for %s objects." % type(obj)
- raise TypeError(msg)
-
-
-class Reference(object):
- """PDF reference object.
- Use PdfFile.reserveObject() to create References.
- """
-
- def __init__(self, id):
- self.id = id
-
- def __repr__(self):
- return "" % self.id
-
- def pdfRepr(self):
- return ("%d 0 R" % self.id).encode('ascii')
-
- def write(self, contents, file):
- write = file.write
- write(("%d 0 obj\n" % self.id).encode('ascii'))
- write(pdfRepr(contents))
- write(b"\nendobj\n")
-
-
-class Name(object):
- """PDF name object."""
- __slots__ = ('name',)
- _regex = re.compile(r'[^!-~]')
-
- def __init__(self, name):
- if isinstance(name, Name):
- self.name = name.name
- else:
- if isinstance(name, bytes):
- name = name.decode('ascii')
- self.name = self._regex.sub(Name.hexify, name).encode('ascii')
-
- def __repr__(self):
- return "" % self.name
-
- def __str__(self):
- return '/' + six.text_type(self.name)
-
- @staticmethod
- def hexify(match):
- return '#%02x' % ord(match.group())
-
- def pdfRepr(self):
- return b'/' + self.name
-
-
-class Operator(object):
- """PDF operator object."""
- __slots__ = ('op',)
-
- def __init__(self, op):
- self.op = op
-
- def __repr__(self):
- return '' % self.op
-
- def pdfRepr(self):
- return self.op
-
-# PDF operators (not an exhaustive list)
-_pdfops = dict(
- close_fill_stroke=b'b', fill_stroke=b'B', fill=b'f', closepath=b'h',
- close_stroke=b's', stroke=b'S', endpath=b'n', begin_text=b'BT',
- end_text=b'ET', curveto=b'c', rectangle=b're', lineto=b'l', moveto=b'm',
- concat_matrix=b'cm', use_xobject=b'Do', setgray_stroke=b'G',
- setgray_nonstroke=b'g', setrgb_stroke=b'RG', setrgb_nonstroke=b'rg',
- setcolorspace_stroke=b'CS', setcolorspace_nonstroke=b'cs',
- setcolor_stroke=b'SCN', setcolor_nonstroke=b'scn', setdash=b'd',
- setlinejoin=b'j', setlinecap=b'J', setgstate=b'gs', gsave=b'q',
- grestore=b'Q', textpos=b'Td', selectfont=b'Tf', textmatrix=b'Tm',
- show=b'Tj', showkern=b'TJ', setlinewidth=b'w', clip=b'W', shading=b'sh')
-
-Op = Bunch(**dict([(name, Operator(value))
- for name, value in six.iteritems(_pdfops)]))
-
-
-def _paint_path(closep, fillp, strokep):
- """Return the PDF operator to paint a path in the following way:
- closep: close the path before painting
- fillp: fill the path with the fill color
- strokep: stroke the outline of the path with the line color"""
- if strokep:
- if closep:
- if fillp:
- return Op.close_fill_stroke
- else:
- return Op.close_stroke
- else:
- if fillp:
- return Op.fill_stroke
- else:
- return Op.stroke
- else:
- if fillp:
- return Op.fill
- else:
- return Op.endpath
-Op.paint_path = _paint_path
-
-
-class Stream(object):
- """PDF stream object.
-
- This has no pdfRepr method. Instead, call begin(), then output the
- contents of the stream by calling write(), and finally call end().
- """
- __slots__ = ('id', 'len', 'pdfFile', 'file', 'compressobj', 'extra', 'pos')
-
- def __init__(self, id, len, file, extra=None):
- """id: object id of stream; len: an unused Reference object for the
- length of the stream, or None (to use a memory buffer); file:
- a PdfFile; extra: a dictionary of extra key-value pairs to
- include in the stream header """
- self.id = id # object id
- self.len = len # id of length object
- self.pdfFile = file
- self.file = file.fh # file to which the stream is written
- self.compressobj = None # compression object
- if extra is None:
- self.extra = dict()
- else:
- self.extra = extra
-
- self.pdfFile.recordXref(self.id)
- if rcParams['pdf.compression']:
- self.compressobj = zlib.compressobj(rcParams['pdf.compression'])
- if self.len is None:
- self.file = BytesIO()
- else:
- self._writeHeader()
- self.pos = self.file.tell()
-
- def _writeHeader(self):
- write = self.file.write
- write(("%d 0 obj\n" % self.id).encode('ascii'))
- dict = self.extra
- dict['Length'] = self.len
- if rcParams['pdf.compression']:
- dict['Filter'] = Name('FlateDecode')
-
- write(pdfRepr(dict))
- write(b"\nstream\n")
-
- def end(self):
- """Finalize stream."""
-
- self._flush()
- if self.len is None:
- contents = self.file.getvalue()
- self.len = len(contents)
- self.file = self.pdfFile.fh
- self._writeHeader()
- self.file.write(contents)
- self.file.write(b"\nendstream\nendobj\n")
- else:
- length = self.file.tell() - self.pos
- self.file.write(b"\nendstream\nendobj\n")
- self.pdfFile.writeObject(self.len, length)
-
- def write(self, data):
- """Write some data on the stream."""
-
- if self.compressobj is None:
- self.file.write(data)
- else:
- compressed = self.compressobj.compress(data)
- self.file.write(compressed)
-
- def _flush(self):
- """Flush the compression object."""
-
- if self.compressobj is not None:
- compressed = self.compressobj.flush()
- self.file.write(compressed)
- self.compressobj = None
-
-
-class PdfFile(object):
- """PDF file object."""
-
- def __init__(self, filename):
- self.nextObject = 1 # next free object id
- self.xrefTable = [[0, 65535, 'the zero object']]
- self.passed_in_file_object = False
- self.original_file_like = None
- self.tell_base = 0
- if is_string_like(filename):
- fh = open(filename, 'wb')
- elif is_writable_file_like(filename):
- try:
- self.tell_base = filename.tell()
- except IOError:
- fh = BytesIO()
- self.original_file_like = filename
- else:
- fh = filename
- self.passed_in_file_object = True
- else:
- raise ValueError("filename must be a path or a file-like object")
-
- self._core14fontdir = os.path.join(
- rcParams['datapath'], 'fonts', 'pdfcorefonts')
- self.fh = fh
- self.currentstream = None # stream object to write to, if any
- fh.write(b"%PDF-1.4\n") # 1.4 is the first version to have alpha
- # Output some eight-bit chars as a comment so various utilities
- # recognize the file as binary by looking at the first few
- # lines (see note in section 3.4.1 of the PDF reference).
- fh.write(b"%\254\334 \253\272\n")
-
- self.rootObject = self.reserveObject('root')
- self.pagesObject = self.reserveObject('pages')
- self.pageList = []
- self.fontObject = self.reserveObject('fonts')
- self.alphaStateObject = self.reserveObject('extended graphics states')
- self.hatchObject = self.reserveObject('tiling patterns')
- self.gouraudObject = self.reserveObject('Gouraud triangles')
- self.XObjectObject = self.reserveObject('external objects')
- self.resourceObject = self.reserveObject('resources')
-
- root = {'Type': Name('Catalog'),
- 'Pages': self.pagesObject}
- self.writeObject(self.rootObject, root)
-
- revision = ''
- self.infoDict = {
- 'Creator': 'matplotlib %s, http://matplotlib.org' % __version__,
- 'Producer': 'matplotlib pdf backend%s' % revision,
- 'CreationDate': datetime.today()
- }
-
- self.fontNames = {} # maps filenames to internal font names
- self.nextFont = 1 # next free internal font name
- self.dviFontInfo = {} # information on dvi fonts
- self.type1Descriptors = {} # differently encoded Type-1 fonts may
- # share the same descriptor
- self.used_characters = {}
-
- self.alphaStates = {} # maps alpha values to graphics state objects
- self.nextAlphaState = 1
- self.hatchPatterns = {}
- self.nextHatch = 1
- self.gouraudTriangles = []
-
- self.images = {}
- self.nextImage = 1
-
- self.markers = {}
- self.multi_byte_charprocs = {}
-
- self.paths = []
-
- # The PDF spec recommends to include every procset
- procsets = [Name(x)
- for x in "PDF Text ImageB ImageC ImageI".split()]
-
- # Write resource dictionary.
- # Possibly TODO: more general ExtGState (graphics state dictionaries)
- # ColorSpace Pattern Shading Properties
- resources = {'Font': self.fontObject,
- 'XObject': self.XObjectObject,
- 'ExtGState': self.alphaStateObject,
- 'Pattern': self.hatchObject,
- 'Shading': self.gouraudObject,
- 'ProcSet': procsets}
- self.writeObject(self.resourceObject, resources)
-
- def newPage(self, width, height):
- self.endStream()
-
- self.width, self.height = width, height
- contentObject = self.reserveObject('page contents')
- thePage = {'Type': Name('Page'),
- 'Parent': self.pagesObject,
- 'Resources': self.resourceObject,
- 'MediaBox': [0, 0, 72 * width, 72 * height],
- 'Contents': contentObject,
- 'Group': {'Type': Name('Group'),
- 'S': Name('Transparency'),
- 'CS': Name('DeviceRGB')}
- }
- pageObject = self.reserveObject('page')
- self.writeObject(pageObject, thePage)
- self.pageList.append(pageObject)
-
- self.beginStream(contentObject.id,
- self.reserveObject('length of content stream'))
- # Initialize the pdf graphics state to match the default mpl
- # graphics context: currently only the join style needs to be set
- self.output(GraphicsContextPdf.joinstyles['round'], Op.setlinejoin)
-
- def close(self):
- self.endStream()
- # Write out the various deferred objects
- self.writeFonts()
- self.writeObject(self.alphaStateObject,
- dict([(val[0], val[1])
- for val in six.itervalues(self.alphaStates)]))
- self.writeHatches()
- self.writeGouraudTriangles()
- xobjects = dict(six.itervalues(self.images))
- for tup in six.itervalues(self.markers):
- xobjects[tup[0]] = tup[1]
- for name, value in six.iteritems(self.multi_byte_charprocs):
- xobjects[name] = value
- for name, path, trans, ob, join, cap, padding, filled, stroked \
- in self.paths:
- xobjects[name] = ob
- self.writeObject(self.XObjectObject, xobjects)
- self.writeImages()
- self.writeMarkers()
- self.writePathCollectionTemplates()
- self.writeObject(self.pagesObject,
- {'Type': Name('Pages'),
- 'Kids': self.pageList,
- 'Count': len(self.pageList)})
- self.writeInfoDict()
-
- # Finalize the file
- self.writeXref()
- self.writeTrailer()
- if self.passed_in_file_object:
- self.fh.flush()
- elif self.original_file_like is not None:
- self.original_file_like.write(self.fh.getvalue())
- self.fh.close()
- else:
- self.fh.close()
-
- def write(self, data):
- if self.currentstream is None:
- self.fh.write(data)
- else:
- self.currentstream.write(data)
-
- def output(self, *data):
- self.write(fill(list(map(pdfRepr, data))))
- self.write(b'\n')
-
- def beginStream(self, id, len, extra=None):
- assert self.currentstream is None
- self.currentstream = Stream(id, len, self, extra)
-
- def endStream(self):
- if self.currentstream is not None:
- self.currentstream.end()
- self.currentstream = None
-
- def fontName(self, fontprop):
- """
- Select a font based on fontprop and return a name suitable for
- Op.selectfont. If fontprop is a string, it will be interpreted
- as the filename (or dvi name) of the font.
- """
-
- if is_string_like(fontprop):
- filename = fontprop
- elif rcParams['pdf.use14corefonts']:
- filename = findfont(
- fontprop, fontext='afm', directory=self._core14fontdir)
- if filename is None:
- filename = findfont(
- "Helvetica", fontext='afm', directory=self._core14fontdir)
- else:
- filename = findfont(fontprop)
-
- Fx = self.fontNames.get(filename)
- if Fx is None:
- Fx = Name('F%d' % self.nextFont)
- self.fontNames[filename] = Fx
- self.nextFont += 1
- matplotlib.verbose.report(
- 'Assigning font %s = %r' % (Fx, filename),
- 'debug')
-
- return Fx
-
- def writeFonts(self):
- fonts = {}
- for filename, Fx in six.iteritems(self.fontNames):
- matplotlib.verbose.report('Embedding font %s' % filename, 'debug')
- if filename.endswith('.afm'):
- # from pdf.use14corefonts
- matplotlib.verbose.report('Writing AFM font', 'debug')
- fonts[Fx] = self._write_afm_font(filename)
- elif filename in self.dviFontInfo:
- # a Type 1 font from a dvi file;
- # the filename is really the TeX name
- matplotlib.verbose.report('Writing Type-1 font', 'debug')
- fonts[Fx] = self.embedTeXFont(filename,
- self.dviFontInfo[filename])
- else:
- # a normal TrueType font
- matplotlib.verbose.report('Writing TrueType font', 'debug')
- realpath, stat_key = get_realpath_and_stat(filename)
- chars = self.used_characters.get(stat_key)
- if chars is not None and len(chars[1]):
- fonts[Fx] = self.embedTTF(realpath, chars[1])
- self.writeObject(self.fontObject, fonts)
-
- def _write_afm_font(self, filename):
- with open(filename, 'rb') as fh:
- font = AFM(fh)
- fontname = font.get_fontname()
- fontdict = {'Type': Name('Font'),
- 'Subtype': Name('Type1'),
- 'BaseFont': Name(fontname),
- 'Encoding': Name('WinAnsiEncoding')}
- fontdictObject = self.reserveObject('font dictionary')
- self.writeObject(fontdictObject, fontdict)
- return fontdictObject
-
- def embedTeXFont(self, texname, fontinfo):
- msg = ('Embedding TeX font ' + texname + ' - fontinfo=' +
- repr(fontinfo.__dict__))
- matplotlib.verbose.report(msg, 'debug')
-
- # Widths
- widthsObject = self.reserveObject('font widths')
- self.writeObject(widthsObject, fontinfo.dvifont.widths)
-
- # Font dictionary
- fontdictObject = self.reserveObject('font dictionary')
- fontdict = {
- 'Type': Name('Font'),
- 'Subtype': Name('Type1'),
- 'FirstChar': 0,
- 'LastChar': len(fontinfo.dvifont.widths) - 1,
- 'Widths': widthsObject,
- }
-
- # Encoding (if needed)
- if fontinfo.encodingfile is not None:
- enc = dviread.Encoding(fontinfo.encodingfile)
- differencesArray = [Name(ch) for ch in enc]
- differencesArray = [0] + differencesArray
- fontdict['Encoding'] = \
- {'Type': Name('Encoding'),
- 'Differences': differencesArray}
-
- # If no file is specified, stop short
- if fontinfo.fontfile is None:
- msg = ('Because of TeX configuration (pdftex.map, see updmap '
- 'option pdftexDownloadBase14) the font {0} is not '
- 'embedded. This is deprecated as of PDF 1.5 and it may '
- 'cause the consumer application to show something that '
- 'was not intended.').format(fontinfo.basefont)
- warnings.warn(msg)
- fontdict['BaseFont'] = Name(fontinfo.basefont)
- self.writeObject(fontdictObject, fontdict)
- return fontdictObject
-
- # We have a font file to embed - read it in and apply any effects
- t1font = type1font.Type1Font(fontinfo.fontfile)
- if fontinfo.effects:
- t1font = t1font.transform(fontinfo.effects)
- fontdict['BaseFont'] = Name(t1font.prop['FontName'])
-
- # Font descriptors may be shared between differently encoded
- # Type-1 fonts, so only create a new descriptor if there is no
- # existing descriptor for this font.
- effects = (fontinfo.effects.get('slant', 0.0),
- fontinfo.effects.get('extend', 1.0))
- fontdesc = self.type1Descriptors.get((fontinfo.fontfile, effects))
- if fontdesc is None:
- fontdesc = self.createType1Descriptor(t1font, fontinfo.fontfile)
- self.type1Descriptors[(fontinfo.fontfile, effects)] = fontdesc
- fontdict['FontDescriptor'] = fontdesc
-
- self.writeObject(fontdictObject, fontdict)
- return fontdictObject
-
- def createType1Descriptor(self, t1font, fontfile):
- # Create and write the font descriptor and the font file
- # of a Type-1 font
- fontdescObject = self.reserveObject('font descriptor')
- fontfileObject = self.reserveObject('font file')
-
- italic_angle = t1font.prop['ItalicAngle']
- fixed_pitch = t1font.prop['isFixedPitch']
-
- flags = 0
- # fixed width
- if fixed_pitch:
- flags |= 1 << 0
- # TODO: serif
- if 0:
- flags |= 1 << 1
- # TODO: symbolic (most TeX fonts are)
- if 1:
- flags |= 1 << 2
- # non-symbolic
- else:
- flags |= 1 << 5
- # italic
- if italic_angle:
- flags |= 1 << 6
- # TODO: all caps
- if 0:
- flags |= 1 << 16
- # TODO: small caps
- if 0:
- flags |= 1 << 17
- # TODO: force bold
- if 0:
- flags |= 1 << 18
-
- ft2font = FT2Font(fontfile)
-
- descriptor = {
- 'Type': Name('FontDescriptor'),
- 'FontName': Name(t1font.prop['FontName']),
- 'Flags': flags,
- 'FontBBox': ft2font.bbox,
- 'ItalicAngle': italic_angle,
- 'Ascent': ft2font.ascender,
- 'Descent': ft2font.descender,
- 'CapHeight': 1000, # TODO: find this out
- 'XHeight': 500, # TODO: this one too
- 'FontFile': fontfileObject,
- 'FontFamily': t1font.prop['FamilyName'],
- 'StemV': 50, # TODO
- # (see also revision 3874; but not all TeX distros have AFM files!)
- #'FontWeight': a number where 400 = Regular, 700 = Bold
- }
-
- self.writeObject(fontdescObject, descriptor)
-
- self.beginStream(fontfileObject.id, None,
- {'Length1': len(t1font.parts[0]),
- 'Length2': len(t1font.parts[1]),
- 'Length3': 0})
- self.currentstream.write(t1font.parts[0])
- self.currentstream.write(t1font.parts[1])
- self.endStream()
-
- return fontdescObject
-
- def _get_xobject_symbol_name(self, filename, symbol_name):
- return "%s-%s" % (
- os.path.splitext(os.path.basename(filename))[0],
- symbol_name)
-
- _identityToUnicodeCMap = """/CIDInit /ProcSet findresource begin
-12 dict begin
-begincmap
-/CIDSystemInfo
-<< /Registry (Adobe)
- /Ordering (UCS)
- /Supplement 0
->> def
-/CMapName /Adobe-Identity-UCS def
-/CMapType 2 def
-1 begincodespacerange
-<0000>
-endcodespacerange
-%d beginbfrange
-%s
-endbfrange
-endcmap
-CMapName currentdict /CMap defineresource pop
-end
-end"""
-
- def embedTTF(self, filename, characters):
- """Embed the TTF font from the named file into the document."""
-
- font = FT2Font(filename)
- fonttype = rcParams['pdf.fonttype']
-
- def cvt(length, upe=font.units_per_EM, nearest=True):
- "Convert font coordinates to PDF glyph coordinates"
- value = length / upe * 1000
- if nearest:
- return round(value)
- # Perhaps best to round away from zero for bounding
- # boxes and the like
- if value < 0:
- return floor(value)
- else:
- return ceil(value)
-
- def embedTTFType3(font, characters, descriptor):
- """The Type 3-specific part of embedding a Truetype font"""
- widthsObject = self.reserveObject('font widths')
- fontdescObject = self.reserveObject('font descriptor')
- fontdictObject = self.reserveObject('font dictionary')
- charprocsObject = self.reserveObject('character procs')
- differencesArray = []
- firstchar, lastchar = 0, 255
- bbox = [cvt(x, nearest=False) for x in font.bbox]
-
- fontdict = {
- 'Type': Name('Font'),
- 'BaseFont': ps_name,
- 'FirstChar': firstchar,
- 'LastChar': lastchar,
- 'FontDescriptor': fontdescObject,
- 'Subtype': Name('Type3'),
- 'Name': descriptor['FontName'],
- 'FontBBox': bbox,
- 'FontMatrix': [.001, 0, 0, .001, 0, 0],
- 'CharProcs': charprocsObject,
- 'Encoding': {
- 'Type': Name('Encoding'),
- 'Differences': differencesArray},
- 'Widths': widthsObject
- }
-
- # Make the "Widths" array
- from encodings import cp1252
- # The "decoding_map" was changed
- # to a "decoding_table" as of Python 2.5.
- if hasattr(cp1252, 'decoding_map'):
- def decode_char(charcode):
- return cp1252.decoding_map[charcode] or 0
- else:
- def decode_char(charcode):
- return ord(cp1252.decoding_table[charcode])
-
- def get_char_width(charcode):
- s = decode_char(charcode)
- width = font.load_char(
- s, flags=LOAD_NO_SCALE | LOAD_NO_HINTING).horiAdvance
- return cvt(width)
-
- widths = [get_char_width(charcode)
- for charcode in range(firstchar, lastchar+1)]
- descriptor['MaxWidth'] = max(widths)
-
- # Make the "Differences" array, sort the ccodes < 255 from
- # the multi-byte ccodes, and build the whole set of glyph ids
- # that we need from this font.
- cmap = font.get_charmap()
- glyph_ids = []
- differences = []
- multi_byte_chars = set()
- for c in characters:
- ccode = c
- gind = cmap.get(ccode) or 0
- glyph_ids.append(gind)
- glyph_name = font.get_glyph_name(gind)
- if ccode <= 255:
- differences.append((ccode, glyph_name))
- else:
- multi_byte_chars.add(glyph_name)
- differences.sort()
-
- last_c = -2
- for c, name in differences:
- if c != last_c + 1:
- differencesArray.append(c)
- differencesArray.append(Name(name))
- last_c = c
-
- # Make the charprocs array (using ttconv to generate the
- # actual outlines)
- rawcharprocs = ttconv.get_pdf_charprocs(
- filename.encode(sys.getfilesystemencoding()), glyph_ids)
- charprocs = {}
- for charname, stream in six.iteritems(rawcharprocs):
- charprocDict = {'Length': len(stream)}
- # The 2-byte characters are used as XObjects, so they
- # need extra info in their dictionary
- if charname in multi_byte_chars:
- charprocDict['Type'] = Name('XObject')
- charprocDict['Subtype'] = Name('Form')
- charprocDict['BBox'] = bbox
- # Each glyph includes bounding box information,
- # but xpdf and ghostscript can't handle it in a
- # Form XObject (they segfault!!!), so we remove it
- # from the stream here. It's not needed anyway,
- # since the Form XObject includes it in its BBox
- # value.
- stream = stream[stream.find(b"d1") + 2:]
- charprocObject = self.reserveObject('charProc')
- self.beginStream(charprocObject.id, None, charprocDict)
- self.currentstream.write(stream)
- self.endStream()
-
- # Send the glyphs with ccode > 255 to the XObject dictionary,
- # and the others to the font itself
- if charname in multi_byte_chars:
- name = self._get_xobject_symbol_name(filename, charname)
- self.multi_byte_charprocs[name] = charprocObject
- else:
- charprocs[charname] = charprocObject
-
- # Write everything out
- self.writeObject(fontdictObject, fontdict)
- self.writeObject(fontdescObject, descriptor)
- self.writeObject(widthsObject, widths)
- self.writeObject(charprocsObject, charprocs)
-
- return fontdictObject
-
- def embedTTFType42(font, characters, descriptor):
- """The Type 42-specific part of embedding a Truetype font"""
- fontdescObject = self.reserveObject('font descriptor')
- cidFontDictObject = self.reserveObject('CID font dictionary')
- type0FontDictObject = self.reserveObject('Type 0 font dictionary')
- cidToGidMapObject = self.reserveObject('CIDToGIDMap stream')
- fontfileObject = self.reserveObject('font file stream')
- wObject = self.reserveObject('Type 0 widths')
- toUnicodeMapObject = self.reserveObject('ToUnicode map')
-
- cidFontDict = {
- 'Type': Name('Font'),
- 'Subtype': Name('CIDFontType2'),
- 'BaseFont': ps_name,
- 'CIDSystemInfo': {
- 'Registry': 'Adobe',
- 'Ordering': 'Identity',
- 'Supplement': 0},
- 'FontDescriptor': fontdescObject,
- 'W': wObject,
- 'CIDToGIDMap': cidToGidMapObject
- }
-
- type0FontDict = {
- 'Type': Name('Font'),
- 'Subtype': Name('Type0'),
- 'BaseFont': ps_name,
- 'Encoding': Name('Identity-H'),
- 'DescendantFonts': [cidFontDictObject],
- 'ToUnicode': toUnicodeMapObject
- }
-
- # Make fontfile stream
- descriptor['FontFile2'] = fontfileObject
- length1Object = self.reserveObject('decoded length of a font')
- self.beginStream(
- fontfileObject.id,
- self.reserveObject('length of font stream'),
- {'Length1': length1Object})
- with open(filename, 'rb') as fontfile:
- length1 = 0
- while True:
- data = fontfile.read(4096)
- if not data:
- break
- length1 += len(data)
- self.currentstream.write(data)
- self.endStream()
- self.writeObject(length1Object, length1)
-
- # Make the 'W' (Widths) array, CidToGidMap and ToUnicode CMap
- # at the same time
- cid_to_gid_map = ['\u0000'] * 65536
- cmap = font.get_charmap()
- widths = []
- max_ccode = 0
- for c in characters:
- ccode = c
- gind = cmap.get(ccode) or 0
- glyph = font.load_char(ccode, flags=LOAD_NO_HINTING)
- widths.append((ccode, glyph.horiAdvance / 6))
- if ccode < 65536:
- cid_to_gid_map[ccode] = unichr(gind)
- max_ccode = max(ccode, max_ccode)
- widths.sort()
- cid_to_gid_map = cid_to_gid_map[:max_ccode + 1]
-
- last_ccode = -2
- w = []
- max_width = 0
- unicode_groups = []
- for ccode, width in widths:
- if ccode != last_ccode + 1:
- w.append(ccode)
- w.append([width])
- unicode_groups.append([ccode, ccode])
- else:
- w[-1].append(width)
- unicode_groups[-1][1] = ccode
- max_width = max(max_width, width)
- last_ccode = ccode
-
- unicode_bfrange = []
- for start, end in unicode_groups:
- unicode_bfrange.append(
- "<%04x> <%04x> [%s]" %
- (start, end,
- " ".join(["<%04x>" % x for x in range(start, end+1)])))
- unicode_cmap = (self._identityToUnicodeCMap %
- (len(unicode_groups),
- "\n".join(unicode_bfrange))).encode('ascii')
-
- # CIDToGIDMap stream
- cid_to_gid_map = "".join(cid_to_gid_map).encode("utf-16be")
- self.beginStream(cidToGidMapObject.id,
- None,
- {'Length': len(cid_to_gid_map)})
- self.currentstream.write(cid_to_gid_map)
- self.endStream()
-
- # ToUnicode CMap
- self.beginStream(toUnicodeMapObject.id,
- None,
- {'Length': unicode_cmap})
- self.currentstream.write(unicode_cmap)
- self.endStream()
-
- descriptor['MaxWidth'] = max_width
-
- # Write everything out
- self.writeObject(cidFontDictObject, cidFontDict)
- self.writeObject(type0FontDictObject, type0FontDict)
- self.writeObject(fontdescObject, descriptor)
- self.writeObject(wObject, w)
-
- return type0FontDictObject
-
- # Beginning of main embedTTF function...
-
- # You are lost in a maze of TrueType tables, all different...
- sfnt = font.get_sfnt()
- try:
- ps_name = sfnt[(1, 0, 0, 6)].decode('macroman') # Macintosh scheme
- except KeyError:
- # Microsoft scheme:
- ps_name = sfnt[(3, 1, 0x0409, 6)].decode('utf-16be')
- # (see freetype/ttnameid.h)
- ps_name = ps_name.encode('ascii', 'replace')
- ps_name = Name(ps_name)
- pclt = font.get_sfnt_table('pclt') or {'capHeight': 0, 'xHeight': 0}
- post = font.get_sfnt_table('post') or {'italicAngle': (0, 0)}
- ff = font.face_flags
- sf = font.style_flags
-
- flags = 0
- symbolic = False # ps_name.name in ('Cmsy10', 'Cmmi10', 'Cmex10')
- if ff & FIXED_WIDTH:
- flags |= 1 << 0
- if 0: # TODO: serif
- flags |= 1 << 1
- if symbolic:
- flags |= 1 << 2
- else:
- flags |= 1 << 5
- if sf & ITALIC:
- flags |= 1 << 6
- if 0: # TODO: all caps
- flags |= 1 << 16
- if 0: # TODO: small caps
- flags |= 1 << 17
- if 0: # TODO: force bold
- flags |= 1 << 18
-
- descriptor = {
- 'Type': Name('FontDescriptor'),
- 'FontName': ps_name,
- 'Flags': flags,
- 'FontBBox': [cvt(x, nearest=False) for x in font.bbox],
- 'Ascent': cvt(font.ascender, nearest=False),
- 'Descent': cvt(font.descender, nearest=False),
- 'CapHeight': cvt(pclt['capHeight'], nearest=False),
- 'XHeight': cvt(pclt['xHeight']),
- 'ItalicAngle': post['italicAngle'][1], # ???
- 'StemV': 0 # ???
- }
-
- # The font subsetting to a Type 3 font does not work for
- # OpenType (.otf) that embed a Postscript CFF font, so avoid that --
- # save as a (non-subsetted) Type 42 font instead.
- if is_opentype_cff_font(filename):
- fonttype = 42
- msg = ("'%s' can not be subsetted into a Type 3 font. "
- "The entire font will be embedded in the output.")
- warnings.warn(msg % os.path.basename(filename))
-
- if fonttype == 3:
- return embedTTFType3(font, characters, descriptor)
- elif fonttype == 42:
- return embedTTFType42(font, characters, descriptor)
-
- def alphaState(self, alpha):
- """Return name of an ExtGState that sets alpha to the given value"""
-
- state = self.alphaStates.get(alpha, None)
- if state is not None:
- return state[0]
-
- name = Name('A%d' % self.nextAlphaState)
- self.nextAlphaState += 1
- self.alphaStates[alpha] = \
- (name, {'Type': Name('ExtGState'),
- 'CA': alpha[0], 'ca': alpha[1]})
- return name
-
- def hatchPattern(self, hatch_style):
- # The colors may come in as numpy arrays, which aren't hashable
- if hatch_style is not None:
- face, edge, hatch = hatch_style
- if face is not None:
- face = tuple(face)
- if edge is not None:
- edge = tuple(edge)
- hatch_style = (face, edge, hatch)
-
- pattern = self.hatchPatterns.get(hatch_style, None)
- if pattern is not None:
- return pattern
-
- name = Name('H%d' % self.nextHatch)
- self.nextHatch += 1
- self.hatchPatterns[hatch_style] = name
- return name
-
- def writeHatches(self):
- hatchDict = dict()
- sidelen = 72.0
- for hatch_style, name in six.iteritems(self.hatchPatterns):
- ob = self.reserveObject('hatch pattern')
- hatchDict[name] = ob
- res = {'Procsets':
- [Name(x) for x in "PDF Text ImageB ImageC ImageI".split()]}
- self.beginStream(
- ob.id, None,
- {'Type': Name('Pattern'),
- 'PatternType': 1, 'PaintType': 1, 'TilingType': 1,
- 'BBox': [0, 0, sidelen, sidelen],
- 'XStep': sidelen, 'YStep': sidelen,
- 'Resources': res})
-
- # lst is a tuple of stroke color, fill color,
- # number of - lines, number of / lines,
- # number of | lines, number of \ lines
- rgb = hatch_style[0]
- self.output(rgb[0], rgb[1], rgb[2], Op.setrgb_stroke)
- if hatch_style[1] is not None:
- rgb = hatch_style[1]
- self.output(rgb[0], rgb[1], rgb[2], Op.setrgb_nonstroke,
- 0, 0, sidelen, sidelen, Op.rectangle,
- Op.fill)
-
- self.output(0.1, Op.setlinewidth)
-
- # TODO: We could make this dpi-dependent, but that would be
- # an API change
- self.output(*self.pathOperations(
- Path.hatch(hatch_style[2]),
- Affine2D().scale(sidelen),
- simplify=False))
- self.output(Op.stroke)
-
- self.endStream()
- self.writeObject(self.hatchObject, hatchDict)
-
- def addGouraudTriangles(self, points, colors):
- name = Name('GT%d' % len(self.gouraudTriangles))
- self.gouraudTriangles.append((name, points, colors))
- return name
-
- def writeGouraudTriangles(self):
- gouraudDict = dict()
- for name, points, colors in self.gouraudTriangles:
- ob = self.reserveObject('Gouraud triangle')
- gouraudDict[name] = ob
- shape = points.shape
- flat_points = points.reshape((shape[0] * shape[1], 2))
- flat_colors = colors.reshape((shape[0] * shape[1], 4))
- points_min = np.min(flat_points, axis=0) - (1 << 8)
- points_max = np.max(flat_points, axis=0) + (1 << 8)
- factor = float(0xffffffff) / (points_max - points_min)
-
- self.beginStream(
- ob.id, None,
- {'ShadingType': 4,
- 'BitsPerCoordinate': 32,
- 'BitsPerComponent': 8,
- 'BitsPerFlag': 8,
- 'ColorSpace': Name('DeviceRGB'),
- 'AntiAlias': True,
- 'Decode': [points_min[0], points_max[0],
- points_min[1], points_max[1],
- 0, 1, 0, 1, 0, 1]
- })
-
- streamarr = np.empty(
- (shape[0] * shape[1],),
- dtype=[(str('flags'), str('u1')),
- (str('points'), str('>u4'), (2,)),
- (str('colors'), str('u1'), (3,))])
- streamarr['flags'] = 0
- streamarr['points'] = (flat_points - points_min) * factor
- streamarr['colors'] = flat_colors[:, :3] * 255.0
-
- self.write(streamarr.tostring())
- self.endStream()
- self.writeObject(self.gouraudObject, gouraudDict)
-
- def imageObject(self, image):
- """Return name of an image XObject representing the given image."""
-
- pair = self.images.get(image, None)
- if pair is not None:
- return pair[0]
-
- name = Name('I%d' % self.nextImage)
- ob = self.reserveObject('image %d' % self.nextImage)
- self.nextImage += 1
- self.images[image] = (name, ob)
- return name
-
- ## These two from backend_ps.py
- ## TODO: alpha (SMask, p. 518 of pdf spec)
-
- def _rgb(self, im):
- h, w, s = im.as_rgba_str()
-
- rgba = np.fromstring(s, np.uint8)
- rgba.shape = (h, w, 4)
- rgb = rgba[:, :, :3]
- a = rgba[:, :, 3:]
- return h, w, rgb.tostring(), a.tostring()
-
- def _gray(self, im, rc=0.3, gc=0.59, bc=0.11):
- rgbat = im.as_rgba_str()
- rgba = np.fromstring(rgbat[2], np.uint8)
- rgba.shape = (rgbat[0], rgbat[1], 4)
- rgba_f = rgba.astype(np.float32)
- r = rgba_f[:, :, 0]
- g = rgba_f[:, :, 1]
- b = rgba_f[:, :, 2]
- gray = (r*rc + g*gc + b*bc).astype(np.uint8)
- return rgbat[0], rgbat[1], gray.tostring()
-
- def writeImages(self):
- for img, pair in six.iteritems(self.images):
- img.flipud_out()
- if img.is_grayscale:
- height, width, data = self._gray(img)
- self.beginStream(
- pair[1].id,
- self.reserveObject('length of image stream'),
- {'Type': Name('XObject'), 'Subtype': Name('Image'),
- 'Width': width, 'Height': height,
- 'ColorSpace': Name('DeviceGray'), 'BitsPerComponent': 8})
- # TODO: predictors (i.e., output png)
- self.currentstream.write(data)
- self.endStream()
- else:
- height, width, data, adata = self._rgb(img)
- smaskObject = self.reserveObject("smask")
- self.beginStream(
- smaskObject.id,
- self.reserveObject('length of smask stream'),
- {'Type': Name('XObject'), 'Subtype': Name('Image'),
- 'Width': width, 'Height': height,
- 'ColorSpace': Name('DeviceGray'), 'BitsPerComponent': 8})
- # TODO: predictors (i.e., output png)
- self.currentstream.write(adata)
- self.endStream()
-
- self.beginStream(
- pair[1].id,
- self.reserveObject('length of image stream'),
- {'Type': Name('XObject'), 'Subtype': Name('Image'),
- 'Width': width, 'Height': height,
- 'ColorSpace': Name('DeviceRGB'), 'BitsPerComponent': 8,
- 'SMask': smaskObject})
- # TODO: predictors (i.e., output png)
- self.currentstream.write(data)
- self.endStream()
-
- img.flipud_out()
-
- def markerObject(self, path, trans, fillp, strokep, lw, joinstyle,
- capstyle):
- """Return name of a marker XObject representing the given path."""
- # self.markers used by markerObject, writeMarkers, close:
- # mapping from (path operations, fill?, stroke?) to
- # [name, object reference, bounding box, linewidth]
- # This enables different draw_markers calls to share the XObject
- # if the gc is sufficiently similar: colors etc can vary, but
- # the choices of whether to fill and whether to stroke cannot.
- # We need a bounding box enclosing all of the XObject path,
- # but since line width may vary, we store the maximum of all
- # occurring line widths in self.markers.
- # close() is somewhat tightly coupled in that it expects the
- # first two components of each value in self.markers to be the
- # name and object reference.
- pathops = self.pathOperations(path, trans, simplify=False)
- key = (tuple(pathops), bool(fillp), bool(strokep), joinstyle, capstyle)
- result = self.markers.get(key)
- if result is None:
- name = Name('M%d' % len(self.markers))
- ob = self.reserveObject('marker %d' % len(self.markers))
- bbox = path.get_extents(trans)
- self.markers[key] = [name, ob, bbox, lw]
- else:
- if result[-1] < lw:
- result[-1] = lw
- name = result[0]
- return name
-
- def writeMarkers(self):
- for ((pathops, fillp, strokep, joinstyle, capstyle),
- (name, ob, bbox, lw)) in six.iteritems(self.markers):
- bbox = bbox.padded(lw * 0.5)
- self.beginStream(
- ob.id, None,
- {'Type': Name('XObject'), 'Subtype': Name('Form'),
- 'BBox': list(bbox.extents)})
- self.output(GraphicsContextPdf.joinstyles[joinstyle],
- Op.setlinejoin)
- self.output(GraphicsContextPdf.capstyles[capstyle], Op.setlinecap)
- self.output(*pathops)
- self.output(Op.paint_path(False, fillp, strokep))
- self.endStream()
-
- def pathCollectionObject(self, gc, path, trans, padding, filled, stroked):
- name = Name('P%d' % len(self.paths))
- ob = self.reserveObject('path %d' % len(self.paths))
- self.paths.append(
- (name, path, trans, ob, gc.get_joinstyle(), gc.get_capstyle(),
- padding, filled, stroked))
- return name
-
- def writePathCollectionTemplates(self):
- for (name, path, trans, ob, joinstyle, capstyle, padding, filled,
- stroked) in self.paths:
- pathops = self.pathOperations(path, trans, simplify=False)
- bbox = path.get_extents(trans)
- if not np.all(np.isfinite(bbox.extents)):
- extents = [0, 0, 0, 0]
- else:
- bbox = bbox.padded(padding)
- extents = list(bbox.extents)
- self.beginStream(
- ob.id, None,
- {'Type': Name('XObject'), 'Subtype': Name('Form'),
- 'BBox': extents})
- self.output(GraphicsContextPdf.joinstyles[joinstyle],
- Op.setlinejoin)
- self.output(GraphicsContextPdf.capstyles[capstyle], Op.setlinecap)
- self.output(*pathops)
- self.output(Op.paint_path(False, filled, stroked))
- self.endStream()
-
- @staticmethod
- def pathOperations(path, transform, clip=None, simplify=None, sketch=None):
- cmds = []
- last_points = None
- for points, code in path.iter_segments(transform, clip=clip,
- simplify=simplify,
- sketch=sketch):
- if code == Path.MOVETO:
- # This is allowed anywhere in the path
- cmds.extend(points)
- cmds.append(Op.moveto)
- elif code == Path.CLOSEPOLY:
- cmds.append(Op.closepath)
- elif last_points is None:
- # The other operations require a previous point
- raise ValueError('Path lacks initial MOVETO')
- elif code == Path.LINETO:
- cmds.extend(points)
- cmds.append(Op.lineto)
- elif code == Path.CURVE3:
- points = quad2cubic(*(list(last_points[-2:]) + list(points)))
- cmds.extend(points[2:])
- cmds.append(Op.curveto)
- elif code == Path.CURVE4:
- cmds.extend(points)
- cmds.append(Op.curveto)
- last_points = points
- return cmds
-
- def writePath(self, path, transform, clip=False, sketch=None):
- if clip:
- clip = (0.0, 0.0, self.width * 72, self.height * 72)
- simplify = path.should_simplify
- else:
- clip = None
- simplify = False
- cmds = self.pathOperations(path, transform, clip, simplify=simplify,
- sketch=sketch)
- self.output(*cmds)
-
- def reserveObject(self, name=''):
- """Reserve an ID for an indirect object.
- The name is used for debugging in case we forget to print out
- the object with writeObject.
- """
-
- id = self.nextObject
- self.nextObject += 1
- self.xrefTable.append([None, 0, name])
- return Reference(id)
-
- def recordXref(self, id):
- self.xrefTable[id][0] = self.fh.tell() - self.tell_base
-
- def writeObject(self, object, contents):
- self.recordXref(object.id)
- object.write(contents, self)
-
- def writeXref(self):
- """Write out the xref table."""
-
- self.startxref = self.fh.tell() - self.tell_base
- self.write(("xref\n0 %d\n" % self.nextObject).encode('ascii'))
- i = 0
- borken = False
- for offset, generation, name in self.xrefTable:
- if offset is None:
- print('No offset for object %d (%s)' % (i, name),
- file=sys.stderr)
- borken = True
- else:
- if name == 'the zero object':
- key = "f"
- else:
- key = "n"
- text = "%010d %05d %s \n" % (offset, generation, key)
- self.write(text.encode('ascii'))
- i += 1
- if borken:
- raise AssertionError('Indirect object does not exist')
-
- def writeInfoDict(self):
- """Write out the info dictionary, checking it for good form"""
-
- is_date = lambda x: isinstance(x, datetime)
- check_trapped = (lambda x: isinstance(x, Name) and
- x.name in ('True', 'False', 'Unknown'))
- keywords = {'Title': is_string_like,
- 'Author': is_string_like,
- 'Subject': is_string_like,
- 'Keywords': is_string_like,
- 'Creator': is_string_like,
- 'Producer': is_string_like,
- 'CreationDate': is_date,
- 'ModDate': is_date,
- 'Trapped': check_trapped}
- for k in six.iterkeys(self.infoDict):
- if k not in keywords:
- warnings.warn('Unknown infodict keyword: %s' % k)
- else:
- if not keywords[k](self.infoDict[k]):
- warnings.warn('Bad value for infodict keyword %s' % k)
-
- self.infoObject = self.reserveObject('info')
- self.writeObject(self.infoObject, self.infoDict)
-
- def writeTrailer(self):
- """Write out the PDF trailer."""
-
- self.write(b"trailer\n")
- self.write(pdfRepr(
- {'Size': self.nextObject,
- 'Root': self.rootObject,
- 'Info': self.infoObject}))
- # Could add 'ID'
- self.write(("\nstartxref\n%d\n%%%%EOF\n" %
- self.startxref).encode('ascii'))
-
-
-class RendererPdf(RendererBase):
- truetype_font_cache = maxdict(50)
- afm_font_cache = maxdict(50)
-
- def __init__(self, file, image_dpi):
- RendererBase.__init__(self)
- self.file = file
- self.gc = self.new_gc()
- self.mathtext_parser = MathTextParser("Pdf")
- self.image_dpi = image_dpi
- self.tex_font_map = None
-
- def finalize(self):
- self.file.output(*self.gc.finalize())
-
- def check_gc(self, gc, fillcolor=None):
- orig_fill = getattr(gc, '_fillcolor', (0., 0., 0.))
- gc._fillcolor = fillcolor
-
- orig_alphas = getattr(gc, '_effective_alphas', (1.0, 1.0))
-
- if gc._forced_alpha:
- gc._effective_alphas = (gc._alpha, gc._alpha)
- elif fillcolor is None or len(fillcolor) < 4:
- gc._effective_alphas = (gc._rgb[3], 1.0)
- else:
- gc._effective_alphas = (gc._rgb[3], fillcolor[3])
-
- delta = self.gc.delta(gc)
- if delta:
- self.file.output(*delta)
-
- # Restore gc to avoid unwanted side effects
- gc._fillcolor = orig_fill
- gc._effective_alphas = orig_alphas
-
- def tex_font_mapping(self, texfont):
- if self.tex_font_map is None:
- self.tex_font_map = \
- dviread.PsfontsMap(dviread.find_tex_file('pdftex.map'))
- return self.tex_font_map[texfont]
-
- def track_characters(self, font, s):
- """Keeps track of which characters are required from
- each font."""
- if isinstance(font, six.string_types):
- fname = font
- else:
- fname = font.fname
- realpath, stat_key = get_realpath_and_stat(fname)
- used_characters = self.file.used_characters.setdefault(
- stat_key, (realpath, set()))
- used_characters[1].update([ord(x) for x in s])
-
- def merge_used_characters(self, other):
- for stat_key, (realpath, charset) in six.iteritems(other):
- used_characters = self.file.used_characters.setdefault(
- stat_key, (realpath, set()))
- used_characters[1].update(charset)
-
- def get_image_magnification(self):
- return self.image_dpi/72.0
-
- def option_scale_image(self):
- """
- pdf backend support arbitrary scaling of image.
- """
- return True
-
- def draw_image(self, gc, x, y, im, dx=None, dy=None, transform=None):
- self.check_gc(gc)
-
- h, w = im.get_size_out()
-
- if dx is None:
- w = 72.0*w/self.image_dpi
- else:
- w = dx
-
- if dy is None:
- h = 72.0*h/self.image_dpi
- else:
- h = dy
-
- imob = self.file.imageObject(im)
-
- if transform is None:
- self.file.output(Op.gsave,
- w, 0, 0, h, x, y, Op.concat_matrix,
- imob, Op.use_xobject, Op.grestore)
- else:
- tr1, tr2, tr3, tr4, tr5, tr6 = transform.to_values()
-
- self.file.output(Op.gsave,
- tr1, tr2, tr3, tr4, tr5, tr6, Op.concat_matrix,
- w, 0, 0, h, x, y, Op.concat_matrix,
- imob, Op.use_xobject, Op.grestore)
-
- def draw_path(self, gc, path, transform, rgbFace=None):
- self.check_gc(gc, rgbFace)
- self.file.writePath(
- path, transform,
- rgbFace is None and gc.get_hatch_path() is None,
- gc.get_sketch_params())
- self.file.output(self.gc.paint())
-
- def draw_path_collection(self, gc, master_transform, paths, all_transforms,
- offsets, offsetTrans, facecolors, edgecolors,
- linewidths, linestyles, antialiaseds, urls,
- offset_position):
- # We can only reuse the objects if the presence of fill and
- # stroke (and the amount of alpha for each) is the same for
- # all of them
- can_do_optimization = True
- facecolors = np.asarray(facecolors)
- edgecolors = np.asarray(edgecolors)
-
- if not len(facecolors):
- filled = False
- can_do_optimization = not gc.get_hatch()
- else:
- if np.all(facecolors[:, 3] == facecolors[0, 3]):
- filled = facecolors[0, 3] != 0.0
- else:
- can_do_optimization = False
-
- if not len(edgecolors):
- stroked = False
- else:
- if np.all(np.asarray(linewidths) == 0.0):
- stroked = False
- elif np.all(edgecolors[:, 3] == edgecolors[0, 3]):
- stroked = edgecolors[0, 3] != 0.0
- else:
- can_do_optimization = False
-
- # Is the optimization worth it? Rough calculation:
- # cost of emitting a path in-line is len_path * uses_per_path
- # cost of XObject is len_path + 5 for the definition,
- # uses_per_path for the uses
- len_path = len(paths[0].vertices) if len(paths) > 0 else 0
- uses_per_path = self._iter_collection_uses_per_path(
- paths, all_transforms, offsets, facecolors, edgecolors)
- should_do_optimization = \
- len_path + uses_per_path + 5 < len_path * uses_per_path
-
- if (not can_do_optimization) or (not should_do_optimization):
- return RendererBase.draw_path_collection(
- self, gc, master_transform, paths, all_transforms,
- offsets, offsetTrans, facecolors, edgecolors,
- linewidths, linestyles, antialiaseds, urls,
- offset_position)
-
- padding = np.max(linewidths)
- path_codes = []
- for i, (path, transform) in enumerate(self._iter_collection_raw_paths(
- master_transform, paths, all_transforms)):
- name = self.file.pathCollectionObject(
- gc, path, transform, padding, filled, stroked)
- path_codes.append(name)
-
- output = self.file.output
- output(*self.gc.push())
- lastx, lasty = 0, 0
- for xo, yo, path_id, gc0, rgbFace in self._iter_collection(
- gc, master_transform, all_transforms, path_codes, offsets,
- offsetTrans, facecolors, edgecolors, linewidths, linestyles,
- antialiaseds, urls, offset_position):
-
- self.check_gc(gc0, rgbFace)
- dx, dy = xo - lastx, yo - lasty
- output(1, 0, 0, 1, dx, dy, Op.concat_matrix, path_id,
- Op.use_xobject)
- lastx, lasty = xo, yo
- output(*self.gc.pop())
-
- def draw_markers(self, gc, marker_path, marker_trans, path, trans,
- rgbFace=None):
- # Same logic as in draw_path_collection
- len_marker_path = len(marker_path)
- uses = len(path)
- if len_marker_path * uses < len_marker_path + uses + 5:
- RendererBase.draw_markers(self, gc, marker_path, marker_trans,
- path, trans, rgbFace)
- return
-
- self.check_gc(gc, rgbFace)
- fillp = gc.fillp(rgbFace)
- strokep = gc.strokep()
-
- output = self.file.output
- marker = self.file.markerObject(
- marker_path, marker_trans, fillp, strokep, self.gc._linewidth,
- gc.get_joinstyle(), gc.get_capstyle())
-
- output(Op.gsave)
- lastx, lasty = 0, 0
- for vertices, code in path.iter_segments(
- trans,
- clip=(0, 0, self.file.width*72, self.file.height*72),
- simplify=False):
- if len(vertices):
- x, y = vertices[-2:]
- if (x < 0 or
- y < 0 or
- x > self.file.width * 72 or
- y > self.file.height * 72):
- continue
- dx, dy = x - lastx, y - lasty
- output(1, 0, 0, 1, dx, dy, Op.concat_matrix,
- marker, Op.use_xobject)
- lastx, lasty = x, y
- output(Op.grestore)
-
- def draw_gouraud_triangle(self, gc, points, colors, trans):
- self.draw_gouraud_triangles(gc, points.reshape((1, 3, 2)),
- colors.reshape((1, 3, 4)), trans)
-
- def draw_gouraud_triangles(self, gc, points, colors, trans):
- assert len(points) == len(colors)
- assert points.ndim == 3
- assert points.shape[1] == 3
- assert points.shape[2] == 2
- assert colors.ndim == 3
- assert colors.shape[1] == 3
- assert colors.shape[2] == 4
-
- shape = points.shape
- points = points.reshape((shape[0] * shape[1], 2))
- tpoints = trans.transform(points)
- tpoints = tpoints.reshape(shape)
- name = self.file.addGouraudTriangles(tpoints, colors)
- self.check_gc(gc)
- self.file.output(name, Op.shading)
-
- def _setup_textpos(self, x, y, angle, oldx=0, oldy=0, oldangle=0):
- if angle == oldangle == 0:
- self.file.output(x - oldx, y - oldy, Op.textpos)
- else:
- angle = angle / 180.0 * pi
- self.file.output(cos(angle), sin(angle),
- -sin(angle), cos(angle),
- x, y, Op.textmatrix)
- self.file.output(0, 0, Op.textpos)
-
- def draw_mathtext(self, gc, x, y, s, prop, angle):
- # TODO: fix positioning and encoding
- width, height, descent, glyphs, rects, used_characters = \
- self.mathtext_parser.parse(s, 72, prop)
- self.merge_used_characters(used_characters)
-
- # When using Type 3 fonts, we can't use character codes higher
- # than 255, so we use the "Do" command to render those
- # instead.
- global_fonttype = rcParams['pdf.fonttype']
-
- # Set up a global transformation matrix for the whole math expression
- a = angle / 180.0 * pi
- self.file.output(Op.gsave)
- self.file.output(cos(a), sin(a), -sin(a), cos(a), x, y,
- Op.concat_matrix)
-
- self.check_gc(gc, gc._rgb)
- self.file.output(Op.begin_text)
- prev_font = None, None
- oldx, oldy = 0, 0
- for ox, oy, fontname, fontsize, num, symbol_name in glyphs:
- if is_opentype_cff_font(fontname):
- fonttype = 42
- else:
- fonttype = global_fonttype
-
- if fonttype == 42 or num <= 255:
- self._setup_textpos(ox, oy, 0, oldx, oldy)
- oldx, oldy = ox, oy
- if (fontname, fontsize) != prev_font:
- self.file.output(self.file.fontName(fontname), fontsize,
- Op.selectfont)
- prev_font = fontname, fontsize
- self.file.output(self.encode_string(unichr(num), fonttype),
- Op.show)
- self.file.output(Op.end_text)
-
- # If using Type 3 fonts, render all of the multi-byte characters
- # as XObjects using the 'Do' command.
- if global_fonttype == 3:
- for ox, oy, fontname, fontsize, num, symbol_name in glyphs:
- if is_opentype_cff_font(fontname):
- fonttype = 42
- else:
- fonttype = global_fonttype
-
- if fonttype == 3 and num > 255:
- self.file.fontName(fontname)
- self.file.output(Op.gsave,
- 0.001 * fontsize, 0,
- 0, 0.001 * fontsize,
- ox, oy, Op.concat_matrix)
- name = self.file._get_xobject_symbol_name(
- fontname, symbol_name)
- self.file.output(Name(name), Op.use_xobject)
- self.file.output(Op.grestore)
-
- # Draw any horizontal lines in the math layout
- for ox, oy, width, height in rects:
- self.file.output(Op.gsave, ox, oy, width, height,
- Op.rectangle, Op.fill, Op.grestore)
-
- # Pop off the global transformation
- self.file.output(Op.grestore)
-
- def draw_tex(self, gc, x, y, s, prop, angle, ismath='TeX!', mtext=None):
- texmanager = self.get_texmanager()
- fontsize = prop.get_size_in_points()
- dvifile = texmanager.make_dvi(s, fontsize)
- dvi = dviread.Dvi(dvifile, 72)
- page = six.next(iter(dvi))
- dvi.close()
-
- # Gather font information and do some setup for combining
- # characters into strings. The variable seq will contain a
- # sequence of font and text entries. A font entry is a list
- # ['font', name, size] where name is a Name object for the
- # font. A text entry is ['text', x, y, glyphs, x+w] where x
- # and y are the starting coordinates, w is the width, and
- # glyphs is a list; in this phase it will always contain just
- # one one-character string, but later it may have longer
- # strings interspersed with kern amounts.
- oldfont, seq = None, []
- for x1, y1, dvifont, glyph, width in page.text:
- if dvifont != oldfont:
- pdfname = self.file.fontName(dvifont.texname)
- if dvifont.texname not in self.file.dviFontInfo:
- psfont = self.tex_font_mapping(dvifont.texname)
- self.file.dviFontInfo[dvifont.texname] = Bunch(
- fontfile=psfont.filename,
- basefont=psfont.psname,
- encodingfile=psfont.encoding,
- effects=psfont.effects,
- dvifont=dvifont)
- seq += [['font', pdfname, dvifont.size]]
- oldfont = dvifont
- # We need to convert the glyph numbers to bytes, and the easiest
- # way to do this on both Python 2 and 3 is .encode('latin-1')
- seq += [['text', x1, y1,
- [six.unichr(glyph).encode('latin-1')], x1+width]]
-
- # Find consecutive text strings with constant y coordinate and
- # combine into a sequence of strings and kerns, or just one
- # string (if any kerns would be less than 0.1 points).
- i, curx, fontsize = 0, 0, None
- while i < len(seq)-1:
- elt, nxt = seq[i:i+2]
- if elt[0] == 'font':
- fontsize = elt[2]
- elif elt[0] == nxt[0] == 'text' and elt[2] == nxt[2]:
- offset = elt[4] - nxt[1]
- if abs(offset) < 0.1:
- elt[3][-1] += nxt[3][0]
- elt[4] += nxt[4]-nxt[1]
- else:
- elt[3] += [offset*1000.0/fontsize, nxt[3][0]]
- elt[4] = nxt[4]
- del seq[i+1]
- continue
- i += 1
-
- # Create a transform to map the dvi contents to the canvas.
- mytrans = Affine2D().rotate_deg(angle).translate(x, y)
-
- # Output the text.
- self.check_gc(gc, gc._rgb)
- self.file.output(Op.begin_text)
- curx, cury, oldx, oldy = 0, 0, 0, 0
- for elt in seq:
- if elt[0] == 'font':
- self.file.output(elt[1], elt[2], Op.selectfont)
- elif elt[0] == 'text':
- curx, cury = mytrans.transform((elt[1], elt[2]))
- self._setup_textpos(curx, cury, angle, oldx, oldy)
- oldx, oldy = curx, cury
- if len(elt[3]) == 1:
- self.file.output(elt[3][0], Op.show)
- else:
- self.file.output(elt[3], Op.showkern)
- else:
- assert False
- self.file.output(Op.end_text)
-
- # Then output the boxes (e.g., variable-length lines of square
- # roots).
- boxgc = self.new_gc()
- boxgc.copy_properties(gc)
- boxgc.set_linewidth(0)
- pathops = [Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO,
- Path.CLOSEPOLY]
- for x1, y1, h, w in page.boxes:
- path = Path([[x1, y1], [x1+w, y1], [x1+w, y1+h], [x1, y1+h],
- [0, 0]], pathops)
- self.draw_path(boxgc, path, mytrans, gc._rgb)
-
- def encode_string(self, s, fonttype):
- if fonttype in (1, 3):
- return s.encode('cp1252', 'replace')
- return s.encode('utf-16be', 'replace')
-
- def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
- # TODO: combine consecutive texts into one BT/ET delimited section
-
- # This function is rather complex, since there is no way to
- # access characters of a Type 3 font with codes > 255. (Type
- # 3 fonts can not have a CIDMap). Therefore, we break the
- # string into chunks, where each chunk contains exclusively
- # 1-byte or exclusively 2-byte characters, and output each
- # chunk a separate command. 1-byte characters use the regular
- # text show command (Tj), whereas 2-byte characters use the
- # use XObject command (Do). If using Type 42 fonts, all of
- # this complication is avoided, but of course, those fonts can
- # not be subsetted.
-
- self.check_gc(gc, gc._rgb)
- if ismath:
- return self.draw_mathtext(gc, x, y, s, prop, angle)
-
- fontsize = prop.get_size_in_points()
-
- if rcParams['pdf.use14corefonts']:
- font = self._get_font_afm(prop)
- l, b, w, h = font.get_str_bbox(s)
- fonttype = 1
- else:
- font = self._get_font_ttf(prop)
- self.track_characters(font, s)
- font.set_text(s, 0.0, flags=LOAD_NO_HINTING)
-
- fonttype = rcParams['pdf.fonttype']
-
- # We can't subset all OpenType fonts, so switch to Type 42
- # in that case.
- if is_opentype_cff_font(font.fname):
- fonttype = 42
-
- def check_simple_method(s):
- """Determine if we should use the simple or woven method
- to output this text, and chunks the string into 1-byte and
- 2-byte sections if necessary."""
- use_simple_method = True
- chunks = []
-
- if not rcParams['pdf.use14corefonts']:
- if fonttype == 3 and not isinstance(s, bytes) and len(s) != 0:
- # Break the string into chunks where each chunk is either
- # a string of chars <= 255, or a single character > 255.
- s = six.text_type(s)
- for c in s:
- if ord(c) <= 255:
- char_type = 1
- else:
- char_type = 2
- if len(chunks) and chunks[-1][0] == char_type:
- chunks[-1][1].append(c)
- else:
- chunks.append((char_type, [c]))
- use_simple_method = (len(chunks) == 1
- and chunks[-1][0] == 1)
- return use_simple_method, chunks
-
- def draw_text_simple():
- """Outputs text using the simple method."""
- self.file.output(Op.begin_text,
- self.file.fontName(prop),
- fontsize,
- Op.selectfont)
- self._setup_textpos(x, y, angle)
- self.file.output(self.encode_string(s, fonttype), Op.show,
- Op.end_text)
-
- def draw_text_woven(chunks):
- """Outputs text using the woven method, alternating
- between chunks of 1-byte characters and 2-byte characters.
- Only used for Type 3 fonts."""
- chunks = [(a, ''.join(b)) for a, b in chunks]
- cmap = font.get_charmap()
-
- # Do the rotation and global translation as a single matrix
- # concatenation up front
- self.file.output(Op.gsave)
- a = angle / 180.0 * pi
- self.file.output(cos(a), sin(a), -sin(a), cos(a), x, y,
- Op.concat_matrix)
-
- # Output all the 1-byte characters in a BT/ET group, then
- # output all the 2-byte characters.
- for mode in (1, 2):
- newx = oldx = 0
- # Output a 1-byte character chunk
- if mode == 1:
- self.file.output(Op.begin_text,
- self.file.fontName(prop),
- fontsize,
- Op.selectfont)
-
- for chunk_type, chunk in chunks:
- if mode == 1 and chunk_type == 1:
- self._setup_textpos(newx, 0, 0, oldx, 0, 0)
- self.file.output(self.encode_string(chunk, fonttype),
- Op.show)
- oldx = newx
-
- lastgind = None
- for c in chunk:
- ccode = ord(c)
- gind = cmap.get(ccode)
- if gind is not None:
- if mode == 2 and chunk_type == 2:
- glyph_name = font.get_glyph_name(gind)
- self.file.output(Op.gsave)
- self.file.output(0.001 * fontsize, 0,
- 0, 0.001 * fontsize,
- newx, 0, Op.concat_matrix)
- name = self.file._get_xobject_symbol_name(
- font.fname, glyph_name)
- self.file.output(Name(name), Op.use_xobject)
- self.file.output(Op.grestore)
-
- # Move the pointer based on the character width
- # and kerning
- glyph = font.load_char(ccode,
- flags=LOAD_NO_HINTING)
- if lastgind is not None:
- kern = font.get_kerning(
- lastgind, gind, KERNING_UNFITTED)
- else:
- kern = 0
- lastgind = gind
- newx += kern/64.0 + glyph.linearHoriAdvance/65536.0
-
- if mode == 1:
- self.file.output(Op.end_text)
-
- self.file.output(Op.grestore)
-
- use_simple_method, chunks = check_simple_method(s)
- if use_simple_method:
- return draw_text_simple()
- else:
- return draw_text_woven(chunks)
-
- def get_text_width_height_descent(self, s, prop, ismath):
- if rcParams['text.usetex']:
- texmanager = self.get_texmanager()
- fontsize = prop.get_size_in_points()
- w, h, d = texmanager.get_text_width_height_descent(s, fontsize,
- renderer=self)
- return w, h, d
-
- if ismath:
- w, h, d, glyphs, rects, used_characters = \
- self.mathtext_parser.parse(s, 72, prop)
-
- elif rcParams['pdf.use14corefonts']:
- font = self._get_font_afm(prop)
- l, b, w, h, d = font.get_str_bbox_and_descent(s)
- scale = prop.get_size_in_points()
- w *= scale / 1000
- h *= scale / 1000
- d *= scale / 1000
- else:
- font = self._get_font_ttf(prop)
- font.set_text(s, 0.0, flags=LOAD_NO_HINTING)
- w, h = font.get_width_height()
- scale = (1.0 / 64.0)
- w *= scale
- h *= scale
- d = font.get_descent()
- d *= scale
- return w, h, d
-
- def _get_font_afm(self, prop):
- key = hash(prop)
- font = self.afm_font_cache.get(key)
- if font is None:
- filename = findfont(
- prop, fontext='afm', directory=self.file._core14fontdir)
- if filename is None:
- filename = findfont(
- "Helvetica", fontext='afm',
- directory=self.file._core14fontdir)
- font = self.afm_font_cache.get(filename)
- if font is None:
- with open(filename, 'rb') as fh:
- font = AFM(fh)
- self.afm_font_cache[filename] = font
- self.afm_font_cache[key] = font
- return font
-
- def _get_font_ttf(self, prop):
- key = hash(prop)
- font = self.truetype_font_cache.get(key)
- if font is None:
- filename = findfont(prop)
- font = self.truetype_font_cache.get(filename)
- if font is None:
- font = FT2Font(filename)
- self.truetype_font_cache[filename] = font
- self.truetype_font_cache[key] = font
- font.clear()
- font.set_size(prop.get_size_in_points(), 72)
- return font
-
- def flipy(self):
- return False
-
- def get_canvas_width_height(self):
- return self.file.width / 72.0, self.file.height / 72.0
-
- def new_gc(self):
- return GraphicsContextPdf(self.file)
-
-
-class GraphicsContextPdf(GraphicsContextBase):
-
- def __init__(self, file):
- GraphicsContextBase.__init__(self)
- self._fillcolor = (0.0, 0.0, 0.0)
- self._effective_alphas = (1.0, 1.0)
- self.file = file
- self.parent = None
-
- def __repr__(self):
- d = dict(self.__dict__)
- del d['file']
- del d['parent']
- return repr(d)
-
- def strokep(self):
- """
- Predicate: does the path need to be stroked (its outline drawn)?
- This tests for the various conditions that disable stroking
- the path, in which case it would presumably be filled.
- """
- # _linewidth > 0: in pdf a line of width 0 is drawn at minimum
- # possible device width, but e.g., agg doesn't draw at all
- return (self._linewidth > 0 and self._alpha > 0 and
- (len(self._rgb) <= 3 or self._rgb[3] != 0.0))
-
- def fillp(self, *args):
- """
- Predicate: does the path need to be filled?
-
- An optional argument can be used to specify an alternative
- _fillcolor, as needed by RendererPdf.draw_markers.
- """
- if len(args):
- _fillcolor = args[0]
- else:
- _fillcolor = self._fillcolor
- return (self._hatch or
- (_fillcolor is not None and
- (len(_fillcolor) <= 3 or _fillcolor[3] != 0.0)))
-
- def close_and_paint(self):
- """
- Return the appropriate pdf operator to close the path and
- cause it to be stroked, filled, or both.
- """
- return Op.paint_path(True, self.fillp(), self.strokep())
-
- def paint(self):
- """
- Return the appropriate pdf operator to cause the path to be
- stroked, filled, or both.
- """
- return Op.paint_path(False, self.fillp(), self.strokep())
-
- capstyles = {'butt': 0, 'round': 1, 'projecting': 2}
- joinstyles = {'miter': 0, 'round': 1, 'bevel': 2}
-
- def capstyle_cmd(self, style):
- return [self.capstyles[style], Op.setlinecap]
-
- def joinstyle_cmd(self, style):
- return [self.joinstyles[style], Op.setlinejoin]
-
- def linewidth_cmd(self, width):
- return [width, Op.setlinewidth]
-
- def dash_cmd(self, dashes):
- offset, dash = dashes
- if dash is None:
- dash = []
- offset = 0
- return [list(dash), offset, Op.setdash]
-
- def alpha_cmd(self, alpha, forced, effective_alphas):
- name = self.file.alphaState(effective_alphas)
- return [name, Op.setgstate]
-
- def hatch_cmd(self, hatch):
- if not hatch:
- if self._fillcolor is not None:
- return self.fillcolor_cmd(self._fillcolor)
- else:
- return [Name('DeviceRGB'), Op.setcolorspace_nonstroke]
- else:
- hatch_style = (self._rgb, self._fillcolor, hatch)
- name = self.file.hatchPattern(hatch_style)
- return [Name('Pattern'), Op.setcolorspace_nonstroke,
- name, Op.setcolor_nonstroke]
-
- def rgb_cmd(self, rgb):
- if rcParams['pdf.inheritcolor']:
- return []
- if rgb[0] == rgb[1] == rgb[2]:
- return [rgb[0], Op.setgray_stroke]
- else:
- return list(rgb[:3]) + [Op.setrgb_stroke]
-
- def fillcolor_cmd(self, rgb):
- if rgb is None or rcParams['pdf.inheritcolor']:
- return []
- elif rgb[0] == rgb[1] == rgb[2]:
- return [rgb[0], Op.setgray_nonstroke]
- else:
- return list(rgb[:3]) + [Op.setrgb_nonstroke]
-
- def push(self):
- parent = GraphicsContextPdf(self.file)
- parent.copy_properties(self)
- parent.parent = self.parent
- self.parent = parent
- return [Op.gsave]
-
- def pop(self):
- assert self.parent is not None
- self.copy_properties(self.parent)
- self.parent = self.parent.parent
- return [Op.grestore]
-
- def clip_cmd(self, cliprect, clippath):
- """Set clip rectangle. Calls self.pop() and self.push()."""
- cmds = []
- # Pop graphics state until we hit the right one or the stack is empty
- while ((self._cliprect, self._clippath) != (cliprect, clippath)
- and self.parent is not None):
- cmds.extend(self.pop())
- # Unless we hit the right one, set the clip polygon
- if ((self._cliprect, self._clippath) != (cliprect, clippath) or
- self.parent is None):
- cmds.extend(self.push())
- if self._cliprect != cliprect:
- cmds.extend([cliprect, Op.rectangle, Op.clip, Op.endpath])
- if self._clippath != clippath:
- path, affine = clippath.get_transformed_path_and_affine()
- cmds.extend(
- PdfFile.pathOperations(path, affine, simplify=False) +
- [Op.clip, Op.endpath])
- return cmds
-
- commands = (
- # must come first since may pop
- (('_cliprect', '_clippath'), clip_cmd),
- (('_alpha', '_forced_alpha', '_effective_alphas'), alpha_cmd),
- (('_capstyle',), capstyle_cmd),
- (('_fillcolor',), fillcolor_cmd),
- (('_joinstyle',), joinstyle_cmd),
- (('_linewidth',), linewidth_cmd),
- (('_dashes',), dash_cmd),
- (('_rgb',), rgb_cmd),
- (('_hatch',), hatch_cmd), # must come after fillcolor and rgb
- )
-
- # TODO: _linestyle
-
- def delta(self, other):
- """
- Copy properties of other into self and return PDF commands
- needed to transform self into other.
- """
- cmds = []
- for params, cmd in self.commands:
- different = False
- for p in params:
- ours = getattr(self, p)
- theirs = getattr(other, p)
- try:
- if (ours is None or theirs is None):
- different = bool(not(ours is theirs))
- else:
- different = bool(ours != theirs)
- except ValueError:
- ours = np.asarray(ours)
- theirs = np.asarray(theirs)
- different = (ours.shape != theirs.shape or
- np.any(ours != theirs))
- if different:
- break
-
- if different:
- theirs = [getattr(other, p) for p in params]
- cmds.extend(cmd(self, *theirs))
- for p in params:
- setattr(self, p, getattr(other, p))
- return cmds
-
- def copy_properties(self, other):
- """
- Copy properties of other into self.
- """
- GraphicsContextBase.copy_properties(self, other)
- fillcolor = getattr(other, '_fillcolor', self._fillcolor)
- effective_alphas = getattr(other, '_effective_alphas',
- self._effective_alphas)
- self._fillcolor = fillcolor
- self._effective_alphas = effective_alphas
-
- def finalize(self):
- """
- Make sure every pushed graphics state is popped.
- """
- cmds = []
- while self.parent is not None:
- cmds.extend(self.pop())
- return cmds
-
-########################################################################
-#
-# The following functions and classes are for pylab and implement
-# window/figure managers, etc...
-#
-########################################################################
-
-
-def new_figure_manager(num, *args, **kwargs):
- """
- Create a new figure manager instance
- """
- # if a main-level app must be created, this is the usual place to
- # do it -- see backend_wx, backend_wxagg and backend_tkagg for
- # examples. Not all GUIs require explicit instantiation of a
- # main-level app (egg backend_gtk, backend_gtkagg) for pylab
- FigureClass = kwargs.pop('FigureClass', Figure)
- thisFig = FigureClass(*args, **kwargs)
- return new_figure_manager_given_figure(num, thisFig)
-
-
-def new_figure_manager_given_figure(num, figure):
- """
- Create a new figure manager instance for the given figure.
- """
- canvas = FigureCanvasPdf(figure)
- manager = FigureManagerPdf(canvas, num)
- return manager
-
-
-class PdfPages(object):
- """
- A multi-page PDF file.
-
- Examples
- --------
-
- >>> import matplotlib.pyplot as plt
- >>> # Initialize:
- >>> with PdfPages('foo.pdf') as pdf:
- ... # As many times as you like, create a figure fig and save it:
- ... fig = plt.figure()
- ... pdf.savefig(fig)
- ... # When no figure is specified the current figure is saved
- ... pdf.savefig()
-
- Notes
- -----
-
- In reality :class:`PdfPages` is a thin wrapper around :class:`PdfFile`, in
- order to avoid confusion when using :func:`~matplotlib.pyplot.savefig` and
- forgetting the format argument.
- """
- __slots__ = ('_file', 'keep_empty')
-
- def __init__(self, filename, keep_empty=True):
- """
- Create a new PdfPages object.
-
- Parameters
- ----------
-
- filename: str
- Plots using :meth:`PdfPages.savefig` will be written to a file at
- this location. The file is opened at once and any older file with
- the same name is overwritten.
- keep_empty: bool, optional
- If set to False, then empty pdf files will be deleted automatically
- when closed.
- """
- self._file = PdfFile(filename)
- self.keep_empty = keep_empty
-
- def __enter__(self):
- return self
-
- def __exit__(self, exc_type, exc_val, exc_tb):
- self.close()
-
- def close(self):
- """
- Finalize this object, making the underlying file a complete
- PDF file.
- """
- self._file.close()
- if (self.get_pagecount() == 0 and not self.keep_empty
- and not self._file.passed_in_file_object):
- os.remove(self._file.fh.name)
- self._file = None
-
- def infodict(self):
- """
- Return a modifiable information dictionary object
- (see PDF reference section 10.2.1 'Document Information
- Dictionary').
- """
- return self._file.infoDict
-
- def savefig(self, figure=None, **kwargs):
- """
- Saves a :class:`~matplotlib.figure.Figure` to this file as a new page.
-
- Any other keyword arguments are passed to
- :meth:`~matplotlib.figure.Figure.savefig`.
-
- Parameters
- ----------
-
- figure: :class:`~matplotlib.figure.Figure` or int, optional
- Specifies what figure is saved to file. If not specified, the
- active figure is saved. If a :class:`~matplotlib.figure.Figure`
- instance is provided, this figure is saved. If an int is specified,
- the figure instance to save is looked up by number.
- """
- if isinstance(figure, Figure):
- figure.savefig(self, format='pdf', **kwargs)
- else:
- if figure is None:
- figureManager = Gcf.get_active()
- else:
- figureManager = Gcf.get_fig_manager(figure)
- if figureManager is None:
- raise ValueError("No such figure: " + repr(figure))
- else:
- figureManager.canvas.figure.savefig(self, format='pdf',
- **kwargs)
-
- def get_pagecount(self):
- """
- Returns the current number of pages in the multipage pdf file.
- """
- return len(self._file.pageList)
-
-
-class FigureCanvasPdf(FigureCanvasBase):
- """
- The canvas the figure renders into. Calls the draw and print fig
- methods, creates the renderers, etc...
-
- Public attribute
-
- figure - A Figure instance
- """
-
- fixed_dpi = 72
-
- def draw(self):
- pass
-
- filetypes = {'pdf': 'Portable Document Format'}
-
- def get_default_filetype(self):
- return 'pdf'
-
- def print_pdf(self, filename, **kwargs):
- image_dpi = kwargs.get('dpi', 72) # dpi to use for images
- self.figure.set_dpi(72) # there are 72 pdf points to an inch
- width, height = self.figure.get_size_inches()
- if isinstance(filename, PdfPages):
- file = filename._file
- else:
- file = PdfFile(filename)
- try:
- file.newPage(width, height)
- _bbox_inches_restore = kwargs.pop("bbox_inches_restore", None)
- renderer = MixedModeRenderer(
- self.figure, width, height, image_dpi,
- RendererPdf(file, image_dpi),
- bbox_inches_restore=_bbox_inches_restore)
- self.figure.draw(renderer)
- renderer.finalize()
- finally:
- if isinstance(filename, PdfPages): # finish off this page
- file.endStream()
- else: # we opened the file above; now finish it off
- file.close()
-
-
-class FigureManagerPdf(FigureManagerBase):
- pass
-
-
-FigureCanvas = FigureCanvasPdf
-FigureManager = FigureManagerPdf
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_pgf.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_pgf.py
deleted file mode 100644
index b64a16f..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_pgf.py
+++ /dev/null
@@ -1,962 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import math
-import os
-import sys
-import re
-import shutil
-import tempfile
-import codecs
-import atexit
-import weakref
-import warnings
-
-import matplotlib as mpl
-from matplotlib.backend_bases import RendererBase, GraphicsContextBase,\
- FigureManagerBase, FigureCanvasBase
-from matplotlib.backends.backend_mixed import MixedModeRenderer
-from matplotlib.figure import Figure
-from matplotlib.text import Text
-from matplotlib.path import Path
-from matplotlib import _png, rcParams
-from matplotlib.cbook import is_string_like, is_writable_file_like
-from matplotlib.compat import subprocess
-from matplotlib.compat.subprocess import check_output
-
-
-###############################################################################
-
-# create a list of system fonts, all of these should work with xe/lua-latex
-system_fonts = []
-if sys.platform.startswith('win'):
- from matplotlib import font_manager
- from matplotlib.ft2font import FT2Font
- for f in font_manager.win32InstalledFonts():
- try:
- system_fonts.append(FT2Font(str(f)).family_name)
- except:
- pass # unknown error, skip this font
-else:
- # assuming fontconfig is installed and the command 'fc-list' exists
- try:
- # list scalable (non-bitmap) fonts
- fc_list = check_output(['fc-list', ':outline,scalable', 'family'])
- fc_list = fc_list.decode('utf8')
- system_fonts = [f.split(',')[0] for f in fc_list.splitlines()]
- system_fonts = list(set(system_fonts))
- except:
- warnings.warn('error getting fonts from fc-list', UserWarning)
-
-def get_texcommand():
- """Get chosen TeX system from rc."""
- texsystem_options = ["xelatex", "lualatex", "pdflatex"]
- texsystem = rcParams.get("pgf.texsystem", "xelatex")
- return texsystem if texsystem in texsystem_options else "xelatex"
-
-
-def get_fontspec():
- """Build fontspec preamble from rc."""
- latex_fontspec = []
- texcommand = get_texcommand()
-
- if texcommand != "pdflatex":
- latex_fontspec.append("\\usepackage{fontspec}")
-
- if texcommand != "pdflatex" and rcParams.get("pgf.rcfonts", True):
- # try to find fonts from rc parameters
- families = ["serif", "sans-serif", "monospace"]
- fontspecs = [r"\setmainfont{%s}", r"\setsansfont{%s}",
- r"\setmonofont{%s}"]
- for family, fontspec in zip(families, fontspecs):
- matches = [f for f in rcParams["font." + family]
- if f in system_fonts]
- if matches:
- latex_fontspec.append(fontspec % matches[0])
- else:
- pass # no fonts found, fallback to LaTeX defaule
-
- return "\n".join(latex_fontspec)
-
-
-def get_preamble():
- """Get LaTeX preamble from rc."""
- latex_preamble = rcParams.get("pgf.preamble", "")
- if type(latex_preamble) == list:
- latex_preamble = "\n".join(latex_preamble)
- return latex_preamble
-
-###############################################################################
-
-# This almost made me cry!!!
-# In the end, it's better to use only one unit for all coordinates, since the
-# arithmetic in latex seems to produce inaccurate conversions.
-latex_pt_to_in = 1. / 72.27
-latex_in_to_pt = 1. / latex_pt_to_in
-mpl_pt_to_in = 1. / 72.
-mpl_in_to_pt = 1. / mpl_pt_to_in
-
-###############################################################################
-# helper functions
-
-NO_ESCAPE = r"(? 3 else 1.0
-
- if has_fill:
- writeln(self.fh, r"\definecolor{currentfill}{rgb}{%f,%f,%f}" % tuple(rgbFace[:3]))
- writeln(self.fh, r"\pgfsetfillcolor{currentfill}")
- if has_fill and fillopacity != 1.0:
- writeln(self.fh, r"\pgfsetfillopacity{%f}" % fillopacity)
-
- # linewidth and color
- lw = gc.get_linewidth() * mpl_pt_to_in * latex_in_to_pt
- stroke_rgba = gc.get_rgb()
- writeln(self.fh, r"\pgfsetlinewidth{%fpt}" % lw)
- writeln(self.fh, r"\definecolor{currentstroke}{rgb}{%f,%f,%f}" % stroke_rgba[:3])
- writeln(self.fh, r"\pgfsetstrokecolor{currentstroke}")
- if strokeopacity != 1.0:
- writeln(self.fh, r"\pgfsetstrokeopacity{%f}" % strokeopacity)
-
- # line style
- dash_offset, dash_list = gc.get_dashes()
- if dash_list is None:
- writeln(self.fh, r"\pgfsetdash{}{0pt}")
- else:
- dash_str = r"\pgfsetdash{"
- for dash in dash_list:
- dash_str += r"{%fpt}" % dash
- dash_str += r"}{%fpt}" % dash_offset
- writeln(self.fh, dash_str)
-
- def _print_pgf_path(self, gc, path, transform):
- f = 1. / self.dpi
- # check for clip box
- bbox = gc.get_clip_rectangle() if gc else None
- if bbox:
- p1, p2 = bbox.get_points()
- clip = (p1[0], p1[1], p2[0], p2[1])
- else:
- clip = None
- # build path
- for points, code in path.iter_segments(transform, clip=clip):
- if code == Path.MOVETO:
- x, y = tuple(points)
- writeln(self.fh, r"\pgfpathmoveto{\pgfqpoint{%fin}{%fin}}" %
- (f * x, f * y))
- elif code == Path.CLOSEPOLY:
- writeln(self.fh, r"\pgfpathclose")
- elif code == Path.LINETO:
- x, y = tuple(points)
- writeln(self.fh, r"\pgfpathlineto{\pgfqpoint{%fin}{%fin}}" %
- (f * x, f * y))
- elif code == Path.CURVE3:
- cx, cy, px, py = tuple(points)
- coords = cx * f, cy * f, px * f, py * f
- writeln(self.fh, r"\pgfpathquadraticcurveto{\pgfqpoint{%fin}{%fin}}{\pgfqpoint{%fin}{%fin}}" % coords)
- elif code == Path.CURVE4:
- c1x, c1y, c2x, c2y, px, py = tuple(points)
- coords = c1x * f, c1y * f, c2x * f, c2y * f, px * f, py * f
- writeln(self.fh, r"\pgfpathcurveto{\pgfqpoint{%fin}{%fin}}{\pgfqpoint{%fin}{%fin}}{\pgfqpoint{%fin}{%fin}}" % coords)
-
- def _pgf_path_draw(self, stroke=True, fill=False):
- actions = []
- if stroke:
- actions.append("stroke")
- if fill:
- actions.append("fill")
- writeln(self.fh, r"\pgfusepath{%s}" % ",".join(actions))
-
- def draw_image(self, gc, x, y, im):
- # TODO: Almost no documentation for the behavior of this function.
- # Something missing?
-
- # save the images to png files
- path = os.path.dirname(self.fh.name)
- fname = os.path.splitext(os.path.basename(self.fh.name))[0]
- fname_img = "%s-img%d.png" % (fname, self.image_counter)
- self.image_counter += 1
- im.flipud_out()
- rows, cols, buf = im.as_rgba_str()
- _png.write_png(buf, cols, rows, os.path.join(path, fname_img))
-
- # reference the image in the pgf picture
- writeln(self.fh, r"\begin{pgfscope}")
- self._print_pgf_clip(gc)
- h, w = im.get_size_out()
- f = 1. / self.dpi # from display coords to inch
- writeln(self.fh, r"\pgftext[at=\pgfqpoint{%fin}{%fin},left,bottom]{\pgfimage[interpolate=true,width=%fin,height=%fin]{%s}}" % (x * f, y * f, w * f, h * f, fname_img))
- writeln(self.fh, r"\end{pgfscope}")
-
- def draw_tex(self, gc, x, y, s, prop, angle, ismath="TeX!", mtext=None):
- self.draw_text(gc, x, y, s, prop, angle, ismath, mtext)
-
- def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
- # prepare string for tex
- s = common_texification(s)
- prop_cmds = _font_properties_str(prop)
- s = r"%s %s" % (prop_cmds, s)
-
-
- writeln(self.fh, r"\begin{pgfscope}")
-
- alpha = gc.get_alpha()
- if alpha != 1.0:
- writeln(self.fh, r"\pgfsetfillopacity{%f}" % alpha)
- writeln(self.fh, r"\pgfsetstrokeopacity{%f}" % alpha)
- rgb = tuple(gc.get_rgb())[:3]
- if rgb != (0, 0, 0):
- writeln(self.fh, r"\definecolor{textcolor}{rgb}{%f,%f,%f}" % rgb)
- writeln(self.fh, r"\pgfsetstrokecolor{textcolor}")
- writeln(self.fh, r"\pgfsetfillcolor{textcolor}")
- s = r"\color{textcolor}" + s
-
- f = 1.0 / self.figure.dpi
- text_args = []
- if mtext and (angle == 0 or mtext.get_rotation_mode() == "anchor"):
- # if text anchoring can be supported, get the original coordinates
- # and add alignment information
- x, y = mtext.get_transform().transform_point(mtext.get_position())
- text_args.append("x=%fin" % (x * f))
- text_args.append("y=%fin" % (y * f))
-
- halign = {"left": "left", "right": "right", "center": ""}
- valign = {"top": "top", "bottom": "bottom",
- "baseline": "base", "center": ""}
- text_args.append(halign[mtext.get_ha()])
- text_args.append(valign[mtext.get_va()])
- else:
- # if not, use the text layout provided by matplotlib
- text_args.append("x=%fin" % (x * f))
- text_args.append("y=%fin" % (y * f))
- text_args.append("left")
- text_args.append("base")
-
- if angle != 0:
- text_args.append("rotate=%f" % angle)
-
- writeln(self.fh, r"\pgftext[%s]{%s}" % (",".join(text_args), s))
- writeln(self.fh, r"\end{pgfscope}")
-
- def get_text_width_height_descent(self, s, prop, ismath):
- # check if the math is supposed to be displaystyled
- s = common_texification(s)
-
- # get text metrics in units of latex pt, convert to display units
- w, h, d = self.latexManager.get_width_height_descent(s, prop)
- # TODO: this should be latex_pt_to_in instead of mpl_pt_to_in
- # but having a little bit more space around the text looks better,
- # plus the bounding box reported by LaTeX is VERY narrow
- f = mpl_pt_to_in * self.dpi
- return w * f, h * f, d * f
-
- def flipy(self):
- return False
-
- def get_canvas_width_height(self):
- return self.figure.get_figwidth(), self.figure.get_figheight()
-
- def points_to_pixels(self, points):
- return points * mpl_pt_to_in * self.dpi
-
- def new_gc(self):
- return GraphicsContextPgf()
-
-
-class GraphicsContextPgf(GraphicsContextBase):
- pass
-
-########################################################################
-
-
-def draw_if_interactive():
- pass
-
-
-def new_figure_manager(num, *args, **kwargs):
- """
- Create a new figure manager instance
- """
- # if a main-level app must be created, this is the usual place to
- # do it -- see backend_wx, backend_wxagg and backend_tkagg for
- # examples. Not all GUIs require explicit instantiation of a
- # main-level app (egg backend_gtk, backend_gtkagg) for pylab
- FigureClass = kwargs.pop('FigureClass', Figure)
- thisFig = FigureClass(*args, **kwargs)
- return new_figure_manager_given_figure(num, thisFig)
-
-
-def new_figure_manager_given_figure(num, figure):
- """
- Create a new figure manager instance for the given figure.
- """
- canvas = FigureCanvasPgf(figure)
- manager = FigureManagerPgf(canvas, num)
- return manager
-
-
-class TmpDirCleaner:
- remaining_tmpdirs = set()
-
- @staticmethod
- def add(tmpdir):
- TmpDirCleaner.remaining_tmpdirs.add(tmpdir)
-
- @staticmethod
- def cleanup_remaining_tmpdirs():
- for tmpdir in TmpDirCleaner.remaining_tmpdirs:
- try:
- shutil.rmtree(tmpdir)
- except:
- sys.stderr.write("error deleting tmp directory %s\n" % tmpdir)
-
-
-class FigureCanvasPgf(FigureCanvasBase):
- filetypes = {"pgf": "LaTeX PGF picture",
- "pdf": "LaTeX compiled PGF picture",
- "png": "Portable Network Graphics", }
-
- def __init__(self, *args):
- FigureCanvasBase.__init__(self, *args)
-
- def get_default_filetype(self):
- return 'pdf'
-
- def _print_pgf_to_fh(self, fh, *args, **kwargs):
- if kwargs.get("dryrun", False):
- renderer = RendererPgf(self.figure, None, dummy=True)
- self.figure.draw(renderer)
- return
-
- header_text = """%% Creator: Matplotlib, PGF backend
-%%
-%% To include the figure in your LaTeX document, write
-%% \\input{.pgf}
-%%
-%% Make sure the required packages are loaded in your preamble
-%% \\usepackage{pgf}
-%%
-%% Figures using additional raster images can only be included by \input if
-%% they are in the same directory as the main LaTeX file. For loading figures
-%% from other directories you can use the `import` package
-%% \\usepackage{import}
-%% and then include the figures with
-%% \\import{}{.pgf}
-%%
-"""
-
- # append the preamble used by the backend as a comment for debugging
- header_info_preamble = ["%% Matplotlib used the following preamble"]
- for line in get_preamble().splitlines():
- header_info_preamble.append("%% " + line)
- for line in get_fontspec().splitlines():
- header_info_preamble.append("%% " + line)
- header_info_preamble.append("%%")
- header_info_preamble = "\n".join(header_info_preamble)
-
- # get figure size in inch
- w, h = self.figure.get_figwidth(), self.figure.get_figheight()
- dpi = self.figure.get_dpi()
-
- # create pgfpicture environment and write the pgf code
- fh.write(header_text)
- fh.write(header_info_preamble)
- fh.write("\n")
- writeln(fh, r"\begingroup")
- writeln(fh, r"\makeatletter")
- writeln(fh, r"\begin{pgfpicture}")
- writeln(fh, r"\pgfpathrectangle{\pgfpointorigin}{\pgfqpoint{%fin}{%fin}}" % (w, h))
- writeln(fh, r"\pgfusepath{use as bounding box, clip}")
- _bbox_inches_restore = kwargs.pop("bbox_inches_restore", None)
- renderer = MixedModeRenderer(self.figure, w, h, dpi,
- RendererPgf(self.figure, fh),
- bbox_inches_restore=_bbox_inches_restore)
- self.figure.draw(renderer)
-
- # end the pgfpicture environment
- writeln(fh, r"\end{pgfpicture}")
- writeln(fh, r"\makeatother")
- writeln(fh, r"\endgroup")
-
- def print_pgf(self, fname_or_fh, *args, **kwargs):
- """
- Output pgf commands for drawing the figure so it can be included and
- rendered in latex documents.
- """
- if kwargs.get("dryrun", False):
- self._print_pgf_to_fh(None, *args, **kwargs)
- return
-
- # figure out where the pgf is to be written to
- if is_string_like(fname_or_fh):
- with codecs.open(fname_or_fh, "w", encoding="utf-8") as fh:
- self._print_pgf_to_fh(fh, *args, **kwargs)
- elif is_writable_file_like(fname_or_fh):
- if not os.path.exists(fname_or_fh.name):
- warnings.warn("streamed pgf-code does not support raster "
- "graphics, consider using the pgf-to-pdf option",
- UserWarning)
- self._print_pgf_to_fh(fname_or_fh, *args, **kwargs)
- else:
- raise ValueError("filename must be a path")
-
- def _print_pdf_to_fh(self, fh, *args, **kwargs):
- w, h = self.figure.get_figwidth(), self.figure.get_figheight()
-
- try:
- # create temporary directory for compiling the figure
- tmpdir = tempfile.mkdtemp(prefix="mpl_pgf_")
- fname_pgf = os.path.join(tmpdir, "figure.pgf")
- fname_tex = os.path.join(tmpdir, "figure.tex")
- fname_pdf = os.path.join(tmpdir, "figure.pdf")
-
- # print figure to pgf and compile it with latex
- self.print_pgf(fname_pgf, *args, **kwargs)
-
- latex_preamble = get_preamble()
- latex_fontspec = get_fontspec()
- latexcode = """
-\\documentclass[12pt]{minimal}
-\\usepackage[paperwidth=%fin, paperheight=%fin, margin=0in]{geometry}
-%s
-%s
-\\usepackage{pgf}
-
-\\begin{document}
-\\centering
-\\input{figure.pgf}
-\\end{document}""" % (w, h, latex_preamble, latex_fontspec)
- with codecs.open(fname_tex, "w", "utf-8") as fh_tex:
- fh_tex.write(latexcode)
-
- texcommand = get_texcommand()
- cmdargs = [texcommand, "-interaction=nonstopmode",
- "-halt-on-error", "figure.tex"]
- try:
- check_output(cmdargs, stderr=subprocess.STDOUT, cwd=tmpdir)
- except subprocess.CalledProcessError as e:
- raise RuntimeError("%s was not able to process your file.\n\nFull log:\n%s" % (texcommand, e.output))
-
- # copy file contents to target
- with open(fname_pdf, "rb") as fh_src:
- shutil.copyfileobj(fh_src, fh)
- finally:
- try:
- shutil.rmtree(tmpdir)
- except:
- TmpDirCleaner.add(tmpdir)
-
- def print_pdf(self, fname_or_fh, *args, **kwargs):
- """
- Use LaTeX to compile a Pgf generated figure to PDF.
- """
- if kwargs.get("dryrun", False):
- self._print_pgf_to_fh(None, *args, **kwargs)
- return
-
- # figure out where the pdf is to be written to
- if is_string_like(fname_or_fh):
- with open(fname_or_fh, "wb") as fh:
- self._print_pdf_to_fh(fh, *args, **kwargs)
- elif is_writable_file_like(fname_or_fh):
- self._print_pdf_to_fh(fname_or_fh, *args, **kwargs)
- else:
- raise ValueError("filename must be a path or a file-like object")
-
- def _print_png_to_fh(self, fh, *args, **kwargs):
- converter = make_pdf_to_png_converter()
-
- try:
- # create temporary directory for pdf creation and png conversion
- tmpdir = tempfile.mkdtemp(prefix="mpl_pgf_")
- fname_pdf = os.path.join(tmpdir, "figure.pdf")
- fname_png = os.path.join(tmpdir, "figure.png")
- # create pdf and try to convert it to png
- self.print_pdf(fname_pdf, *args, **kwargs)
- converter(fname_pdf, fname_png, dpi=self.figure.dpi)
- # copy file contents to target
- with open(fname_png, "rb") as fh_src:
- shutil.copyfileobj(fh_src, fh)
- finally:
- try:
- shutil.rmtree(tmpdir)
- except:
- TmpDirCleaner.add(tmpdir)
-
- def print_png(self, fname_or_fh, *args, **kwargs):
- """
- Use LaTeX to compile a pgf figure to pdf and convert it to png.
- """
- if kwargs.get("dryrun", False):
- self._print_pgf_to_fh(None, *args, **kwargs)
- return
-
- if is_string_like(fname_or_fh):
- with open(fname_or_fh, "wb") as fh:
- self._print_png_to_fh(fh, *args, **kwargs)
- elif is_writable_file_like(fname_or_fh):
- self._print_png_to_fh(fname_or_fh, *args, **kwargs)
- else:
- raise ValueError("filename must be a path or a file-like object")
-
- def get_renderer(self):
- return RendererPgf(self.figure, None, dummy=True)
-
-
-class FigureManagerPgf(FigureManagerBase):
- def __init__(self, *args):
- FigureManagerBase.__init__(self, *args)
-
-
-FigureCanvas = FigureCanvasPgf
-FigureManager = FigureManagerPgf
-
-
-def _cleanup_all():
- LatexManager._cleanup_remaining_instances()
- TmpDirCleaner.cleanup_remaining_tmpdirs()
-
-atexit.register(_cleanup_all)
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_ps.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_ps.py
deleted file mode 100644
index 1e6892e..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_ps.py
+++ /dev/null
@@ -1,1799 +0,0 @@
-"""
-A PostScript backend, which can produce both PostScript .ps and .eps
-"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import StringIO
-
-import glob, math, os, shutil, sys, time
-def _fn_name(): return sys._getframe(1).f_code.co_name
-import io
-
-try:
- from hashlib import md5
-except ImportError:
- from md5 import md5 #Deprecated in 2.5
-
-from tempfile import mkstemp
-from matplotlib import verbose, __version__, rcParams, checkdep_ghostscript
-from matplotlib._pylab_helpers import Gcf
-from matplotlib.afm import AFM
-from matplotlib.backend_bases import RendererBase, GraphicsContextBase,\
- FigureManagerBase, FigureCanvasBase
-
-from matplotlib.cbook import is_string_like, get_realpath_and_stat, \
- is_writable_file_like, maxdict, file_requires_unicode
-from matplotlib.mlab import quad2cubic
-from matplotlib.figure import Figure
-
-from matplotlib.font_manager import findfont, is_opentype_cff_font
-from matplotlib.ft2font import FT2Font, KERNING_DEFAULT, LOAD_NO_HINTING
-from matplotlib.ttconv import convert_ttf_to_ps
-from matplotlib.mathtext import MathTextParser
-from matplotlib._mathtext_data import uni2type1
-from matplotlib.text import Text
-from matplotlib.path import Path
-from matplotlib.transforms import Affine2D
-
-from matplotlib.backends.backend_mixed import MixedModeRenderer
-
-
-import numpy as np
-import binascii
-import re
-try:
- set
-except NameError:
- from sets import Set as set
-
-if sys.platform.startswith('win'): cmd_split = '&'
-else: cmd_split = ';'
-
-backend_version = 'Level II'
-
-debugPS = 0
-
-
-class PsBackendHelper(object):
-
- def __init__(self):
- self._cached = {}
-
- @property
- def gs_exe(self):
- """
- excutable name of ghostscript.
- """
- try:
- return self._cached["gs_exe"]
- except KeyError:
- pass
-
- gs_exe, gs_version = checkdep_ghostscript()
- if gs_exe is None:
- gs_exe = 'gs'
-
- self._cached["gs_exe"] = gs_exe
- return gs_exe
-
- @property
- def gs_version(self):
- """
- version of ghostscript.
- """
- try:
- return self._cached["gs_version"]
- except KeyError:
- pass
-
- from matplotlib.compat.subprocess import Popen, PIPE
- s = Popen(self.gs_exe + " --version",
- shell=True, stdout=PIPE)
- pipe, stderr = s.communicate()
- if six.PY3:
- ver = pipe.decode('ascii')
- else:
- ver = pipe
- try:
- gs_version = tuple(map(int, ver.strip().split(".")))
- except ValueError:
- # if something went wrong parsing return null version number
- gs_version = (0, 0)
- self._cached["gs_version"] = gs_version
- return gs_version
-
- @property
- def supports_ps2write(self):
- """
- True if the installed ghostscript supports ps2write device.
- """
- return self.gs_version[0] >= 9
-
-ps_backend_helper = PsBackendHelper()
-
-papersize = {'letter': (8.5,11),
- 'legal': (8.5,14),
- 'ledger': (11,17),
- 'a0': (33.11,46.81),
- 'a1': (23.39,33.11),
- 'a2': (16.54,23.39),
- 'a3': (11.69,16.54),
- 'a4': (8.27,11.69),
- 'a5': (5.83,8.27),
- 'a6': (4.13,5.83),
- 'a7': (2.91,4.13),
- 'a8': (2.07,2.91),
- 'a9': (1.457,2.05),
- 'a10': (1.02,1.457),
- 'b0': (40.55,57.32),
- 'b1': (28.66,40.55),
- 'b2': (20.27,28.66),
- 'b3': (14.33,20.27),
- 'b4': (10.11,14.33),
- 'b5': (7.16,10.11),
- 'b6': (5.04,7.16),
- 'b7': (3.58,5.04),
- 'b8': (2.51,3.58),
- 'b9': (1.76,2.51),
- 'b10': (1.26,1.76)}
-
-def _get_papertype(w, h):
- keys = list(six.iterkeys(papersize))
- keys.sort()
- keys.reverse()
- for key in keys:
- if key.startswith('l'): continue
- pw, ph = papersize[key]
- if (w < pw) and (h < ph): return key
- else:
- return 'a0'
-
-def _num_to_str(val):
- if is_string_like(val): return val
-
- ival = int(val)
- if val==ival: return str(ival)
-
- s = "%1.3f"%val
- s = s.rstrip("0")
- s = s.rstrip(".")
- return s
-
-def _nums_to_str(*args):
- return ' '.join(map(_num_to_str,args))
-
-def quote_ps_string(s):
- "Quote dangerous characters of S for use in a PostScript string constant."
- s=s.replace("\\", "\\\\")
- s=s.replace("(", "\\(")
- s=s.replace(")", "\\)")
- s=s.replace("'", "\\251")
- s=s.replace("`", "\\301")
- s=re.sub(r"[^ -~\n]", lambda x: r"\%03o"%ord(x.group()), s)
- return s
-
-
-def seq_allequal(seq1, seq2):
- """
- seq1 and seq2 are either None or sequences or arrays
- Return True if both are None or both are seqs with identical
- elements
- """
- if seq1 is None:
- return seq2 is None
-
- if seq2 is None:
- return False
- #ok, neither are None:, assuming iterable
-
- if len(seq1) != len(seq2): return False
- return np.alltrue(np.equal(seq1, seq2))
-
-
-class RendererPS(RendererBase):
- """
- The renderer handles all the drawing primitives using a graphics
- context instance that controls the colors/styles.
- """
-
- fontd = maxdict(50)
- afmfontd = maxdict(50)
-
- def __init__(self, width, height, pswriter, imagedpi=72):
- """
- Although postscript itself is dpi independent, we need to
- imform the image code about a requested dpi to generate high
- res images and them scale them before embeddin them
- """
- RendererBase.__init__(self)
- self.width = width
- self.height = height
- self._pswriter = pswriter
- if rcParams['text.usetex']:
- self.textcnt = 0
- self.psfrag = []
- self.imagedpi = imagedpi
-
- # current renderer state (None=uninitialised)
- self.color = None
- self.linewidth = None
- self.linejoin = None
- self.linecap = None
- self.linedash = None
- self.fontname = None
- self.fontsize = None
- self._hatches = {}
- self.image_magnification = imagedpi/72.0
- self._clip_paths = {}
- self._path_collection_id = 0
-
- self.used_characters = {}
- self.mathtext_parser = MathTextParser("PS")
-
- self._afm_font_dir = os.path.join(
- rcParams['datapath'], 'fonts', 'afm')
-
- def track_characters(self, font, s):
- """Keeps track of which characters are required from
- each font."""
- realpath, stat_key = get_realpath_and_stat(font.fname)
- used_characters = self.used_characters.setdefault(
- stat_key, (realpath, set()))
- used_characters[1].update([ord(x) for x in s])
-
- def merge_used_characters(self, other):
- for stat_key, (realpath, charset) in six.iteritems(other):
- used_characters = self.used_characters.setdefault(
- stat_key, (realpath, set()))
- used_characters[1].update(charset)
-
- def set_color(self, r, g, b, store=1):
- if (r,g,b) != self.color:
- if r==g and r==b:
- self._pswriter.write("%1.3f setgray\n"%r)
- else:
- self._pswriter.write("%1.3f %1.3f %1.3f setrgbcolor\n"%(r,g,b))
- if store: self.color = (r,g,b)
-
- def set_linewidth(self, linewidth, store=1):
- if linewidth != self.linewidth:
- self._pswriter.write("%1.3f setlinewidth\n"%linewidth)
- if store: self.linewidth = linewidth
-
- def set_linejoin(self, linejoin, store=1):
- if linejoin != self.linejoin:
- self._pswriter.write("%d setlinejoin\n"%linejoin)
- if store: self.linejoin = linejoin
-
- def set_linecap(self, linecap, store=1):
- if linecap != self.linecap:
- self._pswriter.write("%d setlinecap\n"%linecap)
- if store: self.linecap = linecap
-
- def set_linedash(self, offset, seq, store=1):
- if self.linedash is not None:
- oldo, oldseq = self.linedash
- if seq_allequal(seq, oldseq): return
-
- if seq is not None and len(seq):
- s="[%s] %d setdash\n"%(_nums_to_str(*seq), offset)
- self._pswriter.write(s)
- else:
- self._pswriter.write("[] 0 setdash\n")
- if store: self.linedash = (offset,seq)
-
- def set_font(self, fontname, fontsize, store=1):
- if rcParams['ps.useafm']: return
- if (fontname,fontsize) != (self.fontname,self.fontsize):
- out = ("/%s findfont\n"
- "%1.3f scalefont\n"
- "setfont\n" % (fontname, fontsize))
-
- self._pswriter.write(out)
- if store: self.fontname = fontname
- if store: self.fontsize = fontsize
-
- def create_hatch(self, hatch):
- sidelen = 72
- if hatch in self._hatches:
- return self._hatches[hatch]
- name = 'H%d' % len(self._hatches)
- self._pswriter.write("""\
- << /PatternType 1
- /PaintType 2
- /TilingType 2
- /BBox[0 0 %(sidelen)d %(sidelen)d]
- /XStep %(sidelen)d
- /YStep %(sidelen)d
-
- /PaintProc {
- pop
- 0 setlinewidth
-""" % locals())
- self._pswriter.write(
- self._convert_path(Path.hatch(hatch), Affine2D().scale(72.0),
- simplify=False))
- self._pswriter.write("""\
- stroke
- } bind
- >>
- matrix
- makepattern
- /%(name)s exch def
-""" % locals())
- self._hatches[hatch] = name
- return name
-
- def get_canvas_width_height(self):
- 'return the canvas width and height in display coords'
- return self.width, self.height
-
- def get_text_width_height_descent(self, s, prop, ismath):
- """
- get the width and height in display coords of the string s
- with FontPropertry prop
-
- """
- if rcParams['text.usetex']:
- texmanager = self.get_texmanager()
- fontsize = prop.get_size_in_points()
- w, h, d = texmanager.get_text_width_height_descent(s, fontsize,
- renderer=self)
- return w, h, d
-
- if ismath:
- width, height, descent, pswriter, used_characters = \
- self.mathtext_parser.parse(s, 72, prop)
- return width, height, descent
-
- if rcParams['ps.useafm']:
- if ismath: s = s[1:-1]
- font = self._get_font_afm(prop)
- l,b,w,h,d = font.get_str_bbox_and_descent(s)
-
- fontsize = prop.get_size_in_points()
- scale = 0.001*fontsize
- w *= scale
- h *= scale
- d *= scale
- return w, h, d
-
- font = self._get_font_ttf(prop)
- font.set_text(s, 0.0, flags=LOAD_NO_HINTING)
- w, h = font.get_width_height()
- w /= 64.0 # convert from subpixels
- h /= 64.0
- d = font.get_descent()
- d /= 64.0
- #print s, w, h
- return w, h, d
-
- def flipy(self):
- 'return true if small y numbers are top for renderer'
- return False
-
- def _get_font_afm(self, prop):
- key = hash(prop)
- font = self.afmfontd.get(key)
- if font is None:
- fname = findfont(prop, fontext='afm', directory=self._afm_font_dir)
- if fname is None:
- fname = findfont(
- "Helvetica", fontext='afm', directory=self._afm_font_dir)
- font = self.afmfontd.get(fname)
- if font is None:
- with io.open(fname, 'rb') as fh:
- font = AFM(fh)
- self.afmfontd[fname] = font
- self.afmfontd[key] = font
- return font
-
- def _get_font_ttf(self, prop):
- key = hash(prop)
- font = self.fontd.get(key)
- if font is None:
- fname = findfont(prop)
- font = self.fontd.get(fname)
- if font is None:
- font = FT2Font(fname)
- self.fontd[fname] = font
- self.fontd[key] = font
- font.clear()
- size = prop.get_size_in_points()
- font.set_size(size, 72.0)
- return font
-
- def _rgba(self, im):
- return im.as_rgba_str()
-
- def _rgb(self, im):
- h,w,s = im.as_rgba_str()
-
- rgba = np.fromstring(s, np.uint8)
- rgba.shape = (h, w, 4)
- rgb = rgba[:,:,:3]
- return h, w, rgb.tostring()
-
- def _gray(self, im, rc=0.3, gc=0.59, bc=0.11):
- rgbat = im.as_rgba_str()
- rgba = np.fromstring(rgbat[2], np.uint8)
- rgba.shape = (rgbat[0], rgbat[1], 4)
- rgba_f = rgba.astype(np.float32)
- r = rgba_f[:,:,0]
- g = rgba_f[:,:,1]
- b = rgba_f[:,:,2]
- gray = (r*rc + g*gc + b*bc).astype(np.uint8)
- return rgbat[0], rgbat[1], gray.tostring()
-
- def _hex_lines(self, s, chars_per_line=128):
- s = binascii.b2a_hex(s)
- nhex = len(s)
- lines = []
- for i in range(0,nhex,chars_per_line):
- limit = min(i+chars_per_line, nhex)
- lines.append(s[i:limit])
- return lines
-
- def get_image_magnification(self):
- """
- Get the factor by which to magnify images passed to draw_image.
- Allows a backend to have images at a different resolution to other
- artists.
- """
- return self.image_magnification
-
- def option_scale_image(self):
- """
- ps backend support arbitrary scaling of image.
- """
- return True
-
- def _get_image_h_w_bits_command(self, im):
- if im.is_grayscale:
- h, w, bits = self._gray(im)
- imagecmd = "image"
- else:
- h, w, bits = self._rgb(im)
- imagecmd = "false 3 colorimage"
-
- return h, w, bits, imagecmd
-
- def draw_image(self, gc, x, y, im, dx=None, dy=None, transform=None):
- """
- Draw the Image instance into the current axes; x is the
- distance in pixels from the left hand side of the canvas and y
- is the distance from bottom
-
- dx, dy is the width and height of the image. If a transform
- (which must be an affine transform) is given, x, y, dx, dy are
- interpreted as the coordinate of the transform.
- """
-
- im.flipud_out()
-
- h, w, bits, imagecmd = self._get_image_h_w_bits_command(im)
- hexlines = b'\n'.join(self._hex_lines(bits)).decode('ascii')
-
- if dx is None:
- xscale = w / self.image_magnification
- else:
- xscale = dx
-
- if dy is None:
- yscale = h/self.image_magnification
- else:
- yscale = dy
-
-
- if transform is None:
- matrix = "1 0 0 1 0 0"
- else:
- matrix = " ".join(map(str, transform.to_values()))
-
- figh = self.height*72
- #print 'values', origin, flipud, figh, h, y
-
- bbox = gc.get_clip_rectangle()
- clippath, clippath_trans = gc.get_clip_path()
-
- clip = []
- if bbox is not None:
- clipx,clipy,clipw,cliph = bbox.bounds
- clip.append('%s clipbox' % _nums_to_str(clipw, cliph, clipx, clipy))
- if clippath is not None:
- id = self._get_clip_path(clippath, clippath_trans)
- clip.append('%s' % id)
- clip = '\n'.join(clip)
-
- #y = figh-(y+h)
- ps = """gsave
-%(clip)s
-[%(matrix)s] concat
-%(x)s %(y)s translate
-%(xscale)s %(yscale)s scale
-/DataString %(w)s string def
-%(w)s %(h)s 8 [ %(w)s 0 0 -%(h)s 0 %(h)s ]
-{
-currentfile DataString readhexstring pop
-} bind %(imagecmd)s
-%(hexlines)s
-grestore
-""" % locals()
- self._pswriter.write(ps)
-
- # unflip
- im.flipud_out()
-
- def _convert_path(self, path, transform, clip=False, simplify=None):
- ps = []
- last_points = None
- if clip:
- clip = (0.0, 0.0, self.width * 72.0,
- self.height * 72.0)
- else:
- clip = None
- for points, code in path.iter_segments(transform, clip=clip,
- simplify=simplify):
- if code == Path.MOVETO:
- ps.append("%g %g m" % tuple(points))
- elif code == Path.CLOSEPOLY:
- ps.append("cl")
- elif last_points is None:
- # The other operations require a previous point
- raise ValueError('Path lacks initial MOVETO')
- elif code == Path.LINETO:
- ps.append("%g %g l" % tuple(points))
- elif code == Path.CURVE3:
- points = quad2cubic(*(list(last_points[-2:]) + list(points)))
- ps.append("%g %g %g %g %g %g c" %
- tuple(points[2:]))
- elif code == Path.CURVE4:
- ps.append("%g %g %g %g %g %g c" % tuple(points))
- last_points = points
-
- ps = "\n".join(ps)
- return ps
-
- def _get_clip_path(self, clippath, clippath_transform):
- key = (clippath, id(clippath_transform))
- pid = self._clip_paths.get(key)
- if pid is None:
- pid = 'c%x' % len(self._clip_paths)
- ps_cmd = ['/%s {' % pid]
- ps_cmd.append(self._convert_path(clippath, clippath_transform,
- simplify=False))
- ps_cmd.extend(['clip', 'newpath', '} bind def\n'])
- self._pswriter.write('\n'.join(ps_cmd))
- self._clip_paths[key] = pid
- return pid
-
- def draw_path(self, gc, path, transform, rgbFace=None):
- """
- Draws a Path instance using the given affine transform.
- """
- clip = (rgbFace is None and gc.get_hatch_path() is None)
- simplify = path.should_simplify and clip
- ps = self._convert_path(
- path, transform, clip=clip, simplify=simplify)
- self._draw_ps(ps, gc, rgbFace)
-
- def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None):
- """
- Draw the markers defined by path at each of the positions in x
- and y. path coordinates are points, x and y coords will be
- transformed by the transform
- """
- if debugPS: self._pswriter.write('% draw_markers \n')
-
- write = self._pswriter.write
-
- if rgbFace:
- if rgbFace[0]==rgbFace[1] and rgbFace[0]==rgbFace[2]:
- ps_color = '%1.3f setgray' % rgbFace[0]
- else:
- ps_color = '%1.3f %1.3f %1.3f setrgbcolor' % rgbFace[:3]
-
- # construct the generic marker command:
- ps_cmd = ['/o {', 'gsave', 'newpath', 'translate'] # dont want the translate to be global
-
- lw = gc.get_linewidth()
- stroke = lw != 0.0
- if stroke:
- ps_cmd.append('%.1f setlinewidth' % lw)
- jint = gc.get_joinstyle()
- ps_cmd.append('%d setlinejoin' % jint)
- cint = gc.get_capstyle()
- ps_cmd.append('%d setlinecap' % cint)
-
- ps_cmd.append(self._convert_path(marker_path, marker_trans,
- simplify=False))
-
- if rgbFace:
- if stroke:
- ps_cmd.append('gsave')
- ps_cmd.extend([ps_color, 'fill'])
- if stroke:
- ps_cmd.append('grestore')
-
- if stroke:
- ps_cmd.append('stroke')
- ps_cmd.extend(['grestore', '} bind def'])
-
- for vertices, code in path.iter_segments(
- trans,
- clip=(0, 0, self.width*72, self.height*72),
- simplify=False):
- if len(vertices):
- x, y = vertices[-2:]
- ps_cmd.append("%g %g o" % (x, y))
-
- ps = '\n'.join(ps_cmd)
- self._draw_ps(ps, gc, rgbFace, fill=False, stroke=False)
-
- def draw_path_collection(self, gc, master_transform, paths, all_transforms,
- offsets, offsetTrans, facecolors, edgecolors,
- linewidths, linestyles, antialiaseds, urls,
- offset_position):
- # Is the optimization worth it? Rough calculation:
- # cost of emitting a path in-line is
- # (len_path + 2) * uses_per_path
- # cost of definition+use is
- # (len_path + 3) + 3 * uses_per_path
- len_path = len(paths[0].vertices) if len(paths) > 0 else 0
- uses_per_path = self._iter_collection_uses_per_path(
- paths, all_transforms, offsets, facecolors, edgecolors)
- should_do_optimization = \
- len_path + 3 * uses_per_path + 3 < (len_path + 2) * uses_per_path
- if not should_do_optimization:
- return RendererBase.draw_path_collection(
- self, gc, master_transform, paths, all_transforms,
- offsets, offsetTrans, facecolors, edgecolors,
- linewidths, linestyles, antialiaseds, urls,
- offset_position)
-
- write = self._pswriter.write
-
- path_codes = []
- for i, (path, transform) in enumerate(self._iter_collection_raw_paths(
- master_transform, paths, all_transforms)):
- name = 'p%x_%x' % (self._path_collection_id, i)
- ps_cmd = ['/%s {' % name,
- 'newpath', 'translate']
- ps_cmd.append(self._convert_path(path, transform, simplify=False))
- ps_cmd.extend(['} bind def\n'])
- write('\n'.join(ps_cmd))
- path_codes.append(name)
-
- for xo, yo, path_id, gc0, rgbFace in self._iter_collection(
- gc, master_transform, all_transforms, path_codes, offsets,
- offsetTrans, facecolors, edgecolors, linewidths, linestyles,
- antialiaseds, urls, offset_position):
- ps = "%g %g %s" % (xo, yo, path_id)
- self._draw_ps(ps, gc0, rgbFace)
-
- self._path_collection_id += 1
-
- def draw_tex(self, gc, x, y, s, prop, angle, ismath='TeX!', mtext=None):
- """
- draw a Text instance
- """
- w, h, bl = self.get_text_width_height_descent(s, prop, ismath)
- fontsize = prop.get_size_in_points()
- thetext = 'psmarker%d' % self.textcnt
- color = '%1.3f,%1.3f,%1.3f'% gc.get_rgb()[:3]
- fontcmd = {'sans-serif' : r'{\sffamily %s}',
- 'monospace' : r'{\ttfamily %s}'}.get(
- rcParams['font.family'][0], r'{\rmfamily %s}')
- s = fontcmd % s
- tex = r'\color[rgb]{%s} %s' % (color, s)
-
- corr = 0#w/2*(fontsize-10)/10
- if rcParams['text.latex.preview']:
- # use baseline alignment!
- pos = _nums_to_str(x-corr, y)
- self.psfrag.append(r'\psfrag{%s}[Bl][Bl][1][%f]{\fontsize{%f}{%f}%s}'%(thetext, angle, fontsize, fontsize*1.25, tex))
- else:
- # stick to the bottom alignment, but this may give incorrect baseline some times.
- pos = _nums_to_str(x-corr, y-bl)
- self.psfrag.append(r'\psfrag{%s}[bl][bl][1][%f]{\fontsize{%f}{%f}%s}'%(thetext, angle, fontsize, fontsize*1.25, tex))
-
- ps = """\
-gsave
-%(pos)s moveto
-(%(thetext)s)
-show
-grestore
- """ % locals()
-
- self._pswriter.write(ps)
- self.textcnt += 1
-
- def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
- """
- draw a Text instance
- """
- # local to avoid repeated attribute lookups
- write = self._pswriter.write
- if debugPS:
- write("% text\n")
-
- if ismath=='TeX':
- return self.tex(gc, x, y, s, prop, angle)
-
- elif ismath:
- return self.draw_mathtext(gc, x, y, s, prop, angle)
-
- elif rcParams['ps.useafm']:
- self.set_color(*gc.get_rgb())
-
- font = self._get_font_afm(prop)
- fontname = font.get_fontname()
- fontsize = prop.get_size_in_points()
- scale = 0.001*fontsize
-
- thisx = 0
- thisy = font.get_str_bbox_and_descent(s)[4] * scale
- last_name = None
- lines = []
- for c in s:
- name = uni2type1.get(ord(c), 'question')
- try:
- width = font.get_width_from_char_name(name)
- except KeyError:
- name = 'question'
- width = font.get_width_char('?')
- if last_name is not None:
- kern = font.get_kern_dist_from_name(last_name, name)
- else:
- kern = 0
- last_name = name
- thisx += kern * scale
-
- lines.append('%f %f m /%s glyphshow'%(thisx, thisy, name))
-
- thisx += width * scale
-
- thetext = "\n".join(lines)
- ps = """\
-gsave
-/%(fontname)s findfont
-%(fontsize)s scalefont
-setfont
-%(x)f %(y)f translate
-%(angle)f rotate
-%(thetext)s
-grestore
- """ % locals()
- self._pswriter.write(ps)
-
- else:
- font = self._get_font_ttf(prop)
- font.set_text(s, 0, flags=LOAD_NO_HINTING)
- self.track_characters(font, s)
-
- self.set_color(*gc.get_rgb())
- sfnt = font.get_sfnt()
- try:
- ps_name = sfnt[(1,0,0,6)].decode('macroman')
- except KeyError:
- ps_name = sfnt[(3,1,0x0409,6)].decode(
- 'utf-16be')
- ps_name = ps_name.encode('ascii', 'replace').decode('ascii')
- self.set_font(ps_name, prop.get_size_in_points())
-
- cmap = font.get_charmap()
- lastgind = None
- #print 'text', s
- lines = []
- thisx = 0
- thisy = 0
- for c in s:
- ccode = ord(c)
- gind = cmap.get(ccode)
- if gind is None:
- ccode = ord('?')
- name = '.notdef'
- gind = 0
- else:
- name = font.get_glyph_name(gind)
- glyph = font.load_char(ccode, flags=LOAD_NO_HINTING)
-
- if lastgind is not None:
- kern = font.get_kerning(lastgind, gind, KERNING_DEFAULT)
- else:
- kern = 0
- lastgind = gind
- thisx += kern/64.0
-
- lines.append('%f %f m /%s glyphshow'%(thisx, thisy, name))
- thisx += glyph.linearHoriAdvance/65536.0
-
-
- thetext = '\n'.join(lines)
- ps = """gsave
-%(x)f %(y)f translate
-%(angle)f rotate
-%(thetext)s
-grestore
-""" % locals()
- self._pswriter.write(ps)
-
- def new_gc(self):
- return GraphicsContextPS()
-
- def draw_mathtext(self, gc,
- x, y, s, prop, angle):
- """
- Draw the math text using matplotlib.mathtext
- """
- if debugPS:
- self._pswriter.write("% mathtext\n")
-
- width, height, descent, pswriter, used_characters = \
- self.mathtext_parser.parse(s, 72, prop)
- self.merge_used_characters(used_characters)
- self.set_color(*gc.get_rgb())
- thetext = pswriter.getvalue()
- ps = """gsave
-%(x)f %(y)f translate
-%(angle)f rotate
-%(thetext)s
-grestore
-""" % locals()
- self._pswriter.write(ps)
-
- def draw_gouraud_triangle(self, gc, points, colors, trans):
- self.draw_gouraud_triangles(gc, points.reshape((1, 3, 2)),
- colors.reshape((1, 3, 4)), trans)
-
- def draw_gouraud_triangles(self, gc, points, colors, trans):
- assert len(points) == len(colors)
- assert points.ndim == 3
- assert points.shape[1] == 3
- assert points.shape[2] == 2
- assert colors.ndim == 3
- assert colors.shape[1] == 3
- assert colors.shape[2] == 4
-
- shape = points.shape
- flat_points = points.reshape((shape[0] * shape[1], 2))
- flat_points = trans.transform(flat_points)
- flat_colors = colors.reshape((shape[0] * shape[1], 4))
- points_min = np.min(flat_points, axis=0) - (1 << 12)
- points_max = np.max(flat_points, axis=0) + (1 << 12)
- factor = np.ceil(float(2 ** 32 - 1) / (points_max - points_min))
-
- xmin, ymin = points_min
- xmax, ymax = points_max
-
- streamarr = np.empty(
- (shape[0] * shape[1],),
- dtype=[('flags', 'u1'),
- ('points', '>u4', (2,)),
- ('colors', 'u1', (3,))])
- streamarr['flags'] = 0
- streamarr['points'] = (flat_points - points_min) * factor
- streamarr['colors'] = flat_colors[:, :3] * 255.0
-
- stream = quote_ps_string(streamarr.tostring())
-
- self._pswriter.write("""
-gsave
-<< /ShadingType 4
- /ColorSpace [/DeviceRGB]
- /BitsPerCoordinate 32
- /BitsPerComponent 8
- /BitsPerFlag 8
- /AntiAlias true
- /Decode [ %(xmin)f %(xmax)f %(ymin)f %(ymax)f 0 1 0 1 0 1 ]
- /DataSource (%(stream)s)
->>
-shfill
-grestore
-""" % locals())
-
- def _draw_ps(self, ps, gc, rgbFace, fill=True, stroke=True, command=None):
- """
- Emit the PostScript sniplet 'ps' with all the attributes from 'gc'
- applied. 'ps' must consist of PostScript commands to construct a path.
-
- The fill and/or stroke kwargs can be set to False if the
- 'ps' string already includes filling and/or stroking, in
- which case _draw_ps is just supplying properties and
- clipping.
- """
- # local variable eliminates all repeated attribute lookups
- write = self._pswriter.write
- if debugPS and command:
- write("% "+command+"\n")
- mightstroke = gc.shouldstroke()
- stroke = stroke and mightstroke
- fill = (fill and rgbFace is not None and
- (len(rgbFace) <= 3 or rgbFace[3] != 0.0))
-
- if mightstroke:
- self.set_linewidth(gc.get_linewidth())
- jint = gc.get_joinstyle()
- self.set_linejoin(jint)
- cint = gc.get_capstyle()
- self.set_linecap(cint)
- self.set_linedash(*gc.get_dashes())
- self.set_color(*gc.get_rgb()[:3])
- write('gsave\n')
-
- cliprect = gc.get_clip_rectangle()
- if cliprect:
- x,y,w,h=cliprect.bounds
- write('%1.4g %1.4g %1.4g %1.4g clipbox\n' % (w,h,x,y))
- clippath, clippath_trans = gc.get_clip_path()
- if clippath:
- id = self._get_clip_path(clippath, clippath_trans)
- write('%s\n' % id)
-
- # Jochen, is the strip necessary? - this could be a honking big string
- write(ps.strip())
- write("\n")
-
- if fill:
- if stroke:
- write("gsave\n")
- self.set_color(store=0, *rgbFace[:3])
- write("fill\n")
- if stroke:
- write("grestore\n")
-
- hatch = gc.get_hatch()
- if hatch:
- hatch_name = self.create_hatch(hatch)
- write("gsave\n")
- write("[/Pattern [/DeviceRGB]] setcolorspace %f %f %f " % gc.get_rgb()[:3])
- write("%s setcolor fill grestore\n" % hatch_name)
-
- if stroke:
- write("stroke\n")
-
- write("grestore\n")
-
-
-
-class GraphicsContextPS(GraphicsContextBase):
- def get_capstyle(self):
- return {'butt':0,
- 'round':1,
- 'projecting':2}[GraphicsContextBase.get_capstyle(self)]
-
- def get_joinstyle(self):
- return {'miter':0,
- 'round':1,
- 'bevel':2}[GraphicsContextBase.get_joinstyle(self)]
-
- def shouldstroke(self):
- return (self.get_linewidth() > 0.0 and
- (len(self.get_rgb()) <= 3 or self.get_rgb()[3] != 0.0))
-
-def new_figure_manager(num, *args, **kwargs):
- FigureClass = kwargs.pop('FigureClass', Figure)
- thisFig = FigureClass(*args, **kwargs)
- return new_figure_manager_given_figure(num, thisFig)
-
-
-def new_figure_manager_given_figure(num, figure):
- """
- Create a new figure manager instance for the given figure.
- """
- canvas = FigureCanvasPS(figure)
- manager = FigureManagerPS(canvas, num)
- return manager
-
-class FigureCanvasPS(FigureCanvasBase):
- _renderer_class = RendererPS
-
- fixed_dpi = 72
-
- def draw(self):
- pass
-
- filetypes = {'ps' : 'Postscript',
- 'eps' : 'Encapsulated Postscript'}
-
- def get_default_filetype(self):
- return 'ps'
-
- def print_ps(self, outfile, *args, **kwargs):
- return self._print_ps(outfile, 'ps', *args, **kwargs)
-
- def print_eps(self, outfile, *args, **kwargs):
- return self._print_ps(outfile, 'eps', *args, **kwargs)
-
- def _print_ps(self, outfile, format, *args, **kwargs):
- papertype = kwargs.pop("papertype", rcParams['ps.papersize'])
- papertype = papertype.lower()
- if papertype == 'auto':
- pass
- elif papertype not in papersize:
- raise RuntimeError( '%s is not a valid papertype. Use one \
- of %s'% (papertype, ', '.join(six.iterkeys(papersize))))
-
- orientation = kwargs.pop("orientation", "portrait").lower()
- if orientation == 'landscape': isLandscape = True
- elif orientation == 'portrait': isLandscape = False
- else: raise RuntimeError('Orientation must be "portrait" or "landscape"')
-
- self.figure.set_dpi(72) # Override the dpi kwarg
- imagedpi = kwargs.pop("dpi", 72)
- facecolor = kwargs.pop("facecolor", "w")
- edgecolor = kwargs.pop("edgecolor", "w")
-
- if rcParams['text.usetex']:
- self._print_figure_tex(outfile, format, imagedpi, facecolor, edgecolor,
- orientation, isLandscape, papertype,
- **kwargs)
- else:
- self._print_figure(outfile, format, imagedpi, facecolor, edgecolor,
- orientation, isLandscape, papertype,
- **kwargs)
-
- def _print_figure(self, outfile, format, dpi=72, facecolor='w', edgecolor='w',
- orientation='portrait', isLandscape=False, papertype=None,
- **kwargs):
- """
- Render the figure to hardcopy. Set the figure patch face and
- edge colors. This is useful because some of the GUIs have a
- gray figure face color background and you'll probably want to
- override this on hardcopy
-
- If outfile is a string, it is interpreted as a file name.
- If the extension matches .ep* write encapsulated postscript,
- otherwise write a stand-alone PostScript file.
-
- If outfile is a file object, a stand-alone PostScript file is
- written into this file object.
- """
- isEPSF = format == 'eps'
- passed_in_file_object = False
- if is_string_like(outfile):
- title = outfile
- elif is_writable_file_like(outfile):
- title = None
- passed_in_file_object = True
- else:
- raise ValueError("outfile must be a path or a file-like object")
-
- # find the appropriate papertype
- width, height = self.figure.get_size_inches()
- if papertype == 'auto':
- if isLandscape: papertype = _get_papertype(height, width)
- else: papertype = _get_papertype(width, height)
-
- if isLandscape: paperHeight, paperWidth = papersize[papertype]
- else: paperWidth, paperHeight = papersize[papertype]
-
- if rcParams['ps.usedistiller'] and not papertype == 'auto':
- # distillers will improperly clip eps files if the pagesize is
- # too small
- if width>paperWidth or height>paperHeight:
- if isLandscape:
- papertype = _get_papertype(height, width)
- paperHeight, paperWidth = papersize[papertype]
- else:
- papertype = _get_papertype(width, height)
- paperWidth, paperHeight = papersize[papertype]
-
- # center the figure on the paper
- xo = 72*0.5*(paperWidth - width)
- yo = 72*0.5*(paperHeight - height)
-
- l, b, w, h = self.figure.bbox.bounds
- llx = xo
- lly = yo
- urx = llx + w
- ury = lly + h
- rotation = 0
- if isLandscape:
- llx, lly, urx, ury = lly, llx, ury, urx
- xo, yo = 72*paperHeight - yo, xo
- rotation = 90
- bbox = (llx, lly, urx, ury)
-
- # generate PostScript code for the figure and store it in a string
- origfacecolor = self.figure.get_facecolor()
- origedgecolor = self.figure.get_edgecolor()
- self.figure.set_facecolor(facecolor)
- self.figure.set_edgecolor(edgecolor)
-
-
- dryrun = kwargs.get("dryrun", False)
- if dryrun:
- class NullWriter(object):
- def write(self, *kl, **kwargs):
- pass
-
- self._pswriter = NullWriter()
- else:
- self._pswriter = io.StringIO()
-
-
- # mixed mode rendering
- _bbox_inches_restore = kwargs.pop("bbox_inches_restore", None)
- ps_renderer = self._renderer_class(width, height, self._pswriter,
- imagedpi=dpi)
- renderer = MixedModeRenderer(self.figure,
- width, height, dpi, ps_renderer,
- bbox_inches_restore=_bbox_inches_restore)
-
- self.figure.draw(renderer)
-
- if dryrun: # return immediately if dryrun (tightbbox=True)
- return
-
- self.figure.set_facecolor(origfacecolor)
- self.figure.set_edgecolor(origedgecolor)
-
- def print_figure_impl():
- # write the PostScript headers
- if isEPSF: print("%!PS-Adobe-3.0 EPSF-3.0", file=fh)
- else: print("%!PS-Adobe-3.0", file=fh)
- if title: print("%%Title: "+title, file=fh)
- print(("%%Creator: matplotlib version "
- +__version__+", http://matplotlib.org/"), file=fh)
- print("%%CreationDate: "+time.ctime(time.time()), file=fh)
- print("%%Orientation: " + orientation, file=fh)
- if not isEPSF: print("%%DocumentPaperSizes: "+papertype, file=fh)
- print("%%%%BoundingBox: %d %d %d %d" % bbox, file=fh)
- if not isEPSF: print("%%Pages: 1", file=fh)
- print("%%EndComments", file=fh)
-
- Ndict = len(psDefs)
- print("%%BeginProlog", file=fh)
- if not rcParams['ps.useafm']:
- Ndict += len(ps_renderer.used_characters)
- print("/mpldict %d dict def"%Ndict, file=fh)
- print("mpldict begin", file=fh)
- for d in psDefs:
- d=d.strip()
- for l in d.split('\n'):
- print(l.strip(), file=fh)
- if not rcParams['ps.useafm']:
- for font_filename, chars in six.itervalues(ps_renderer.used_characters):
- if len(chars):
- font = FT2Font(font_filename)
- cmap = font.get_charmap()
- glyph_ids = []
- for c in chars:
- gind = cmap.get(c) or 0
- glyph_ids.append(gind)
-
- fonttype = rcParams['ps.fonttype']
-
- # Can not use more than 255 characters from a
- # single font for Type 3
- if len(glyph_ids) > 255:
- fonttype = 42
-
- # The ttf to ps (subsetting) support doesn't work for
- # OpenType fonts that are Postscript inside (like the
- # STIX fonts). This will simply turn that off to avoid
- # errors.
- if is_opentype_cff_font(font_filename):
- raise RuntimeError("OpenType CFF fonts can not be saved using the internal Postscript backend at this time.\nConsider using the Cairo backend.")
- else:
- fh.flush()
- convert_ttf_to_ps(
- font_filename.encode(sys.getfilesystemencoding()),
- fh, fonttype, glyph_ids)
- print("end", file=fh)
- print("%%EndProlog", file=fh)
-
- if not isEPSF: print("%%Page: 1 1", file=fh)
- print("mpldict begin", file=fh)
- #print >>fh, "gsave"
- print("%s translate"%_nums_to_str(xo, yo), file=fh)
- if rotation: print("%d rotate"%rotation, file=fh)
- print("%s clipbox"%_nums_to_str(width*72, height*72, 0, 0), file=fh)
-
- # write the figure
- content = self._pswriter.getvalue()
- if not isinstance(content, six.text_type):
- content = content.decode('ascii')
- print(content, file=fh)
-
- # write the trailer
- #print >>fh, "grestore"
- print("end", file=fh)
- print("showpage", file=fh)
- if not isEPSF: print("%%EOF", file=fh)
- fh.flush()
-
- if rcParams['ps.usedistiller']:
- # We are going to use an external program to process the output.
- # Write to a temporary file.
- fd, tmpfile = mkstemp()
- with io.open(fd, 'w', encoding='latin-1') as fh:
- print_figure_impl()
- else:
- # Write directly to outfile.
- if passed_in_file_object:
- requires_unicode = file_requires_unicode(outfile)
-
- if (not requires_unicode and
- (six.PY3 or not isinstance(outfile, StringIO))):
- fh = io.TextIOWrapper(outfile, encoding="latin-1")
- # Prevent the io.TextIOWrapper from closing the
- # underlying file
- def do_nothing():
- pass
- fh.close = do_nothing
- else:
- fh = outfile
-
- print_figure_impl()
- else:
- with io.open(outfile, 'w', encoding='latin-1') as fh:
- print_figure_impl()
-
- if rcParams['ps.usedistiller']:
- if rcParams['ps.usedistiller'] == 'ghostscript':
- gs_distill(tmpfile, isEPSF, ptype=papertype, bbox=bbox)
- elif rcParams['ps.usedistiller'] == 'xpdf':
- xpdf_distill(tmpfile, isEPSF, ptype=papertype, bbox=bbox)
-
- if passed_in_file_object:
- if file_requires_unicode(outfile):
- with io.open(tmpfile, 'rb') as fh:
- outfile.write(fh.read().decode('latin-1'))
- else:
- with io.open(tmpfile, 'rb') as fh:
- outfile.write(fh.read())
- else:
- with io.open(outfile, 'w') as fh:
- pass
- mode = os.stat(outfile).st_mode
- shutil.move(tmpfile, outfile)
- os.chmod(outfile, mode)
-
- def _print_figure_tex(self, outfile, format, dpi, facecolor, edgecolor,
- orientation, isLandscape, papertype,
- **kwargs):
- """
- If text.usetex is True in rc, a temporary pair of tex/eps files
- are created to allow tex to manage the text layout via the PSFrags
- package. These files are processed to yield the final ps or eps file.
- """
- isEPSF = format == 'eps'
- if is_string_like(outfile):
- title = outfile
- elif is_writable_file_like(outfile):
- title = None
- else:
- raise ValueError("outfile must be a path or a file-like object")
-
- self.figure.dpi = 72 # ignore the dpi kwarg
- width, height = self.figure.get_size_inches()
- xo = 0
- yo = 0
-
- l, b, w, h = self.figure.bbox.bounds
- llx = xo
- lly = yo
- urx = llx + w
- ury = lly + h
- bbox = (llx, lly, urx, ury)
-
- # generate PostScript code for the figure and store it in a string
- origfacecolor = self.figure.get_facecolor()
- origedgecolor = self.figure.get_edgecolor()
- self.figure.set_facecolor(facecolor)
- self.figure.set_edgecolor(edgecolor)
-
- dryrun = kwargs.get("dryrun", False)
- if dryrun:
- class NullWriter(object):
- def write(self, *kl, **kwargs):
- pass
-
- self._pswriter = NullWriter()
- else:
- self._pswriter = io.StringIO()
-
-
- # mixed mode rendering
- _bbox_inches_restore = kwargs.pop("bbox_inches_restore", None)
- ps_renderer = self._renderer_class(width, height,
- self._pswriter, imagedpi=dpi)
- renderer = MixedModeRenderer(self.figure,
- width, height, dpi, ps_renderer,
- bbox_inches_restore=_bbox_inches_restore)
-
- self.figure.draw(renderer)
-
- if dryrun: # return immediately if dryrun (tightbbox=True)
- return
-
- self.figure.set_facecolor(origfacecolor)
- self.figure.set_edgecolor(origedgecolor)
-
- # write to a temp file, we'll move it to outfile when done
- fd, tmpfile = mkstemp()
- with io.open(fd, 'w', encoding='latin-1') as fh:
- # write the Encapsulated PostScript headers
- print("%!PS-Adobe-3.0 EPSF-3.0", file=fh)
- if title: print("%%Title: "+title, file=fh)
- print(("%%Creator: matplotlib version "
- +__version__+", http://matplotlib.org/"), file=fh)
- print("%%CreationDate: "+time.ctime(time.time()), file=fh)
- print("%%%%BoundingBox: %d %d %d %d" % bbox, file=fh)
- print("%%EndComments", file=fh)
-
- Ndict = len(psDefs)
- print("%%BeginProlog", file=fh)
- print("/mpldict %d dict def"%Ndict, file=fh)
- print("mpldict begin", file=fh)
- for d in psDefs:
- d=d.strip()
- for l in d.split('\n'):
- print(l.strip(), file=fh)
- print("end", file=fh)
- print("%%EndProlog", file=fh)
-
- print("mpldict begin", file=fh)
- #print >>fh, "gsave"
- print("%s translate"%_nums_to_str(xo, yo), file=fh)
- print("%s clipbox"%_nums_to_str(width*72, height*72, 0, 0), file=fh)
-
- # write the figure
- print(self._pswriter.getvalue(), file=fh)
-
- # write the trailer
- #print >>fh, "grestore"
- print("end", file=fh)
- print("showpage", file=fh)
- fh.flush()
-
- if isLandscape: # now we are ready to rotate
- isLandscape = True
- width, height = height, width
- bbox = (lly, llx, ury, urx)
-
- # set the paper size to the figure size if isEPSF. The
- # resulting ps file has the given size with correct bounding
- # box so that there is no need to call 'pstoeps'
- if isEPSF:
- paperWidth, paperHeight = self.figure.get_size_inches()
- if isLandscape:
- paperWidth, paperHeight = paperHeight, paperWidth
- else:
- temp_papertype = _get_papertype(width, height)
- if papertype=='auto':
- papertype = temp_papertype
- paperWidth, paperHeight = papersize[temp_papertype]
- else:
- paperWidth, paperHeight = papersize[papertype]
- if (width>paperWidth or height>paperHeight) and isEPSF:
- paperWidth, paperHeight = papersize[temp_papertype]
- verbose.report('Your figure is too big to fit on %s paper. %s \
- paper will be used to prevent clipping.'%(papertype, temp_papertype), 'helpful')
-
-
- texmanager = ps_renderer.get_texmanager()
- font_preamble = texmanager.get_font_preamble()
- custom_preamble = texmanager.get_custom_preamble()
-
- psfrag_rotated = convert_psfrags(tmpfile, ps_renderer.psfrag,
- font_preamble,
- custom_preamble, paperWidth, paperHeight,
- orientation)
-
- if rcParams['ps.usedistiller'] == 'ghostscript':
- gs_distill(tmpfile, isEPSF, ptype=papertype, bbox=bbox,
- rotated=psfrag_rotated)
- elif rcParams['ps.usedistiller'] == 'xpdf':
- xpdf_distill(tmpfile, isEPSF, ptype=papertype, bbox=bbox,
- rotated=psfrag_rotated)
- elif rcParams['text.usetex']:
- if False: pass # for debugging
- else: gs_distill(tmpfile, isEPSF, ptype=papertype, bbox=bbox,
- rotated=psfrag_rotated)
-
- if is_writable_file_like(outfile):
- if file_requires_unicode(outfile):
- with io.open(tmpfile, 'rb') as fh:
- outfile.write(fh.read().decode('latin-1'))
- else:
- with io.open(tmpfile, 'rb') as fh:
- outfile.write(fh.read())
- else:
- with io.open(outfile, 'wb') as fh:
- pass
- mode = os.stat(outfile).st_mode
- shutil.move(tmpfile, outfile)
- os.chmod(outfile, mode)
-
-def convert_psfrags(tmpfile, psfrags, font_preamble, custom_preamble,
- paperWidth, paperHeight, orientation):
- """
- When we want to use the LaTeX backend with postscript, we write PSFrag tags
- to a temporary postscript file, each one marking a position for LaTeX to
- render some text. convert_psfrags generates a LaTeX document containing the
- commands to convert those tags to text. LaTeX/dvips produces the postscript
- file that includes the actual text.
- """
- tmpdir = os.path.split(tmpfile)[0]
- epsfile = tmpfile+'.eps'
- shutil.move(tmpfile, epsfile)
- latexfile = tmpfile+'.tex'
- outfile = tmpfile+'.output'
- dvifile = tmpfile+'.dvi'
- psfile = tmpfile+'.ps'
-
- if orientation=='landscape': angle = 90
- else: angle = 0
-
- if rcParams['text.latex.unicode']:
- unicode_preamble = """\\usepackage{ucs}
-\\usepackage[utf8x]{inputenc}"""
- else:
- unicode_preamble = ''
-
- s = """\\documentclass{article}
-%s
-%s
-%s
-\\usepackage[dvips, papersize={%sin,%sin}, body={%sin,%sin}, margin={0in,0in}]{geometry}
-\\usepackage{psfrag}
-\\usepackage[dvips]{graphicx}
-\\usepackage{color}
-\\pagestyle{empty}
-\\begin{document}
-\\begin{figure}
-\\centering
-\\leavevmode
-%s
-\\includegraphics*[angle=%s]{%s}
-\\end{figure}
-\\end{document}
-"""% (font_preamble, unicode_preamble, custom_preamble, paperWidth, paperHeight,
- paperWidth, paperHeight,
- '\n'.join(psfrags), angle, os.path.split(epsfile)[-1])
-
- with io.open(latexfile, 'wb') as latexh:
- if rcParams['text.latex.unicode']:
- latexh.write(s.encode('utf8'))
- else:
- try:
- latexh.write(s.encode('ascii'))
- except UnicodeEncodeError:
- verbose.report("You are using unicode and latex, but have "
- "not enabled the matplotlib 'text.latex.unicode' "
- "rcParam.", 'helpful')
- raise
-
- # the split drive part of the command is necessary for windows users with
- # multiple
- if sys.platform == 'win32': precmd = '%s &&'% os.path.splitdrive(tmpdir)[0]
- else: precmd = ''
- command = '%s cd "%s" && latex -interaction=nonstopmode "%s" > "%s"'\
- %(precmd, tmpdir, latexfile, outfile)
- verbose.report(command, 'debug')
- exit_status = os.system(command)
-
- with io.open(outfile, 'rb') as fh:
- if exit_status:
- raise RuntimeError('LaTeX was not able to process your file:\
- \nHere is the full report generated by LaTeX: \n\n%s'% fh.read())
- else:
- verbose.report(fh.read(), 'debug')
- os.remove(outfile)
-
- command = '%s cd "%s" && dvips -q -R0 -o "%s" "%s" > "%s"'%(precmd, tmpdir,
- os.path.split(psfile)[-1], os.path.split(dvifile)[-1], outfile)
- verbose.report(command, 'debug')
- exit_status = os.system(command)
-
- with io.open(outfile, 'rb') as fh:
- if exit_status:
- raise RuntimeError('dvips was not able to \
- process the following file:\n%s\nHere is the full report generated by dvips: \
- \n\n'% dvifile + fh.read())
- else:
- verbose.report(fh.read(), 'debug')
- os.remove(outfile)
- os.remove(epsfile)
- shutil.move(psfile, tmpfile)
-
- # check if the dvips created a ps in landscape paper. Somehow,
- # above latex+dvips results in a ps file in a landscape mode for a
- # certain figure sizes (e.g., 8.3in,5.8in which is a5). And the
- # bounding box of the final output got messed up. We check see if
- # the generated ps file is in landscape and return this
- # information. The return value is used in pstoeps step to recover
- # the correct bounding box. 2010-06-05 JJL
- with io.open(tmpfile) as fh:
- if "Landscape" in fh.read(1000):
- psfrag_rotated = True
- else:
- psfrag_rotated = False
-
- if not debugPS:
- for fname in glob.glob(tmpfile+'.*'):
- os.remove(fname)
-
- return psfrag_rotated
-
-def gs_distill(tmpfile, eps=False, ptype='letter', bbox=None, rotated=False):
- """
- Use ghostscript's pswrite or epswrite device to distill a file.
- This yields smaller files without illegal encapsulated postscript
- operators. The output is low-level, converting text to outlines.
- """
-
- if eps: paper_option = "-dEPSCrop"
- else: paper_option = "-sPAPERSIZE=%s" % ptype
-
- psfile = tmpfile + '.ps'
- outfile = tmpfile + '.output'
- dpi = rcParams['ps.distiller.res']
-
-
- gs_exe = ps_backend_helper.gs_exe
- if ps_backend_helper.supports_ps2write: # gs version >= 9
- device_name = "ps2write"
- else:
- device_name = "pswrite"
-
- command = '%s -dBATCH -dNOPAUSE -r%d -sDEVICE=%s %s -sOutputFile="%s" \
- "%s" > "%s"'% (gs_exe, dpi, device_name,
- paper_option, psfile, tmpfile, outfile)
-
- verbose.report(command, 'debug')
- exit_status = os.system(command)
-
- with io.open(outfile, 'rb') as fh:
- if exit_status:
- raise RuntimeError('ghostscript was not able to process \
- your image.\nHere is the full report generated by ghostscript:\n\n' + fh.read())
- else:
- verbose.report(fh.read(), 'debug')
- os.remove(outfile)
- os.remove(tmpfile)
- shutil.move(psfile, tmpfile)
-
-
- # While it is best if above steps preserve the original bounding
- # box, there seem to be cases when it is not. For those cases,
- # the original bbox can be restored during the pstoeps step.
-
- if eps:
- # For some versions of gs, above steps result in an ps file
- # where the original bbox is no more correct. Do not adjust
- # bbox for now.
- if ps_backend_helper.supports_ps2write:
- # fo gs version >= 9 w/ ps2write device
- pstoeps(tmpfile, bbox, rotated=rotated)
- else:
- pstoeps(tmpfile)
-
-
-def xpdf_distill(tmpfile, eps=False, ptype='letter', bbox=None, rotated=False):
- """
- Use ghostscript's ps2pdf and xpdf's/poppler's pdftops to distill a file.
- This yields smaller files without illegal encapsulated postscript
- operators. This distiller is preferred, generating high-level postscript
- output that treats text as text.
- """
- pdffile = tmpfile + '.pdf'
- psfile = tmpfile + '.ps'
- outfile = tmpfile + '.output'
-
- if eps: paper_option = "-dEPSCrop"
- else: paper_option = "-sPAPERSIZE=%s" % ptype
-
- command = 'ps2pdf -dAutoFilterColorImages=false \
--sColorImageFilter=FlateEncode %s "%s" "%s" > "%s"'% \
-(paper_option, tmpfile, pdffile, outfile)
- if sys.platform == 'win32': command = command.replace('=', '#')
- verbose.report(command, 'debug')
- exit_status = os.system(command)
- with io.open(outfile, 'rb') as fh:
- if exit_status:
- raise RuntimeError('ps2pdf was not able to process your \
-image.\n\Here is the report generated by ghostscript:\n\n' + fh.read())
- else:
- verbose.report(fh.read(), 'debug')
- os.remove(outfile)
- command = 'pdftops -paper match -level2 "%s" "%s" > "%s"'% \
- (pdffile, psfile, outfile)
- verbose.report(command, 'debug')
- exit_status = os.system(command)
-
- with io.open(outfile, 'rb') as fh:
- if exit_status:
- raise RuntimeError('pdftops was not able to process your \
-image.\nHere is the full report generated by pdftops: \n\n' + fh.read())
- else:
- verbose.report(fh.read(), 'debug')
- os.remove(outfile)
- os.remove(tmpfile)
- shutil.move(psfile, tmpfile)
-
- if eps:
- pstoeps(tmpfile)
-
- for fname in glob.glob(tmpfile+'.*'):
- os.remove(fname)
-
-def get_bbox_header(lbrt, rotated=False):
- """
- return a postscript header stringfor the given bbox lbrt=(l, b, r, t).
- Optionally, return rotate command.
- """
-
- l, b, r, t = lbrt
- if rotated:
- rotate = "%.2f %.2f translate\n90 rotate" % (l+r, 0)
- else:
- rotate = ""
- bbox_info = '%%%%BoundingBox: %d %d %d %d' % (l, b, np.ceil(r), np.ceil(t))
- hires_bbox_info = '%%%%HiResBoundingBox: %.6f %.6f %.6f %.6f' % (l, b, r, t)
-
- return '\n'.join([bbox_info, hires_bbox_info]), rotate
-
-
-# get_bbox is deprecated. I don't see any reason to use ghostscript to
-# find the bounding box, as the required bounding box is alread known.
-def get_bbox(tmpfile, bbox):
- """
- Use ghostscript's bbox device to find the center of the bounding box. Return
- an appropriately sized bbox centered around that point. A bit of a hack.
- """
-
- outfile = tmpfile + '.output'
- gs_exe = ps_backend_helper.gs_exe
- command = '%s -dBATCH -dNOPAUSE -sDEVICE=bbox "%s"' %\
- (gs_exe, tmpfile)
- verbose.report(command, 'debug')
- stdin, stdout, stderr = os.popen3(command)
- verbose.report(stdout.read(), 'debug-annoying')
- bbox_info = stderr.read()
- verbose.report(bbox_info, 'helpful')
- bbox_found = re.search('%%HiResBoundingBox: .*', bbox_info)
- if bbox_found:
- bbox_info = bbox_found.group()
- else:
- raise RuntimeError('Ghostscript was not able to extract a bounding box.\
-Here is the Ghostscript output:\n\n%s'% bbox_info)
- l, b, r, t = [float(i) for i in bbox_info.split()[-4:]]
-
- # this is a hack to deal with the fact that ghostscript does not return the
- # intended bbox, but a tight bbox. For now, we just center the ink in the
- # intended bbox. This is not ideal, users may intend the ink to not be
- # centered.
- if bbox is None:
- l, b, r, t = (l-1, b-1, r+1, t+1)
- else:
- x = (l+r)/2
- y = (b+t)/2
- dx = (bbox[2]-bbox[0])/2
- dy = (bbox[3]-bbox[1])/2
- l,b,r,t = (x-dx, y-dy, x+dx, y+dy)
-
- bbox_info = '%%%%BoundingBox: %d %d %d %d' % (l, b, np.ceil(r), np.ceil(t))
- hires_bbox_info = '%%%%HiResBoundingBox: %.6f %.6f %.6f %.6f' % (l, b, r, t)
-
- return '\n'.join([bbox_info, hires_bbox_info])
-
-
-def pstoeps(tmpfile, bbox=None, rotated=False):
- """
- Convert the postscript to encapsulated postscript. The bbox of
- the eps file will be replaced with the given *bbox* argument. If
- None, original bbox will be used.
- """
-
- # if rotated==True, the output eps file need to be rotated
- if bbox:
- bbox_info, rotate = get_bbox_header(bbox, rotated=rotated)
- else:
- bbox_info, rotate = None, None
-
- epsfile = tmpfile + '.eps'
- with io.open(epsfile, 'wb') as epsh:
- write = epsh.write
- with io.open(tmpfile, 'rb') as tmph:
- line = tmph.readline()
- # Modify the header:
- while line:
- if line.startswith(b'%!PS'):
- write(b"%!PS-Adobe-3.0 EPSF-3.0\n")
- if bbox:
- write(bbox_info.encode('ascii') + b'\n')
- elif line.startswith(b'%%EndComments'):
- write(line)
- write(b'%%BeginProlog\n')
- write(b'save\n')
- write(b'countdictstack\n')
- write(b'mark\n')
- write(b'newpath\n')
- write(b'/showpage {} def\n')
- write(b'/setpagedevice {pop} def\n')
- write(b'%%EndProlog\n')
- write(b'%%Page 1 1\n')
- if rotate:
- write(rotate.encode('ascii') + b'\n')
- break
- elif bbox and (line.startswith(b'%%Bound') \
- or line.startswith(b'%%HiResBound') \
- or line.startswith(b'%%DocumentMedia') \
- or line.startswith(b'%%Pages')):
- pass
- else:
- write(line)
- line = tmph.readline()
- # Now rewrite the rest of the file, and modify the trailer.
- # This is done in a second loop such that the header of the embedded
- # eps file is not modified.
- line = tmph.readline()
- while line:
- if line.startswith(b'%%EOF'):
- write(b'cleartomark\n')
- write(b'countdictstack\n')
- write(b'exch sub { end } repeat\n')
- write(b'restore\n')
- write(b'%%EOF\n')
- elif line.startswith(b'%%PageBoundingBox'):
- pass
- else:
- write(line)
- line = tmph.readline()
-
- os.remove(tmpfile)
- shutil.move(epsfile, tmpfile)
-
-
-class FigureManagerPS(FigureManagerBase):
- pass
-
-
-# The following Python dictionary psDefs contains the entries for the
-# PostScript dictionary mpldict. This dictionary implements most of
-# the matplotlib primitives and some abbreviations.
-#
-# References:
-# http://www.adobe.com/products/postscript/pdfs/PLRM.pdf
-# http://www.mactech.com/articles/mactech/Vol.09/09.04/PostscriptTutorial/
-# http://www.math.ubc.ca/people/faculty/cass/graphics/text/www/
-#
-
-# The usage comments use the notation of the operator summary
-# in the PostScript Language reference manual.
-psDefs = [
- # x y *m* -
- "/m { moveto } bind def",
- # x y *l* -
- "/l { lineto } bind def",
- # x y *r* -
- "/r { rlineto } bind def",
- # x1 y1 x2 y2 x y *c* -
- "/c { curveto } bind def",
- # *closepath* -
- "/cl { closepath } bind def",
- # w h x y *box* -
- """/box {
- m
- 1 index 0 r
- 0 exch r
- neg 0 r
- cl
- } bind def""",
- # w h x y *clipbox* -
- """/clipbox {
- box
- clip
- newpath
- } bind def""",
-]
-
-FigureCanvas = FigureCanvasPS
-FigureManager = FigureManagerPS
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_qt4.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_qt4.py
deleted file mode 100644
index 8298ae3..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_qt4.py
+++ /dev/null
@@ -1,95 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six import unichr
-import os
-import re
-import signal
-import sys
-
-import matplotlib
-
-from matplotlib.cbook import is_string_like
-from matplotlib.backend_bases import FigureManagerBase
-from matplotlib.backend_bases import FigureCanvasBase
-from matplotlib.backend_bases import NavigationToolbar2
-
-from matplotlib.backend_bases import cursors
-from matplotlib.backend_bases import TimerBase
-from matplotlib.backend_bases import ShowBase
-
-from matplotlib._pylab_helpers import Gcf
-from matplotlib.figure import Figure
-
-
-from matplotlib.widgets import SubplotTool
-try:
- import matplotlib.backends.qt_editor.figureoptions as figureoptions
-except ImportError:
- figureoptions = None
-
-from .qt_compat import QtCore, QtWidgets, _getSaveFileName, __version__
-from matplotlib.backends.qt_editor.formsubplottool import UiSubplotTool
-
-from .backend_qt5 import (backend_version, SPECIAL_KEYS, SUPER, ALT, CTRL,
- SHIFT, MODIFIER_KEYS, fn_name, cursord,
- draw_if_interactive, _create_qApp, show, TimerQT,
- MainWindow, FigureManagerQT, NavigationToolbar2QT,
- SubplotToolQt, error_msg_qt, exception_handler)
-
-from .backend_qt5 import FigureCanvasQT as FigureCanvasQT5
-
-DEBUG = False
-
-
-def new_figure_manager(num, *args, **kwargs):
- """
- Create a new figure manager instance
- """
- thisFig = Figure(*args, **kwargs)
- return new_figure_manager_given_figure(num, thisFig)
-
-
-def new_figure_manager_given_figure(num, figure):
- """
- Create a new figure manager instance for the given figure.
- """
- canvas = FigureCanvasQT(figure)
- manager = FigureManagerQT(canvas, num)
- return manager
-
-
-class FigureCanvasQT(FigureCanvasQT5):
-
- def __init__(self, figure):
- if DEBUG:
- print('FigureCanvasQt qt4: ', figure)
- _create_qApp()
-
- # Note different super-calling style to backend_qt5
- QtWidgets.QWidget.__init__(self)
- FigureCanvasBase.__init__(self, figure)
- self.figure = figure
- self.setMouseTracking(True)
- self._idle = True
- # hide until we can test and fix
- # self.startTimer(backend_IdleEvent.milliseconds)
- w, h = self.get_width_height()
- self.resize(w, h)
-
- def wheelEvent(self, event):
- x = event.x()
- # flipy so y=0 is bottom of canvas
- y = self.figure.bbox.height - event.y()
- # from QWheelEvent::delta doc
- steps = event.delta()/120
- if (event.orientation() == QtCore.Qt.Vertical):
- FigureCanvasBase.scroll_event(self, x, y, steps)
- if DEBUG:
- print('scroll event: delta = %i, '
- 'steps = %i ' % (event.delta(), steps))
-
-
-FigureCanvas = FigureCanvasQT
-FigureManager = FigureManagerQT
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_qt4agg.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_qt4agg.py
deleted file mode 100644
index a597dc2..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_qt4agg.py
+++ /dev/null
@@ -1,96 +0,0 @@
-"""
-Render to qt from agg
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import os # not used
-import sys
-import ctypes
-import warnings
-
-import matplotlib
-from matplotlib.figure import Figure
-
-from .backend_qt5agg import NavigationToolbar2QTAgg
-from .backend_qt5agg import FigureCanvasQTAggBase
-
-from .backend_agg import FigureCanvasAgg
-from .backend_qt4 import QtCore
-from .backend_qt4 import FigureManagerQT
-from .backend_qt4 import FigureCanvasQT
-from .backend_qt4 import NavigationToolbar2QT
-##### not used
-from .backend_qt4 import show
-from .backend_qt4 import draw_if_interactive
-from .backend_qt4 import backend_version
-######
-from matplotlib.cbook import mplDeprecation
-
-DEBUG = False
-
-_decref = ctypes.pythonapi.Py_DecRef
-_decref.argtypes = [ctypes.py_object]
-_decref.restype = None
-
-
-def new_figure_manager(num, *args, **kwargs):
- """
- Create a new figure manager instance
- """
- if DEBUG:
- print('backend_qt4agg.new_figure_manager')
- FigureClass = kwargs.pop('FigureClass', Figure)
- thisFig = FigureClass(*args, **kwargs)
- return new_figure_manager_given_figure(num, thisFig)
-
-
-def new_figure_manager_given_figure(num, figure):
- """
- Create a new figure manager instance for the given figure.
- """
- canvas = FigureCanvasQTAgg(figure)
- return FigureManagerQT(canvas, num)
-
-
-class FigureCanvasQTAgg(FigureCanvasQTAggBase,
- FigureCanvasQT, FigureCanvasAgg):
- """
- The canvas the figure renders into. Calls the draw and print fig
- methods, creates the renderers, etc...
-
- Public attribute
-
- figure - A Figure instance
- """
-
- def __init__(self, figure):
- if DEBUG:
- print('FigureCanvasQtAgg: ', figure)
- FigureCanvasQT.__init__(self, figure)
- FigureCanvasAgg.__init__(self, figure)
- self._drawRect = None
- self.blitbox = None
- self.setAttribute(QtCore.Qt.WA_OpaquePaintEvent)
- # it has been reported that Qt is semi-broken in a windows
- # environment. If `self.draw()` uses `update` to trigger a
- # system-level window repaint (as is explicitly advised in the
- # Qt documentation) the figure responds very slowly to mouse
- # input. The work around is to directly use `repaint`
- # (against the advice of the Qt documentation). The
- # difference between `update` and repaint is that `update`
- # schedules a `repaint` for the next time the system is idle,
- # where as `repaint` repaints the window immediately. The
- # risk is if `self.draw` gets called with in another `repaint`
- # method there will be an infinite recursion. Thus, we only
- # expose windows users to this risk.
- if sys.platform.startswith('win'):
- self._priv_update = self.repaint
- else:
- self._priv_update = self.update
-
-
-FigureCanvas = FigureCanvasQTAgg
-FigureManager = FigureManagerQT
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_qt5.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_qt5.py
deleted file mode 100644
index 766f886..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_qt5.py
+++ /dev/null
@@ -1,855 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-import six
-
-import os
-import re
-import signal
-import sys
-from six import unichr
-
-import matplotlib
-
-from matplotlib.cbook import is_string_like
-from matplotlib.backend_bases import FigureManagerBase
-from matplotlib.backend_bases import FigureCanvasBase
-from matplotlib.backend_bases import NavigationToolbar2
-
-from matplotlib.backend_bases import cursors
-from matplotlib.backend_bases import TimerBase
-from matplotlib.backend_bases import ShowBase
-
-from matplotlib._pylab_helpers import Gcf
-from matplotlib.figure import Figure
-
-from matplotlib.widgets import SubplotTool
-try:
- import matplotlib.backends.qt_editor.figureoptions as figureoptions
-except ImportError:
- figureoptions = None
-
-from .qt_compat import QtCore, QtGui, QtWidgets, _getSaveFileName, __version__
-from matplotlib.backends.qt_editor.formsubplottool import UiSubplotTool
-
-backend_version = __version__
-
-# SPECIAL_KEYS are keys that do *not* return their unicode name
-# instead they have manually specified names
-SPECIAL_KEYS = {QtCore.Qt.Key_Control: 'control',
- QtCore.Qt.Key_Shift: 'shift',
- QtCore.Qt.Key_Alt: 'alt',
- QtCore.Qt.Key_Meta: 'super',
- QtCore.Qt.Key_Return: 'enter',
- QtCore.Qt.Key_Left: 'left',
- QtCore.Qt.Key_Up: 'up',
- QtCore.Qt.Key_Right: 'right',
- QtCore.Qt.Key_Down: 'down',
- QtCore.Qt.Key_Escape: 'escape',
- QtCore.Qt.Key_F1: 'f1',
- QtCore.Qt.Key_F2: 'f2',
- QtCore.Qt.Key_F3: 'f3',
- QtCore.Qt.Key_F4: 'f4',
- QtCore.Qt.Key_F5: 'f5',
- QtCore.Qt.Key_F6: 'f6',
- QtCore.Qt.Key_F7: 'f7',
- QtCore.Qt.Key_F8: 'f8',
- QtCore.Qt.Key_F9: 'f9',
- QtCore.Qt.Key_F10: 'f10',
- QtCore.Qt.Key_F11: 'f11',
- QtCore.Qt.Key_F12: 'f12',
- QtCore.Qt.Key_Home: 'home',
- QtCore.Qt.Key_End: 'end',
- QtCore.Qt.Key_PageUp: 'pageup',
- QtCore.Qt.Key_PageDown: 'pagedown',
- QtCore.Qt.Key_Tab: 'tab',
- QtCore.Qt.Key_Backspace: 'backspace',
- QtCore.Qt.Key_Enter: 'enter',
- QtCore.Qt.Key_Insert: 'insert',
- QtCore.Qt.Key_Delete: 'delete',
- QtCore.Qt.Key_Pause: 'pause',
- QtCore.Qt.Key_SysReq: 'sysreq',
- QtCore.Qt.Key_Clear: 'clear', }
-
-# define which modifier keys are collected on keyboard events.
-# elements are (mpl names, Modifier Flag, Qt Key) tuples
-SUPER = 0
-ALT = 1
-CTRL = 2
-SHIFT = 3
-MODIFIER_KEYS = [('super', QtCore.Qt.MetaModifier, QtCore.Qt.Key_Meta),
- ('alt', QtCore.Qt.AltModifier, QtCore.Qt.Key_Alt),
- ('ctrl', QtCore.Qt.ControlModifier, QtCore.Qt.Key_Control),
- ('shift', QtCore.Qt.ShiftModifier, QtCore.Qt.Key_Shift),
- ]
-
-if sys.platform == 'darwin':
- # in OSX, the control and super (aka cmd/apple) keys are switched, so
- # switch them back.
- SPECIAL_KEYS.update({QtCore.Qt.Key_Control: 'super', # cmd/apple key
- QtCore.Qt.Key_Meta: 'control',
- })
- MODIFIER_KEYS[0] = ('super', QtCore.Qt.ControlModifier,
- QtCore.Qt.Key_Control)
- MODIFIER_KEYS[2] = ('ctrl', QtCore.Qt.MetaModifier,
- QtCore.Qt.Key_Meta)
-
-
-def fn_name():
- return sys._getframe(1).f_code.co_name
-
-DEBUG = False
-
-cursord = {
- cursors.MOVE: QtCore.Qt.SizeAllCursor,
- cursors.HAND: QtCore.Qt.PointingHandCursor,
- cursors.POINTER: QtCore.Qt.ArrowCursor,
- cursors.SELECT_REGION: QtCore.Qt.CrossCursor,
- }
-
-
-def draw_if_interactive():
- """
- Is called after every pylab drawing command
- """
- if matplotlib.is_interactive():
- figManager = Gcf.get_active()
- if figManager is not None:
- figManager.canvas.draw_idle()
-
-# make place holder
-qApp = None
-
-
-def _create_qApp():
- """
- Only one qApp can exist at a time, so check before creating one.
- """
- global qApp
-
- if qApp is None:
- if DEBUG:
- print("Starting up QApplication")
- app = QtWidgets.QApplication.instance()
- if app is None:
- # check for DISPLAY env variable on X11 build of Qt
- if hasattr(QtGui, "QX11Info"):
- display = os.environ.get('DISPLAY')
- if display is None or not re.search(':\d', display):
- raise RuntimeError('Invalid DISPLAY variable')
-
- qApp = QtWidgets.QApplication([str(" ")])
- qApp.lastWindowClosed.connect(qApp.quit)
- else:
- qApp = app
-
-
-class Show(ShowBase):
- def mainloop(self):
- # allow KeyboardInterrupt exceptions to close the plot window.
- signal.signal(signal.SIGINT, signal.SIG_DFL)
- global qApp
- qApp.exec_()
-
-show = Show()
-
-
-def new_figure_manager(num, *args, **kwargs):
- """
- Create a new figure manager instance
- """
- thisFig = Figure(*args, **kwargs)
- return new_figure_manager_given_figure(num, thisFig)
-
-
-def new_figure_manager_given_figure(num, figure):
- """
- Create a new figure manager instance for the given figure.
- """
- canvas = FigureCanvasQT(figure)
- manager = FigureManagerQT(canvas, num)
- return manager
-
-
-class TimerQT(TimerBase):
- '''
- Subclass of :class:`backend_bases.TimerBase` that uses Qt4 timer events.
-
- Attributes:
- * interval: The time between timer events in milliseconds. Default
- is 1000 ms.
- * single_shot: Boolean flag indicating whether this timer should
- operate as single shot (run once and then stop). Defaults to False.
- * callbacks: Stores list of (func, args) tuples that will be called
- upon timer events. This list can be manipulated directly, or the
- functions add_callback and remove_callback can be used.
- '''
-
- def __init__(self, *args, **kwargs):
- TimerBase.__init__(self, *args, **kwargs)
-
- # Create a new timer and connect the timeout() signal to the
- # _on_timer method.
- self._timer = QtCore.QTimer()
- self._timer.timeout.connect(self._on_timer)
- self._timer_set_interval()
-
- def __del__(self):
- # Probably not necessary in practice, but is good behavior to
- # disconnect
- try:
- TimerBase.__del__(self)
- self._timer.timeout.disconnect(self._on_timer)
- except RuntimeError:
- # Timer C++ object already deleted
- pass
-
- def _timer_set_single_shot(self):
- self._timer.setSingleShot(self._single)
-
- def _timer_set_interval(self):
- self._timer.setInterval(self._interval)
-
- def _timer_start(self):
- self._timer.start()
-
- def _timer_stop(self):
- self._timer.stop()
-
-
-class FigureCanvasQT(QtWidgets.QWidget, FigureCanvasBase):
-
- # map Qt button codes to MouseEvent's ones:
- buttond = {QtCore.Qt.LeftButton: 1,
- QtCore.Qt.MidButton: 2,
- QtCore.Qt.RightButton: 3,
- # QtCore.Qt.XButton1: None,
- # QtCore.Qt.XButton2: None,
- }
-
- def __init__(self, figure):
- if DEBUG:
- print('FigureCanvasQt qt5: ', figure)
- _create_qApp()
-
- # NB: Using super for this call to avoid a TypeError:
- # __init__() takes exactly 2 arguments (1 given) on QWidget
- # PyQt5
- super(FigureCanvasQT, self).__init__(figure=figure)
- self.figure = figure
- self.setMouseTracking(True)
- self._idle = True
- # hide until we can test and fix
- # self.startTimer(backend_IdleEvent.milliseconds)
- w, h = self.get_width_height()
- self.resize(w, h)
-
- def __timerEvent(self, event):
- # hide until we can test and fix
- self.mpl_idle_event(event)
-
- def enterEvent(self, event):
- FigureCanvasBase.enter_notify_event(self, event)
-
- def leaveEvent(self, event):
- QtWidgets.QApplication.restoreOverrideCursor()
- FigureCanvasBase.leave_notify_event(self, event)
-
- def mousePressEvent(self, event):
- x = event.pos().x()
- # flipy so y=0 is bottom of canvas
- y = self.figure.bbox.height - event.pos().y()
- button = self.buttond.get(event.button())
- if button is not None:
- FigureCanvasBase.button_press_event(self, x, y, button)
- if DEBUG:
- print('button pressed:', event.button())
-
- def mouseDoubleClickEvent(self, event):
- x = event.pos().x()
- # flipy so y=0 is bottom of canvas
- y = self.figure.bbox.height - event.pos().y()
- button = self.buttond.get(event.button())
- if button is not None:
- FigureCanvasBase.button_press_event(self, x, y,
- button, dblclick=True)
- if DEBUG:
- print('button doubleclicked:', event.button())
-
- def mouseMoveEvent(self, event):
- x = event.x()
- # flipy so y=0 is bottom of canvas
- y = self.figure.bbox.height - event.y()
- FigureCanvasBase.motion_notify_event(self, x, y)
- # if DEBUG: print('mouse move')
-
- def mouseReleaseEvent(self, event):
- x = event.x()
- # flipy so y=0 is bottom of canvas
- y = self.figure.bbox.height - event.y()
- button = self.buttond.get(event.button())
- if button is not None:
- FigureCanvasBase.button_release_event(self, x, y, button)
- if DEBUG:
- print('button released')
-
- def wheelEvent(self, event):
- x = event.x()
- # flipy so y=0 is bottom of canvas
- y = self.figure.bbox.height - event.y()
- # from QWheelEvent::delta doc
- if event.pixelDelta().x() == 0 and event.pixelDelta().y() == 0:
- steps = event.angleDelta().y() / 120
- else:
- steps = event.pixelDelta().y()
-
- if steps != 0:
- FigureCanvasBase.scroll_event(self, x, y, steps)
- if DEBUG:
- print('scroll event: delta = %i, '
- 'steps = %i ' % (event.delta(), steps))
-
- def keyPressEvent(self, event):
- key = self._get_key(event)
- if key is None:
- return
- FigureCanvasBase.key_press_event(self, key)
- if DEBUG:
- print('key press', key)
-
- def keyReleaseEvent(self, event):
- key = self._get_key(event)
- if key is None:
- return
- FigureCanvasBase.key_release_event(self, key)
- if DEBUG:
- print('key release', key)
-
- def resizeEvent(self, event):
- w = event.size().width()
- h = event.size().height()
- if DEBUG:
- print('resize (%d x %d)' % (w, h))
- print("FigureCanvasQt.resizeEvent(%d, %d)" % (w, h))
- dpival = self.figure.dpi
- winch = w / dpival
- hinch = h / dpival
- self.figure.set_size_inches(winch, hinch)
- FigureCanvasBase.resize_event(self)
- self.draw()
- self.update()
- QtWidgets.QWidget.resizeEvent(self, event)
-
- def sizeHint(self):
- w, h = self.get_width_height()
- return QtCore.QSize(w, h)
-
- def minumumSizeHint(self):
- return QtCore.QSize(10, 10)
-
- def _get_key(self, event):
- if event.isAutoRepeat():
- return None
-
- event_key = event.key()
- event_mods = int(event.modifiers()) # actually a bitmask
-
- # get names of the pressed modifier keys
- # bit twiddling to pick out modifier keys from event_mods bitmask,
- # if event_key is a MODIFIER, it should not be duplicated in mods
- mods = [name for name, mod_key, qt_key in MODIFIER_KEYS
- if event_key != qt_key and (event_mods & mod_key) == mod_key]
- try:
- # for certain keys (enter, left, backspace, etc) use a word for the
- # key, rather than unicode
- key = SPECIAL_KEYS[event_key]
- except KeyError:
- # unicode defines code points up to 0x0010ffff
- # QT will use Key_Codes larger than that for keyboard keys that are
- # are not unicode characters (like multimedia keys)
- # skip these
- # if you really want them, you should add them to SPECIAL_KEYS
- MAX_UNICODE = 0x10ffff
- if event_key > MAX_UNICODE:
- return None
-
- key = unichr(event_key)
- # qt delivers capitalized letters. fix capitalization
- # note that capslock is ignored
- if 'shift' in mods:
- mods.remove('shift')
- else:
- key = key.lower()
-
- mods.reverse()
- return '+'.join(mods + [key])
-
- def new_timer(self, *args, **kwargs):
- """
- Creates a new backend-specific subclass of
- :class:`backend_bases.Timer`. This is useful for getting
- periodic events through the backend's native event
- loop. Implemented only for backends with GUIs.
-
- optional arguments:
-
- *interval*
- Timer interval in milliseconds
-
- *callbacks*
- Sequence of (func, args, kwargs) where func(*args, **kwargs)
- will be executed by the timer every *interval*.
-
- """
- return TimerQT(*args, **kwargs)
-
- def flush_events(self):
- global qApp
- qApp.processEvents()
-
- def start_event_loop(self, timeout):
- FigureCanvasBase.start_event_loop_default(self, timeout)
-
- start_event_loop.__doc__ = \
- FigureCanvasBase.start_event_loop_default.__doc__
-
- def stop_event_loop(self):
- FigureCanvasBase.stop_event_loop_default(self)
-
- stop_event_loop.__doc__ = FigureCanvasBase.stop_event_loop_default.__doc__
-
- def draw_idle(self):
- 'update drawing area only if idle'
- d = self._idle
- self._idle = False
-
- def idle_draw(*args):
- try:
- self.draw()
- finally:
- self._idle = True
- if d:
- QtCore.QTimer.singleShot(0, idle_draw)
-
-
-class MainWindow(QtWidgets.QMainWindow):
- closing = QtCore.Signal()
-
- def closeEvent(self, event):
- self.closing.emit()
- QtWidgets.QMainWindow.closeEvent(self, event)
-
-
-class FigureManagerQT(FigureManagerBase):
- """
- Public attributes
-
- canvas : The FigureCanvas instance
- num : The Figure number
- toolbar : The qt.QToolBar
- window : The qt.QMainWindow
- """
-
- def __init__(self, canvas, num):
- if DEBUG:
- print('FigureManagerQT.%s' % fn_name())
- FigureManagerBase.__init__(self, canvas, num)
- self.canvas = canvas
- self.window = MainWindow()
- self.window.closing.connect(canvas.close_event)
- self.window.closing.connect(self._widgetclosed)
-
- self.window.setWindowTitle("Figure %d" % num)
- image = os.path.join(matplotlib.rcParams['datapath'],
- 'images', 'matplotlib.png')
- self.window.setWindowIcon(QtGui.QIcon(image))
-
- # Give the keyboard focus to the figure instead of the
- # manager; StrongFocus accepts both tab and click to focus and
- # will enable the canvas to process event w/o clicking.
- # ClickFocus only takes the focus is the window has been
- # clicked
- # on. http://qt-project.org/doc/qt-4.8/qt.html#FocusPolicy-enum or
- # http://doc.qt.digia.com/qt/qt.html#FocusPolicy-enum
- self.canvas.setFocusPolicy(QtCore.Qt.StrongFocus)
- self.canvas.setFocus()
-
- self.window._destroying = False
-
- self.toolbar = self._get_toolbar(self.canvas, self.window)
- if self.toolbar is not None:
- self.window.addToolBar(self.toolbar)
- self.toolbar.message.connect(self._show_message)
- tbs_height = self.toolbar.sizeHint().height()
- else:
- tbs_height = 0
-
- # resize the main window so it will display the canvas with the
- # requested size:
- cs = canvas.sizeHint()
- sbs = self.window.statusBar().sizeHint()
- self._status_and_tool_height = tbs_height + sbs.height()
- height = cs.height() + self._status_and_tool_height
- self.window.resize(cs.width(), height)
-
- self.window.setCentralWidget(self.canvas)
-
- if matplotlib.is_interactive():
- self.window.show()
-
- def notify_axes_change(fig):
- # This will be called whenever the current axes is changed
- if self.toolbar is not None:
- self.toolbar.update()
- self.canvas.figure.add_axobserver(notify_axes_change)
-
- @QtCore.Slot()
- def _show_message(self, s):
- # Fixes a PySide segfault.
- self.window.statusBar().showMessage(s)
-
- def full_screen_toggle(self):
- if self.window.isFullScreen():
- self.window.showNormal()
- else:
- self.window.showFullScreen()
-
- def _widgetclosed(self):
- if self.window._destroying:
- return
- self.window._destroying = True
- try:
- Gcf.destroy(self.num)
- except AttributeError:
- pass
- # It seems that when the python session is killed,
- # Gcf can get destroyed before the Gcf.destroy
- # line is run, leading to a useless AttributeError.
-
- def _get_toolbar(self, canvas, parent):
- # must be inited after the window, drawingArea and figure
- # attrs are set
- if matplotlib.rcParams['toolbar'] == 'toolbar2':
- toolbar = NavigationToolbar2QT(canvas, parent, False)
- else:
- toolbar = None
- return toolbar
-
- def resize(self, width, height):
- 'set the canvas size in pixels'
- self.window.resize(width, height + self._status_and_tool_height)
-
- def show(self):
- self.window.show()
-
- def destroy(self, *args):
- # check for qApp first, as PySide deletes it in its atexit handler
- if QtWidgets.QApplication.instance() is None:
- return
- if self.window._destroying:
- return
- self.window._destroying = True
- self.window.destroyed.connect(self._widgetclosed)
-
- if self.toolbar:
- self.toolbar.destroy()
- if DEBUG:
- print("destroy figure manager")
- self.window.close()
-
- def get_window_title(self):
- return str(self.window.windowTitle())
-
- def set_window_title(self, title):
- self.window.setWindowTitle(title)
-
-
-class NavigationToolbar2QT(NavigationToolbar2, QtWidgets.QToolBar):
- message = QtCore.Signal(str)
-
- def __init__(self, canvas, parent, coordinates=True):
- """ coordinates: should we show the coordinates on the right? """
- self.canvas = canvas
- self.parent = parent
- self.coordinates = coordinates
- self._actions = {}
- """A mapping of toolitem method names to their QActions"""
-
- QtWidgets.QToolBar.__init__(self, parent)
- NavigationToolbar2.__init__(self, canvas)
-
- def _icon(self, name):
- return QtGui.QIcon(os.path.join(self.basedir, name))
-
- def _init_toolbar(self):
- self.basedir = os.path.join(matplotlib.rcParams['datapath'], 'images')
-
- for text, tooltip_text, image_file, callback in self.toolitems:
- if text is None:
- self.addSeparator()
- else:
- a = self.addAction(self._icon(image_file + '.png'),
- text, getattr(self, callback))
- self._actions[callback] = a
- if callback in ['zoom', 'pan']:
- a.setCheckable(True)
- if tooltip_text is not None:
- a.setToolTip(tooltip_text)
-
- if figureoptions is not None:
- a = self.addAction(self._icon("qt4_editor_options.png"),
- 'Customize', self.edit_parameters)
- a.setToolTip('Edit curves line and axes parameters')
-
- self.buttons = {}
-
- # Add the x,y location widget at the right side of the toolbar
- # The stretch factor is 1 which means any resizing of the toolbar
- # will resize this label instead of the buttons.
- if self.coordinates:
- self.locLabel = QtWidgets.QLabel("", self)
- self.locLabel.setAlignment(
- QtCore.Qt.AlignRight | QtCore.Qt.AlignTop)
- self.locLabel.setSizePolicy(
- QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding,
- QtWidgets.QSizePolicy.Ignored))
- labelAction = self.addWidget(self.locLabel)
- labelAction.setVisible(True)
-
- # reference holder for subplots_adjust window
- self.adj_window = None
-
- if figureoptions is not None:
- def edit_parameters(self):
- allaxes = self.canvas.figure.get_axes()
- if len(allaxes) == 1:
- axes = allaxes[0]
- else:
- titles = []
- for axes in allaxes:
- title = axes.get_title()
- ylabel = axes.get_ylabel()
- label = axes.get_label()
- if title:
- fmt = "%(title)s"
- if ylabel:
- fmt += ": %(ylabel)s"
- fmt += " (%(axes_repr)s)"
- elif ylabel:
- fmt = "%(axes_repr)s (%(ylabel)s)"
- elif label:
- fmt = "%(axes_repr)s (%(label)s)"
- else:
- fmt = "%(axes_repr)s"
- titles.append(fmt % dict(title=title,
- ylabel=ylabel, label=label,
- axes_repr=repr(axes)))
- item, ok = QtWidgets.QInputDialog.getItem(
- self.parent, 'Customize', 'Select axes:', titles, 0, False)
- if ok:
- axes = allaxes[titles.index(six.text_type(item))]
- else:
- return
-
- figureoptions.figure_edit(axes, self)
-
- def _update_buttons_checked(self):
- # sync button checkstates to match active mode
- self._actions['pan'].setChecked(self._active == 'PAN')
- self._actions['zoom'].setChecked(self._active == 'ZOOM')
-
- def pan(self, *args):
- super(NavigationToolbar2QT, self).pan(*args)
- self._update_buttons_checked()
-
- def zoom(self, *args):
- super(NavigationToolbar2QT, self).zoom(*args)
- self._update_buttons_checked()
-
- def dynamic_update(self):
- self.canvas.draw()
-
- def set_message(self, s):
- self.message.emit(s)
- if self.coordinates:
- self.locLabel.setText(s.replace(', ', '\n'))
-
- def set_cursor(self, cursor):
- if DEBUG:
- print('Set cursor', cursor)
- self.canvas.setCursor(cursord[cursor])
-
- def draw_rubberband(self, event, x0, y0, x1, y1):
- height = self.canvas.figure.bbox.height
- y1 = height - y1
- y0 = height - y0
-
- w = abs(x1 - x0)
- h = abs(y1 - y0)
-
- rect = [int(val)for val in (min(x0, x1), min(y0, y1), w, h)]
- self.canvas.drawRectangle(rect)
-
- def configure_subplots(self):
- image = os.path.join(matplotlib.rcParams['datapath'],
- 'images', 'matplotlib.png')
- dia = SubplotToolQt(self.canvas.figure, self.parent)
- dia.setWindowIcon(QtGui.QIcon(image))
- dia.exec_()
-
- def save_figure(self, *args):
- filetypes = self.canvas.get_supported_filetypes_grouped()
- sorted_filetypes = list(six.iteritems(filetypes))
- sorted_filetypes.sort()
- default_filetype = self.canvas.get_default_filetype()
-
- startpath = matplotlib.rcParams.get('savefig.directory', '')
- startpath = os.path.expanduser(startpath)
- start = os.path.join(startpath, self.canvas.get_default_filename())
- filters = []
- selectedFilter = None
- for name, exts in sorted_filetypes:
- exts_list = " ".join(['*.%s' % ext for ext in exts])
- filter = '%s (%s)' % (name, exts_list)
- if default_filetype in exts:
- selectedFilter = filter
- filters.append(filter)
- filters = ';;'.join(filters)
-
- fname, filter = _getSaveFileName(self.parent,
- "Choose a filename to save to",
- start, filters, selectedFilter)
- if fname:
- if startpath == '':
- # explicitly missing key or empty str signals to use cwd
- matplotlib.rcParams['savefig.directory'] = startpath
- else:
- # save dir for next time
- savefig_dir = os.path.dirname(six.text_type(fname))
- matplotlib.rcParams['savefig.directory'] = savefig_dir
- try:
- self.canvas.print_figure(six.text_type(fname))
- except Exception as e:
- QtWidgets.QMessageBox.critical(
- self, "Error saving file", str(e),
- QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.NoButton)
-
-
-class SubplotToolQt(SubplotTool, UiSubplotTool):
- def __init__(self, targetfig, parent):
- UiSubplotTool.__init__(self, None)
-
- self.targetfig = targetfig
- self.parent = parent
- self.donebutton.clicked.connect(self.close)
- self.resetbutton.clicked.connect(self.reset)
- self.tightlayout.clicked.connect(self.functight)
-
- # constraints
- self.sliderleft.valueChanged.connect(self.sliderright.setMinimum)
- self.sliderright.valueChanged.connect(self.sliderleft.setMaximum)
- self.sliderbottom.valueChanged.connect(self.slidertop.setMinimum)
- self.slidertop.valueChanged.connect(self.sliderbottom.setMaximum)
-
- self.defaults = {}
- for attr in ('left', 'bottom', 'right', 'top', 'wspace', 'hspace', ):
- self.defaults[attr] = getattr(self.targetfig.subplotpars, attr)
- slider = getattr(self, 'slider' + attr)
- slider.setMinimum(0)
- slider.setMaximum(1000)
- slider.setSingleStep(5)
- slider.valueChanged.connect(getattr(self, 'func' + attr))
-
- self._setSliderPositions()
-
- def _setSliderPositions(self):
- for attr in ('left', 'bottom', 'right', 'top', 'wspace', 'hspace', ):
- slider = getattr(self, 'slider' + attr)
- slider.setSliderPosition(int(self.defaults[attr] * 1000))
-
- def funcleft(self, val):
- if val == self.sliderright.value():
- val -= 1
- val /= 1000.
- self.targetfig.subplots_adjust(left=val)
- self.leftvalue.setText("%.2f" % val)
- if self.drawon:
- self.targetfig.canvas.draw()
-
- def funcright(self, val):
- if val == self.sliderleft.value():
- val += 1
- val /= 1000.
- self.targetfig.subplots_adjust(right=val)
- self.rightvalue.setText("%.2f" % val)
- if self.drawon:
- self.targetfig.canvas.draw()
-
- def funcbottom(self, val):
- if val == self.slidertop.value():
- val -= 1
- val /= 1000.
- self.targetfig.subplots_adjust(bottom=val)
- self.bottomvalue.setText("%.2f" % val)
- if self.drawon:
- self.targetfig.canvas.draw()
-
- def functop(self, val):
- if val == self.sliderbottom.value():
- val += 1
- val /= 1000.
- self.targetfig.subplots_adjust(top=val)
- self.topvalue.setText("%.2f" % val)
- if self.drawon:
- self.targetfig.canvas.draw()
-
- def funcwspace(self, val):
- val /= 1000.
- self.targetfig.subplots_adjust(wspace=val)
- self.wspacevalue.setText("%.2f" % val)
- if self.drawon:
- self.targetfig.canvas.draw()
-
- def funchspace(self, val):
- val /= 1000.
- self.targetfig.subplots_adjust(hspace=val)
- self.hspacevalue.setText("%.2f" % val)
- if self.drawon:
- self.targetfig.canvas.draw()
-
- def functight(self):
- self.targetfig.tight_layout()
- self._setSliderPositions()
- self.targetfig.canvas.draw()
-
- def reset(self):
- self.targetfig.subplots_adjust(**self.defaults)
- self._setSliderPositions()
- self.targetfig.canvas.draw()
-
-
-def error_msg_qt(msg, parent=None):
- if not is_string_like(msg):
- msg = ','.join(map(str, msg))
-
- QtWidgets.QMessageBox.warning(None, "Matplotlib",
- msg, QtGui.QMessageBox.Ok)
-
-
-def exception_handler(type, value, tb):
- """Handle uncaught exceptions
- It does not catch SystemExit
- """
- msg = ''
- # get the filename attribute if available (for IOError)
- if hasattr(value, 'filename') and value.filename is not None:
- msg = value.filename + ': '
- if hasattr(value, 'strerror') and value.strerror is not None:
- msg += value.strerror
- else:
- msg += str(value)
-
- if len(msg):
- error_msg_qt(msg)
-
-FigureCanvas = FigureCanvasQT
-FigureManager = FigureManagerQT
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_qt5agg.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_qt5agg.py
deleted file mode 100644
index 9b21636..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_qt5agg.py
+++ /dev/null
@@ -1,215 +0,0 @@
-"""
-Render to qt from agg
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import os # not used
-import sys
-import ctypes
-import warnings
-
-import matplotlib
-from matplotlib.figure import Figure
-
-from .backend_agg import FigureCanvasAgg
-from .backend_qt5 import QtCore
-from .backend_qt5 import QtGui
-from .backend_qt5 import FigureManagerQT
-from .backend_qt5 import NavigationToolbar2QT
-##### Modified Qt5 backend import
-from .backend_qt5 import FigureCanvasQT
-##### not used
-from .backend_qt5 import show
-from .backend_qt5 import draw_if_interactive
-from .backend_qt5 import backend_version
-######
-
-
-from matplotlib.cbook import mplDeprecation
-
-DEBUG = False
-
-_decref = ctypes.pythonapi.Py_DecRef
-_decref.argtypes = [ctypes.py_object]
-_decref.restype = None
-
-
-def new_figure_manager(num, *args, **kwargs):
- """
- Create a new figure manager instance
- """
- if DEBUG:
- print('backend_qt5agg.new_figure_manager')
- FigureClass = kwargs.pop('FigureClass', Figure)
- thisFig = FigureClass(*args, **kwargs)
- return new_figure_manager_given_figure(num, thisFig)
-
-
-def new_figure_manager_given_figure(num, figure):
- """
- Create a new figure manager instance for the given figure.
- """
- canvas = FigureCanvasQTAgg(figure)
- return FigureManagerQT(canvas, num)
-
-
-class FigureCanvasQTAggBase(object):
- """
- The canvas the figure renders into. Calls the draw and print fig
- methods, creates the renderers, etc...
-
- Public attribute
-
- figure - A Figure instance
- """
-
- def drawRectangle(self, rect):
- self._drawRect = rect
- self.repaint()
-
- def paintEvent(self, e):
- """
- Copy the image from the Agg canvas to the qt.drawable.
- In Qt, all drawing should be done inside of here when a widget is
- shown onscreen.
- """
-
- # FigureCanvasQT.paintEvent(self, e)
- if DEBUG:
- print('FigureCanvasQtAgg.paintEvent: ', self,
- self.get_width_height())
-
- if self.blitbox is None:
- # matplotlib is in rgba byte order. QImage wants to put the bytes
- # into argb format and is in a 4 byte unsigned int. Little endian
- # system is LSB first and expects the bytes in reverse order
- # (bgra).
- if QtCore.QSysInfo.ByteOrder == QtCore.QSysInfo.LittleEndian:
- stringBuffer = self.renderer._renderer.tostring_bgra()
- else:
- stringBuffer = self.renderer._renderer.tostring_argb()
-
- refcnt = sys.getrefcount(stringBuffer)
-
- # convert the Agg rendered image -> qImage
- qImage = QtGui.QImage(stringBuffer, self.renderer.width,
- self.renderer.height,
- QtGui.QImage.Format_ARGB32)
- # get the rectangle for the image
- rect = qImage.rect()
- p = QtGui.QPainter(self)
- # reset the image area of the canvas to be the back-ground color
- p.eraseRect(rect)
- # draw the rendered image on to the canvas
- p.drawPixmap(QtCore.QPoint(0, 0), QtGui.QPixmap.fromImage(qImage))
-
- # draw the zoom rectangle to the QPainter
- if self._drawRect is not None:
- p.setPen(QtGui.QPen(QtCore.Qt.black, 1, QtCore.Qt.DotLine))
- x, y, w, h = self._drawRect
- p.drawRect(x, y, w, h)
- p.end()
-
- # This works around a bug in PySide 1.1.2 on Python 3.x,
- # where the reference count of stringBuffer is incremented
- # but never decremented by QImage.
- # TODO: revert PR #1323 once the issue is fixed in PySide.
- del qImage
- if refcnt != sys.getrefcount(stringBuffer):
- _decref(stringBuffer)
- else:
- bbox = self.blitbox
- l, b, r, t = bbox.extents
- w = int(r) - int(l)
- h = int(t) - int(b)
- t = int(b) + h
- reg = self.copy_from_bbox(bbox)
- stringBuffer = reg.to_string_argb()
- qImage = QtGui.QImage(stringBuffer, w, h,
- QtGui.QImage.Format_ARGB32)
- pixmap = QtGui.QPixmap.fromImage(qImage)
- p = QtGui.QPainter(self)
- p.drawPixmap(QtCore.QPoint(l, self.renderer.height-t), pixmap)
- p.end()
- self.blitbox = None
- self._drawRect = None
-
- def draw(self):
- """
- Draw the figure with Agg, and queue a request
- for a Qt draw.
- """
- # The Agg draw is done here; delaying it until the paintEvent
- # causes problems with code that uses the result of the
- # draw() to update plot elements.
- FigureCanvasAgg.draw(self)
- self._priv_update()
-
- def blit(self, bbox=None):
- """
- Blit the region in bbox
- """
- self.blitbox = bbox
- l, b, w, h = bbox.bounds
- t = b + h
- self.repaint(l, self.renderer.height-t, w, h)
-
- def print_figure(self, *args, **kwargs):
- FigureCanvasAgg.print_figure(self, *args, **kwargs)
- self.draw()
-
-
-class FigureCanvasQTAgg(FigureCanvasQTAggBase,
- FigureCanvasQT, FigureCanvasAgg):
- """
- The canvas the figure renders into. Calls the draw and print fig
- methods, creates the renderers, etc.
-
- Modified to import from Qt5 backend for new-style mouse events.
-
- Public attribute
-
- figure - A Figure instance
- """
-
- def __init__(self, figure):
- if DEBUG:
- print('FigureCanvasQtAgg: ', figure)
- FigureCanvasQT.__init__(self, figure)
- FigureCanvasAgg.__init__(self, figure)
- self._drawRect = None
- self.blitbox = None
- self.setAttribute(QtCore.Qt.WA_OpaquePaintEvent)
- # it has been reported that Qt is semi-broken in a windows
- # environment. If `self.draw()` uses `update` to trigger a
- # system-level window repaint (as is explicitly advised in the
- # Qt documentation) the figure responds very slowly to mouse
- # input. The work around is to directly use `repaint`
- # (against the advice of the Qt documentation). The
- # difference between `update` and repaint is that `update`
- # schedules a `repaint` for the next time the system is idle,
- # where as `repaint` repaints the window immediately. The
- # risk is if `self.draw` gets called with in another `repaint`
- # method there will be an infinite recursion. Thus, we only
- # expose windows users to this risk.
- if sys.platform.startswith('win'):
- self._priv_update = self.repaint
- else:
- self._priv_update = self.update
-
-
-class NavigationToolbar2QTAgg(NavigationToolbar2QT):
- def __init__(*args, **kwargs):
- warnings.warn('This class has been deprecated in 1.4 ' +
- 'as it has no additional functionality over ' +
- '`NavigationToolbar2QT`. Please change your code to '
- 'use `NavigationToolbar2QT` instead',
- mplDeprecation)
- NavigationToolbar2QT.__init__(*args, **kwargs)
-
-
-FigureCanvas = FigureCanvasQTAgg
-FigureManager = FigureManagerQT
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_svg.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_svg.py
deleted file mode 100644
index 36deeeb..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_svg.py
+++ /dev/null
@@ -1,1258 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import xrange
-from six import unichr
-
-import os, base64, tempfile, gzip, io, sys, codecs, re
-
-import numpy as np
-
-from hashlib import md5
-
-from matplotlib import verbose, __version__, rcParams
-from matplotlib.backend_bases import RendererBase, GraphicsContextBase,\
- FigureManagerBase, FigureCanvasBase
-from matplotlib.backends.backend_mixed import MixedModeRenderer
-from matplotlib.cbook import is_string_like, is_writable_file_like, maxdict
-from matplotlib.colors import rgb2hex
-from matplotlib.figure import Figure
-from matplotlib.font_manager import findfont, FontProperties
-from matplotlib.ft2font import FT2Font, KERNING_DEFAULT, LOAD_NO_HINTING
-from matplotlib.mathtext import MathTextParser
-from matplotlib.path import Path
-from matplotlib import _path
-from matplotlib.transforms import Affine2D, Affine2DBase
-from matplotlib import _png
-
-from xml.sax.saxutils import escape as escape_xml_text
-
-backend_version = __version__
-
-# ----------------------------------------------------------------------
-# SimpleXMLWriter class
-#
-# Based on an original by Fredrik Lundh, but modified here to:
-# 1. Support modern Python idioms
-# 2. Remove encoding support (it's handled by the file writer instead)
-# 3. Support proper indentation
-# 4. Minify things a little bit
-
-# --------------------------------------------------------------------
-# The SimpleXMLWriter module is
-#
-# Copyright (c) 2001-2004 by Fredrik Lundh
-#
-# By obtaining, using, and/or copying this software and/or its
-# associated documentation, you agree that you have read, understood,
-# and will comply with the following terms and conditions:
-#
-# Permission to use, copy, modify, and distribute this software and
-# its associated documentation for any purpose and without fee is
-# hereby granted, provided that the above copyright notice appears in
-# all copies, and that both that copyright notice and this permission
-# notice appear in supporting documentation, and that the name of
-# Secret Labs AB or the author not be used in advertising or publicity
-# pertaining to distribution of the software without specific, written
-# prior permission.
-#
-# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
-# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
-# ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR
-# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
-# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
-# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
-# OF THIS SOFTWARE.
-# --------------------------------------------------------------------
-
-def escape_cdata(s):
- s = s.replace("&", "&")
- s = s.replace("<", "<")
- s = s.replace(">", ">")
- return s
-
-_escape_xml_comment = re.compile(r'-(?=-)')
-def escape_comment(s):
- s = escape_cdata(s)
- return _escape_xml_comment.sub('- ', s)
-
-def escape_attrib(s):
- s = s.replace("&", "&")
- s = s.replace("'", "'")
- s = s.replace("\"", """)
- s = s.replace("<", "<")
- s = s.replace(">", ">")
- return s
-
-##
-# XML writer class.
-#
-# @param file A file or file-like object. This object must implement
-# a write method that takes an 8-bit string.
-
-class XMLWriter:
- def __init__(self, file):
- self.__write = file.write
- if hasattr(file, "flush"):
- self.flush = file.flush
- self.__open = 0 # true if start tag is open
- self.__tags = []
- self.__data = []
- self.__indentation = " " * 64
-
- def __flush(self, indent=True):
- # flush internal buffers
- if self.__open:
- if indent:
- self.__write(">\n")
- else:
- self.__write(">")
- self.__open = 0
- if self.__data:
- data = ''.join(self.__data)
- self.__write(escape_cdata(data))
- self.__data = []
-
- ## Opens a new element. Attributes can be given as keyword
- # arguments, or as a string/string dictionary. The method returns
- # an opaque identifier that can be passed to the close
- # method, to close all open elements up to and including this one.
- #
- # @param tag Element tag.
- # @param attrib Attribute dictionary. Alternatively, attributes
- # can be given as keyword arguments.
- # @return An element identifier.
-
- def start(self, tag, attrib={}, **extra):
- self.__flush()
- tag = escape_cdata(tag)
- self.__data = []
- self.__tags.append(tag)
- self.__write(self.__indentation[:len(self.__tags) - 1])
- self.__write("<%s" % tag)
- if attrib or extra:
- attrib = attrib.copy()
- attrib.update(extra)
- attrib = list(six.iteritems(attrib))
- attrib.sort()
- for k, v in attrib:
- if not v == '':
- k = escape_cdata(k)
- v = escape_attrib(v)
- self.__write(" %s=\"%s\"" % (k, v))
- self.__open = 1
- return len(self.__tags)-1
-
- ##
- # Adds a comment to the output stream.
- #
- # @param comment Comment text, as a Unicode string.
-
- def comment(self, comment):
- self.__flush()
- self.__write(self.__indentation[:len(self.__tags)])
- self.__write("\n" % escape_comment(comment))
-
- ##
- # Adds character data to the output stream.
- #
- # @param text Character data, as a Unicode string.
-
- def data(self, text):
- self.__data.append(text)
-
- ##
- # Closes the current element (opened by the most recent call to
- # start).
- #
- # @param tag Element tag. If given, the tag must match the start
- # tag. If omitted, the current element is closed.
-
- def end(self, tag=None, indent=True):
- if tag:
- assert self.__tags, "unbalanced end(%s)" % tag
- assert escape_cdata(tag) == self.__tags[-1],\
- "expected end(%s), got %s" % (self.__tags[-1], tag)
- else:
- assert self.__tags, "unbalanced end()"
- tag = self.__tags.pop()
- if self.__data:
- self.__flush(indent)
- elif self.__open:
- self.__open = 0
- self.__write("/>\n")
- return
- if indent:
- self.__write(self.__indentation[:len(self.__tags)])
- self.__write("%s>\n" % tag)
-
- ##
- # Closes open elements, up to (and including) the element identified
- # by the given identifier.
- #
- # @param id Element identifier, as returned by the start method.
-
- def close(self, id):
- while len(self.__tags) > id:
- self.end()
-
- ##
- # Adds an entire element. This is the same as calling start,
- # data, and end in sequence. The text argument
- # can be omitted.
-
- def element(self, tag, text=None, attrib={}, **extra):
- self.start(*(tag, attrib), **extra)
- if text:
- self.data(text)
- self.end(indent=False)
-
- ##
- # Flushes the output stream.
-
- def flush(self):
- pass # replaced by the constructor
-
-# ----------------------------------------------------------------------
-
-def generate_transform(transform_list=[]):
- if len(transform_list):
- output = io.StringIO()
- for type, value in transform_list:
- if type == 'scale' and (value == (1.0,) or value == (1.0, 1.0)):
- continue
- if type == 'translate' and value == (0.0, 0.0):
- continue
- if type == 'rotate' and value == (0.0,):
- continue
- if type == 'matrix' and isinstance(value, Affine2DBase):
- value = value.to_values()
-
- output.write('%s(%s)' % (type, ' '.join(str(x) for x in value)))
- return output.getvalue()
- return ''
-
-def generate_css(attrib={}):
- if attrib:
- output = io.StringIO()
- attrib = list(six.iteritems(attrib))
- attrib.sort()
- for k, v in attrib:
- k = escape_attrib(k)
- v = escape_attrib(v)
- output.write("%s:%s;" % (k, v))
- return output.getvalue()
- return ''
-
-_capstyle_d = {'projecting' : 'square', 'butt' : 'butt', 'round': 'round',}
-class RendererSVG(RendererBase):
- FONT_SCALE = 100.0
- fontd = maxdict(50)
-
- def __init__(self, width, height, svgwriter, basename=None, image_dpi=72):
- self.width = width
- self.height = height
- self.writer = XMLWriter(svgwriter)
- self.image_dpi = image_dpi # the actual dpi we want to rasterize stuff with
-
- self._groupd = {}
- if not rcParams['svg.image_inline']:
- assert basename is not None
- self.basename = basename
- self._imaged = {}
- self._clipd = {}
- self._char_defs = {}
- self._markers = {}
- self._path_collection_id = 0
- self._imaged = {}
- self._hatchd = {}
- self._has_gouraud = False
- self._n_gradients = 0
- self._fonts = {}
- self.mathtext_parser = MathTextParser('SVG')
-
- RendererBase.__init__(self)
- self._glyph_map = dict()
-
- svgwriter.write(svgProlog)
- self._start_id = self.writer.start(
- 'svg',
- width='%ipt' % width, height='%ipt' % height,
- viewBox='0 0 %i %i' % (width, height),
- xmlns="http://www.w3.org/2000/svg",
- version="1.1",
- attrib={'xmlns:xlink': "http://www.w3.org/1999/xlink"})
- self._write_default_style()
-
- def finalize(self):
- self._write_clips()
- self._write_hatches()
- self._write_svgfonts()
- self.writer.close(self._start_id)
- self.writer.flush()
-
- def _write_default_style(self):
- writer = self.writer
- default_style = generate_css({
- 'stroke-linejoin': 'round',
- 'stroke-linecap': 'butt'})
- writer.start('defs')
- writer.start('style', type='text/css')
- writer.data('*{%s}\n' % default_style)
- writer.end('style')
- writer.end('defs')
-
- def _make_id(self, type, content):
- content = str(content)
- if six.PY3:
- content = content.encode('utf8')
- return '%s%s' % (type, md5(content).hexdigest()[:10])
-
- def _make_flip_transform(self, transform):
- return (transform +
- Affine2D()
- .scale(1.0, -1.0)
- .translate(0.0, self.height))
-
- def _get_font(self, prop):
- key = hash(prop)
- font = self.fontd.get(key)
- if font is None:
- fname = findfont(prop)
- font = self.fontd.get(fname)
- if font is None:
- font = FT2Font(fname)
- self.fontd[fname] = font
- self.fontd[key] = font
- font.clear()
- size = prop.get_size_in_points()
- font.set_size(size, 72.0)
- return font
-
- def _get_hatch(self, gc, rgbFace):
- """
- Create a new hatch pattern
- """
- if rgbFace is not None:
- rgbFace = tuple(rgbFace)
- edge = gc.get_rgb()
- if edge is not None:
- edge = tuple(edge)
- dictkey = (gc.get_hatch(), rgbFace, edge)
- oid = self._hatchd.get(dictkey)
- if oid is None:
- oid = self._make_id('h', dictkey)
- self._hatchd[dictkey] = ((gc.get_hatch_path(), rgbFace, edge), oid)
- else:
- _, oid = oid
- return oid
-
- def _write_hatches(self):
- if not len(self._hatchd):
- return
- HATCH_SIZE = 72
- writer = self.writer
- writer.start('defs')
- for ((path, face, stroke), oid) in six.itervalues(self._hatchd):
- writer.start(
- 'pattern',
- id=oid,
- patternUnits="userSpaceOnUse",
- x="0", y="0", width=six.text_type(HATCH_SIZE),
- height=six.text_type(HATCH_SIZE))
- path_data = self._convert_path(
- path,
- Affine2D().scale(HATCH_SIZE).scale(1.0, -1.0).translate(0, HATCH_SIZE),
- simplify=False)
- if face is None:
- fill = 'none'
- else:
- fill = rgb2hex(face)
- writer.element(
- 'rect',
- x="0", y="0", width=six.text_type(HATCH_SIZE+1),
- height=six.text_type(HATCH_SIZE+1),
- fill=fill)
- writer.element(
- 'path',
- d=path_data,
- style=generate_css({
- 'fill': rgb2hex(stroke),
- 'stroke': rgb2hex(stroke),
- 'stroke-width': '1.0',
- 'stroke-linecap': 'butt',
- 'stroke-linejoin': 'miter'
- })
- )
- writer.end('pattern')
- writer.end('defs')
-
- def _get_style_dict(self, gc, rgbFace):
- """
- return the style string. style is generated from the
- GraphicsContext and rgbFace
- """
- attrib = {}
-
- forced_alpha = gc.get_forced_alpha()
-
- if gc.get_hatch() is not None:
- attrib['fill'] = "url(#%s)" % self._get_hatch(gc, rgbFace)
- if rgbFace is not None and len(rgbFace) == 4 and rgbFace[3] != 1.0 and not forced_alpha:
- attrib['fill-opacity'] = str(rgbFace[3])
- else:
- if rgbFace is None:
- attrib['fill'] = 'none'
- else:
- if tuple(rgbFace[:3]) != (0, 0, 0):
- attrib['fill'] = rgb2hex(rgbFace)
- if len(rgbFace) == 4 and rgbFace[3] != 1.0 and not forced_alpha:
- attrib['fill-opacity'] = str(rgbFace[3])
-
- if forced_alpha and gc.get_alpha() != 1.0:
- attrib['opacity'] = str(gc.get_alpha())
-
- offset, seq = gc.get_dashes()
- if seq is not None:
- attrib['stroke-dasharray'] = ','.join(['%f' % val for val in seq])
- attrib['stroke-dashoffset'] = six.text_type(float(offset))
-
- linewidth = gc.get_linewidth()
- if linewidth:
- rgb = gc.get_rgb()
- attrib['stroke'] = rgb2hex(rgb)
- if not forced_alpha and rgb[3] != 1.0:
- attrib['stroke-opacity'] = str(rgb[3])
- if linewidth != 1.0:
- attrib['stroke-width'] = str(linewidth)
- if gc.get_joinstyle() != 'round':
- attrib['stroke-linejoin'] = gc.get_joinstyle()
- if gc.get_capstyle() != 'butt':
- attrib['stroke-linecap'] = _capstyle_d[gc.get_capstyle()]
-
- return attrib
-
- def _get_style(self, gc, rgbFace):
- return generate_css(self._get_style_dict(gc, rgbFace))
-
- def _get_clip(self, gc):
- cliprect = gc.get_clip_rectangle()
- clippath, clippath_trans = gc.get_clip_path()
- if clippath is not None:
- clippath_trans = self._make_flip_transform(clippath_trans)
- dictkey = (id(clippath), str(clippath_trans))
- elif cliprect is not None:
- x, y, w, h = cliprect.bounds
- y = self.height-(y+h)
- dictkey = (x, y, w, h)
- else:
- return None
-
- clip = self._clipd.get(dictkey)
- if clip is None:
- oid = self._make_id('p', dictkey)
- if clippath is not None:
- self._clipd[dictkey] = ((clippath, clippath_trans), oid)
- else:
- self._clipd[dictkey] = (dictkey, oid)
- else:
- clip, oid = clip
- return oid
-
- def _write_clips(self):
- if not len(self._clipd):
- return
- writer = self.writer
- writer.start('defs')
- for clip, oid in six.itervalues(self._clipd):
- writer.start('clipPath', id=oid)
- if len(clip) == 2:
- clippath, clippath_trans = clip
- path_data = self._convert_path(clippath, clippath_trans, simplify=False)
- writer.element('path', d=path_data)
- else:
- x, y, w, h = clip
- writer.element('rect', x=six.text_type(x), y=six.text_type(y),
- width=six.text_type(w), height=six.text_type(h))
- writer.end('clipPath')
- writer.end('defs')
-
- def _write_svgfonts(self):
- if not rcParams['svg.fonttype'] == 'svgfont':
- return
-
- writer = self.writer
- writer.start('defs')
- for font_fname, chars in six.iteritems(self._fonts):
- font = FT2Font(font_fname)
- font.set_size(72, 72)
- sfnt = font.get_sfnt()
- writer.start('font', id=sfnt[(1, 0, 0, 4)])
- writer.element(
- 'font-face',
- attrib={
- 'font-family': font.family_name,
- 'font-style': font.style_name.lower(),
- 'units-per-em': '72',
- 'bbox': ' '.join(six.text_type(x / 64.0) for x in font.bbox)})
- for char in chars:
- glyph = font.load_char(char, flags=LOAD_NO_HINTING)
- verts, codes = font.get_path()
- path = Path(verts, codes)
- path_data = self._convert_path(path)
- # name = font.get_glyph_name(char)
- writer.element(
- 'glyph',
- d=path_data,
- attrib={
- # 'glyph-name': name,
- 'unicode': unichr(char),
- 'horiz-adv-x': six.text_type(glyph.linearHoriAdvance / 65536.0)})
- writer.end('font')
- writer.end('defs')
-
- def open_group(self, s, gid=None):
- """
- Open a grouping element with label *s*. If *gid* is given, use
- *gid* as the id of the group.
- """
- if gid:
- self.writer.start('g', id=gid)
- else:
- self._groupd[s] = self._groupd.get(s, 0) + 1
- self.writer.start('g', id="%s_%d" % (s, self._groupd[s]))
-
- def close_group(self, s):
- self.writer.end('g')
-
- def option_image_nocomposite(self):
- """
- if svg.image_noscale is True, compositing multiple images into one is prohibited
- """
- return rcParams['svg.image_noscale']
-
- def _convert_path(self, path, transform=None, clip=None, simplify=None):
- if clip:
- clip = (0.0, 0.0, self.width, self.height)
- else:
- clip = None
- return _path.convert_to_svg(path, transform, clip, simplify, 6)
-
- def draw_path(self, gc, path, transform, rgbFace=None):
- trans_and_flip = self._make_flip_transform(transform)
- clip = (rgbFace is None and gc.get_hatch_path() is None)
- simplify = path.should_simplify and clip
- path_data = self._convert_path(
- path, trans_and_flip, clip=clip, simplify=simplify)
-
- attrib = {}
- attrib['style'] = self._get_style(gc, rgbFace)
-
- clipid = self._get_clip(gc)
- if clipid is not None:
- attrib['clip-path'] = 'url(#%s)' % clipid
-
- if gc.get_url() is not None:
- self.writer.start('a', {'xlink:href': gc.get_url()})
- self.writer.element('path', d=path_data, attrib=attrib)
- if gc.get_url() is not None:
- self.writer.end('a')
-
- def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None):
- if not len(path.vertices):
- return
-
- writer = self.writer
- path_data = self._convert_path(
- marker_path,
- marker_trans + Affine2D().scale(1.0, -1.0),
- simplify=False)
- style = self._get_style_dict(gc, rgbFace)
- dictkey = (path_data, generate_css(style))
- oid = self._markers.get(dictkey)
- for key in list(six.iterkeys(style)):
- if not key.startswith('stroke'):
- del style[key]
- style = generate_css(style)
-
- if oid is None:
- oid = self._make_id('m', dictkey)
- writer.start('defs')
- writer.element('path', id=oid, d=path_data, style=style)
- writer.end('defs')
- self._markers[dictkey] = oid
-
- attrib = {}
- clipid = self._get_clip(gc)
- if clipid is not None:
- attrib['clip-path'] = 'url(#%s)' % clipid
- writer.start('g', attrib=attrib)
-
- trans_and_flip = self._make_flip_transform(trans)
- attrib = {'xlink:href': '#%s' % oid}
- clip = (0, 0, self.width*72, self.height*72)
- for vertices, code in path.iter_segments(
- trans_and_flip, clip=clip, simplify=False):
- if len(vertices):
- x, y = vertices[-2:]
- attrib['x'] = six.text_type(x)
- attrib['y'] = six.text_type(y)
- attrib['style'] = self._get_style(gc, rgbFace)
- writer.element('use', attrib=attrib)
- writer.end('g')
-
- def draw_path_collection(self, gc, master_transform, paths, all_transforms,
- offsets, offsetTrans, facecolors, edgecolors,
- linewidths, linestyles, antialiaseds, urls,
- offset_position):
- # Is the optimization worth it? Rough calculation:
- # cost of emitting a path in-line is
- # (len_path + 5) * uses_per_path
- # cost of definition+use is
- # (len_path + 3) + 9 * uses_per_path
- len_path = len(paths[0].vertices) if len(paths) > 0 else 0
- uses_per_path = self._iter_collection_uses_per_path(
- paths, all_transforms, offsets, facecolors, edgecolors)
- should_do_optimization = \
- len_path + 9 * uses_per_path + 3 < (len_path + 5) * uses_per_path
- if not should_do_optimization:
- return RendererBase.draw_path_collection(
- self, gc, master_transform, paths, all_transforms,
- offsets, offsetTrans, facecolors, edgecolors,
- linewidths, linestyles, antialiaseds, urls,
- offset_position)
-
- writer = self.writer
- path_codes = []
- writer.start('defs')
- for i, (path, transform) in enumerate(self._iter_collection_raw_paths(
- master_transform, paths, all_transforms)):
- transform = Affine2D(transform.get_matrix()).scale(1.0, -1.0)
- d = self._convert_path(path, transform, simplify=False)
- oid = 'C%x_%x_%s' % (self._path_collection_id, i,
- self._make_id('', d))
- writer.element('path', id=oid, d=d)
- path_codes.append(oid)
- writer.end('defs')
-
- for xo, yo, path_id, gc0, rgbFace in self._iter_collection(
- gc, master_transform, all_transforms, path_codes, offsets,
- offsetTrans, facecolors, edgecolors, linewidths, linestyles,
- antialiaseds, urls, offset_position):
- clipid = self._get_clip(gc0)
- url = gc0.get_url()
- if url is not None:
- writer.start('a', attrib={'xlink:href': url})
- if clipid is not None:
- writer.start('g', attrib={'clip-path': 'url(#%s)' % clipid})
- attrib = {
- 'xlink:href': '#%s' % path_id,
- 'x': six.text_type(xo),
- 'y': six.text_type(self.height - yo),
- 'style': self._get_style(gc0, rgbFace)
- }
- writer.element('use', attrib=attrib)
- if clipid is not None:
- writer.end('g')
- if url is not None:
- writer.end('a')
-
- self._path_collection_id += 1
-
- def draw_gouraud_triangle(self, gc, points, colors, trans):
- # This uses a method described here:
- #
- # http://www.svgopen.org/2005/papers/Converting3DFaceToSVG/index.html
- #
- # that uses three overlapping linear gradients to simulate a
- # Gouraud triangle. Each gradient goes from fully opaque in
- # one corner to fully transparent along the opposite edge.
- # The line between the stop points is perpendicular to the
- # opposite edge. Underlying these three gradients is a solid
- # triangle whose color is the average of all three points.
-
- writer = self.writer
- if not self._has_gouraud:
- self._has_gouraud = True
- writer.start(
- 'filter',
- id='colorAdd')
- writer.element(
- 'feComposite',
- attrib={'in': 'SourceGraphic'},
- in2='BackgroundImage',
- operator='arithmetic',
- k2="1", k3="1")
- writer.end('filter')
-
- avg_color = np.sum(colors[:, :], axis=0) / 3.0
- # Just skip fully-transparent triangles
- if avg_color[-1] == 0.0:
- return
-
- trans_and_flip = self._make_flip_transform(trans)
- tpoints = trans_and_flip.transform(points)
-
- writer.start('defs')
- for i in range(3):
- x1, y1 = tpoints[i]
- x2, y2 = tpoints[(i + 1) % 3]
- x3, y3 = tpoints[(i + 2) % 3]
- c = colors[i][:]
-
- if x2 == x3:
- xb = x2
- yb = y1
- elif y2 == y3:
- xb = x1
- yb = y2
- else:
- m1 = (y2 - y3) / (x2 - x3)
- b1 = y2 - (m1 * x2)
- m2 = -(1.0 / m1)
- b2 = y1 - (m2 * x1)
- xb = (-b1 + b2) / (m1 - m2)
- yb = m2 * xb + b2
-
- writer.start(
- 'linearGradient',
- id="GR%x_%d" % (self._n_gradients, i),
- x1=six.text_type(x1), y1=six.text_type(y1),
- x2=six.text_type(xb), y2=six.text_type(yb))
- writer.element(
- 'stop',
- offset='0',
- style=generate_css({'stop-color': rgb2hex(c),
- 'stop-opacity': six.text_type(c[-1])}))
- writer.element(
- 'stop',
- offset='1',
- style=generate_css({'stop-color': rgb2hex(c),
- 'stop-opacity': "0"}))
- writer.end('linearGradient')
-
- writer.element(
- 'polygon',
- id='GT%x' % self._n_gradients,
- points=" ".join([six.text_type(x)
- for x in (x1, y1, x2, y2, x3, y3)]))
- writer.end('defs')
-
- avg_color = np.sum(colors[:, :], axis=0) / 3.0
- href = '#GT%x' % self._n_gradients
- writer.element(
- 'use',
- attrib={'xlink:href': href,
- 'fill': rgb2hex(avg_color),
- 'fill-opacity': str(avg_color[-1])})
- for i in range(3):
- writer.element(
- 'use',
- attrib={'xlink:href': href,
- 'fill': 'url(#GR%x_%d)' % (self._n_gradients, i),
- 'fill-opacity': '1',
- 'filter': 'url(#colorAdd)'})
-
- self._n_gradients += 1
-
- def draw_gouraud_triangles(self, gc, triangles_array, colors_array,
- transform):
- attrib = {}
- clipid = self._get_clip(gc)
- if clipid is not None:
- attrib['clip-path'] = 'url(#%s)' % clipid
-
- self.writer.start('g', attrib=attrib)
-
- transform = transform.frozen()
- for tri, col in zip(triangles_array, colors_array):
- self.draw_gouraud_triangle(gc, tri, col, transform)
-
- self.writer.end('g')
-
- def option_scale_image(self):
- return True
-
- def get_image_magnification(self):
- return self.image_dpi / 72.0
-
- def draw_image(self, gc, x, y, im, dx=None, dy=None, transform=None):
- attrib = {}
- clipid = self._get_clip(gc)
- if clipid is not None:
- # Can't apply clip-path directly to the image because the
- # image has a transformation, which would also be applied
- # to the clip-path
- self.writer.start('g', attrib={'clip-path': 'url(#%s)' % clipid})
-
- trans = [1,0,0,1,0,0]
- if rcParams['svg.image_noscale']:
- trans = list(im.get_matrix())
- trans[5] = -trans[5]
- attrib['transform'] = generate_transform([('matrix', tuple(trans))])
- assert trans[1] == 0
- assert trans[2] == 0
- numrows, numcols = im.get_size()
- im.reset_matrix()
- im.set_interpolation(0)
- im.resize(numcols, numrows)
-
- h,w = im.get_size_out()
-
- if dx is None:
- w = 72.0*w/self.image_dpi
- else:
- w = dx
-
- if dy is None:
- h = 72.0*h/self.image_dpi
- else:
- h = dy
-
- oid = getattr(im, '_gid', None)
- url = getattr(im, '_url', None)
- if url is not None:
- self.writer.start('a', attrib={'xlink:href': url})
- if rcParams['svg.image_inline']:
- bytesio = io.BytesIO()
- im.flipud_out()
- rows, cols, buffer = im.as_rgba_str()
- _png.write_png(buffer, cols, rows, bytesio)
- im.flipud_out()
- oid = oid or self._make_id('image', bytesio)
- attrib['xlink:href'] = (
- "data:image/png;base64,\n" +
- base64.b64encode(bytesio.getvalue()).decode('ascii'))
- else:
- self._imaged[self.basename] = self._imaged.get(self.basename,0) + 1
- filename = '%s.image%d.png'%(self.basename, self._imaged[self.basename])
- verbose.report( 'Writing image file for inclusion: %s' % filename)
- im.flipud_out()
- rows, cols, buffer = im.as_rgba_str()
- _png.write_png(buffer, cols, rows, filename)
- im.flipud_out()
- oid = oid or 'Im_' + self._make_id('image', filename)
- attrib['xlink:href'] = filename
-
- alpha = gc.get_alpha()
- if alpha != 1.0:
- attrib['opacity'] = str(alpha)
-
- attrib['id'] = oid
-
- if transform is None:
- self.writer.element(
- 'image',
- x=six.text_type(x/trans[0]),
- y=six.text_type((self.height-y)/trans[3]-h),
- width=six.text_type(w), height=six.text_type(h),
- attrib=attrib)
- else:
- flipped = self._make_flip_transform(transform)
- flipped = np.array(flipped.to_values())
- y = y+dy
- if dy > 0.0:
- flipped[3] *= -1.0
- y *= -1.0
- attrib['transform'] = generate_transform(
- [('matrix', flipped)])
- self.writer.element(
- 'image',
- x=six.text_type(x), y=six.text_type(y),
- width=six.text_type(dx), height=six.text_type(abs(dy)),
- attrib=attrib)
-
- if url is not None:
- self.writer.end('a')
- if clipid is not None:
- self.writer.end('g')
-
- def _adjust_char_id(self, char_id):
- return char_id.replace("%20", "_")
-
- def _draw_text_as_path(self, gc, x, y, s, prop, angle, ismath, mtext=None):
- """
- draw the text by converting them to paths using textpath module.
-
- *prop*
- font property
-
- *s*
- text to be converted
-
- *usetex*
- If True, use matplotlib usetex mode.
-
- *ismath*
- If True, use mathtext parser. If "TeX", use *usetex* mode.
- """
- writer = self.writer
-
- writer.comment(s)
-
- glyph_map=self._glyph_map
-
- text2path = self._text2path
- color = rgb2hex(gc.get_rgb())
- fontsize = prop.get_size_in_points()
-
- style = {}
- if color != '#000000':
- style['fill'] = color
- if gc.get_alpha() != 1.0:
- style['opacity'] = six.text_type(gc.get_alpha())
-
- if not ismath:
- font = text2path._get_font(prop)
- _glyphs = text2path.get_glyphs_with_font(
- font, s, glyph_map=glyph_map, return_new_glyphs_only=True)
- glyph_info, glyph_map_new, rects = _glyphs
-
- if glyph_map_new:
- writer.start('defs')
- for char_id, glyph_path in six.iteritems(glyph_map_new):
- path = Path(*glyph_path)
- path_data = self._convert_path(path, simplify=False)
- writer.element('path', id=char_id, d=path_data)
- writer.end('defs')
-
- glyph_map.update(glyph_map_new)
-
- attrib = {}
- attrib['style'] = generate_css(style)
- font_scale = fontsize / text2path.FONT_SCALE
- attrib['transform'] = generate_transform([
- ('translate', (x, y)),
- ('rotate', (-angle,)),
- ('scale', (font_scale, -font_scale))])
-
- writer.start('g', attrib=attrib)
- for glyph_id, xposition, yposition, scale in glyph_info:
- attrib={'xlink:href': '#%s' % glyph_id}
- if xposition != 0.0:
- attrib['x'] = six.text_type(xposition)
- if yposition != 0.0:
- attrib['y'] = six.text_type(yposition)
- writer.element(
- 'use',
- attrib=attrib)
-
- writer.end('g')
- else:
- if ismath == "TeX":
- _glyphs = text2path.get_glyphs_tex(prop, s, glyph_map=glyph_map,
- return_new_glyphs_only=True)
- else:
- _glyphs = text2path.get_glyphs_mathtext(prop, s, glyph_map=glyph_map,
- return_new_glyphs_only=True)
-
- glyph_info, glyph_map_new, rects = _glyphs
-
- # we store the character glyphs w/o flipping. Instead, the
- # coordinate will be flipped when this characters are
- # used.
- if glyph_map_new:
- writer.start('defs')
- for char_id, glyph_path in six.iteritems(glyph_map_new):
- char_id = self._adjust_char_id(char_id)
- # Some characters are blank
- if not len(glyph_path[0]):
- path_data = ""
- else:
- path = Path(*glyph_path)
- path_data = self._convert_path(path, simplify=False)
- writer.element('path', id=char_id, d=path_data)
- writer.end('defs')
-
- glyph_map.update(glyph_map_new)
-
- attrib = {}
- font_scale = fontsize / text2path.FONT_SCALE
- attrib['style'] = generate_css(style)
- attrib['transform'] = generate_transform([
- ('translate', (x, y)),
- ('rotate', (-angle,)),
- ('scale', (font_scale, -font_scale))])
-
- writer.start('g', attrib=attrib)
- for char_id, xposition, yposition, scale in glyph_info:
- char_id = self._adjust_char_id(char_id)
-
- writer.element(
- 'use',
- transform=generate_transform([
- ('translate', (xposition, yposition)),
- ('scale', (scale,)),
- ]),
- attrib={'xlink:href': '#%s' % char_id})
-
- for verts, codes in rects:
- path = Path(verts, codes)
- path_data = self._convert_path(path, simplify=False)
- writer.element('path', d=path_data)
-
- writer.end('g')
-
- def _draw_text_as_text(self, gc, x, y, s, prop, angle, ismath, mtext=None):
- writer = self.writer
-
- color = rgb2hex(gc.get_rgb())
- style = {}
- if color != '#000000':
- style['fill'] = color
- if gc.get_alpha() != 1.0:
- style['opacity'] = six.text_type(gc.get_alpha())
-
- if not ismath:
- font = self._get_font(prop)
- font.set_text(s, 0.0, flags=LOAD_NO_HINTING)
-
- fontsize = prop.get_size_in_points()
-
- fontfamily = font.family_name
- fontstyle = prop.get_style()
-
- attrib = {}
- # Must add "px" to workaround a Firefox bug
- style['font-size'] = six.text_type(fontsize) + 'px'
- style['font-family'] = six.text_type(fontfamily)
- style['font-style'] = prop.get_style().lower()
- attrib['style'] = generate_css(style)
-
- if mtext and (angle == 0 or mtext.get_rotation_mode() == "anchor"):
- # If text anchoring can be supported, get the original
- # coordinates and add alignment information.
-
- # Get anchor coordinates.
- transform = mtext.get_transform()
- ax, ay = transform.transform_point(mtext.get_position())
- ay = self.height - ay
-
- # Don't do vertical anchor alignment. Most applications do not
- # support 'alignment-baseline' yet. Apply the vertical layout
- # to the anchor point manually for now.
- angle_rad = angle * np.pi / 180.
- dir_vert = np.array([np.sin(angle_rad), np.cos(angle_rad)])
- v_offset = np.dot(dir_vert, [(x - ax), (y - ay)])
- ax = ax + v_offset * dir_vert[0]
- ay = ay + v_offset * dir_vert[1]
-
- ha_mpl_to_svg = {'left': 'start', 'right': 'end',
- 'center': 'middle'}
- style['text-anchor'] = ha_mpl_to_svg[mtext.get_ha()]
-
- attrib['x'] = str(ax)
- attrib['y'] = str(ay)
- attrib['style'] = generate_css(style)
- attrib['transform'] = "rotate(%f, %f, %f)" % (-angle, ax, ay)
- writer.element('text', s, attrib=attrib)
- else:
- attrib['transform'] = generate_transform([
- ('translate', (x, y)),
- ('rotate', (-angle,))])
-
- writer.element('text', s, attrib=attrib)
-
- if rcParams['svg.fonttype'] == 'svgfont':
- fontset = self._fonts.setdefault(font.fname, set())
- for c in s:
- fontset.add(ord(c))
- else:
- writer.comment(s)
-
- width, height, descent, svg_elements, used_characters = \
- self.mathtext_parser.parse(s, 72, prop)
- svg_glyphs = svg_elements.svg_glyphs
- svg_rects = svg_elements.svg_rects
-
- attrib = {}
- attrib['style'] = generate_css(style)
- attrib['transform'] = generate_transform([
- ('translate', (x, y)),
- ('rotate', (-angle,))])
-
- # Apply attributes to 'g', not 'text', because we likely
- # have some rectangles as well with the same style and
- # transformation
- writer.start('g', attrib=attrib)
-
- writer.start('text')
-
- # Sort the characters by font, and output one tspan for
- # each
- spans = {}
- for font, fontsize, thetext, new_x, new_y, metrics in svg_glyphs:
- style = generate_css({
- 'font-size': six.text_type(fontsize) + 'px',
- 'font-family': font.family_name,
- 'font-style': font.style_name.lower()})
- if thetext == 32:
- thetext = 0xa0 # non-breaking space
- spans.setdefault(style, []).append((new_x, -new_y, thetext))
-
- if rcParams['svg.fonttype'] == 'svgfont':
- for font, fontsize, thetext, new_x, new_y, metrics in svg_glyphs:
- fontset = self._fonts.setdefault(font.fname, set())
- fontset.add(thetext)
-
- for style, chars in list(six.iteritems(spans)):
- chars.sort()
-
- same_y = True
- if len(chars) > 1:
- last_y = chars[0][1]
- for i in xrange(1, len(chars)):
- if chars[i][1] != last_y:
- same_y = False
- break
- if same_y:
- ys = six.text_type(chars[0][1])
- else:
- ys = ' '.join(six.text_type(c[1]) for c in chars)
-
- attrib = {
- 'style': style,
- 'x': ' '.join(six.text_type(c[0]) for c in chars),
- 'y': ys
- }
-
- writer.element(
- 'tspan',
- ''.join(unichr(c[2]) for c in chars),
- attrib=attrib)
-
- writer.end('text')
-
- if len(svg_rects):
- for x, y, width, height in svg_rects:
- writer.element(
- 'rect',
- x=six.text_type(x), y=six.text_type(-y + height),
- width=six.text_type(width), height=six.text_type(height)
- )
-
- writer.end('g')
-
- def draw_tex(self, gc, x, y, s, prop, angle, ismath='TeX!', mtext=None):
- self._draw_text_as_path(gc, x, y, s, prop, angle, ismath="TeX")
-
- def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
- clipid = self._get_clip(gc)
- if clipid is not None:
- # Cannot apply clip-path directly to the text, because
- # is has a transformation
- self.writer.start(
- 'g', attrib={'clip-path': 'url(#%s)' % clipid})
-
- if gc.get_url() is not None:
- self.writer.start('a', {'xlink:href': gc.get_url()})
-
- if rcParams['svg.fonttype'] == 'path':
- self._draw_text_as_path(gc, x, y, s, prop, angle, ismath, mtext)
- else:
- self._draw_text_as_text(gc, x, y, s, prop, angle, ismath, mtext)
-
- if gc.get_url() is not None:
- self.writer.end('a')
-
- if clipid is not None:
- self.writer.end('g')
-
- def flipy(self):
- return True
-
- def get_canvas_width_height(self):
- return self.width, self.height
-
- def get_text_width_height_descent(self, s, prop, ismath):
- return self._text2path.get_text_width_height_descent(s, prop, ismath)
-
-
-class FigureCanvasSVG(FigureCanvasBase):
- filetypes = {'svg': 'Scalable Vector Graphics',
- 'svgz': 'Scalable Vector Graphics'}
-
- fixed_dpi = 72
-
- def print_svg(self, filename, *args, **kwargs):
- if is_string_like(filename):
- fh_to_close = svgwriter = io.open(filename, 'w', encoding='utf-8')
- elif is_writable_file_like(filename):
- if not isinstance(filename, io.TextIOBase):
- if six.PY3:
- svgwriter = io.TextIOWrapper(filename, 'utf-8')
- else:
- svgwriter = codecs.getwriter('utf-8')(filename)
- else:
- svgwriter = filename
- fh_to_close = None
- else:
- raise ValueError("filename must be a path or a file-like object")
- return self._print_svg(filename, svgwriter, fh_to_close, **kwargs)
-
- def print_svgz(self, filename, *args, **kwargs):
- if is_string_like(filename):
- fh_to_close = gzipwriter = gzip.GzipFile(filename, 'w')
- svgwriter = io.TextIOWrapper(gzipwriter, 'utf-8')
- elif is_writable_file_like(filename):
- fh_to_close = gzipwriter = gzip.GzipFile(fileobj=filename, mode='w')
- svgwriter = io.TextIOWrapper(gzipwriter, 'utf-8')
- else:
- raise ValueError("filename must be a path or a file-like object")
- return self._print_svg(filename, svgwriter, fh_to_close)
-
- def _print_svg(self, filename, svgwriter, fh_to_close=None, **kwargs):
- try:
- image_dpi = kwargs.pop("dpi", 72)
- self.figure.set_dpi(72.0)
- width, height = self.figure.get_size_inches()
- w, h = width*72, height*72
-
- if rcParams['svg.image_noscale']:
- renderer = RendererSVG(w, h, svgwriter, filename, image_dpi)
- else:
- _bbox_inches_restore = kwargs.pop("bbox_inches_restore", None)
- renderer = MixedModeRenderer(self.figure,
- width, height, image_dpi, RendererSVG(w, h, svgwriter, filename, image_dpi),
- bbox_inches_restore=_bbox_inches_restore)
-
- self.figure.draw(renderer)
- renderer.finalize()
- finally:
- if fh_to_close is not None:
- svgwriter.close()
-
- def get_default_filetype(self):
- return 'svg'
-
-class FigureManagerSVG(FigureManagerBase):
- pass
-
-
-def new_figure_manager(num, *args, **kwargs):
- FigureClass = kwargs.pop('FigureClass', Figure)
- thisFig = FigureClass(*args, **kwargs)
- return new_figure_manager_given_figure(num, thisFig)
-
-
-def new_figure_manager_given_figure(num, figure):
- """
- Create a new figure manager instance for the given figure.
- """
- canvas = FigureCanvasSVG(figure)
- manager = FigureManagerSVG(canvas, num)
- return manager
-
-
-svgProlog = """\
-
-
-
-"""
-
-
-FigureCanvas = FigureCanvasSVG
-FigureManager = FigureManagerSVG
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_template.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_template.py
deleted file mode 100644
index f3e483d..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_template.py
+++ /dev/null
@@ -1,274 +0,0 @@
-"""
-This is a fully functional do nothing backend to provide a template to
-backend writers. It is fully functional in that you can select it as
-a backend with
-
- import matplotlib
- matplotlib.use('Template')
-
-and your matplotlib scripts will (should!) run without error, though
-no output is produced. This provides a nice starting point for
-backend writers because you can selectively implement methods
-(draw_rectangle, draw_lines, etc...) and slowly see your figure come
-to life w/o having to have a full blown implementation before getting
-any results.
-
-Copy this to backend_xxx.py and replace all instances of 'template'
-with 'xxx'. Then implement the class methods and functions below, and
-add 'xxx' to the switchyard in matplotlib/backends/__init__.py and
-'xxx' to the backends list in the validate_backend methon in
-matplotlib/__init__.py and you're off. You can use your backend with::
-
- import matplotlib
- matplotlib.use('xxx')
- from pylab import *
- plot([1,2,3])
- show()
-
-matplotlib also supports external backends, so you can place you can
-use any module in your PYTHONPATH with the syntax::
-
- import matplotlib
- matplotlib.use('module://my_backend')
-
-where my_backend.py is your module name. This syntax is also
-recognized in the rc file and in the -d argument in pylab, e.g.,::
-
- python simple_plot.py -dmodule://my_backend
-
-If your backend implements support for saving figures (i.e. has a print_xyz()
-method) you can register it as the default handler for a given file type
-
- from matplotlib.backend_bases import register_backend
- register_backend('xyz', 'my_backend', 'XYZ File Format')
- ...
- plt.savefig("figure.xyz")
-
-The files that are most relevant to backend_writers are
-
- matplotlib/backends/backend_your_backend.py
- matplotlib/backend_bases.py
- matplotlib/backends/__init__.py
- matplotlib/__init__.py
- matplotlib/_pylab_helpers.py
-
-Naming Conventions
-
- * classes Upper or MixedUpperCase
-
- * varables lower or lowerUpper
-
- * functions lower or underscore_separated
-
-"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import matplotlib
-from matplotlib._pylab_helpers import Gcf
-from matplotlib.backend_bases import RendererBase, GraphicsContextBase,\
- FigureManagerBase, FigureCanvasBase
-from matplotlib.figure import Figure
-from matplotlib.transforms import Bbox
-
-
-class RendererTemplate(RendererBase):
- """
- The renderer handles drawing/rendering operations.
-
- This is a minimal do-nothing class that can be used to get started when
- writing a new backend. Refer to backend_bases.RendererBase for
- documentation of the classes methods.
- """
- def __init__(self, dpi):
- self.dpi = dpi
-
- def draw_path(self, gc, path, transform, rgbFace=None):
- pass
-
- # draw_markers is optional, and we get more correct relative
- # timings by leaving it out. backend implementers concerned with
- # performance will probably want to implement it
-# def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None):
-# pass
-
- # draw_path_collection is optional, and we get more correct
- # relative timings by leaving it out. backend implementers concerned with
- # performance will probably want to implement it
-# def draw_path_collection(self, gc, master_transform, paths,
-# all_transforms, offsets, offsetTrans, facecolors,
-# edgecolors, linewidths, linestyles,
-# antialiaseds):
-# pass
-
- # draw_quad_mesh is optional, and we get more correct
- # relative timings by leaving it out. backend implementers concerned with
- # performance will probably want to implement it
-# def draw_quad_mesh(self, gc, master_transform, meshWidth, meshHeight,
-# coordinates, offsets, offsetTrans, facecolors,
-# antialiased, edgecolors):
-# pass
-
- def draw_image(self, gc, x, y, im):
- pass
-
- def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
- pass
-
- def flipy(self):
- return True
-
- def get_canvas_width_height(self):
- return 100, 100
-
- def get_text_width_height_descent(self, s, prop, ismath):
- return 1, 1, 1
-
- def new_gc(self):
- return GraphicsContextTemplate()
-
- def points_to_pixels(self, points):
- # if backend doesn't have dpi, e.g., postscript or svg
- return points
- # elif backend assumes a value for pixels_per_inch
- #return points/72.0 * self.dpi.get() * pixels_per_inch/72.0
- # else
- #return points/72.0 * self.dpi.get()
-
-
-class GraphicsContextTemplate(GraphicsContextBase):
- """
- The graphics context provides the color, line styles, etc... See the gtk
- and postscript backends for examples of mapping the graphics context
- attributes (cap styles, join styles, line widths, colors) to a particular
- backend. In GTK this is done by wrapping a gtk.gdk.GC object and
- forwarding the appropriate calls to it using a dictionary mapping styles
- to gdk constants. In Postscript, all the work is done by the renderer,
- mapping line styles to postscript calls.
-
- If it's more appropriate to do the mapping at the renderer level (as in
- the postscript backend), you don't need to override any of the GC methods.
- If it's more appropriate to wrap an instance (as in the GTK backend) and
- do the mapping here, you'll need to override several of the setter
- methods.
-
- The base GraphicsContext stores colors as a RGB tuple on the unit
- interval, e.g., (0.5, 0.0, 1.0). You may need to map this to colors
- appropriate for your backend.
- """
- pass
-
-
-
-########################################################################
-#
-# The following functions and classes are for pylab and implement
-# window/figure managers, etc...
-#
-########################################################################
-
-def draw_if_interactive():
- """
- For image backends - is not required
- For GUI backends - this should be overriden if drawing should be done in
- interactive python mode
- """
- pass
-
-def show():
- """
- For image backends - is not required
- For GUI backends - show() is usually the last line of a pylab script and
- tells the backend that it is time to draw. In interactive mode, this may
- be a do nothing func. See the GTK backend for an example of how to handle
- interactive versus batch mode
- """
- for manager in Gcf.get_all_fig_managers():
- # do something to display the GUI
- pass
-
-
-def new_figure_manager(num, *args, **kwargs):
- """
- Create a new figure manager instance
- """
- # if a main-level app must be created, this (and
- # new_figure_manager_given_figure) is the usual place to
- # do it -- see backend_wx, backend_wxagg and backend_tkagg for
- # examples. Not all GUIs require explicit instantiation of a
- # main-level app (egg backend_gtk, backend_gtkagg) for pylab
- FigureClass = kwargs.pop('FigureClass', Figure)
- thisFig = FigureClass(*args, **kwargs)
- return new_figure_manager_given_figure(num, thisFig)
-
-
-def new_figure_manager_given_figure(num, figure):
- """
- Create a new figure manager instance for the given figure.
- """
- canvas = FigureCanvasTemplate(figure)
- manager = FigureManagerTemplate(canvas, num)
- return manager
-
-
-class FigureCanvasTemplate(FigureCanvasBase):
- """
- The canvas the figure renders into. Calls the draw and print fig
- methods, creates the renderers, etc...
-
- Public attribute
-
- figure - A Figure instance
-
- Note GUI templates will want to connect events for button presses,
- mouse movements and key presses to functions that call the base
- class methods button_press_event, button_release_event,
- motion_notify_event, key_press_event, and key_release_event. See,
- e.g., backend_gtk.py, backend_wx.py and backend_tkagg.py
- """
-
- def draw(self):
- """
- Draw the figure using the renderer
- """
- renderer = RendererTemplate(self.figure.dpi)
- self.figure.draw(renderer)
-
- # You should provide a print_xxx function for every file format
- # you can write.
-
- # If the file type is not in the base set of filetypes,
- # you should add it to the class-scope filetypes dictionary as follows:
- filetypes = FigureCanvasBase.filetypes.copy()
- filetypes['foo'] = 'My magic Foo format'
-
- def print_foo(self, filename, *args, **kwargs):
- """
- Write out format foo. The dpi, facecolor and edgecolor are restored
- to their original values after this call, so you don't need to
- save and restore them.
- """
- pass
-
- def get_default_filetype(self):
- return 'foo'
-
-class FigureManagerTemplate(FigureManagerBase):
- """
- Wrap everything up into a window for the pylab interface
-
- For non interactive backends, the base class does all the work
- """
- pass
-
-########################################################################
-#
-# Now just provide the standard names that backend.__init__ is expecting
-#
-########################################################################
-
-FigureCanvas = FigureCanvasTemplate
-FigureManager = FigureManagerTemplate
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_tkagg.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_tkagg.py
deleted file mode 100644
index 751ed01..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_tkagg.py
+++ /dev/null
@@ -1,875 +0,0 @@
-# Todd Miller jmiller@stsci.edu
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import tkinter as Tk
-from six.moves import tkinter_filedialog as FileDialog
-
-import os, sys, math
-import os.path
-
-# Paint image to Tk photo blitter extension
-import matplotlib.backends.tkagg as tkagg
-
-from matplotlib.backends.backend_agg import FigureCanvasAgg
-import matplotlib.backends.windowing as windowing
-
-import matplotlib
-from matplotlib.cbook import is_string_like
-from matplotlib.backend_bases import RendererBase, GraphicsContextBase
-from matplotlib.backend_bases import FigureManagerBase, FigureCanvasBase
-from matplotlib.backend_bases import NavigationToolbar2, cursors, TimerBase
-from matplotlib.backend_bases import ShowBase
-from matplotlib._pylab_helpers import Gcf
-
-from matplotlib.figure import Figure
-
-from matplotlib.widgets import SubplotTool
-
-import matplotlib.cbook as cbook
-
-rcParams = matplotlib.rcParams
-verbose = matplotlib.verbose
-
-
-backend_version = Tk.TkVersion
-
-# the true dots per inch on the screen; should be display dependent
-# see http://groups.google.com/groups?q=screen+dpi+x11&hl=en&lr=&ie=UTF-8&oe=UTF-8&safe=off&selm=7077.26e81ad5%40swift.cs.tcd.ie&rnum=5 for some info about screen dpi
-PIXELS_PER_INCH = 75
-
-cursord = {
- cursors.MOVE: "fleur",
- cursors.HAND: "hand2",
- cursors.POINTER: "arrow",
- cursors.SELECT_REGION: "tcross",
- }
-
-
-def round(x):
- return int(math.floor(x+0.5))
-
-def raise_msg_to_str(msg):
- """msg is a return arg from a raise. Join with new lines"""
- if not is_string_like(msg):
- msg = '\n'.join(map(str, msg))
- return msg
-
-def error_msg_tkpaint(msg, parent=None):
- from six.moves import tkinter_messagebox as tkMessageBox
- tkMessageBox.showerror("matplotlib", msg)
-
-def draw_if_interactive():
- if matplotlib.is_interactive():
- figManager = Gcf.get_active()
- if figManager is not None:
- figManager.show()
-
-class Show(ShowBase):
- def mainloop(self):
- Tk.mainloop()
-
-show = Show()
-
-def new_figure_manager(num, *args, **kwargs):
- """
- Create a new figure manager instance
- """
- FigureClass = kwargs.pop('FigureClass', Figure)
- figure = FigureClass(*args, **kwargs)
- return new_figure_manager_given_figure(num, figure)
-
-
-def new_figure_manager_given_figure(num, figure):
- """
- Create a new figure manager instance for the given figure.
- """
- _focus = windowing.FocusManager()
- window = Tk.Tk()
- window.withdraw()
-
- if Tk.TkVersion >= 8.5:
- # put a mpl icon on the window rather than the default tk icon. Tkinter
- # doesn't allow colour icons on linux systems, but tk >=8.5 has a iconphoto
- # command which we call directly. Source:
- # http://mail.python.org/pipermail/tkinter-discuss/2006-November/000954.html
- icon_fname = os.path.join(rcParams['datapath'], 'images', 'matplotlib.gif')
- icon_img = Tk.PhotoImage(file=icon_fname)
- try:
- window.tk.call('wm', 'iconphoto', window._w, icon_img)
- except (SystemExit, KeyboardInterrupt):
- # re-raise exit type Exceptions
- raise
- except:
- # log the failure, but carry on
- verbose.report('Could not load matplotlib icon: %s' % sys.exc_info()[1])
-
- canvas = FigureCanvasTkAgg(figure, master=window)
- figManager = FigureManagerTkAgg(canvas, num, window)
- if matplotlib.is_interactive():
- figManager.show()
- return figManager
-
-
-class TimerTk(TimerBase):
- '''
- Subclass of :class:`backend_bases.TimerBase` that uses Tk's timer events.
-
- Attributes:
- * interval: The time between timer events in milliseconds. Default
- is 1000 ms.
- * single_shot: Boolean flag indicating whether this timer should
- operate as single shot (run once and then stop). Defaults to False.
- * callbacks: Stores list of (func, args) tuples that will be called
- upon timer events. This list can be manipulated directly, or the
- functions add_callback and remove_callback can be used.
- '''
- def __init__(self, parent, *args, **kwargs):
- TimerBase.__init__(self, *args, **kwargs)
- self.parent = parent
- self._timer = None
-
- def _timer_start(self):
- self._timer_stop()
- self._timer = self.parent.after(self._interval, self._on_timer)
-
- def _timer_stop(self):
- if self._timer is not None:
- self.parent.after_cancel(self._timer)
- self._timer = None
-
- def _on_timer(self):
- TimerBase._on_timer(self)
-
- # Tk after() is only a single shot, so we need to add code here to
- # reset the timer if we're not operating in single shot mode.
- if not self._single and len(self.callbacks) > 0:
- self._timer = self.parent.after(self._interval, self._on_timer)
- else:
- self._timer = None
-
-
-class FigureCanvasTkAgg(FigureCanvasAgg):
- keyvald = {65507 : 'control',
- 65505 : 'shift',
- 65513 : 'alt',
- 65515 : 'super',
- 65508 : 'control',
- 65506 : 'shift',
- 65514 : 'alt',
- 65361 : 'left',
- 65362 : 'up',
- 65363 : 'right',
- 65364 : 'down',
- 65307 : 'escape',
- 65470 : 'f1',
- 65471 : 'f2',
- 65472 : 'f3',
- 65473 : 'f4',
- 65474 : 'f5',
- 65475 : 'f6',
- 65476 : 'f7',
- 65477 : 'f8',
- 65478 : 'f9',
- 65479 : 'f10',
- 65480 : 'f11',
- 65481 : 'f12',
- 65300 : 'scroll_lock',
- 65299 : 'break',
- 65288 : 'backspace',
- 65293 : 'enter',
- 65379 : 'insert',
- 65535 : 'delete',
- 65360 : 'home',
- 65367 : 'end',
- 65365 : 'pageup',
- 65366 : 'pagedown',
- 65438 : '0',
- 65436 : '1',
- 65433 : '2',
- 65435 : '3',
- 65430 : '4',
- 65437 : '5',
- 65432 : '6',
- 65429 : '7',
- 65431 : '8',
- 65434 : '9',
- 65451 : '+',
- 65453 : '-',
- 65450 : '*',
- 65455 : '/',
- 65439 : 'dec',
- 65421 : 'enter',
- }
-
- _keycode_lookup = {
- 262145: 'control',
- 524320: 'alt',
- 524352: 'alt',
- 1048584: 'super',
- 1048592: 'super',
- 131074: 'shift',
- 131076: 'shift',
- }
- """_keycode_lookup is used for badly mapped (i.e. no event.key_sym set)
- keys on apple keyboards."""
-
- def __init__(self, figure, master=None, resize_callback=None):
- FigureCanvasAgg.__init__(self, figure)
- self._idle = True
- self._idle_callback = None
- t1,t2,w,h = self.figure.bbox.bounds
- w, h = int(w), int(h)
- self._tkcanvas = Tk.Canvas(
- master=master, width=w, height=h, borderwidth=4)
- self._tkphoto = Tk.PhotoImage(
- master=self._tkcanvas, width=w, height=h)
- self._tkcanvas.create_image(w//2, h//2, image=self._tkphoto)
- self._resize_callback = resize_callback
- self._tkcanvas.bind("", self.resize)
- self._tkcanvas.bind("", self.key_press)
- self._tkcanvas.bind("", self.motion_notify_event)
- self._tkcanvas.bind("", self.key_release)
- for name in "", "", "":
- self._tkcanvas.bind(name, self.button_press_event)
- for name in "", "", "":
- self._tkcanvas.bind(name, self.button_dblclick_event)
- for name in "", "", "":
- self._tkcanvas.bind(name, self.button_release_event)
-
- # Mouse wheel on Linux generates button 4/5 events
- for name in "", "":
- self._tkcanvas.bind(name, self.scroll_event)
- # Mouse wheel for windows goes to the window with the focus.
- # Since the canvas won't usually have the focus, bind the
- # event to the window containing the canvas instead.
- # See http://wiki.tcl.tk/3893 (mousewheel) for details
- root = self._tkcanvas.winfo_toplevel()
- root.bind("", self.scroll_event_windows)
-
- # Can't get destroy events by binding to _tkcanvas. Therefore, bind
- # to the window and filter.
- def filter_destroy(evt):
- if evt.widget is self._tkcanvas:
- self.close_event()
- root.bind("", filter_destroy)
-
- self._master = master
- self._tkcanvas.focus_set()
-
- def resize(self, event):
- width, height = event.width, event.height
- if self._resize_callback is not None:
- self._resize_callback(event)
-
- # compute desired figure size in inches
- dpival = self.figure.dpi
- winch = width/dpival
- hinch = height/dpival
- self.figure.set_size_inches(winch, hinch)
-
-
- self._tkcanvas.delete(self._tkphoto)
- self._tkphoto = Tk.PhotoImage(
- master=self._tkcanvas, width=int(width), height=int(height))
- self._tkcanvas.create_image(int(width/2),int(height/2),image=self._tkphoto)
- self.resize_event()
- self.show()
-
- # a resizing will in general move the pointer position
- # relative to the canvas, so process it as a motion notify
- # event. An intended side effect of this call is to allow
- # window raises (which trigger a resize) to get the cursor
- # position to the mpl event framework so key presses which are
- # over the axes will work w/o clicks or explicit motion
- self._update_pointer_position(event)
-
- def _update_pointer_position(self, guiEvent=None):
- """
- Figure out if we are inside the canvas or not and update the
- canvas enter/leave events
- """
- # if the pointer if over the canvas, set the lastx and lasty
- # attrs of the canvas so it can process event w/o mouse click
- # or move
-
- # the window's upper, left coords in screen coords
- xw = self._tkcanvas.winfo_rootx()
- yw = self._tkcanvas.winfo_rooty()
- # the pointer's location in screen coords
- xp, yp = self._tkcanvas.winfo_pointerxy()
-
- # not figure out the canvas coordinates of the pointer
- xc = xp - xw
- yc = yp - yw
-
- # flip top/bottom
- yc = self.figure.bbox.height - yc
-
- # JDH: this method was written originally to get the pointer
- # location to the backend lastx and lasty attrs so that events
- # like KeyEvent can be handled without mouse events. e.g., if
- # the cursor is already above the axes, then key presses like
- # 'g' should toggle the grid. In order for this to work in
- # backend_bases, the canvas needs to know _lastx and _lasty.
- # There are three ways to get this info the canvas:
- #
- # 1) set it explicity
- #
- # 2) call enter/leave events explicity. The downside of this
- # in the impl below is that enter could be repeatedly
- # triggered if thes mouse is over the axes and one is
- # resizing with the keyboard. This is not entirely bad,
- # because the mouse position relative to the canvas is
- # changing, but it may be surprising to get repeated entries
- # without leaves
- #
- # 3) process it as a motion notify event. This also has pros
- # and cons. The mouse is moving relative to the window, but
- # this may surpise an event handler writer who is getting
- # motion_notify_events even if the mouse has not moved
-
- # here are the three scenarios
- if 1:
- # just manually set it
- self._lastx, self._lasty = xc, yc
- elif 0:
- # alternate implementation: process it as a motion
- FigureCanvasBase.motion_notify_event(self, xc, yc, guiEvent)
- elif 0:
- # alternate implementation -- process enter/leave events
- # instead of motion/notify
- if self.figure.bbox.contains(xc, yc):
- self.enter_notify_event(guiEvent, xy=(xc,yc))
- else:
- self.leave_notify_event(guiEvent)
-
- def draw(self):
- FigureCanvasAgg.draw(self)
- tkagg.blit(self._tkphoto, self.renderer._renderer, colormode=2)
- self._master.update_idletasks()
-
- def blit(self, bbox=None):
- tkagg.blit(self._tkphoto, self.renderer._renderer, bbox=bbox, colormode=2)
- self._master.update_idletasks()
-
- show = draw
-
- def draw_idle(self):
- 'update drawing area only if idle'
- d = self._idle
- self._idle = False
- def idle_draw(*args):
- try:
- self.draw()
- finally:
- self._idle = True
-
- if d:
- self._idle_callback = self._tkcanvas.after_idle(idle_draw)
-
- def get_tk_widget(self):
- """returns the Tk widget used to implement FigureCanvasTkAgg.
- Although the initial implementation uses a Tk canvas, this routine
- is intended to hide that fact.
- """
- return self._tkcanvas
-
- def motion_notify_event(self, event):
- x = event.x
- # flipy so y=0 is bottom of canvas
- y = self.figure.bbox.height - event.y
- FigureCanvasBase.motion_notify_event(self, x, y, guiEvent=event)
-
-
- def button_press_event(self, event, dblclick=False):
- x = event.x
- # flipy so y=0 is bottom of canvas
- y = self.figure.bbox.height - event.y
- num = getattr(event, 'num', None)
-
- if sys.platform=='darwin':
- # 2 and 3 were reversed on the OSX platform I
- # tested under tkagg
- if num==2: num=3
- elif num==3: num=2
-
- FigureCanvasBase.button_press_event(self, x, y, num, dblclick=dblclick, guiEvent=event)
-
- def button_dblclick_event(self,event):
- self.button_press_event(event,dblclick=True)
-
- def button_release_event(self, event):
- x = event.x
- # flipy so y=0 is bottom of canvas
- y = self.figure.bbox.height - event.y
-
- num = getattr(event, 'num', None)
-
- if sys.platform=='darwin':
- # 2 and 3 were reversed on the OSX platform I
- # tested under tkagg
- if num==2: num=3
- elif num==3: num=2
-
- FigureCanvasBase.button_release_event(self, x, y, num, guiEvent=event)
-
- def scroll_event(self, event):
- x = event.x
- y = self.figure.bbox.height - event.y
- num = getattr(event, 'num', None)
- if num==4: step = +1
- elif num==5: step = -1
- else: step = 0
-
- FigureCanvasBase.scroll_event(self, x, y, step, guiEvent=event)
-
- def scroll_event_windows(self, event):
- """MouseWheel event processor"""
- # need to find the window that contains the mouse
- w = event.widget.winfo_containing(event.x_root, event.y_root)
- if w == self._tkcanvas:
- x = event.x_root - w.winfo_rootx()
- y = event.y_root - w.winfo_rooty()
- y = self.figure.bbox.height - y
- step = event.delta/120.
- FigureCanvasBase.scroll_event(self, x, y, step, guiEvent=event)
-
- def _get_key(self, event):
- val = event.keysym_num
- if val in self.keyvald:
- key = self.keyvald[val]
- elif val == 0 and sys.platform == 'darwin' and \
- event.keycode in self._keycode_lookup:
- key = self._keycode_lookup[event.keycode]
- elif val < 256:
- key = chr(val)
- else:
- key = None
-
- # add modifier keys to the key string. Bit details originate from
- # http://effbot.org/tkinterbook/tkinter-events-and-bindings.htm
- # BIT_SHIFT = 0x001; BIT_CAPSLOCK = 0x002; BIT_CONTROL = 0x004;
- # BIT_LEFT_ALT = 0x008; BIT_NUMLOCK = 0x010; BIT_RIGHT_ALT = 0x080;
- # BIT_MB_1 = 0x100; BIT_MB_2 = 0x200; BIT_MB_3 = 0x400;
- # In general, the modifier key is excluded from the modifier flag,
- # however this is not the case on "darwin", so double check that
- # we aren't adding repeat modifier flags to a modifier key.
- if sys.platform == 'win32':
- modifiers = [(17, 'alt', 'alt'),
- (2, 'ctrl', 'control'),
- ]
- elif sys.platform == 'darwin':
- modifiers = [(3, 'super', 'super'),
- (4, 'alt', 'alt'),
- (2, 'ctrl', 'control'),
- ]
- else:
- modifiers = [(6, 'super', 'super'),
- (3, 'alt', 'alt'),
- (2, 'ctrl', 'control'),
- ]
-
- if key is not None:
- # note, shift is not added to the keys as this is already accounted for
- for bitmask, prefix, key_name in modifiers:
- if event.state & (1 << bitmask) and key_name not in key:
- key = '{0}+{1}'.format(prefix, key)
-
- return key
-
- def key_press(self, event):
- key = self._get_key(event)
- FigureCanvasBase.key_press_event(self, key, guiEvent=event)
-
- def key_release(self, event):
- key = self._get_key(event)
- FigureCanvasBase.key_release_event(self, key, guiEvent=event)
-
- def new_timer(self, *args, **kwargs):
- """
- Creates a new backend-specific subclass of :class:`backend_bases.Timer`.
- This is useful for getting periodic events through the backend's native
- event loop. Implemented only for backends with GUIs.
-
- optional arguments:
-
- *interval*
- Timer interval in milliseconds
- *callbacks*
- Sequence of (func, args, kwargs) where func(*args, **kwargs) will
- be executed by the timer every *interval*.
- """
- return TimerTk(self._tkcanvas, *args, **kwargs)
-
- def flush_events(self):
- self._master.update()
-
- def start_event_loop(self,timeout):
- FigureCanvasBase.start_event_loop_default(self,timeout)
- start_event_loop.__doc__=FigureCanvasBase.start_event_loop_default.__doc__
-
- def stop_event_loop(self):
- FigureCanvasBase.stop_event_loop_default(self)
- stop_event_loop.__doc__=FigureCanvasBase.stop_event_loop_default.__doc__
-
-class FigureManagerTkAgg(FigureManagerBase):
- """
- Public attributes
-
- canvas : The FigureCanvas instance
- num : The Figure number
- toolbar : The tk.Toolbar
- window : The tk.Window
- """
- def __init__(self, canvas, num, window):
- FigureManagerBase.__init__(self, canvas, num)
- self.window = window
- self.window.withdraw()
- self.set_window_title("Figure %d" % num)
- self.canvas = canvas
- self._num = num
- if matplotlib.rcParams['toolbar']=='toolbar2':
- self.toolbar = NavigationToolbar2TkAgg( canvas, self.window )
- else:
- self.toolbar = None
- if self.toolbar is not None:
- self.toolbar.update()
- self.canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
- self._shown = False
-
- def notify_axes_change(fig):
- 'this will be called whenever the current axes is changed'
- if self.toolbar != None: self.toolbar.update()
- self.canvas.figure.add_axobserver(notify_axes_change)
-
- def resize(self, width, height=None):
- # before 09-12-22, the resize method takes a single *event*
- # parameter. On the other hand, the resize method of other
- # FigureManager class takes *width* and *height* parameter,
- # which is used to change the size of the window. For the
- # Figure.set_size_inches with forward=True work with Tk
- # backend, I changed the function signature but tried to keep
- # it backward compatible. -JJL
-
- # when a single parameter is given, consider it as a event
- if height is None:
- width = width.width
- else:
- self.canvas._tkcanvas.master.geometry("%dx%d" % (width, height))
-
- if self.toolbar is not None:
- self.toolbar.configure(width=width)
-
- def show(self):
- """
- this function doesn't segfault but causes the
- PyEval_RestoreThread: NULL state bug on win32
- """
- _focus = windowing.FocusManager()
- if not self._shown:
- def destroy(*args):
- self.window = None
- Gcf.destroy(self._num)
- self.canvas._tkcanvas.bind("", destroy)
- self.window.deiconify()
- # anim.py requires this
- self.window.update()
- else:
- self.canvas.draw_idle()
- self._shown = True
-
- def destroy(self, *args):
- if self.window is not None:
- #self.toolbar.destroy()
- if self.canvas._idle_callback:
- self.canvas._tkcanvas.after_cancel(self.canvas._idle_callback)
- self.window.destroy()
- if Gcf.get_num_fig_managers()==0:
- if self.window is not None:
- self.window.quit()
- self.window = None
-
- def get_window_title(self):
- return self.window.wm_title()
-
- def set_window_title(self, title):
- self.window.wm_title(title)
-
- def full_screen_toggle(self):
- is_fullscreen = bool(self.window.attributes('-fullscreen'))
- self.window.attributes('-fullscreen', not is_fullscreen)
-
-
-class AxisMenu:
- def __init__(self, master, naxes):
- self._master = master
- self._naxes = naxes
- self._mbar = Tk.Frame(master=master, relief=Tk.RAISED, borderwidth=2)
- self._mbar.pack(side=Tk.LEFT)
- self._mbutton = Tk.Menubutton(
- master=self._mbar, text="Axes", underline=0)
- self._mbutton.pack(side=Tk.LEFT, padx="2m")
- self._mbutton.menu = Tk.Menu(self._mbutton)
- self._mbutton.menu.add_command(
- label="Select All", command=self.select_all)
- self._mbutton.menu.add_command(
- label="Invert All", command=self.invert_all)
- self._axis_var = []
- self._checkbutton = []
- for i in range(naxes):
- self._axis_var.append(Tk.IntVar())
- self._axis_var[i].set(1)
- self._checkbutton.append(self._mbutton.menu.add_checkbutton(
- label = "Axis %d" % (i+1),
- variable=self._axis_var[i],
- command=self.set_active))
- self._mbutton.menu.invoke(self._mbutton.menu.index("Select All"))
- self._mbutton['menu'] = self._mbutton.menu
- self._mbar.tk_menuBar(self._mbutton)
- self.set_active()
-
- def adjust(self, naxes):
- if self._naxes < naxes:
- for i in range(self._naxes, naxes):
- self._axis_var.append(Tk.IntVar())
- self._axis_var[i].set(1)
- self._checkbutton.append( self._mbutton.menu.add_checkbutton(
- label = "Axis %d" % (i+1),
- variable=self._axis_var[i],
- command=self.set_active))
- elif self._naxes > naxes:
- for i in range(self._naxes-1, naxes-1, -1):
- del self._axis_var[i]
- self._mbutton.menu.forget(self._checkbutton[i])
- del self._checkbutton[i]
- self._naxes = naxes
- self.set_active()
-
- def get_indices(self):
- a = [i for i in range(len(self._axis_var)) if self._axis_var[i].get()]
- return a
-
- def set_active(self):
- self._master.set_active(self.get_indices())
-
- def invert_all(self):
- for a in self._axis_var:
- a.set(not a.get())
- self.set_active()
-
- def select_all(self):
- for a in self._axis_var:
- a.set(1)
- self.set_active()
-
-
-class NavigationToolbar2TkAgg(NavigationToolbar2, Tk.Frame):
- """
- Public attributes
-
- canvas - the FigureCanvas (gtk.DrawingArea)
- win - the gtk.Window
- """
- def __init__(self, canvas, window):
- self.canvas = canvas
- self.window = window
- self._idle = True
- #Tk.Frame.__init__(self, master=self.canvas._tkcanvas)
- NavigationToolbar2.__init__(self, canvas)
-
- def destroy(self, *args):
- del self.message
- Tk.Frame.destroy(self, *args)
-
- def set_message(self, s):
- self.message.set(s)
-
- def draw_rubberband(self, event, x0, y0, x1, y1):
- height = self.canvas.figure.bbox.height
- y0 = height-y0
- y1 = height-y1
- try: self.lastrect
- except AttributeError: pass
- else: self.canvas._tkcanvas.delete(self.lastrect)
- self.lastrect = self.canvas._tkcanvas.create_rectangle(x0, y0, x1, y1)
-
- #self.canvas.draw()
-
- def release(self, event):
- try: self.lastrect
- except AttributeError: pass
- else:
- self.canvas._tkcanvas.delete(self.lastrect)
- del self.lastrect
-
- def set_cursor(self, cursor):
- self.window.configure(cursor=cursord[cursor])
-
- def _Button(self, text, file, command, extension='.ppm'):
- img_file = os.path.join(rcParams['datapath'], 'images', file + extension)
- im = Tk.PhotoImage(master=self, file=img_file)
- b = Tk.Button(
- master=self, text=text, padx=2, pady=2, image=im, command=command)
- b._ntimage = im
- b.pack(side=Tk.LEFT)
- return b
-
- def _init_toolbar(self):
- xmin, xmax = self.canvas.figure.bbox.intervalx
- height, width = 50, xmax-xmin
- Tk.Frame.__init__(self, master=self.window,
- width=int(width), height=int(height),
- borderwidth=2)
-
- self.update() # Make axes menu
-
- for text, tooltip_text, image_file, callback in self.toolitems:
- if text is None:
- # spacer, unhandled in Tk
- pass
- else:
- button = self._Button(text=text, file=image_file,
- command=getattr(self, callback))
- if tooltip_text is not None:
- ToolTip.createToolTip(button, tooltip_text)
-
- self.message = Tk.StringVar(master=self)
- self._message_label = Tk.Label(master=self, textvariable=self.message)
- self._message_label.pack(side=Tk.RIGHT)
- self.pack(side=Tk.BOTTOM, fill=Tk.X)
-
-
- def configure_subplots(self):
- toolfig = Figure(figsize=(6,3))
- window = Tk.Tk()
- canvas = FigureCanvasTkAgg(toolfig, master=window)
- toolfig.subplots_adjust(top=0.9)
- tool = SubplotTool(self.canvas.figure, toolfig)
- canvas.show()
- canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
-
- def save_figure(self, *args):
- from six.moves import tkinter_tkfiledialog, tkinter_messagebox
- filetypes = self.canvas.get_supported_filetypes().copy()
- default_filetype = self.canvas.get_default_filetype()
-
- # Tk doesn't provide a way to choose a default filetype,
- # so we just have to put it first
- default_filetype_name = filetypes[default_filetype]
- del filetypes[default_filetype]
-
- sorted_filetypes = list(six.iteritems(filetypes))
- sorted_filetypes.sort()
- sorted_filetypes.insert(0, (default_filetype, default_filetype_name))
-
- tk_filetypes = [
- (name, '*.%s' % ext) for (ext, name) in sorted_filetypes]
-
- # adding a default extension seems to break the
- # asksaveasfilename dialog when you choose various save types
- # from the dropdown. Passing in the empty string seems to
- # work - JDH!
- #defaultextension = self.canvas.get_default_filetype()
- defaultextension = ''
- initialdir = rcParams.get('savefig.directory', '')
- initialdir = os.path.expanduser(initialdir)
- initialfile = self.canvas.get_default_filename()
- fname = tkinter_tkfiledialog.asksaveasfilename(
- master=self.window,
- title='Save the figure',
- filetypes=tk_filetypes,
- defaultextension=defaultextension,
- initialdir=initialdir,
- initialfile=initialfile,
- )
-
- if fname == "" or fname == ():
- return
- else:
- if initialdir == '':
- # explicitly missing key or empty str signals to use cwd
- rcParams['savefig.directory'] = initialdir
- else:
- # save dir for next time
- rcParams['savefig.directory'] = os.path.dirname(six.text_type(fname))
- try:
- # This method will handle the delegation to the correct type
- self.canvas.print_figure(fname)
- except Exception as e:
- tkinter_messagebox.showerror("Error saving file", str(e))
-
- def set_active(self, ind):
- self._ind = ind
- self._active = [ self._axes[i] for i in self._ind ]
-
- def update(self):
- _focus = windowing.FocusManager()
- self._axes = self.canvas.figure.axes
- naxes = len(self._axes)
- #if not hasattr(self, "omenu"):
- # self.set_active(range(naxes))
- # self.omenu = AxisMenu(master=self, naxes=naxes)
- #else:
- # self.omenu.adjust(naxes)
- NavigationToolbar2.update(self)
-
- def dynamic_update(self):
- 'update drawing area only if idle'
- # legacy method; new method is canvas.draw_idle
- self.canvas.draw_idle()
-
-
-class ToolTip(object):
- """
- Tooltip recipe from
- http://www.voidspace.org.uk/python/weblog/arch_d7_2006_07_01.shtml#e387
- """
- @staticmethod
- def createToolTip(widget, text):
- toolTip = ToolTip(widget)
- def enter(event):
- toolTip.showtip(text)
- def leave(event):
- toolTip.hidetip()
- widget.bind('', enter)
- widget.bind('', leave)
-
- def __init__(self, widget):
- self.widget = widget
- self.tipwindow = None
- self.id = None
- self.x = self.y = 0
-
- def showtip(self, text):
- "Display text in tooltip window"
- self.text = text
- if self.tipwindow or not self.text:
- return
- x, y, _, _ = self.widget.bbox("insert")
- x = x + self.widget.winfo_rootx() + 27
- y = y + self.widget.winfo_rooty()
- self.tipwindow = tw = Tk.Toplevel(self.widget)
- tw.wm_overrideredirect(1)
- tw.wm_geometry("+%d+%d" % (x, y))
- try:
- # For Mac OS
- tw.tk.call("::tk::unsupported::MacWindowStyle",
- "style", tw._w,
- "help", "noActivates")
- except Tk.TclError:
- pass
- label = Tk.Label(tw, text=self.text, justify=Tk.LEFT,
- background="#ffffe0", relief=Tk.SOLID, borderwidth=1,
- )
- label.pack(ipadx=1)
-
- def hidetip(self):
- tw = self.tipwindow
- self.tipwindow = None
- if tw:
- tw.destroy()
-
-FigureCanvas = FigureCanvasTkAgg
-FigureManager = FigureManagerTkAgg
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_webagg.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_webagg.py
deleted file mode 100644
index fe03107..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_webagg.py
+++ /dev/null
@@ -1,370 +0,0 @@
-"""
-Displays Agg images in the browser, with interactivity
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-# The WebAgg backend is divided into two modules:
-#
-# - `backend_webagg_core.py` contains code necessary to embed a WebAgg
-# plot inside of a web application, and communicate in an abstract
-# way over a web socket.
-#
-# - `backend_webagg.py` contains a concrete implementation of a basic
-# application, implemented with tornado.
-
-import six
-
-import datetime
-import errno
-import json
-import os
-import random
-import sys
-import socket
-import threading
-
-try:
- import tornado
-except ImportError:
- raise RuntimeError("The WebAgg backend requires Tornado.")
-
-import tornado.web
-import tornado.ioloop
-import tornado.websocket
-
-import matplotlib
-from matplotlib import rcParams
-from matplotlib import backend_bases
-from matplotlib.figure import Figure
-from matplotlib._pylab_helpers import Gcf
-from . import backend_webagg_core as core
-from .backend_nbagg import TimerTornado
-
-
-def new_figure_manager(num, *args, **kwargs):
- """
- Create a new figure manager instance
- """
- FigureClass = kwargs.pop('FigureClass', Figure)
- thisFig = FigureClass(*args, **kwargs)
- return new_figure_manager_given_figure(num, thisFig)
-
-
-def new_figure_manager_given_figure(num, figure):
- """
- Create a new figure manager instance for the given figure.
- """
- canvas = FigureCanvasWebAgg(figure)
- manager = core.FigureManagerWebAgg(canvas, num)
- return manager
-
-
-def draw_if_interactive():
- """
- Is called after every pylab drawing command
- """
- if matplotlib.is_interactive():
- figManager = Gcf.get_active()
- if figManager is not None:
- figManager.canvas.draw_idle()
-
-
-class Show(backend_bases.ShowBase):
- def mainloop(self):
- WebAggApplication.initialize()
-
- url = "http://127.0.0.1:{port}{prefix}".format(
- port=WebAggApplication.port,
- prefix=WebAggApplication.url_prefix)
-
- if rcParams['webagg.open_in_browser']:
- import webbrowser
- webbrowser.open(url)
- else:
- print("To view figure, visit {0}".format(url))
-
- WebAggApplication.start()
-
-
-show = Show().mainloop
-
-
-class ServerThread(threading.Thread):
- def run(self):
- tornado.ioloop.IOLoop.instance().start()
-
-webagg_server_thread = ServerThread()
-
-
-class FigureCanvasWebAgg(core.FigureCanvasWebAggCore):
- def show(self):
- # show the figure window
- show()
-
- def new_timer(self, *args, **kwargs):
- return TimerTornado(*args, **kwargs)
-
- def start_event_loop(self, timeout):
- backend_bases.FigureCanvasBase.start_event_loop_default(
- self, timeout)
- start_event_loop.__doc__ = \
- backend_bases.FigureCanvasBase.start_event_loop_default.__doc__
-
- def stop_event_loop(self):
- backend_bases.FigureCanvasBase.stop_event_loop_default(self)
- stop_event_loop.__doc__ = \
- backend_bases.FigureCanvasBase.stop_event_loop_default.__doc__
-
-
-class WebAggApplication(tornado.web.Application):
- initialized = False
- started = False
-
- class FavIcon(tornado.web.RequestHandler):
- def get(self):
- image_path = os.path.join(
- os.path.dirname(os.path.dirname(__file__)),
- 'mpl-data', 'images')
-
- self.set_header('Content-Type', 'image/png')
- with open(os.path.join(image_path,
- 'matplotlib.png'), 'rb') as fd:
- self.write(fd.read())
-
- class SingleFigurePage(tornado.web.RequestHandler):
- def __init__(self, application, request, **kwargs):
- self.url_prefix = kwargs.pop('url_prefix', '')
- return tornado.web.RequestHandler.__init__(self, application,
- request, **kwargs)
-
- def get(self, fignum):
- fignum = int(fignum)
- manager = Gcf.get_fig_manager(fignum)
-
- ws_uri = 'ws://{req.host}{prefix}/'.format(req=self.request,
- prefix=self.url_prefix)
- self.render(
- "single_figure.html",
- prefix=self.url_prefix,
- ws_uri=ws_uri,
- fig_id=fignum,
- toolitems=core.NavigationToolbar2WebAgg.toolitems,
- canvas=manager.canvas)
-
- class AllFiguresPage(tornado.web.RequestHandler):
- def __init__(self, application, request, **kwargs):
- self.url_prefix = kwargs.pop('url_prefix', '')
- return tornado.web.RequestHandler.__init__(self, application,
- request, **kwargs)
-
- def get(self):
- ws_uri = 'ws://{req.host}{prefix}/'.format(req=self.request,
- prefix=self.url_prefix)
- self.render(
- "all_figures.html",
- prefix=self.url_prefix,
- ws_uri=ws_uri,
- figures=sorted(
- list(Gcf.figs.items()), key=lambda item: item[0]),
- toolitems=core.NavigationToolbar2WebAgg.toolitems)
-
- class MplJs(tornado.web.RequestHandler):
- def get(self):
- self.set_header('Content-Type', 'application/javascript')
-
- js_content = core.FigureManagerWebAgg.get_javascript()
-
- self.write(js_content)
-
- class Download(tornado.web.RequestHandler):
- def get(self, fignum, fmt):
- fignum = int(fignum)
- manager = Gcf.get_fig_manager(fignum)
-
- # TODO: Move this to a central location
- mimetypes = {
- 'ps': 'application/postscript',
- 'eps': 'application/postscript',
- 'pdf': 'application/pdf',
- 'svg': 'image/svg+xml',
- 'png': 'image/png',
- 'jpeg': 'image/jpeg',
- 'tif': 'image/tiff',
- 'emf': 'application/emf'
- }
-
- self.set_header('Content-Type', mimetypes.get(fmt, 'binary'))
-
- buff = six.BytesIO()
- manager.canvas.print_figure(buff, format=fmt)
- self.write(buff.getvalue())
-
- class WebSocket(tornado.websocket.WebSocketHandler):
- supports_binary = True
-
- def open(self, fignum):
- self.fignum = int(fignum)
- self.manager = Gcf.get_fig_manager(self.fignum)
- self.manager.add_web_socket(self)
- if hasattr(self, 'set_nodelay'):
- self.set_nodelay(True)
-
- def on_close(self):
- self.manager.remove_web_socket(self)
-
- def on_message(self, message):
- message = json.loads(message)
- # The 'supports_binary' message is on a client-by-client
- # basis. The others affect the (shared) canvas as a
- # whole.
- if message['type'] == 'supports_binary':
- self.supports_binary = message['value']
- else:
- manager = Gcf.get_fig_manager(self.fignum)
- # It is possible for a figure to be closed,
- # but a stale figure UI is still sending messages
- # from the browser.
- if manager is not None:
- manager.handle_json(message)
-
- def send_json(self, content):
- self.write_message(json.dumps(content))
-
- def send_binary(self, blob):
- if self.supports_binary:
- self.write_message(blob, binary=True)
- else:
- data_uri = "data:image/png;base64,{0}".format(
- blob.encode('base64').replace('\n', ''))
- self.write_message(data_uri)
-
- def __init__(self, url_prefix=''):
- if url_prefix:
- assert url_prefix[0] == '/' and url_prefix[-1] != '/', \
- 'url_prefix must start with a "/" and not end with one.'
-
- super(WebAggApplication, self).__init__(
- [
- # Static files for the CSS and JS
- (url_prefix + r'/_static/(.*)',
- tornado.web.StaticFileHandler,
- {'path': core.FigureManagerWebAgg.get_static_file_path()}),
-
- # An MPL favicon
- (url_prefix + r'/favicon.ico', self.FavIcon),
-
- # The page that contains all of the pieces
- (url_prefix + r'/([0-9]+)', self.SingleFigurePage,
- {'url_prefix': url_prefix}),
-
- # The page that contains all of the figures
- (url_prefix + r'/?', self.AllFiguresPage,
- {'url_prefix': url_prefix}),
-
- (url_prefix + r'/mpl.js', self.MplJs),
-
- # Sends images and events to the browser, and receives
- # events from the browser
- (url_prefix + r'/([0-9]+)/ws', self.WebSocket),
-
- # Handles the downloading (i.e., saving) of static images
- (url_prefix + r'/([0-9]+)/download.([a-z0-9.]+)',
- self.Download),
- ],
- template_path=core.FigureManagerWebAgg.get_static_file_path())
-
- @classmethod
- def initialize(cls, url_prefix='', port=None):
- if cls.initialized:
- return
-
- # Create the class instance
- app = cls(url_prefix=url_prefix)
-
- cls.url_prefix = url_prefix
-
- # This port selection algorithm is borrowed, more or less
- # verbatim, from IPython.
- def random_ports(port, n):
- """
- Generate a list of n random ports near the given port.
-
- The first 5 ports will be sequential, and the remaining n-5 will be
- randomly selected in the range [port-2*n, port+2*n].
- """
- for i in range(min(5, n)):
- yield port + i
- for i in range(n - 5):
- yield port + random.randint(-2 * n, 2 * n)
-
- success = None
- cls.port = rcParams['webagg.port']
- for port in random_ports(cls.port, rcParams['webagg.port_retries']):
- try:
- app.listen(port)
- except socket.error as e:
- if e.errno != errno.EADDRINUSE:
- raise
- else:
- cls.port = port
- success = True
- break
-
- if not success:
- raise SystemExit(
- "The webagg server could not be started because an available "
- "port could not be found")
-
- cls.initialized = True
-
- @classmethod
- def start(cls):
- if cls.started:
- return
-
- # Set the flag to True *before* blocking on IOLoop.instance().start()
- cls.started = True
-
- """
- IOLoop.running() was removed as of Tornado 2.4; see for example
- https://groups.google.com/forum/#!topic/python-tornado/QLMzkpQBGOY
- Thus there is no correct way to check if the loop has already been
- launched. We may end up with two concurrently running loops in that
- unlucky case with all the expected consequences.
- """
- print("Press Ctrl+C to stop WebAgg server")
- sys.stdout.flush()
- try:
- tornado.ioloop.IOLoop.instance().start()
- except KeyboardInterrupt:
- print("Server is stopped")
- sys.stdout.flush()
- finally:
- cls.started = False
-
-
-def ipython_inline_display(figure):
- import tornado.template
-
- WebAggApplication.initialize()
- if not webagg_server_thread.is_alive():
- webagg_server_thread.start()
-
- with open(os.path.join(
- core.FigureManagerWebAgg.get_static_file_path(),
- 'ipython_inline_figure.html')) as fd:
- tpl = fd.read()
-
- fignum = figure.number
-
- t = tornado.template.Template(tpl)
- return t.generate(
- prefix=WebAggApplication.url_prefix,
- fig_id=fignum,
- toolitems=core.NavigationToolbar2WebAgg.toolitems,
- canvas=figure.canvas,
- port=WebAggApplication.port).decode('utf-8')
-
-
-FigureCanvas = FigureCanvasWebAgg
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_webagg_core.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_webagg_core.py
deleted file mode 100644
index 0088183..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_webagg_core.py
+++ /dev/null
@@ -1,517 +0,0 @@
-"""
-Displays Agg images in the browser, with interactivity
-"""
-# The WebAgg backend is divided into two modules:
-#
-# - `backend_webagg_core.py` contains code necessary to embed a WebAgg
-# plot inside of a web application, and communicate in an abstract
-# way over a web socket.
-#
-# - `backend_webagg.py` contains a concrete implementation of a basic
-# application, implemented with tornado.
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import io
-import json
-import os
-import time
-import warnings
-
-import numpy as np
-
-from matplotlib.backends import backend_agg
-from matplotlib.figure import Figure
-from matplotlib import backend_bases
-from matplotlib import _png
-
-
-def new_figure_manager(num, *args, **kwargs):
- """
- Create a new figure manager instance
- """
- FigureClass = kwargs.pop('FigureClass', Figure)
- thisFig = FigureClass(*args, **kwargs)
- return new_figure_manager_given_figure(num, thisFig)
-
-
-def new_figure_manager_given_figure(num, figure):
- """
- Create a new figure manager instance for the given figure.
- """
- canvas = FigureCanvasWebAggCore(figure)
- manager = FigureManagerWebAgg(canvas, num)
- return manager
-
-
-# http://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes
-_SHIFT_LUT = {59: ':',
- 61: '+',
- 173: '_',
- 186: ':',
- 187: '+',
- 188: '<',
- 189: '_',
- 190: '>',
- 191: '?',
- 192: '~',
- 219: '{',
- 220: '|',
- 221: '}',
- 222: '"'}
-
-_LUT = {8: 'backspace',
- 9: 'tab',
- 13: 'enter',
- 16: 'shift',
- 17: 'control',
- 18: 'alt',
- 19: 'pause',
- 20: 'caps',
- 27: 'escape',
- 32: ' ',
- 33: 'pageup',
- 34: 'pagedown',
- 35: 'end',
- 36: 'home',
- 37: 'left',
- 38: 'up',
- 39: 'right',
- 40: 'down',
- 45: 'insert',
- 46: 'delete',
- 91: 'super',
- 92: 'super',
- 93: 'select',
- 106: '*',
- 107: '+',
- 109: '-',
- 110: '.',
- 111: '/',
- 144: 'num_lock',
- 145: 'scroll_lock',
- 186: ':',
- 187: '=',
- 188: ',',
- 189: '-',
- 190: '.',
- 191: '/',
- 192: '`',
- 219: '[',
- 220: '\\',
- 221: ']',
- 222: "'"}
-
-
-def _handle_key(key):
- """Handle key codes"""
- code = int(key[key.index('k') + 1:])
- value = chr(code)
- # letter keys
- if code >= 65 and code <= 90:
- if 'shift+' in key:
- key = key.replace('shift+', '')
- else:
- value = value.lower()
- # number keys
- elif code >= 48 and code <= 57:
- if 'shift+' in key:
- value = ')!@#$%^&*('[int(value)]
- key = key.replace('shift+', '')
- # function keys
- elif code >= 112 and code <= 123:
- value = 'f%s' % (code - 111)
- # number pad keys
- elif code >= 96 and code <= 105:
- value = '%s' % (code - 96)
- # keys with shift alternatives
- elif code in _SHIFT_LUT and 'shift+' in key:
- key = key.replace('shift+', '')
- value = _SHIFT_LUT[code]
- elif code in _LUT:
- value = _LUT[code]
- key = key[:key.index('k')] + value
- return key
-
-
-class FigureCanvasWebAggCore(backend_agg.FigureCanvasAgg):
- supports_blit = False
-
- def __init__(self, *args, **kwargs):
- backend_agg.FigureCanvasAgg.__init__(self, *args, **kwargs)
-
- # A buffer to hold the PNG data for the last frame. This is
- # retained so it can be resent to each client without
- # regenerating it.
- self._png_buffer = io.BytesIO()
-
- # Set to True when the renderer contains data that is newer
- # than the PNG buffer.
- self._png_is_old = True
-
- # Set to True by the `refresh` message so that the next frame
- # sent to the clients will be a full frame.
- self._force_full = True
-
- # Store the current image mode so that at any point, clients can
- # request the information. This should be changed by calling
- # self.set_image_mode(mode) so that the notification can be given
- # to the connected clients.
- self._current_image_mode = 'full'
-
- def show(self):
- # show the figure window
- from matplotlib.pyplot import show
- show()
-
- def draw(self):
- renderer = self.get_renderer(cleared=True)
-
- self._png_is_old = True
-
- backend_agg.RendererAgg.lock.acquire()
- try:
- self.figure.draw(renderer)
- finally:
- backend_agg.RendererAgg.lock.release()
- # Swap the frames
- self.manager.refresh_all()
-
- def draw_idle(self):
- self.send_event("draw")
-
- def set_image_mode(self, mode):
- """
- Set the image mode for any subsequent images which will be sent
- to the clients. The modes may currently be either 'full' or 'diff'.
-
- Note: diff images may not contain transparency, therefore upon
- draw this mode may be changed if the resulting image has any
- transparent component.
-
- """
- if mode not in ['full', 'diff']:
- raise ValueError('image mode must be either full or diff.')
- if self._current_image_mode != mode:
- self._current_image_mode = mode
- self.handle_send_image_mode(None)
-
- def get_diff_image(self):
- if self._png_is_old:
- renderer = self.get_renderer()
-
- # The buffer is created as type uint32 so that entire
- # pixels can be compared in one numpy call, rather than
- # needing to compare each plane separately.
- buff = np.frombuffer(renderer.buffer_rgba(), dtype=np.uint32)
- buff.shape = (renderer.height, renderer.width)
-
- # If any pixels have transparency, we need to force a full
- # draw as we cannot overlay new on top of old.
- pixels = buff.view(dtype=np.uint8).reshape(buff.shape + (4,))
-
- if self._force_full or np.any(pixels[:, :, 3] != 255):
- self.set_image_mode('full')
- output = buff
- else:
- self.set_image_mode('diff')
- last_buffer = np.frombuffer(self._last_renderer.buffer_rgba(),
- dtype=np.uint32)
- last_buffer.shape = (renderer.height, renderer.width)
-
- diff = buff != last_buffer
- output = np.where(diff, buff, 0)
-
- # Clear out the PNG data buffer rather than recreating it
- # each time. This reduces the number of memory
- # (de)allocations.
- self._png_buffer.truncate()
- self._png_buffer.seek(0)
-
- # TODO: We should write a new version of write_png that
- # handles the differencing inline
- _png.write_png(
- output.tostring(),
- output.shape[1], output.shape[0],
- self._png_buffer)
-
- # Swap the renderer frames
- self._renderer, self._last_renderer = (
- self._last_renderer, renderer)
- self._force_full = False
- self._png_is_old = False
- return self._png_buffer.getvalue()
-
- def get_renderer(self, cleared=None):
- # Mirrors super.get_renderer, but caches the old one
- # so that we can do things such as produce a diff image
- # in get_diff_image
- _, _, w, h = self.figure.bbox.bounds
- key = w, h, self.figure.dpi
- try:
- self._lastKey, self._renderer
- except AttributeError:
- need_new_renderer = True
- else:
- need_new_renderer = (self._lastKey != key)
-
- if need_new_renderer:
- self._renderer = backend_agg.RendererAgg(
- w, h, self.figure.dpi)
- self._last_renderer = backend_agg.RendererAgg(
- w, h, self.figure.dpi)
- self._lastKey = key
-
- elif cleared:
- self._renderer.clear()
-
- return self._renderer
-
- def handle_event(self, event):
- e_type = event['type']
- if e_type == 'ack':
- # Network latency tends to decrease if traffic is flowing
- # in both directions. Therefore, the browser sends back
- # an "ack" message after each image frame is received.
- # This could also be used as a simple sanity check in the
- # future, but for now the performance increase is enough
- # to justify it, even if the server does nothing with it.
- pass
- elif e_type == 'draw':
- self.draw()
- elif e_type in ('button_press', 'button_release', 'motion_notify',
- 'figure_enter', 'figure_leave', 'scroll'):
- x = event['x']
- y = event['y']
- y = self.get_renderer().height - y
-
- # Javascript button numbers and matplotlib button numbers are
- # off by 1
- button = event['button'] + 1
-
- # The right mouse button pops up a context menu, which
- # doesn't work very well, so use the middle mouse button
- # instead. It doesn't seem that it's possible to disable
- # the context menu in recent versions of Chrome.
- if button == 2:
- button = 3
-
- if e_type == 'button_press':
- self.button_press_event(x, y, button)
- elif e_type == 'button_release':
- self.button_release_event(x, y, button)
- elif e_type == 'motion_notify':
- self.motion_notify_event(x, y)
- elif e_type == 'figure_enter':
- self.enter_notify_event(xy=(x, y))
- elif e_type == 'figure_leave':
- self.leave_notify_event()
- elif e_type == 'scroll':
- self.scroll_event(x, y, event['step'])
- elif e_type in ('key_press', 'key_release'):
- key = _handle_key(event['key'])
- if e_type == 'key_press':
- self.key_press_event(key)
- elif e_type == 'key_release':
- self.key_release_event(key)
- elif e_type == 'toolbar_button':
- # TODO: Be more suspicious of the input
- getattr(self.toolbar, event['name'])()
- elif e_type == 'refresh':
- figure_label = self.figure.get_label()
- if not figure_label:
- figure_label = "Figure {0}".format(self.manager.num)
- self.send_event('figure_label', label=figure_label)
- self._force_full = True
- self.draw_idle()
- else:
- handler = getattr(self, 'handle_{}'.format(e_type), None)
- if handler is None:
- import warnings
- warnings.warn('Unhandled message type {}. {}'.format(
- e_type, event))
- else:
- return handler(event)
-
- def handle_resize(self, event):
- x, y = event.get('width', 800), event.get('height', 800)
- x, y = int(x), int(y)
- fig = self.figure
- # An attempt at approximating the figure size in pixels.
- fig.set_size_inches(x / fig.dpi, y / fig.dpi)
-
- _, _, w, h = self.figure.bbox.bounds
- # Acknowledge the resize, and force the viewer to update the
- # canvas size to the figure's new size (which is hopefully
- # identical or within a pixel or so).
- self._png_is_old = True
- self.manager.resize(w, h)
- self.resize_event()
-
- def handle_send_image_mode(self, event):
- # The client requests notification of what the current image mode is.
- self.send_event('image_mode', mode=self._current_image_mode)
-
- def send_event(self, event_type, **kwargs):
- self.manager._send_event(event_type, **kwargs)
-
- def start_event_loop(self, timeout):
- backend_bases.FigureCanvasBase.start_event_loop_default(
- self, timeout)
- start_event_loop.__doc__ = \
- backend_bases.FigureCanvasBase.start_event_loop_default.__doc__
-
- def stop_event_loop(self):
- backend_bases.FigureCanvasBase.stop_event_loop_default(self)
- stop_event_loop.__doc__ = \
- backend_bases.FigureCanvasBase.stop_event_loop_default.__doc__
-
-
-_JQUERY_ICON_CLASSES = {
- 'home': 'ui-icon ui-icon-home',
- 'back': 'ui-icon ui-icon-circle-arrow-w',
- 'forward': 'ui-icon ui-icon-circle-arrow-e',
- 'zoom_to_rect': 'ui-icon ui-icon-search',
- 'move': 'ui-icon ui-icon-arrow-4',
- 'download': 'ui-icon ui-icon-disk',
- None: None,
-}
-
-
-class NavigationToolbar2WebAgg(backend_bases.NavigationToolbar2):
-
- # Use the standard toolbar items + download button
- toolitems = [(text, tooltip_text, _JQUERY_ICON_CLASSES[image_file],
- name_of_method)
- for text, tooltip_text, image_file, name_of_method
- in (backend_bases.NavigationToolbar2.toolitems +
- (('Download', 'Download plot', 'download', 'download'),))
- if image_file in _JQUERY_ICON_CLASSES]
-
- def _init_toolbar(self):
- self.message = ''
- self.cursor = 0
-
- def set_message(self, message):
- if message != self.message:
- self.canvas.send_event("message", message=message)
- self.message = message
-
- def set_cursor(self, cursor):
- if cursor != self.cursor:
- self.canvas.send_event("cursor", cursor=cursor)
- self.cursor = cursor
-
- def dynamic_update(self):
- self.canvas.draw_idle()
-
- def draw_rubberband(self, event, x0, y0, x1, y1):
- self.canvas.send_event(
- "rubberband", x0=x0, y0=y0, x1=x1, y1=y1)
-
- def release_zoom(self, event):
- backend_bases.NavigationToolbar2.release_zoom(self, event)
- self.canvas.send_event(
- "rubberband", x0=-1, y0=-1, x1=-1, y1=-1)
-
- def save_figure(self, *args):
- """Save the current figure"""
- self.canvas.send_event('save')
-
-
-class FigureManagerWebAgg(backend_bases.FigureManagerBase):
- ToolbarCls = NavigationToolbar2WebAgg
-
- def __init__(self, canvas, num):
- backend_bases.FigureManagerBase.__init__(self, canvas, num)
-
- self.web_sockets = set()
-
- self.toolbar = self._get_toolbar(canvas)
-
- def show(self):
- pass
-
- def _get_toolbar(self, canvas):
- toolbar = self.ToolbarCls(canvas)
- return toolbar
-
- def resize(self, w, h):
- self._send_event('resize', size=(w, h))
-
- def set_window_title(self, title):
- self._send_event('figure_label', label=title)
-
- # The following methods are specific to FigureManagerWebAgg
-
- def add_web_socket(self, web_socket):
- assert hasattr(web_socket, 'send_binary')
- assert hasattr(web_socket, 'send_json')
-
- self.web_sockets.add(web_socket)
-
- _, _, w, h = self.canvas.figure.bbox.bounds
- self.resize(w, h)
- self._send_event('refresh')
-
- def remove_web_socket(self, web_socket):
- self.web_sockets.remove(web_socket)
-
- def handle_json(self, content):
- self.canvas.handle_event(content)
-
- def refresh_all(self):
- if self.web_sockets:
- diff = self.canvas.get_diff_image()
- for s in self.web_sockets:
- s.send_binary(diff)
-
- @classmethod
- def get_javascript(cls, stream=None):
- if stream is None:
- output = io.StringIO()
- else:
- output = stream
-
- with io.open(os.path.join(
- os.path.dirname(__file__),
- "web_backend",
- "mpl.js"), encoding='utf8') as fd:
- output.write(fd.read())
-
- toolitems = []
- for name, tooltip, image, method in cls.ToolbarCls.toolitems:
- if name is None:
- toolitems.append(['', '', '', ''])
- else:
- toolitems.append([name, tooltip, image, method])
- output.write("mpl.toolbar_items = {0};\n\n".format(
- json.dumps(toolitems)))
-
- extensions = []
- for filetype, ext in sorted(FigureCanvasWebAggCore.
- get_supported_filetypes_grouped().
- items()):
- if not ext[0] == 'pgf': # pgf does not support BytesIO
- extensions.append(ext[0])
- output.write("mpl.extensions = {0};\n\n".format(
- json.dumps(extensions)))
-
- output.write("mpl.default_extension = {0};".format(
- json.dumps(FigureCanvasWebAggCore.get_default_filetype())))
-
- if stream is None:
- return output.getvalue()
-
- @classmethod
- def get_static_file_path(cls):
- return os.path.join(os.path.dirname(__file__), 'web_backend')
-
- def _send_event(self, event_type, **kwargs):
- payload = {'type': event_type}
- payload.update(kwargs)
- for s in self.web_sockets:
- s.send_json(payload)
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_wx.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_wx.py
deleted file mode 100644
index 34c9316..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_wx.py
+++ /dev/null
@@ -1,1870 +0,0 @@
-"""
- A wxPython backend for matplotlib, based (very heavily) on
- backend_template.py and backend_gtk.py
-
- Author: Jeremy O'Donoghue (jeremy@o-donoghue.com)
-
- Derived from original copyright work by John Hunter
- (jdhunter@ace.bsd.uchicago.edu)
-
- Copyright (C) Jeremy O'Donoghue & John Hunter, 2003-4
-
- License: This work is licensed under a PSF compatible license. A copy
- should be included with this source code.
-
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import xrange
-
-import sys
-import os
-import os.path
-import math
-import weakref
-import warnings
-
-import numpy as np
-
-from matplotlib.cbook import mplDeprecation
-
-# Debugging settings here...
-# Debug level set here. If the debug level is less than 5, information
-# messages (progressively more info for lower value) are printed. In addition,
-# traceback is performed, and pdb activated, for all uncaught exceptions in
-# this case
-_DEBUG = 5
-if _DEBUG < 5:
- import traceback, pdb
-_DEBUG_lvls = {1 : 'Low ', 2 : 'Med ', 3 : 'High', 4 : 'Error' }
-
-if six.PY3:
- warnings.warn(
- "The wx and wxagg backends have not been tested with Python 3.x",
- ImportWarning)
-
-missingwx = "Matplotlib backend_wx and backend_wxagg require wxPython >=2.8"
-missingwxversion = ("Matplotlib backend_wx and backend_wxagg "
- "require wxversion, which was not found.")
-
-if not hasattr(sys, 'frozen'): # i.e., not py2exe
- try:
- import wxversion
- except ImportError:
- raise ImportError(missingwxversion)
-
- # Some early versions of wxversion lack AlreadyImportedError.
- # It was added around 2.8.4?
- try:
- _wx_ensure_failed = wxversion.AlreadyImportedError
- except AttributeError:
- _wx_ensure_failed = wxversion.VersionError
-
- try:
- wxversion.ensureMinimal(str('2.8'))
- except _wx_ensure_failed:
- pass
- # We don't really want to pass in case of VersionError, but when
- # AlreadyImportedError is not available, we have to.
-
-try:
- import wx
- backend_version = wx.VERSION_STRING
-except ImportError:
- raise ImportError(missingwx)
-
-# Extra version check in case wxversion lacks AlreadyImportedError;
-# then VersionError might have been raised and ignored when
-# there really *is* a problem with the version.
-major, minor = [int(n) for n in backend_version.split('.')[:2]]
-if major < 2 or (major < 3 and minor < 8):
- print(" wxPython version %s was imported." % backend_version)
- raise ImportError(missingwx)
-
-
-#!!! this is the call that is causing the exception swallowing !!!
-#wx.InitAllImageHandlers()
-
-def DEBUG_MSG(string, lvl=3, o=None):
- if lvl >= _DEBUG:
- cls = o.__class__
- # Jeremy, often times the commented line won't print but the
- # one below does. I think WX is redefining stderr, damned
- # beast
- #print >>sys.stderr, "%s- %s in %s" % (_DEBUG_lvls[lvl], string, cls)
- print("%s- %s in %s" % (_DEBUG_lvls[lvl], string, cls))
-
-def debug_on_error(type, value, tb):
- """Code due to Thomas Heller - published in Python Cookbook (O'Reilley)"""
- traceback.print_exc(type, value, tb)
- print()
- pdb.pm() # jdh uncomment
-
-class fake_stderr:
- """Wx does strange things with stderr, as it makes the assumption that there
- is probably no console. This redirects stderr to the console, since we know
- that there is one!"""
- def write(self, msg):
- print("Stderr: %s\n\r" % msg)
-
-#if _DEBUG < 5:
-# sys.excepthook = debug_on_error
-# WxLogger =wx.LogStderr()
-# sys.stderr = fake_stderr
-
-# Event binding code changed after version 2.5
-if wx.VERSION_STRING >= '2.5':
- def bind(actor,event,action,**kw):
- actor.Bind(event,action,**kw)
-else:
- def bind(actor,event,action,id=None):
- if id is not None:
- event(actor, id, action)
- else:
- event(actor,action)
-
-import matplotlib
-from matplotlib import verbose
-from matplotlib.backend_bases import RendererBase, GraphicsContextBase,\
- FigureCanvasBase, FigureManagerBase, NavigationToolbar2, \
- cursors, TimerBase
-from matplotlib.backend_bases import ShowBase
-from matplotlib.backend_bases import _has_pil
-
-from matplotlib._pylab_helpers import Gcf
-from matplotlib.artist import Artist
-from matplotlib.cbook import exception_to_str, is_string_like, is_writable_file_like
-from matplotlib.figure import Figure
-from matplotlib.path import Path
-from matplotlib.text import _process_text_args, Text
-from matplotlib.transforms import Affine2D
-from matplotlib.widgets import SubplotTool
-from matplotlib import rcParams
-
-# the True dots per inch on the screen; should be display dependent
-# see http://groups.google.com/groups?q=screen+dpi+x11&hl=en&lr=&ie=UTF-8&oe=UTF-8&safe=off&selm=7077.26e81ad5%40swift.cs.tcd.ie&rnum=5 for some info about screen dpi
-PIXELS_PER_INCH = 75
-
-# Delay time for idle checks
-IDLE_DELAY = 5
-
-def error_msg_wx(msg, parent=None):
- """
- Signal an error condition -- in a GUI, popup a error dialog
- """
- dialog =wx.MessageDialog(parent = parent,
- message = msg,
- caption = 'Matplotlib backend_wx error',
- style=wx.OK | wx.CENTRE)
- dialog.ShowModal()
- dialog.Destroy()
- return None
-
-def raise_msg_to_str(msg):
- """msg is a return arg from a raise. Join with new lines"""
- if not is_string_like(msg):
- msg = '\n'.join(map(str, msg))
- return msg
-
-
-class TimerWx(TimerBase):
- '''
- Subclass of :class:`backend_bases.TimerBase` that uses WxTimer events.
-
- Attributes:
- * interval: The time between timer events in milliseconds. Default
- is 1000 ms.
- * single_shot: Boolean flag indicating whether this timer should
- operate as single shot (run once and then stop). Defaults to False.
- * callbacks: Stores list of (func, args) tuples that will be called
- upon timer events. This list can be manipulated directly, or the
- functions add_callback and remove_callback can be used.
- '''
- def __init__(self, parent, *args, **kwargs):
- TimerBase.__init__(self, *args, **kwargs)
-
- # Create a new timer and connect the timer event to our handler.
- # For WX, the events have to use a widget for binding.
- self.parent = parent
- self._timer = wx.Timer(self.parent, wx.NewId())
- self.parent.Bind(wx.EVT_TIMER, self._on_timer, self._timer)
-
- # Unbinding causes Wx to stop for some reason. Disabling for now.
-# def __del__(self):
-# TimerBase.__del__(self)
-# self.parent.Bind(wx.EVT_TIMER, None, self._timer)
-
- def _timer_start(self):
- self._timer.Start(self._interval, self._single)
-
- def _timer_stop(self):
- self._timer.Stop()
-
- def _timer_set_interval(self):
- self._timer_start()
-
- def _timer_set_single_shot(self):
- self._timer.Start()
-
- def _on_timer(self, *args):
- TimerBase._on_timer(self)
-
-
-class RendererWx(RendererBase):
- """
- The renderer handles all the drawing primitives using a graphics
- context instance that controls the colors/styles. It acts as the
- 'renderer' instance used by many classes in the hierarchy.
- """
- #In wxPython, drawing is performed on a wxDC instance, which will
- #generally be mapped to the client aread of the window displaying
- #the plot. Under wxPython, the wxDC instance has a wx.Pen which
- #describes the colour and weight of any lines drawn, and a wxBrush
- #which describes the fill colour of any closed polygon.
-
-
- fontweights = {
- 100 : wx.LIGHT,
- 200 : wx.LIGHT,
- 300 : wx.LIGHT,
- 400 : wx.NORMAL,
- 500 : wx.NORMAL,
- 600 : wx.NORMAL,
- 700 : wx.BOLD,
- 800 : wx.BOLD,
- 900 : wx.BOLD,
- 'ultralight' : wx.LIGHT,
- 'light' : wx.LIGHT,
- 'normal' : wx.NORMAL,
- 'medium' : wx.NORMAL,
- 'semibold' : wx.NORMAL,
- 'bold' : wx.BOLD,
- 'heavy' : wx.BOLD,
- 'ultrabold' : wx.BOLD,
- 'black' : wx.BOLD
- }
- fontangles = {
- 'italic' : wx.ITALIC,
- 'normal' : wx.NORMAL,
- 'oblique' : wx.SLANT }
-
- # wxPython allows for portable font styles, choosing them appropriately
- # for the target platform. Map some standard font names to the portable
- # styles
- # QUESTION: Is it be wise to agree standard fontnames across all backends?
- fontnames = { 'Sans' : wx.SWISS,
- 'Roman' : wx.ROMAN,
- 'Script' : wx.SCRIPT,
- 'Decorative' : wx.DECORATIVE,
- 'Modern' : wx.MODERN,
- 'Courier' : wx.MODERN,
- 'courier' : wx.MODERN }
-
-
- def __init__(self, bitmap, dpi):
- """
- Initialise a wxWindows renderer instance.
- """
- RendererBase.__init__(self)
- DEBUG_MSG("__init__()", 1, self)
- if wx.VERSION_STRING < "2.8":
- raise RuntimeError("matplotlib no longer supports wxPython < 2.8 for the Wx backend.\nYou may, however, use the WxAgg backend.")
- self.width = bitmap.GetWidth()
- self.height = bitmap.GetHeight()
- self.bitmap = bitmap
- self.fontd = {}
- self.dpi = dpi
- self.gc = None
-
- def flipy(self):
- return True
-
- def offset_text_height(self):
- return True
-
- def get_text_width_height_descent(self, s, prop, ismath):
- """
- get the width and height in display coords of the string s
- with FontPropertry prop
- """
- #return 1, 1
- if ismath: s = self.strip_math(s)
-
- if self.gc is None:
- gc = self.new_gc()
- else:
- gc = self.gc
- gfx_ctx = gc.gfx_ctx
- font = self.get_wx_font(s, prop)
- gfx_ctx.SetFont(font, wx.BLACK)
- w, h, descent, leading = gfx_ctx.GetFullTextExtent(s)
-
- return w, h, descent
-
- def get_canvas_width_height(self):
- 'return the canvas width and height in display coords'
- return self.width, self.height
-
- def handle_clip_rectangle(self, gc):
- new_bounds = gc.get_clip_rectangle()
- if new_bounds is not None:
- new_bounds = new_bounds.bounds
- gfx_ctx = gc.gfx_ctx
- if gfx_ctx._lastcliprect != new_bounds:
- gfx_ctx._lastcliprect = new_bounds
- if new_bounds is None:
- gfx_ctx.ResetClip()
- else:
- gfx_ctx.Clip(new_bounds[0], self.height - new_bounds[1] - new_bounds[3],
- new_bounds[2], new_bounds[3])
-
- @staticmethod
- def convert_path(gfx_ctx, path, transform):
- wxpath = gfx_ctx.CreatePath()
- for points, code in path.iter_segments(transform):
- if code == Path.MOVETO:
- wxpath.MoveToPoint(*points)
- elif code == Path.LINETO:
- wxpath.AddLineToPoint(*points)
- elif code == Path.CURVE3:
- wxpath.AddQuadCurveToPoint(*points)
- elif code == Path.CURVE4:
- wxpath.AddCurveToPoint(*points)
- elif code == Path.CLOSEPOLY:
- wxpath.CloseSubpath()
- return wxpath
-
- def draw_path(self, gc, path, transform, rgbFace=None):
- gc.select()
- self.handle_clip_rectangle(gc)
- gfx_ctx = gc.gfx_ctx
- transform = transform + Affine2D().scale(1.0, -1.0).translate(0.0, self.height)
- wxpath = self.convert_path(gfx_ctx, path, transform)
- if rgbFace is not None:
- gfx_ctx.SetBrush(wx.Brush(gc.get_wxcolour(rgbFace)))
- gfx_ctx.DrawPath(wxpath)
- else:
- gfx_ctx.StrokePath(wxpath)
- gc.unselect()
-
- def draw_image(self, gc, x, y, im):
- bbox = gc.get_clip_rectangle()
- if bbox != None:
- l,b,w,h = bbox.bounds
- else:
- l=0
- b=0,
- w=self.width
- h=self.height
- rows, cols, image_str = im.as_rgba_str()
- image_array = np.fromstring(image_str, np.uint8)
- image_array.shape = rows, cols, 4
- bitmap = wx.BitmapFromBufferRGBA(cols,rows,image_array)
- gc = self.get_gc()
- gc.select()
- gc.gfx_ctx.DrawBitmap(bitmap,int(l),int(self.height-b),int(w),int(-h))
- gc.unselect()
-
- def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
- if ismath: s = self.strip_math(s)
- DEBUG_MSG("draw_text()", 1, self)
- gc.select()
- self.handle_clip_rectangle(gc)
- gfx_ctx = gc.gfx_ctx
-
- font = self.get_wx_font(s, prop)
- color = gc.get_wxcolour(gc.get_rgb())
- gfx_ctx.SetFont(font, color)
-
- w, h, d = self.get_text_width_height_descent(s, prop, ismath)
- x = int(x)
- y = int(y-h)
-
- if angle == 0.0:
- gfx_ctx.DrawText(s, x, y)
- else:
- rads = angle / 180.0 * math.pi
- xo = h * math.sin(rads)
- yo = h * math.cos(rads)
- gfx_ctx.DrawRotatedText(s, x - xo, y - yo, rads)
-
- gc.unselect()
-
- def new_gc(self):
- """
- Return an instance of a GraphicsContextWx, and sets the current gc copy
- """
- DEBUG_MSG('new_gc()', 2, self)
- self.gc = GraphicsContextWx(self.bitmap, self)
- self.gc.select()
- self.gc.unselect()
- return self.gc
-
- def get_gc(self):
- """
- Fetch the locally cached gc.
- """
- # This is a dirty hack to allow anything with access to a renderer to
- # access the current graphics context
- assert self.gc != None, "gc must be defined"
- return self.gc
-
- def get_wx_font(self, s, prop):
- """
- Return a wx font. Cache instances in a font dictionary for
- efficiency
- """
- DEBUG_MSG("get_wx_font()", 1, self)
-
-
- key = hash(prop)
- fontprop = prop
- fontname = fontprop.get_name()
-
- font = self.fontd.get(key)
- if font is not None:
- return font
-
- # Allow use of platform independent and dependent font names
- wxFontname = self.fontnames.get(fontname, wx.ROMAN)
- wxFacename = '' # Empty => wxPython chooses based on wx_fontname
-
- # Font colour is determined by the active wx.Pen
- # TODO: It may be wise to cache font information
- size = self.points_to_pixels(fontprop.get_size_in_points())
-
-
- font =wx.Font(int(size+0.5), # Size
- wxFontname, # 'Generic' name
- self.fontangles[fontprop.get_style()], # Angle
- self.fontweights[fontprop.get_weight()], # Weight
- False, # Underline
- wxFacename) # Platform font name
-
- # cache the font and gc and return it
- self.fontd[key] = font
-
- return font
-
- def points_to_pixels(self, points):
- """
- convert point measures to pixes using dpi and the pixels per
- inch of the display
- """
- return points*(PIXELS_PER_INCH/72.0*self.dpi/72.0)
-
-
-class GraphicsContextWx(GraphicsContextBase):
- """
- The graphics context provides the color, line styles, etc...
-
- This class stores a reference to a wxMemoryDC, and a
- wxGraphicsContext that draws to it. Creating a wxGraphicsContext
- seems to be fairly heavy, so these objects are cached based on the
- bitmap object that is passed in.
-
- The base GraphicsContext stores colors as a RGB tuple on the unit
- interval, e.g., (0.5, 0.0, 1.0). wxPython uses an int interval, but
- since wxPython colour management is rather simple, I have not chosen
- to implement a separate colour manager class.
- """
- _capd = { 'butt': wx.CAP_BUTT,
- 'projecting': wx.CAP_PROJECTING,
- 'round': wx.CAP_ROUND }
-
- _joind = { 'bevel': wx.JOIN_BEVEL,
- 'miter': wx.JOIN_MITER,
- 'round': wx.JOIN_ROUND }
-
- _dashd_wx = { 'solid': wx.SOLID,
- 'dashed': wx.SHORT_DASH,
- 'dashdot': wx.DOT_DASH,
- 'dotted': wx.DOT }
- _cache = weakref.WeakKeyDictionary()
-
- def __init__(self, bitmap, renderer):
- GraphicsContextBase.__init__(self)
- #assert self.Ok(), "wxMemoryDC not OK to use"
- DEBUG_MSG("__init__()", 1, self)
-
- dc, gfx_ctx = self._cache.get(bitmap, (None, None))
- if dc is None:
- dc = wx.MemoryDC()
- dc.SelectObject(bitmap)
- gfx_ctx = wx.GraphicsContext.Create(dc)
- gfx_ctx._lastcliprect = None
- self._cache[bitmap] = dc, gfx_ctx
-
- self.bitmap = bitmap
- self.dc = dc
- self.gfx_ctx = gfx_ctx
- self._pen = wx.Pen('BLACK', 1, wx.SOLID)
- gfx_ctx.SetPen(self._pen)
- self._style = wx.SOLID
- self.renderer = renderer
-
- def select(self):
- """
- Select the current bitmap into this wxDC instance
- """
-
- if sys.platform=='win32':
- self.dc.SelectObject(self.bitmap)
- self.IsSelected = True
-
- def unselect(self):
- """
- Select a Null bitmasp into this wxDC instance
- """
- if sys.platform=='win32':
- self.dc.SelectObject(wx.NullBitmap)
- self.IsSelected = False
-
- def set_foreground(self, fg, isRGBA=None):
- """
- Set the foreground color. fg can be a matlab format string, a
- html hex color string, an rgb unit tuple, or a float between 0
- and 1. In the latter case, grayscale is used.
- """
- # Implementation note: wxPython has a separate concept of pen and
- # brush - the brush fills any outline trace left by the pen.
- # Here we set both to the same colour - if a figure is not to be
- # filled, the renderer will set the brush to be transparent
- # Same goes for text foreground...
- DEBUG_MSG("set_foreground()", 1, self)
- self.select()
- GraphicsContextBase.set_foreground(self, fg, isRGBA)
-
- self._pen.SetColour(self.get_wxcolour(self.get_rgb()))
- self.gfx_ctx.SetPen(self._pen)
- self.unselect()
-
- def set_graylevel(self, frac):
- """
- Set the foreground color. fg can be a matlab format string, a
- html hex color string, an rgb unit tuple, or a float between 0
- and 1. In the latter case, grayscale is used.
- """
- DEBUG_MSG("set_graylevel()", 1, self)
- self.select()
- GraphicsContextBase.set_graylevel(self, frac)
- self._pen.SetColour(self.get_wxcolour(self.get_rgb()))
- self.gfx_ctx.SetPen(self._pen)
- self.unselect()
-
- def set_linewidth(self, w):
- """
- Set the line width.
- """
- DEBUG_MSG("set_linewidth()", 1, self)
- self.select()
- if w>0 and w<1: w = 1
- GraphicsContextBase.set_linewidth(self, w)
- lw = int(self.renderer.points_to_pixels(self._linewidth))
- if lw==0: lw = 1
- self._pen.SetWidth(lw)
- self.gfx_ctx.SetPen(self._pen)
- self.unselect()
-
- def set_capstyle(self, cs):
- """
- Set the capstyle as a string in ('butt', 'round', 'projecting')
- """
- DEBUG_MSG("set_capstyle()", 1, self)
- self.select()
- GraphicsContextBase.set_capstyle(self, cs)
- self._pen.SetCap(GraphicsContextWx._capd[self._capstyle])
- self.gfx_ctx.SetPen(self._pen)
- self.unselect()
-
- def set_joinstyle(self, js):
- """
- Set the join style to be one of ('miter', 'round', 'bevel')
- """
- DEBUG_MSG("set_joinstyle()", 1, self)
- self.select()
- GraphicsContextBase.set_joinstyle(self, js)
- self._pen.SetJoin(GraphicsContextWx._joind[self._joinstyle])
- self.gfx_ctx.SetPen(self._pen)
- self.unselect()
-
- def set_linestyle(self, ls):
- """
- Set the line style to be one of
- """
- DEBUG_MSG("set_linestyle()", 1, self)
- self.select()
- GraphicsContextBase.set_linestyle(self, ls)
- try:
- self._style = GraphicsContextWx._dashd_wx[ls]
- except KeyError:
- self._style = wx.LONG_DASH# Style not used elsewhere...
-
- # On MS Windows platform, only line width of 1 allowed for dash lines
- if wx.Platform == '__WXMSW__':
- self.set_linewidth(1)
-
- self._pen.SetStyle(self._style)
- self.gfx_ctx.SetPen(self._pen)
- self.unselect()
-
- def get_wxcolour(self, color):
- """return a wx.Colour from RGB format"""
- DEBUG_MSG("get_wx_color()", 1, self)
- if len(color) == 3:
- r, g, b = color
- r *= 255
- g *= 255
- b *= 255
- return wx.Colour(red=int(r), green=int(g), blue=int(b))
- else:
- r, g, b, a = color
- r *= 255
- g *= 255
- b *= 255
- a *= 255
- return wx.Colour(red=int(r), green=int(g), blue=int(b), alpha=int(a))
-
-
-class FigureCanvasWx(FigureCanvasBase, wx.Panel):
- """
- The FigureCanvas contains the figure and does event handling.
-
- In the wxPython backend, it is derived from wxPanel, and (usually) lives
- inside a frame instantiated by a FigureManagerWx. The parent window probably
- implements a wx.Sizer to control the displayed control size - but we give a
- hint as to our preferred minimum size.
- """
-
- keyvald = {
- wx.WXK_CONTROL : 'control',
- wx.WXK_SHIFT : 'shift',
- wx.WXK_ALT : 'alt',
- wx.WXK_LEFT : 'left',
- wx.WXK_UP : 'up',
- wx.WXK_RIGHT : 'right',
- wx.WXK_DOWN : 'down',
- wx.WXK_ESCAPE : 'escape',
- wx.WXK_F1 : 'f1',
- wx.WXK_F2 : 'f2',
- wx.WXK_F3 : 'f3',
- wx.WXK_F4 : 'f4',
- wx.WXK_F5 : 'f5',
- wx.WXK_F6 : 'f6',
- wx.WXK_F7 : 'f7',
- wx.WXK_F8 : 'f8',
- wx.WXK_F9 : 'f9',
- wx.WXK_F10 : 'f10',
- wx.WXK_F11 : 'f11',
- wx.WXK_F12 : 'f12',
- wx.WXK_SCROLL : 'scroll_lock',
- wx.WXK_PAUSE : 'break',
- wx.WXK_BACK : 'backspace',
- wx.WXK_RETURN : 'enter',
- wx.WXK_INSERT : 'insert',
- wx.WXK_DELETE : 'delete',
- wx.WXK_HOME : 'home',
- wx.WXK_END : 'end',
- wx.WXK_PRIOR : 'pageup',
- wx.WXK_NEXT : 'pagedown',
- wx.WXK_PAGEUP : 'pageup',
- wx.WXK_PAGEDOWN : 'pagedown',
- wx.WXK_NUMPAD0 : '0',
- wx.WXK_NUMPAD1 : '1',
- wx.WXK_NUMPAD2 : '2',
- wx.WXK_NUMPAD3 : '3',
- wx.WXK_NUMPAD4 : '4',
- wx.WXK_NUMPAD5 : '5',
- wx.WXK_NUMPAD6 : '6',
- wx.WXK_NUMPAD7 : '7',
- wx.WXK_NUMPAD8 : '8',
- wx.WXK_NUMPAD9 : '9',
- wx.WXK_NUMPAD_ADD : '+',
- wx.WXK_NUMPAD_SUBTRACT : '-',
- wx.WXK_NUMPAD_MULTIPLY : '*',
- wx.WXK_NUMPAD_DIVIDE : '/',
- wx.WXK_NUMPAD_DECIMAL : 'dec',
- wx.WXK_NUMPAD_ENTER : 'enter',
- wx.WXK_NUMPAD_UP : 'up',
- wx.WXK_NUMPAD_RIGHT : 'right',
- wx.WXK_NUMPAD_DOWN : 'down',
- wx.WXK_NUMPAD_LEFT : 'left',
- wx.WXK_NUMPAD_PRIOR : 'pageup',
- wx.WXK_NUMPAD_NEXT : 'pagedown',
- wx.WXK_NUMPAD_PAGEUP : 'pageup',
- wx.WXK_NUMPAD_PAGEDOWN : 'pagedown',
- wx.WXK_NUMPAD_HOME : 'home',
- wx.WXK_NUMPAD_END : 'end',
- wx.WXK_NUMPAD_INSERT : 'insert',
- wx.WXK_NUMPAD_DELETE : 'delete',
- }
-
- def __init__(self, parent, id, figure):
- """
- Initialise a FigureWx instance.
-
- - Initialise the FigureCanvasBase and wxPanel parents.
- - Set event handlers for:
- EVT_SIZE (Resize event)
- EVT_PAINT (Paint event)
- """
-
- FigureCanvasBase.__init__(self, figure)
- # Set preferred window size hint - helps the sizer (if one is
- # connected)
- l,b,w,h = figure.bbox.bounds
- w = int(math.ceil(w))
- h = int(math.ceil(h))
-
- wx.Panel.__init__(self, parent, id, size=wx.Size(w, h))
-
- def do_nothing(*args, **kwargs):
- warnings.warn('could not find a setinitialsize function for backend_wx; please report your wxpython version=%s to the matplotlib developers list'%backend_version)
- pass
-
- # try to find the set size func across wx versions
- try:
- getattr(self, 'SetInitialSize')
- except AttributeError:
- self.SetInitialSize = getattr(self, 'SetBestFittingSize', do_nothing)
-
-
- if not hasattr(self,'IsShownOnScreen'):
- self.IsShownOnScreen = getattr(self, 'IsVisible', lambda *args: True)
-
-
- # Create the drawing bitmap
- self.bitmap =wx.EmptyBitmap(w, h)
- DEBUG_MSG("__init__() - bitmap w:%d h:%d" % (w,h), 2, self)
- # TODO: Add support for 'point' inspection and plot navigation.
- self._isDrawn = False
-
- bind(self, wx.EVT_SIZE, self._onSize)
- bind(self, wx.EVT_PAINT, self._onPaint)
- bind(self, wx.EVT_ERASE_BACKGROUND, self._onEraseBackground)
- bind(self, wx.EVT_KEY_DOWN, self._onKeyDown)
- bind(self, wx.EVT_KEY_UP, self._onKeyUp)
- bind(self, wx.EVT_RIGHT_DOWN, self._onRightButtonDown)
- bind(self, wx.EVT_RIGHT_DCLICK, self._onRightButtonDClick)
- bind(self, wx.EVT_RIGHT_UP, self._onRightButtonUp)
- bind(self, wx.EVT_MOUSEWHEEL, self._onMouseWheel)
- bind(self, wx.EVT_LEFT_DOWN, self._onLeftButtonDown)
- bind(self, wx.EVT_LEFT_DCLICK, self._onLeftButtonDClick)
- bind(self, wx.EVT_LEFT_UP, self._onLeftButtonUp)
- bind(self, wx.EVT_MOTION, self._onMotion)
- bind(self, wx.EVT_LEAVE_WINDOW, self._onLeave)
- bind(self, wx.EVT_ENTER_WINDOW, self._onEnter)
- bind(self, wx.EVT_IDLE, self._onIdle)
- #Add middle button events
- bind(self, wx.EVT_MIDDLE_DOWN, self._onMiddleButtonDown)
- bind(self, wx.EVT_MIDDLE_DCLICK, self._onMiddleButtonDClick)
- bind(self, wx.EVT_MIDDLE_UP, self._onMiddleButtonUp)
-
- self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
-
- self.macros = {} # dict from wx id to seq of macros
-
- # printer attributes and methods deprecated, 2010/06/19
- self._printerData = None
- self._printerPageData = None
- self.printer_width = 5.5
- self.printer_margin = 0.5
-
- def Destroy(self, *args, **kwargs):
- wx.Panel.Destroy(self, *args, **kwargs)
-
-
- def Copy_to_Clipboard(self, event=None):
- "copy bitmap of canvas to system clipboard"
- bmp_obj = wx.BitmapDataObject()
- bmp_obj.SetBitmap(self.bitmap)
-
- if not wx.TheClipboard.IsOpened():
- open_success = wx.TheClipboard.Open()
- if open_success:
- wx.TheClipboard.SetData(bmp_obj)
- wx.TheClipboard.Close()
- wx.TheClipboard.Flush()
-
- def draw_idle(self):
- """
- Delay rendering until the GUI is idle.
- """
- DEBUG_MSG("draw_idle()", 1, self)
- self._isDrawn = False # Force redraw
-
- # Triggering a paint event is all that is needed to defer drawing
- # until later. The platform will send the event when it thinks it is
- # a good time (usually as soon as there are no other events pending).
- self.Refresh(eraseBackground=False)
-
- def draw(self, drawDC=None):
- """
- Render the figure using RendererWx instance renderer, or using a
- previously defined renderer if none is specified.
- """
- DEBUG_MSG("draw()", 1, self)
- self.renderer = RendererWx(self.bitmap, self.figure.dpi)
- self.figure.draw(self.renderer)
- self._isDrawn = True
- self.gui_repaint(drawDC=drawDC)
-
- def new_timer(self, *args, **kwargs):
- """
- Creates a new backend-specific subclass of :class:`backend_bases.Timer`.
- This is useful for getting periodic events through the backend's native
- event loop. Implemented only for backends with GUIs.
-
- optional arguments:
-
- *interval*
- Timer interval in milliseconds
- *callbacks*
- Sequence of (func, args, kwargs) where func(*args, **kwargs) will
- be executed by the timer every *interval*.
- """
- return TimerWx(self, *args, **kwargs)
-
- def flush_events(self):
- wx.Yield()
-
- def start_event_loop(self, timeout=0):
- """
- Start an event loop. This is used to start a blocking event
- loop so that interactive functions, such as ginput and
- waitforbuttonpress, can wait for events. This should not be
- confused with the main GUI event loop, which is always running
- and has nothing to do with this.
-
- Call signature::
-
- start_event_loop(self,timeout=0)
-
- This call blocks until a callback function triggers
- stop_event_loop() or *timeout* is reached. If *timeout* is
- <=0, never timeout.
-
- Raises RuntimeError if event loop is already running.
- """
- if hasattr(self, '_event_loop'):
- raise RuntimeError("Event loop already running")
- id = wx.NewId()
- timer = wx.Timer(self, id=id)
- if timeout > 0:
- timer.Start(timeout*1000, oneShot=True)
- bind(self, wx.EVT_TIMER, self.stop_event_loop, id=id)
-
- # Event loop handler for start/stop event loop
- self._event_loop = wx.EventLoop()
- self._event_loop.Run()
- timer.Stop()
-
- def stop_event_loop(self, event=None):
- """
- Stop an event loop. This is used to stop a blocking event
- loop so that interactive functions, such as ginput and
- waitforbuttonpress, can wait for events.
-
- Call signature::
-
- stop_event_loop_default(self)
- """
- if hasattr(self,'_event_loop'):
- if self._event_loop.IsRunning():
- self._event_loop.Exit()
- del self._event_loop
-
-
- def _get_imagesave_wildcards(self):
- 'return the wildcard string for the filesave dialog'
- default_filetype = self.get_default_filetype()
- filetypes = self.get_supported_filetypes_grouped()
- sorted_filetypes = list(six.iteritems(filetypes))
- sorted_filetypes.sort()
- wildcards = []
- extensions = []
- filter_index = 0
- for i, (name, exts) in enumerate(sorted_filetypes):
- ext_list = ';'.join(['*.%s' % ext for ext in exts])
- extensions.append(exts[0])
- wildcard = '%s (%s)|%s' % (name, ext_list, ext_list)
- if default_filetype in exts:
- filter_index = i
- wildcards.append(wildcard)
- wildcards = '|'.join(wildcards)
- return wildcards, extensions, filter_index
-
- def gui_repaint(self, drawDC=None):
- """
- Performs update of the displayed image on the GUI canvas, using the
- supplied device context. If drawDC is None, a ClientDC will be used to
- redraw the image.
- """
- DEBUG_MSG("gui_repaint()", 1, self)
- if self.IsShownOnScreen():
- if drawDC is None:
- drawDC=wx.ClientDC(self)
-
- drawDC.BeginDrawing()
- drawDC.DrawBitmap(self.bitmap, 0, 0)
- drawDC.EndDrawing()
- #wx.GetApp().Yield()
- else:
- pass
-
- filetypes = FigureCanvasBase.filetypes.copy()
- filetypes['bmp'] = 'Windows bitmap'
- filetypes['jpeg'] = 'JPEG'
- filetypes['jpg'] = 'JPEG'
- filetypes['pcx'] = 'PCX'
- filetypes['png'] = 'Portable Network Graphics'
- filetypes['tif'] = 'Tagged Image Format File'
- filetypes['tiff'] = 'Tagged Image Format File'
- filetypes['xpm'] = 'X pixmap'
-
- def print_figure(self, filename, *args, **kwargs):
- # Use pure Agg renderer to draw
- FigureCanvasBase.print_figure(self, filename, *args, **kwargs)
- # Restore the current view; this is needed because the
- # artist contains methods rely on particular attributes
- # of the rendered figure for determining things like
- # bounding boxes.
- if self._isDrawn:
- self.draw()
-
- def print_bmp(self, filename, *args, **kwargs):
- return self._print_image(filename, wx.BITMAP_TYPE_BMP, *args, **kwargs)
-
- if not _has_pil:
- def print_jpeg(self, filename, *args, **kwargs):
- return self._print_image(filename, wx.BITMAP_TYPE_JPEG, *args, **kwargs)
- print_jpg = print_jpeg
-
- def print_pcx(self, filename, *args, **kwargs):
- return self._print_image(filename, wx.BITMAP_TYPE_PCX, *args, **kwargs)
-
- def print_png(self, filename, *args, **kwargs):
- return self._print_image(filename, wx.BITMAP_TYPE_PNG, *args, **kwargs)
-
- if not _has_pil:
- def print_tiff(self, filename, *args, **kwargs):
- return self._print_image(filename, wx.BITMAP_TYPE_TIF, *args, **kwargs)
- print_tif = print_tiff
-
- def print_xpm(self, filename, *args, **kwargs):
- return self._print_image(filename, wx.BITMAP_TYPE_XPM, *args, **kwargs)
-
- def _print_image(self, filename, filetype, *args, **kwargs):
- origBitmap = self.bitmap
-
- l,b,width,height = self.figure.bbox.bounds
- width = int(math.ceil(width))
- height = int(math.ceil(height))
-
- self.bitmap = wx.EmptyBitmap(width, height)
- renderer = RendererWx(self.bitmap, self.figure.dpi)
-
- gc = renderer.new_gc()
-
- self.figure.draw(renderer)
-
- # image is the object that we call SaveFile on.
- image = self.bitmap
- # set the JPEG quality appropriately. Unfortunately, it is only possible
- # to set the quality on a wx.Image object. So if we are saving a JPEG,
- # convert the wx.Bitmap to a wx.Image, and set the quality.
- if filetype == wx.BITMAP_TYPE_JPEG:
- jpeg_quality = kwargs.get('quality',rcParams['savefig.jpeg_quality'])
- image = self.bitmap.ConvertToImage()
- image.SetOption(wx.IMAGE_OPTION_QUALITY,str(jpeg_quality))
-
- # Now that we have rendered into the bitmap, save it
- # to the appropriate file type and clean up
- if is_string_like(filename):
- if not image.SaveFile(filename, filetype):
- DEBUG_MSG('print_figure() file save error', 4, self)
- raise RuntimeError('Could not save figure to %s\n' % (filename))
- elif is_writable_file_like(filename):
- if not isinstance(image,wx.Image):
- image = image.ConvertToImage()
- if not image.SaveStream(filename, filetype):
- DEBUG_MSG('print_figure() file save error', 4, self)
- raise RuntimeError('Could not save figure to %s\n' % (filename))
-
- # Restore everything to normal
- self.bitmap = origBitmap
-
- # Note: draw is required here since bits of state about the
- # last renderer are strewn about the artist draw methods. Do
- # not remove the draw without first verifying that these have
- # been cleaned up. The artist contains() methods will fail
- # otherwise.
- if self._isDrawn:
- self.draw()
- self.Refresh()
-
- def _onPaint(self, evt):
- """
- Called when wxPaintEvt is generated
- """
-
- DEBUG_MSG("_onPaint()", 1, self)
- drawDC = wx.PaintDC(self)
- if not self._isDrawn:
- self.draw(drawDC=drawDC)
- else:
- self.gui_repaint(drawDC=drawDC)
- evt.Skip()
-
- def _onEraseBackground(self, evt):
- """
- Called when window is redrawn; since we are blitting the entire
- image, we can leave this blank to suppress flicker.
- """
- pass
-
- def _onSize(self, evt):
- """
- Called when wxEventSize is generated.
-
- In this application we attempt to resize to fit the window, so it
- is better to take the performance hit and redraw the whole window.
- """
-
- DEBUG_MSG("_onSize()", 2, self)
- # Create a new, correctly sized bitmap
- self._width, self._height = self.GetClientSize()
- self.bitmap =wx.EmptyBitmap(self._width, self._height)
- self._isDrawn = False
-
- if self._width <= 1 or self._height <= 1: return # Empty figure
-
- dpival = self.figure.dpi
- winch = self._width/dpival
- hinch = self._height/dpival
- self.figure.set_size_inches(winch, hinch)
-
- # Rendering will happen on the associated paint event
- # so no need to do anything here except to make sure
- # the whole background is repainted.
- self.Refresh(eraseBackground=False)
- FigureCanvasBase.resize_event(self)
-
- def _get_key(self, evt):
-
- keyval = evt.m_keyCode
- if keyval in self.keyvald:
- key = self.keyvald[keyval]
- elif keyval < 256:
- key = chr(keyval)
- # wx always returns an uppercase, so make it lowercase if the shift
- # key is not depressed (NOTE: this will not handle Caps Lock)
- if not evt.ShiftDown():
- key = key.lower()
- else:
- key = None
-
- for meth, prefix in (
- [evt.AltDown, 'alt'],
- [evt.ControlDown, 'ctrl'], ):
- if meth():
- key = '{0}+{1}'.format(prefix, key)
-
- return key
-
- def _onIdle(self, evt):
- 'a GUI idle event'
- evt.Skip()
- FigureCanvasBase.idle_event(self, guiEvent=evt)
-
- def _onKeyDown(self, evt):
- """Capture key press."""
- key = self._get_key(evt)
- evt.Skip()
- FigureCanvasBase.key_press_event(self, key, guiEvent=evt)
-
- def _onKeyUp(self, evt):
- """Release key."""
- key = self._get_key(evt)
- #print 'release key', key
- evt.Skip()
- FigureCanvasBase.key_release_event(self, key, guiEvent=evt)
-
- def _onRightButtonDown(self, evt):
- """Start measuring on an axis."""
- x = evt.GetX()
- y = self.figure.bbox.height - evt.GetY()
- evt.Skip()
- self.CaptureMouse()
- FigureCanvasBase.button_press_event(self, x, y, 3, guiEvent=evt)
-
- def _onRightButtonDClick(self, evt):
- """Start measuring on an axis."""
- x = evt.GetX()
- y = self.figure.bbox.height - evt.GetY()
- evt.Skip()
- self.CaptureMouse()
- FigureCanvasBase.button_press_event(self, x, y, 3, dblclick=True,guiEvent=evt)
-
- def _onRightButtonUp(self, evt):
- """End measuring on an axis."""
- x = evt.GetX()
- y = self.figure.bbox.height - evt.GetY()
- evt.Skip()
- if self.HasCapture(): self.ReleaseMouse()
- FigureCanvasBase.button_release_event(self, x, y, 3, guiEvent=evt)
-
- def _onLeftButtonDown(self, evt):
- """Start measuring on an axis."""
- x = evt.GetX()
- y = self.figure.bbox.height - evt.GetY()
- evt.Skip()
- self.CaptureMouse()
- FigureCanvasBase.button_press_event(self, x, y, 1, guiEvent=evt)
-
- def _onLeftButtonDClick(self, evt):
- """Start measuring on an axis."""
- x = evt.GetX()
- y = self.figure.bbox.height - evt.GetY()
- evt.Skip()
- self.CaptureMouse()
- FigureCanvasBase.button_press_event(self, x, y, 1, dblclick=True, guiEvent=evt)
-
- def _onLeftButtonUp(self, evt):
- """End measuring on an axis."""
- x = evt.GetX()
- y = self.figure.bbox.height - evt.GetY()
- #print 'release button', 1
- evt.Skip()
- if self.HasCapture(): self.ReleaseMouse()
- FigureCanvasBase.button_release_event(self, x, y, 1, guiEvent=evt)
-
- #Add middle button events
- def _onMiddleButtonDown(self, evt):
- """Start measuring on an axis."""
- x = evt.GetX()
- y = self.figure.bbox.height - evt.GetY()
- evt.Skip()
- self.CaptureMouse()
- FigureCanvasBase.button_press_event(self, x, y, 2, guiEvent=evt)
-
- def _onMiddleButtonDClick(self, evt):
- """Start measuring on an axis."""
- x = evt.GetX()
- y = self.figure.bbox.height - evt.GetY()
- evt.Skip()
- self.CaptureMouse()
- FigureCanvasBase.button_press_event(self, x, y, 2, dblclick=True, guiEvent=evt)
-
- def _onMiddleButtonUp(self, evt):
- """End measuring on an axis."""
- x = evt.GetX()
- y = self.figure.bbox.height - evt.GetY()
- #print 'release button', 1
- evt.Skip()
- if self.HasCapture(): self.ReleaseMouse()
- FigureCanvasBase.button_release_event(self, x, y, 2, guiEvent=evt)
-
- def _onMouseWheel(self, evt):
- """Translate mouse wheel events into matplotlib events"""
-
- # Determine mouse location
- x = evt.GetX()
- y = self.figure.bbox.height - evt.GetY()
-
- # Convert delta/rotation/rate into a floating point step size
- delta = evt.GetWheelDelta()
- rotation = evt.GetWheelRotation()
- rate = evt.GetLinesPerAction()
- #print "delta,rotation,rate",delta,rotation,rate
- step = rate*float(rotation)/delta
-
- # Done handling event
- evt.Skip()
-
- # Mac is giving two events for every wheel event
- # Need to skip every second one
- if wx.Platform == '__WXMAC__':
- if not hasattr(self,'_skipwheelevent'):
- self._skipwheelevent = True
- elif self._skipwheelevent:
- self._skipwheelevent = False
- return # Return without processing event
- else:
- self._skipwheelevent = True
-
- # Convert to mpl event
- FigureCanvasBase.scroll_event(self, x, y, step, guiEvent=evt)
-
- def _onMotion(self, evt):
- """Start measuring on an axis."""
-
- x = evt.GetX()
- y = self.figure.bbox.height - evt.GetY()
- evt.Skip()
- FigureCanvasBase.motion_notify_event(self, x, y, guiEvent=evt)
-
- def _onLeave(self, evt):
- """Mouse has left the window."""
-
- evt.Skip()
- FigureCanvasBase.leave_notify_event(self, guiEvent = evt)
-
- def _onEnter(self, evt):
- """Mouse has entered the window."""
- FigureCanvasBase.enter_notify_event(self, guiEvent = evt)
-
-
-########################################################################
-#
-# The following functions and classes are for pylab compatibility
-# mode (matplotlib.pylab) and implement figure managers, etc...
-#
-########################################################################
-
-
-def _create_wx_app():
- """
- Creates a wx.App instance if it has not been created sofar.
- """
- wxapp = wx.GetApp()
- if wxapp is None:
- wxapp = wx.App(False)
- wxapp.SetExitOnFrameDelete(True)
- # retain a reference to the app object so it does not get garbage
- # collected and cause segmentation faults
- _create_wx_app.theWxApp = wxapp
-
-
-def draw_if_interactive():
- """
- This should be overriden in a windowing environment if drawing
- should be done in interactive python mode
- """
- DEBUG_MSG("draw_if_interactive()", 1, None)
-
- if matplotlib.is_interactive():
-
- figManager = Gcf.get_active()
- if figManager is not None:
- figManager.canvas.draw_idle()
-
-class Show(ShowBase):
- def mainloop(self):
- needmain = not wx.App.IsMainLoopRunning()
- if needmain:
- wxapp = wx.GetApp()
- if wxapp is not None:
- wxapp.MainLoop()
-
-show = Show()
-
-def new_figure_manager(num, *args, **kwargs):
- """
- Create a new figure manager instance
- """
- # in order to expose the Figure constructor to the pylab
- # interface we need to create the figure here
- DEBUG_MSG("new_figure_manager()", 3, None)
- _create_wx_app()
-
- FigureClass = kwargs.pop('FigureClass', Figure)
- fig = FigureClass(*args, **kwargs)
- return new_figure_manager_given_figure(num, fig)
-
-
-def new_figure_manager_given_figure(num, figure):
- """
- Create a new figure manager instance for the given figure.
- """
- fig = figure
- frame = FigureFrameWx(num, fig)
- figmgr = frame.get_figure_manager()
- if matplotlib.is_interactive():
- figmgr.frame.Show()
-
- return figmgr
-
-
-class FigureFrameWx(wx.Frame):
- def __init__(self, num, fig):
- # On non-Windows platform, explicitly set the position - fix
- # positioning bug on some Linux platforms
- if wx.Platform == '__WXMSW__':
- pos = wx.DefaultPosition
- else:
- pos =wx.Point(20,20)
- l,b,w,h = fig.bbox.bounds
- wx.Frame.__init__(self, parent=None, id=-1, pos=pos,
- title="Figure %d" % num)
- # Frame will be sized later by the Fit method
- DEBUG_MSG("__init__()", 1, self)
- self.num = num
-
- statbar = StatusBarWx(self)
- self.SetStatusBar(statbar)
- self.canvas = self.get_canvas(fig)
- self.canvas.SetInitialSize(wx.Size(fig.bbox.width, fig.bbox.height))
- self.canvas.SetFocus()
- self.sizer =wx.BoxSizer(wx.VERTICAL)
- self.sizer.Add(self.canvas, 1, wx.TOP | wx.LEFT | wx.EXPAND)
- # By adding toolbar in sizer, we are able to put it at the bottom
- # of the frame - so appearance is closer to GTK version
-
- self.toolbar = self._get_toolbar(statbar)
-
- if self.toolbar is not None:
- self.toolbar.Realize()
- # On Windows platform, default window size is incorrect, so set
- # toolbar width to figure width.
- tw, th = self.toolbar.GetSizeTuple()
- fw, fh = self.canvas.GetSizeTuple()
- # By adding toolbar in sizer, we are able to put it at the bottom
- # of the frame - so appearance is closer to GTK version.
- self.toolbar.SetSize(wx.Size(fw, th))
- self.sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND)
- self.SetSizer(self.sizer)
- self.Fit()
-
- self.canvas.SetMinSize((2, 2))
-
- # give the window a matplotlib icon rather than the stock one.
- # This is not currently working on Linux and is untested elsewhere.
- #icon_path = os.path.join(matplotlib.rcParams['datapath'],
- # 'images', 'matplotlib.png')
- #icon = wx.IconFromBitmap(wx.Bitmap(icon_path))
- # for xpm type icons try:
- #icon = wx.Icon(icon_path, wx.BITMAP_TYPE_XPM)
- #self.SetIcon(icon)
-
- self.figmgr = FigureManagerWx(self.canvas, num, self)
-
- bind(self, wx.EVT_CLOSE, self._onClose)
-
- def _get_toolbar(self, statbar):
- if rcParams['toolbar']=='toolbar2':
- toolbar = NavigationToolbar2Wx(self.canvas)
- toolbar.set_status_bar(statbar)
- else:
- toolbar = None
- return toolbar
-
- def get_canvas(self, fig):
- return FigureCanvasWx(self, -1, fig)
-
- def get_figure_manager(self):
- DEBUG_MSG("get_figure_manager()", 1, self)
- return self.figmgr
-
- def _onClose(self, evt):
- DEBUG_MSG("onClose()", 1, self)
- self.canvas.close_event()
- self.canvas.stop_event_loop()
- Gcf.destroy(self.num)
- #self.Destroy()
-
- def GetToolBar(self):
- """Override wxFrame::GetToolBar as we don't have managed toolbar"""
- return self.toolbar
-
- def Destroy(self, *args, **kwargs):
- try:
- self.canvas.mpl_disconnect(self.toolbar._idDrag)
- # Rationale for line above: see issue 2941338.
- except AttributeError:
- pass # classic toolbar lacks the attribute
- wx.Frame.Destroy(self, *args, **kwargs)
- if self.toolbar is not None:
- self.toolbar.Destroy()
- wxapp = wx.GetApp()
- if wxapp:
- wxapp.Yield()
- return True
-
-
-class FigureManagerWx(FigureManagerBase):
- """
- This class contains the FigureCanvas and GUI frame
-
- It is instantiated by GcfWx whenever a new figure is created. GcfWx is
- responsible for managing multiple instances of FigureManagerWx.
-
- public attrs
-
- canvas - a FigureCanvasWx(wx.Panel) instance
- window - a wxFrame instance - http://www.lpthe.jussieu.fr/~zeitlin/wxWindows/docs/wxwin_wxframe.html#wxframe
- """
- def __init__(self, canvas, num, frame):
- DEBUG_MSG("__init__()", 1, self)
- FigureManagerBase.__init__(self, canvas, num)
- self.frame = frame
- self.window = frame
-
- self.tb = frame.GetToolBar()
- self.toolbar = self.tb # consistent with other backends
- def notify_axes_change(fig):
- 'this will be called whenever the current axes is changed'
- if self.tb != None: self.tb.update()
- self.canvas.figure.add_axobserver(notify_axes_change)
-
- def show(self):
- self.frame.Show()
-
- def destroy(self, *args):
- DEBUG_MSG("destroy()", 1, self)
- self.frame.Destroy()
- #if self.tb is not None: self.tb.Destroy()
- #wx.GetApp().ProcessIdle()
- wx.WakeUpIdle()
-
- def get_window_title(self):
- return self.window.GetTitle()
-
- def set_window_title(self, title):
- self.window.SetTitle(title)
-
- def resize(self, width, height):
- 'Set the canvas size in pixels'
- self.canvas.SetInitialSize(wx.Size(width, height))
- self.window.GetSizer().Fit(self.window)
-
-# Identifiers for toolbar controls - images_wx contains bitmaps for the images
-# used in the controls. wxWindows does not provide any stock images, so I've
-# 'stolen' those from GTK2, and transformed them into the appropriate format.
-#import images_wx
-
-_NTB_AXISMENU =wx.NewId()
-_NTB_AXISMENU_BUTTON =wx.NewId()
-_NTB_X_PAN_LEFT =wx.NewId()
-_NTB_X_PAN_RIGHT =wx.NewId()
-_NTB_X_ZOOMIN =wx.NewId()
-_NTB_X_ZOOMOUT =wx.NewId()
-_NTB_Y_PAN_UP =wx.NewId()
-_NTB_Y_PAN_DOWN =wx.NewId()
-_NTB_Y_ZOOMIN =wx.NewId()
-_NTB_Y_ZOOMOUT =wx.NewId()
-#_NTB_SUBPLOT =wx.NewId()
-_NTB_SAVE =wx.NewId()
-_NTB_CLOSE =wx.NewId()
-
-def _load_bitmap(filename):
- """
- Load a bitmap file from the backends/images subdirectory in which the
- matplotlib library is installed. The filename parameter should not
- contain any path information as this is determined automatically.
-
- Returns a wx.Bitmap object
- """
-
- basedir = os.path.join(rcParams['datapath'],'images')
-
- bmpFilename = os.path.normpath(os.path.join(basedir, filename))
- if not os.path.exists(bmpFilename):
- raise IOError('Could not find bitmap file "%s"; dying'%bmpFilename)
-
- bmp = wx.Bitmap(bmpFilename)
- return bmp
-
-class MenuButtonWx(wx.Button):
- """
- wxPython does not permit a menu to be incorporated directly into a toolbar.
- This class simulates the effect by associating a pop-up menu with a button
- in the toolbar, and managing this as though it were a menu.
- """
- def __init__(self, parent):
-
- wx.Button.__init__(self, parent, _NTB_AXISMENU_BUTTON, "Axes: ",
- style=wx.BU_EXACTFIT)
- self._toolbar = parent
- self._menu =wx.Menu()
- self._axisId = []
- # First two menu items never change...
- self._allId =wx.NewId()
- self._invertId =wx.NewId()
- self._menu.Append(self._allId, "All", "Select all axes", False)
- self._menu.Append(self._invertId, "Invert", "Invert axes selected", False)
- self._menu.AppendSeparator()
-
- bind(self, wx.EVT_BUTTON, self._onMenuButton, id=_NTB_AXISMENU_BUTTON)
- bind(self, wx.EVT_MENU, self._handleSelectAllAxes, id=self._allId)
- bind(self, wx.EVT_MENU, self._handleInvertAxesSelected, id=self._invertId)
-
- def Destroy(self):
- self._menu.Destroy()
- self.Destroy()
-
- def _onMenuButton(self, evt):
- """Handle menu button pressed."""
- x, y = self.GetPositionTuple()
- w, h = self.GetSizeTuple()
- self.PopupMenuXY(self._menu, x, y+h-4)
- # When menu returned, indicate selection in button
- evt.Skip()
-
- def _handleSelectAllAxes(self, evt):
- """Called when the 'select all axes' menu item is selected."""
- if len(self._axisId) == 0:
- return
- for i in range(len(self._axisId)):
- self._menu.Check(self._axisId[i], True)
- self._toolbar.set_active(self.getActiveAxes())
- evt.Skip()
-
- def _handleInvertAxesSelected(self, evt):
- """Called when the invert all menu item is selected"""
- if len(self._axisId) == 0: return
- for i in range(len(self._axisId)):
- if self._menu.IsChecked(self._axisId[i]):
- self._menu.Check(self._axisId[i], False)
- else:
- self._menu.Check(self._axisId[i], True)
- self._toolbar.set_active(self.getActiveAxes())
- evt.Skip()
-
- def _onMenuItemSelected(self, evt):
- """Called whenever one of the specific axis menu items is selected"""
- current = self._menu.IsChecked(evt.GetId())
- if current:
- new = False
- else:
- new = True
- self._menu.Check(evt.GetId(), new)
- # Lines above would be deleted based on svn tracker ID 2841525;
- # not clear whether this matters or not.
- self._toolbar.set_active(self.getActiveAxes())
- evt.Skip()
-
- def updateAxes(self, maxAxis):
- """Ensures that there are entries for max_axis axes in the menu
- (selected by default)."""
- if maxAxis > len(self._axisId):
- for i in range(len(self._axisId) + 1, maxAxis + 1, 1):
- menuId =wx.NewId()
- self._axisId.append(menuId)
- self._menu.Append(menuId, "Axis %d" % i, "Select axis %d" % i, True)
- self._menu.Check(menuId, True)
- bind(self, wx.EVT_MENU, self._onMenuItemSelected, id=menuId)
- elif maxAxis < len(self._axisId):
- for menuId in self._axisId[maxAxis:]:
- self._menu.Delete(menuId)
- self._axisId = self._axisId[:maxAxis]
- self._toolbar.set_active(list(xrange(maxAxis)))
-
- def getActiveAxes(self):
- """Return a list of the selected axes."""
- active = []
- for i in range(len(self._axisId)):
- if self._menu.IsChecked(self._axisId[i]):
- active.append(i)
- return active
-
- def updateButtonText(self, lst):
- """Update the list of selected axes in the menu button"""
- axis_txt = ''
- for e in lst:
- axis_txt += '%d,' % (e+1)
- # remove trailing ',' and add to button string
- self.SetLabel("Axes: %s" % axis_txt[:-1])
-
-
-cursord = {
- cursors.MOVE : wx.CURSOR_HAND,
- cursors.HAND : wx.CURSOR_HAND,
- cursors.POINTER : wx.CURSOR_ARROW,
- cursors.SELECT_REGION : wx.CURSOR_CROSS,
- }
-
-
-class SubplotToolWX(wx.Frame):
- def __init__(self, targetfig):
- wx.Frame.__init__(self, None, -1, "Configure subplots")
-
- toolfig = Figure((6,3))
- canvas = FigureCanvasWx(self, -1, toolfig)
-
- # Create a figure manager to manage things
- figmgr = FigureManager(canvas, 1, self)
-
- # Now put all into a sizer
- sizer = wx.BoxSizer(wx.VERTICAL)
- # This way of adding to sizer allows resizing
- sizer.Add(canvas, 1, wx.LEFT|wx.TOP|wx.GROW)
- self.SetSizer(sizer)
- self.Fit()
- tool = SubplotTool(targetfig, toolfig)
-
-
-class NavigationToolbar2Wx(NavigationToolbar2, wx.ToolBar):
-
- def __init__(self, canvas):
- wx.ToolBar.__init__(self, canvas.GetParent(), -1)
- NavigationToolbar2.__init__(self, canvas)
- self.canvas = canvas
- self._idle = True
- self.statbar = None
-
- def get_canvas(self, frame, fig):
- return FigureCanvasWx(frame, -1, fig)
-
- def _init_toolbar(self):
- DEBUG_MSG("_init_toolbar", 1, self)
-
- self._parent = self.canvas.GetParent()
-
-
- self.wx_ids = {}
- for text, tooltip_text, image_file, callback in self.toolitems:
- if text is None:
- self.AddSeparator()
- continue
- self.wx_ids[text] = wx.NewId()
- if text in ['Pan', 'Zoom']:
- self.AddCheckTool(self.wx_ids[text], _load_bitmap(image_file + '.png'),
- shortHelp=text, longHelp=tooltip_text)
- else:
- self.AddSimpleTool(self.wx_ids[text], _load_bitmap(image_file + '.png'),
- text, tooltip_text)
- bind(self, wx.EVT_TOOL, getattr(self, callback), id=self.wx_ids[text])
-
- self.Realize()
-
- def zoom(self, *args):
- self.ToggleTool(self.wx_ids['Pan'], False)
- NavigationToolbar2.zoom(self, *args)
-
- def pan(self, *args):
- self.ToggleTool(self.wx_ids['Zoom'], False)
- NavigationToolbar2.pan(self, *args)
-
- def configure_subplots(self, evt):
- frame = wx.Frame(None, -1, "Configure subplots")
-
- toolfig = Figure((6,3))
- canvas = self.get_canvas(frame, toolfig)
-
- # Create a figure manager to manage things
- figmgr = FigureManager(canvas, 1, frame)
-
- # Now put all into a sizer
- sizer = wx.BoxSizer(wx.VERTICAL)
- # This way of adding to sizer allows resizing
- sizer.Add(canvas, 1, wx.LEFT|wx.TOP|wx.GROW)
- frame.SetSizer(sizer)
- frame.Fit()
- tool = SubplotTool(self.canvas.figure, toolfig)
- frame.Show()
-
- def save_figure(self, *args):
- # Fetch the required filename and file type.
- filetypes, exts, filter_index = self.canvas._get_imagesave_wildcards()
- default_file = self.canvas.get_default_filename()
- dlg = wx.FileDialog(self._parent, "Save to file", "", default_file,
- filetypes,
- wx.SAVE|wx.OVERWRITE_PROMPT)
- dlg.SetFilterIndex(filter_index)
- if dlg.ShowModal() == wx.ID_OK:
- dirname = dlg.GetDirectory()
- filename = dlg.GetFilename()
- DEBUG_MSG('Save file dir:%s name:%s' % (dirname, filename), 3, self)
- format = exts[dlg.GetFilterIndex()]
- basename, ext = os.path.splitext(filename)
- if ext.startswith('.'):
- ext = ext[1:]
- if ext in ('svg', 'pdf', 'ps', 'eps', 'png') and format!=ext:
- #looks like they forgot to set the image type drop
- #down, going with the extension.
- warnings.warn('extension %s did not match the selected image type %s; going with %s'%(ext, format, ext), stacklevel=0)
- format = ext
- try:
- self.canvas.print_figure(
- os.path.join(dirname, filename), format=format)
- except Exception as e:
- error_msg_wx(str(e))
-
- def set_cursor(self, cursor):
- cursor =wx.StockCursor(cursord[cursor])
- self.canvas.SetCursor( cursor )
-
- def release(self, event):
- try: del self.lastrect
- except AttributeError: pass
-
- def dynamic_update(self):
- d = self._idle
- self._idle = False
- if d:
- self.canvas.draw()
- self._idle = True
-
- def press(self, event):
- if self._active == 'ZOOM':
- self.wxoverlay = wx.Overlay()
-
- def release(self, event):
- if self._active == 'ZOOM':
- # When the mouse is released we reset the overlay and it
- # restores the former content to the window.
- self.wxoverlay.Reset()
- del self.wxoverlay
-
- def draw_rubberband(self, event, x0, y0, x1, y1):
- # Use an Overlay to draw a rubberband-like bounding box.
-
- dc = wx.ClientDC(self.canvas)
- odc = wx.DCOverlay(self.wxoverlay, dc)
- odc.Clear()
-
- # Mac's DC is already the same as a GCDC, and it causes
- # problems with the overlay if we try to use an actual
- # wx.GCDC so don't try it.
- if 'wxMac' not in wx.PlatformInfo:
- dc = wx.GCDC(dc)
-
- height = self.canvas.figure.bbox.height
- y1 = height - y1
- y0 = height - y0
-
- if y1 0)
- can_forward = (self._views._pos < len(self._views._elements) - 1)
- self.EnableTool(self.wx_ids['Back'], can_backward)
- self.EnableTool(self.wx_ids['Forward'], can_forward)
-
-
-class StatusBarWx(wx.StatusBar):
- """
- A status bar is added to _FigureFrame to allow measurements and the
- previously selected scroll function to be displayed as a user
- convenience.
- """
- def __init__(self, parent):
- wx.StatusBar.__init__(self, parent, -1)
- self.SetFieldsCount(2)
- self.SetStatusText("None", 1)
- #self.SetStatusText("Measurement: None", 2)
- #self.Reposition()
-
- def set_function(self, string):
- self.SetStatusText("%s" % string, 1)
-
- #def set_measurement(self, string):
- # self.SetStatusText("Measurement: %s" % string, 2)
-
-
-#< Additions for printing support: Matt Newville
-
-class PrintoutWx(wx.Printout):
- """Simple wrapper around wx Printout class -- all the real work
- here is scaling the matplotlib canvas bitmap to the current
- printer's definition.
- """
- def __init__(self, canvas, width=5.5,margin=0.5, title='matplotlib'):
- wx.Printout.__init__(self,title=title)
- self.canvas = canvas
- # width, in inches of output figure (approximate)
- self.width = width
- self.margin = margin
-
- def HasPage(self, page):
- #current only supports 1 page print
- return page == 1
-
- def GetPageInfo(self):
- return (1, 1, 1, 1)
-
- def OnPrintPage(self, page):
- self.canvas.draw()
-
- dc = self.GetDC()
- (ppw,pph) = self.GetPPIPrinter() # printer's pixels per in
- (pgw,pgh) = self.GetPageSizePixels() # page size in pixels
- (dcw,dch) = dc.GetSize()
- (grw,grh) = self.canvas.GetSizeTuple()
-
- # save current figure dpi resolution and bg color,
- # so that we can temporarily set them to the dpi of
- # the printer, and the bg color to white
- bgcolor = self.canvas.figure.get_facecolor()
- fig_dpi = self.canvas.figure.dpi
-
- # draw the bitmap, scaled appropriately
- vscale = float(ppw) / fig_dpi
-
- # set figure resolution,bg color for printer
- self.canvas.figure.dpi = ppw
- self.canvas.figure.set_facecolor('#FFFFFF')
-
- renderer = RendererWx(self.canvas.bitmap, self.canvas.figure.dpi)
- self.canvas.figure.draw(renderer)
- self.canvas.bitmap.SetWidth( int(self.canvas.bitmap.GetWidth() * vscale))
- self.canvas.bitmap.SetHeight( int(self.canvas.bitmap.GetHeight()* vscale))
- self.canvas.draw()
-
- # page may need additional scaling on preview
- page_scale = 1.0
- if self.IsPreview(): page_scale = float(dcw)/pgw
-
- # get margin in pixels = (margin in in) * (pixels/in)
- top_margin = int(self.margin * pph * page_scale)
- left_margin = int(self.margin * ppw * page_scale)
-
- # set scale so that width of output is self.width inches
- # (assuming grw is size of graph in inches....)
- user_scale = (self.width * fig_dpi * page_scale)/float(grw)
-
- dc.SetDeviceOrigin(left_margin,top_margin)
- dc.SetUserScale(user_scale,user_scale)
-
- # this cute little number avoid API inconsistencies in wx
- try:
- dc.DrawBitmap(self.canvas.bitmap, 0, 0)
- except:
- try:
- dc.DrawBitmap(self.canvas.bitmap, (0, 0))
- except:
- pass
-
- # restore original figure resolution
- self.canvas.figure.set_facecolor(bgcolor)
- self.canvas.figure.dpi = fig_dpi
- self.canvas.draw()
- return True
-#>
-
-########################################################################
-#
-# Now just provide the standard names that backend.__init__ is expecting
-#
-########################################################################
-
-FigureCanvas = FigureCanvasWx
-FigureManager = FigureManagerWx
-Toolbar = NavigationToolbar2Wx
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_wxagg.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_wxagg.py
deleted file mode 100644
index 5dd0103..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/backend_wxagg.py
+++ /dev/null
@@ -1,194 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import matplotlib
-from matplotlib.figure import Figure
-
-from .backend_agg import FigureCanvasAgg
-from . import backend_wx # already uses wxversion.ensureMinimal('2.8')
-from .backend_wx import FigureManagerWx, FigureCanvasWx, \
- FigureFrameWx, DEBUG_MSG, NavigationToolbar2Wx, error_msg_wx, \
- draw_if_interactive, show, Toolbar, backend_version
-import wx
-
-
-class FigureFrameWxAgg(FigureFrameWx):
- def get_canvas(self, fig):
- return FigureCanvasWxAgg(self, -1, fig)
-
- def _get_toolbar(self, statbar):
- if matplotlib.rcParams['toolbar']=='toolbar2':
- toolbar = NavigationToolbar2WxAgg(self.canvas)
- toolbar.set_status_bar(statbar)
- else:
- toolbar = None
- return toolbar
-
-
-class FigureCanvasWxAgg(FigureCanvasAgg, FigureCanvasWx):
- """
- The FigureCanvas contains the figure and does event handling.
-
- In the wxPython backend, it is derived from wxPanel, and (usually)
- lives inside a frame instantiated by a FigureManagerWx. The parent
- window probably implements a wxSizer to control the displayed
- control size - but we give a hint as to our preferred minimum
- size.
- """
-
- def draw(self, drawDC=None):
- """
- Render the figure using agg.
- """
- DEBUG_MSG("draw()", 1, self)
- FigureCanvasAgg.draw(self)
-
- self.bitmap = _convert_agg_to_wx_bitmap(self.get_renderer(), None)
- self._isDrawn = True
- self.gui_repaint(drawDC=drawDC)
-
- def blit(self, bbox=None):
- """
- Transfer the region of the agg buffer defined by bbox to the display.
- If bbox is None, the entire buffer is transferred.
- """
- if bbox is None:
- self.bitmap = _convert_agg_to_wx_bitmap(self.get_renderer(), None)
- self.gui_repaint()
- return
-
- l, b, w, h = bbox.bounds
- r = l + w
- t = b + h
- x = int(l)
- y = int(self.bitmap.GetHeight() - t)
-
- srcBmp = _convert_agg_to_wx_bitmap(self.get_renderer(), None)
- srcDC = wx.MemoryDC()
- srcDC.SelectObject(srcBmp)
-
- destDC = wx.MemoryDC()
- destDC.SelectObject(self.bitmap)
-
- destDC.BeginDrawing()
- destDC.Blit(x, y, int(w), int(h), srcDC, x, y)
- destDC.EndDrawing()
-
- destDC.SelectObject(wx.NullBitmap)
- srcDC.SelectObject(wx.NullBitmap)
- self.gui_repaint()
-
- filetypes = FigureCanvasAgg.filetypes
-
- def print_figure(self, filename, *args, **kwargs):
- # Use pure Agg renderer to draw
- FigureCanvasAgg.print_figure(self, filename, *args, **kwargs)
- # Restore the current view; this is needed because the
- # artist contains methods rely on particular attributes
- # of the rendered figure for determining things like
- # bounding boxes.
- if self._isDrawn:
- self.draw()
-
-
-class NavigationToolbar2WxAgg(NavigationToolbar2Wx):
- def get_canvas(self, frame, fig):
- return FigureCanvasWxAgg(frame, -1, fig)
-
-
-def new_figure_manager(num, *args, **kwargs):
- """
- Create a new figure manager instance
- """
- # in order to expose the Figure constructor to the pylab
- # interface we need to create the figure here
- DEBUG_MSG("new_figure_manager()", 3, None)
- backend_wx._create_wx_app()
-
- FigureClass = kwargs.pop('FigureClass', Figure)
- fig = FigureClass(*args, **kwargs)
-
- return new_figure_manager_given_figure(num, fig)
-
-def new_figure_manager_given_figure(num, figure):
- """
- Create a new figure manager instance for the given figure.
- """
- frame = FigureFrameWxAgg(num, figure)
- figmgr = frame.get_figure_manager()
- if matplotlib.is_interactive():
- figmgr.frame.Show()
- return figmgr
-
-
-#
-# agg/wxPython image conversion functions (wxPython >= 2.8)
-#
-
-def _convert_agg_to_wx_image(agg, bbox):
- """
- Convert the region of the agg buffer bounded by bbox to a wx.Image. If
- bbox is None, the entire buffer is converted.
-
- Note: agg must be a backend_agg.RendererAgg instance.
- """
- if bbox is None:
- # agg => rgb -> image
- image = wx.EmptyImage(int(agg.width), int(agg.height))
- image.SetData(agg.tostring_rgb())
- return image
- else:
- # agg => rgba buffer -> bitmap => clipped bitmap => image
- return wx.ImageFromBitmap(_WX28_clipped_agg_as_bitmap(agg, bbox))
-
-
-def _convert_agg_to_wx_bitmap(agg, bbox):
- """
- Convert the region of the agg buffer bounded by bbox to a wx.Bitmap. If
- bbox is None, the entire buffer is converted.
-
- Note: agg must be a backend_agg.RendererAgg instance.
- """
- if bbox is None:
- # agg => rgba buffer -> bitmap
- return wx.BitmapFromBufferRGBA(int(agg.width), int(agg.height),
- agg.buffer_rgba())
- else:
- # agg => rgba buffer -> bitmap => clipped bitmap
- return _WX28_clipped_agg_as_bitmap(agg, bbox)
-
-
-def _WX28_clipped_agg_as_bitmap(agg, bbox):
- """
- Convert the region of a the agg buffer bounded by bbox to a wx.Bitmap.
-
- Note: agg must be a backend_agg.RendererAgg instance.
- """
- l, b, width, height = bbox.bounds
- r = l + width
- t = b + height
-
- srcBmp = wx.BitmapFromBufferRGBA(int(agg.width), int(agg.height),
- agg.buffer_rgba())
- srcDC = wx.MemoryDC()
- srcDC.SelectObject(srcBmp)
-
- destBmp = wx.EmptyBitmap(int(width), int(height))
- destDC = wx.MemoryDC()
- destDC.SelectObject(destBmp)
-
- destDC.BeginDrawing()
- x = int(l)
- y = int(int(agg.height) - t)
- destDC.Blit(0, 0, int(width), int(height), srcDC, x, y)
- destDC.EndDrawing()
-
- srcDC.SelectObject(wx.NullBitmap)
- destDC.SelectObject(wx.NullBitmap)
-
- return destBmp
-
-FigureCanvas = FigureCanvasWxAgg
-FigureManager = FigureManagerWx
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/qt4_compat.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/qt4_compat.py
deleted file mode 100644
index b425e02..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/qt4_compat.py
+++ /dev/null
@@ -1,11 +0,0 @@
-import warnings
-from matplotlib.cbook import mplDeprecation
-_warn_str = ("This module has been deprecated in 1.4 in favor "
- "of matplotlib.backends.qt_compat\n"
- "This module will be removed in 1.5, please update "
- "your imports.")
-# bulk-imports because we are pretending that file is this file
-from .qt_compat import *
-
-
-warnings.warn(_warn_str, mplDeprecation)
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/qt_compat.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/qt_compat.py
deleted file mode 100644
index e5983c4..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/qt_compat.py
+++ /dev/null
@@ -1,143 +0,0 @@
-""" A Qt API selector that can be used to switch between PyQt and PySide.
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import os
-from matplotlib import rcParams, verbose
-
-# Available APIs.
-QT_API_PYQT = 'PyQt4' # API is not set here; Python 2.x default is V 1
-QT_API_PYQTv2 = 'PyQt4v2' # forced to Version 2 API
-QT_API_PYSIDE = 'PySide' # only supports Version 2 API
-QT_API_PYQT5 = 'PyQt5' # use PyQt5 API; Version 2 with module shim
-
-ETS = dict(pyqt=(QT_API_PYQTv2, 4), pyside=(QT_API_PYSIDE, 4),
- pyqt5=(QT_API_PYQT5, 5))
-# ETS is a dict of env variable to (QT_API, QT_MAJOR_VERSION)
-# If the ETS QT_API environment variable is set, use it, but only
-# if the varible if of the same major QT version. Note that
-# ETS requires the version 2 of PyQt4, which is not the platform
-# default for Python 2.x.
-
-QT_API_ENV = os.environ.get('QT_API')
-
-if rcParams['backend'] == 'Qt5Agg':
- QT_RC_MAJOR_VERSION = 5
-else:
- QT_RC_MAJOR_VERSION = 4
-
-QT_API = None
-
-if (QT_API_ENV is not None):
- try:
- QT_ENV_MAJOR_VERSION = ETS[QT_API_ENV][1]
- except KeyError:
- raise RuntimeError(
- ('Unrecognized environment variable %r, valid values are:'
- ' %r, %r or %r' % (QT_API_ENV, 'pyqt', 'pyside', 'pyqt5')))
- if QT_ENV_MAJOR_VERSION == QT_RC_MAJOR_VERSION:
- # Only if backend and env qt major version are
- # compatible use the env variable.
- QT_API = ETS[QT_API_ENV][0]
-
-if QT_API is None:
- # No ETS environment or incompatible so use rcParams.
- if rcParams['backend'] == 'Qt5Agg':
- QT_API = rcParams['backend.qt5']
- else:
- QT_API = rcParams['backend.qt4']
-
-# We will define an appropriate wrapper for the differing versions
-# of file dialog.
-_getSaveFileName = None
-
-# Flag to check if sip could be imported
-_sip_imported = False
-
-# Now perform the imports.
-if QT_API in (QT_API_PYQT, QT_API_PYQTv2, QT_API_PYQT5):
- try:
- import sip
- _sip_imported = True
- except ImportError:
- # Try using PySide
- QT_API = QT_API_PYSIDE
-
-if _sip_imported:
- if QT_API == QT_API_PYQTv2:
- if QT_API_ENV == 'pyqt':
- cond = ("Found 'QT_API=pyqt' environment variable. "
- "Setting PyQt4 API accordingly.\n")
- else:
- cond = "PyQt API v2 specified."
- try:
- sip.setapi('QString', 2)
- except:
- res = 'QString API v2 specification failed. Defaulting to v1.'
- verbose.report(cond + res, 'helpful')
- # condition has now been reported, no need to repeat it:
- cond = ""
- try:
- sip.setapi('QVariant', 2)
- except:
- res = 'QVariant API v2 specification failed. Defaulting to v1.'
- verbose.report(cond + res, 'helpful')
-
- if QT_API in [QT_API_PYQT, QT_API_PYQTv2]: # PyQt4 API
-
- from PyQt4 import QtCore, QtGui
-
- try:
- if sip.getapi("QString") > 1:
- # Use new getSaveFileNameAndFilter()
- _getSaveFileName = QtGui.QFileDialog.getSaveFileNameAndFilter
- else:
-
- # Use old getSaveFileName()
- def _getSaveFileName(*args, **kwargs):
- return (QtGui.QFileDialog.getSaveFileName(*args, **kwargs),
- None)
-
- except (AttributeError, KeyError):
-
- # call to getapi() can fail in older versions of sip
- def _getSaveFileName(*args, **kwargs):
- return QtGui.QFileDialog.getSaveFileName(*args, **kwargs), None
-
- else: # PyQt5 API
- from PyQt5 import QtCore, QtGui, QtWidgets
- _getSaveFileName = QtWidgets.QFileDialog.getSaveFileName
-
- # Alias PyQt-specific functions for PySide compatibility.
- QtCore.Signal = QtCore.pyqtSignal
- try:
- QtCore.Slot = QtCore.pyqtSlot
- except AttributeError:
- # Not a perfect match but works in simple cases
- QtCore.Slot = QtCore.pyqtSignature
-
- QtCore.Property = QtCore.pyqtProperty
- __version__ = QtCore.PYQT_VERSION_STR
-
-else: # try importing pyside
- from PySide import QtCore, QtGui, __version__, __version_info__
- if __version_info__ < (1, 0, 3):
- raise ImportError(
- "Matplotlib backend_qt4 and backend_qt4agg require PySide >=1.0.3")
-
- _getSaveFileName = QtGui.QFileDialog.getSaveFileName
-
-
-# Apply shim to Qt4 APIs to make them look like Qt5
-if QT_API in (QT_API_PYQT, QT_API_PYQTv2, QT_API_PYSIDE):
- '''Import all used QtGui objects into QtWidgets
-
- Here I've opted to simple copy QtGui into QtWidgets as that
- achieves the same result as copying over the objects, and will
- continue to work if other objects are used.
-
- '''
- QtWidgets = QtGui
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/qt_editor/__init__.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/qt_editor/__init__.py
deleted file mode 100644
index 800d82e..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/qt_editor/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/qt_editor/figureoptions.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/qt_editor/figureoptions.py
deleted file mode 100644
index 76920a7..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/qt_editor/figureoptions.py
+++ /dev/null
@@ -1,148 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Copyright © 2009 Pierre Raybaut
-# Licensed under the terms of the MIT License
-# see the mpl licenses directory for a copy of the license
-
-
-"""Module that provides a GUI-based editor for matplotlib's figure options"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import os.path as osp
-
-import matplotlib.backends.qt_editor.formlayout as formlayout
-from matplotlib.backends.qt_compat import QtGui
-from matplotlib import markers
-
-
-def get_icon(name):
- import matplotlib
- basedir = osp.join(matplotlib.rcParams['datapath'], 'images')
- return QtGui.QIcon(osp.join(basedir, name))
-
-LINESTYLES = {'-': 'Solid',
- '--': 'Dashed',
- '-.': 'DashDot',
- ':': 'Dotted',
- 'steps': 'Steps',
- 'none': 'None',
- }
-
-MARKERS = markers.MarkerStyle.markers
-
-
-def figure_edit(axes, parent=None):
- """Edit matplotlib figure options"""
- sep = (None, None) # separator
-
- has_curve = len(axes.get_lines()) > 0
-
- # Get / General
- xmin, xmax = axes.get_xlim()
- ymin, ymax = axes.get_ylim()
- general = [('Title', axes.get_title()),
- sep,
- (None, "X-Axis"),
- ('Min', xmin), ('Max', xmax),
- ('Label', axes.get_xlabel()),
- ('Scale', [axes.get_xscale(), 'linear', 'log']),
- sep,
- (None, "Y-Axis"),
- ('Min', ymin), ('Max', ymax),
- ('Label', axes.get_ylabel()),
- ('Scale', [axes.get_yscale(), 'linear', 'log']),
- sep,
- ('(Re-)Generate automatic legend', False),
- ]
-
- if has_curve:
- # Get / Curves
- linedict = {}
- for line in axes.get_lines():
- label = line.get_label()
- if label == '_nolegend_':
- continue
- linedict[label] = line
- curves = []
- linestyles = list(six.iteritems(LINESTYLES))
- markers = list(six.iteritems(MARKERS))
- curvelabels = sorted(linedict.keys())
- for label in curvelabels:
- line = linedict[label]
- curvedata = [('Label', label),
- sep,
- (None, 'Line'),
- ('Style', [line.get_linestyle()] + linestyles),
- ('Width', line.get_linewidth()),
- ('Color', line.get_color()),
- sep,
- (None, 'Marker'),
- ('Style', [line.get_marker()] + markers),
- ('Size', line.get_markersize()),
- ('Facecolor', line.get_markerfacecolor()),
- ('Edgecolor', line.get_markeredgecolor()),
- ]
- curves.append([curvedata, label, ""])
-
- datalist = [(general, "Axes", "")]
- if has_curve:
- datalist.append((curves, "Curves", ""))
-
- def apply_callback(data):
- """This function will be called to apply changes"""
- if has_curve:
- general, curves = data
- else:
- general, = data
-
- # Set / General
- title, xmin, xmax, xlabel, xscale, ymin, ymax, ylabel, yscale, \
- generate_legend = general
- axes.set_xscale(xscale)
- axes.set_yscale(yscale)
- axes.set_title(title)
- axes.set_xlim(xmin, xmax)
- axes.set_xlabel(xlabel)
- axes.set_ylim(ymin, ymax)
- axes.set_ylabel(ylabel)
-
- if has_curve:
- # Set / Curves
- for index, curve in enumerate(curves):
- line = linedict[curvelabels[index]]
- label, linestyle, linewidth, color, \
- marker, markersize, markerfacecolor, markeredgecolor \
- = curve
- line.set_label(label)
- line.set_linestyle(linestyle)
- line.set_linewidth(linewidth)
- line.set_color(color)
- if marker is not 'none':
- line.set_marker(marker)
- line.set_markersize(markersize)
- line.set_markerfacecolor(markerfacecolor)
- line.set_markeredgecolor(markeredgecolor)
-
- # re-generate legend, if checkbox is checked
- if generate_legend:
- if axes.legend_ is not None:
- old_legend = axes.get_legend()
- new_legend = axes.legend(ncol=old_legend._ncol)
- new_legend.draggable(old_legend._draggable is not None)
- else:
- new_legend = axes.legend()
- new_legend.draggable(True)
-
- # Redraw
- figure = axes.get_figure()
- figure.canvas.draw()
-
- data = formlayout.fedit(datalist, title="Figure options", parent=parent,
- icon=get_icon('qt4_editor_options.svg'),
- apply=apply_callback)
- if data is not None:
- apply_callback(data)
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/qt_editor/formlayout.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/qt_editor/formlayout.py
deleted file mode 100644
index bc6d0a2..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/qt_editor/formlayout.py
+++ /dev/null
@@ -1,558 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
-formlayout
-==========
-
-Module creating Qt form dialogs/layouts to edit various type of parameters
-
-
-formlayout License Agreement (MIT License)
-------------------------------------------
-
-Copyright (c) 2009 Pierre Raybaut
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import xrange
-
-# History:
-# 1.0.10: added float validator (disable "Ok" and "Apply" button when not valid)
-# 1.0.7: added support for "Apply" button
-# 1.0.6: code cleaning
-
-__version__ = '1.0.10'
-__license__ = __doc__
-
-DEBUG = False
-
-import sys
-STDERR = sys.stderr
-
-from matplotlib.colors import is_color_like
-from matplotlib.colors import rgb2hex
-from matplotlib.colors import colorConverter
-
-from matplotlib.backends.qt_compat import QtGui, QtWidgets, QtCore
-if not hasattr(QtWidgets, 'QFormLayout'):
- raise ImportError("Warning: formlayout requires PyQt4 >v4.3 or PySide")
-
-import datetime
-
-
-def col2hex(color):
- """Convert matplotlib color to hex before passing to Qt"""
- return rgb2hex(colorConverter.to_rgb(color))
-
-
-class ColorButton(QtWidgets.QPushButton):
- """
- Color choosing push button
- """
- colorChanged = QtCore.Signal(QtGui.QColor)
-
- def __init__(self, parent=None):
- QtWidgets.QPushButton.__init__(self, parent)
- self.setFixedSize(20, 20)
- self.setIconSize(QtCore.QSize(12, 12))
- self.clicked.connect(self.choose_color)
- self._color = QtGui.QColor()
-
- def choose_color(self):
- color = QtWidgets.QColorDialog.getColor(self._color, self.parentWidget(), '')
- if color.isValid():
- self.set_color(color)
-
- def get_color(self):
- return self._color
-
- @QtCore.Slot(QtGui.QColor)
- def set_color(self, color):
- if color != self._color:
- self._color = color
- self.colorChanged.emit(self._color)
- pixmap = QtGui.QPixmap(self.iconSize())
- pixmap.fill(color)
- self.setIcon(QtGui.QIcon(pixmap))
-
- color = QtCore.Property(QtGui.QColor, get_color, set_color)
-
-def col2hex(color):
- """Convert matplotlib color to hex before passing to Qt"""
- return rgb2hex(colorConverter.to_rgb(color))
-
-def to_qcolor(color):
- """Create a QColor from a matplotlib color"""
- qcolor = QtGui.QColor()
- color = str(color)
- try:
- color = col2hex(color)
- except ValueError:
- #print('WARNING: ignoring invalid color %r' % color)
- return qcolor # return invalid QColor
- qcolor.setNamedColor(color) # set using hex color
- return qcolor # return valid QColor
-
-
-class ColorLayout(QtWidgets.QHBoxLayout):
- """Color-specialized QLineEdit layout"""
- def __init__(self, color, parent=None):
- QtWidgets.QHBoxLayout.__init__(self)
- assert isinstance(color, QtGui.QColor)
- self.lineedit = QtWidgets.QLineEdit(color.name(), parent)
- self.lineedit.editingFinished.connect(self.update_color)
- self.addWidget(self.lineedit)
- self.colorbtn = ColorButton(parent)
- self.colorbtn.color = color
- self.colorbtn.colorChanged.connect(self.update_text)
- self.addWidget(self.colorbtn)
-
- def update_color(self):
- color = self.text()
- qcolor = to_qcolor(color)
- self.colorbtn.color = qcolor # defaults to black if not qcolor.isValid()
-
- def update_text(self, color):
- self.lineedit.setText(color.name())
-
- def text(self):
- return self.lineedit.text()
-
-
-def font_is_installed(font):
- """Check if font is installed"""
- return [fam for fam in QtGui.QFontDatabase().families()
- if six.text_type(fam) == font]
-
-
-def tuple_to_qfont(tup):
- """
- Create a QFont from tuple:
- (family [string], size [int], italic [bool], bold [bool])
- """
- if not isinstance(tup, tuple) or len(tup) != 4 \
- or not font_is_installed(tup[0]) \
- or not isinstance(tup[1], int) \
- or not isinstance(tup[2], bool) \
- or not isinstance(tup[3], bool):
- return None
- font = QtGui.QFont()
- family, size, italic, bold = tup
- font.setFamily(family)
- font.setPointSize(size)
- font.setItalic(italic)
- font.setBold(bold)
- return font
-
-
-def qfont_to_tuple(font):
- return (six.text_type(font.family()), int(font.pointSize()),
- font.italic(), font.bold())
-
-
-class FontLayout(QtWidgets.QGridLayout):
- """Font selection"""
- def __init__(self, value, parent=None):
- QtWidgets.QGridLayout.__init__(self)
- font = tuple_to_qfont(value)
- assert font is not None
-
- # Font family
- self.family = QtWidgets.QFontComboBox(parent)
- self.family.setCurrentFont(font)
- self.addWidget(self.family, 0, 0, 1, -1)
-
- # Font size
- self.size = QtWidgets.QComboBox(parent)
- self.size.setEditable(True)
- sizelist = list(xrange(6, 12)) + list(xrange(12, 30, 2)) + [36, 48, 72]
- size = font.pointSize()
- if size not in sizelist:
- sizelist.append(size)
- sizelist.sort()
- self.size.addItems([str(s) for s in sizelist])
- self.size.setCurrentIndex(sizelist.index(size))
- self.addWidget(self.size, 1, 0)
-
- # Italic or not
- self.italic = QtWidgets.QCheckBox(self.tr("Italic"), parent)
- self.italic.setChecked(font.italic())
- self.addWidget(self.italic, 1, 1)
-
- # Bold or not
- self.bold = QtWidgets.QCheckBox(self.tr("Bold"), parent)
- self.bold.setChecked(font.bold())
- self.addWidget(self.bold, 1, 2)
-
- def get_font(self):
- font = self.family.currentFont()
- font.setItalic(self.italic.isChecked())
- font.setBold(self.bold.isChecked())
- font.setPointSize(int(self.size.currentText()))
- return qfont_to_tuple(font)
-
-
-def is_edit_valid(edit):
- text = edit.text()
- state = edit.validator().validate(text, 0)[0]
-
- return state == QtGui.QDoubleValidator.Acceptable
-
-
-class FormWidget(QtWidgets.QWidget):
- update_buttons = QtCore.Signal()
- def __init__(self, data, comment="", parent=None):
- QtWidgets.QWidget.__init__(self, parent)
- from copy import deepcopy
- self.data = deepcopy(data)
- self.widgets = []
- self.formlayout = QtWidgets.QFormLayout(self)
- if comment:
- self.formlayout.addRow(QtWidgets.QLabel(comment))
- self.formlayout.addRow(QtWidgets.QLabel(" "))
- if DEBUG:
- print("\n"+("*"*80))
- print("DATA:", self.data)
- print("*"*80)
- print("COMMENT:", comment)
- print("*"*80)
-
- def get_dialog(self):
- """Return FormDialog instance"""
- dialog = self.parent()
- while not isinstance(dialog, QtWidgets.QDialog):
- dialog = dialog.parent()
- return dialog
-
- def setup(self):
- for label, value in self.data:
- if DEBUG:
- print("value:", value)
- if label is None and value is None:
- # Separator: (None, None)
- self.formlayout.addRow(QtWidgets.QLabel(" "), QtWidgets.QLabel(" "))
- self.widgets.append(None)
- continue
- elif label is None:
- # Comment
- self.formlayout.addRow(QtWidgets.QLabel(value))
- self.widgets.append(None)
- continue
- elif tuple_to_qfont(value) is not None:
- field = FontLayout(value, self)
- elif is_color_like(value):
- field = ColorLayout(to_qcolor(value), self)
- elif isinstance(value, six.string_types):
- field = QtWidgets.QLineEdit(value, self)
- elif isinstance(value, (list, tuple)):
- if isinstance(value, tuple):
- value = list(value)
- selindex = value.pop(0)
- field = QtWidgets.QComboBox(self)
- if isinstance(value[0], (list, tuple)):
- keys = [key for key, _val in value]
- value = [val for _key, val in value]
- else:
- keys = value
- field.addItems(value)
- if selindex in value:
- selindex = value.index(selindex)
- elif selindex in keys:
- selindex = keys.index(selindex)
- elif not isinstance(selindex, int):
- print("Warning: '%s' index is invalid (label: "
- "%s, value: %s)" % (selindex, label, value), file=STDERR)
- selindex = 0
- field.setCurrentIndex(selindex)
- elif isinstance(value, bool):
- field = QtWidgets.QCheckBox(self)
- if value:
- field.setCheckState(QtCore.Qt.Checked)
- else:
- field.setCheckState(QtCore.Qt.Unchecked)
- elif isinstance(value, float):
- field = QtWidgets.QLineEdit(repr(value), self)
- field.setValidator(QtGui.QDoubleValidator(field))
- dialog = self.get_dialog()
- dialog.register_float_field(field)
- field.textChanged.connect(lambda text: dialog.update_buttons())
- elif isinstance(value, int):
- field = QtWidgets.QSpinBox(self)
- field.setRange(-1e9, 1e9)
- field.setValue(value)
- elif isinstance(value, datetime.datetime):
- field = QtWidgets.QDateTimeEdit(self)
- field.setDateTime(value)
- elif isinstance(value, datetime.date):
- field = QtWidgets.QDateEdit(self)
- field.setDate(value)
- else:
- field = QtWidgets.QLineEdit(repr(value), self)
- self.formlayout.addRow(label, field)
- self.widgets.append(field)
-
- def get(self):
- valuelist = []
- for index, (label, value) in enumerate(self.data):
- field = self.widgets[index]
- if label is None:
- # Separator / Comment
- continue
- elif tuple_to_qfont(value) is not None:
- value = field.get_font()
- elif isinstance(value, six.string_types) or is_color_like(value):
- value = six.text_type(field.text())
- elif isinstance(value, (list, tuple)):
- index = int(field.currentIndex())
- if isinstance(value[0], (list, tuple)):
- value = value[index][0]
- else:
- value = value[index]
- elif isinstance(value, bool):
- value = field.checkState() == QtCore.Qt.Checked
- elif isinstance(value, float):
- value = float(str(field.text()))
- elif isinstance(value, int):
- value = int(field.value())
- elif isinstance(value, datetime.datetime):
- value = field.dateTime().toPyDateTime()
- elif isinstance(value, datetime.date):
- value = field.date().toPyDate()
- else:
- value = eval(str(field.text()))
- valuelist.append(value)
- return valuelist
-
-
-class FormComboWidget(QtWidgets.QWidget):
- update_buttons = QtCore.Signal()
-
- def __init__(self, datalist, comment="", parent=None):
- QtWidgets.QWidget.__init__(self, parent)
- layout = QtWidgets.QVBoxLayout()
- self.setLayout(layout)
- self.combobox = QtWidgets.QComboBox()
- layout.addWidget(self.combobox)
-
- self.stackwidget = QtWidgets.QStackedWidget(self)
- layout.addWidget(self.stackwidget)
- self.combobox.currentIndexChanged.connect(self.stackwidget.setCurrentIndex)
-
- self.widgetlist = []
- for data, title, comment in datalist:
- self.combobox.addItem(title)
- widget = FormWidget(data, comment=comment, parent=self)
- self.stackwidget.addWidget(widget)
- self.widgetlist.append(widget)
-
- def setup(self):
- for widget in self.widgetlist:
- widget.setup()
-
- def get(self):
- return [widget.get() for widget in self.widgetlist]
-
-
-class FormTabWidget(QtWidgets.QWidget):
- update_buttons = QtCore.Signal()
-
- def __init__(self, datalist, comment="", parent=None):
- QtWidgets.QWidget.__init__(self, parent)
- layout = QtWidgets.QVBoxLayout()
- self.tabwidget = QtWidgets.QTabWidget()
- layout.addWidget(self.tabwidget)
- self.setLayout(layout)
- self.widgetlist = []
- for data, title, comment in datalist:
- if len(data[0]) == 3:
- widget = FormComboWidget(data, comment=comment, parent=self)
- else:
- widget = FormWidget(data, comment=comment, parent=self)
- index = self.tabwidget.addTab(widget, title)
- self.tabwidget.setTabToolTip(index, comment)
- self.widgetlist.append(widget)
-
- def setup(self):
- for widget in self.widgetlist:
- widget.setup()
-
- def get(self):
- return [widget.get() for widget in self.widgetlist]
-
-
-class FormDialog(QtWidgets.QDialog):
- """Form Dialog"""
- def __init__(self, data, title="", comment="",
- icon=None, parent=None, apply=None):
- QtWidgets.QDialog.__init__(self, parent)
-
- self.apply_callback = apply
-
- # Form
- if isinstance(data[0][0], (list, tuple)):
- self.formwidget = FormTabWidget(data, comment=comment,
- parent=self)
- elif len(data[0]) == 3:
- self.formwidget = FormComboWidget(data, comment=comment,
- parent=self)
- else:
- self.formwidget = FormWidget(data, comment=comment,
- parent=self)
- layout = QtWidgets.QVBoxLayout()
- layout.addWidget(self.formwidget)
-
- self.float_fields = []
- self.formwidget.setup()
-
- # Button box
- self.bbox = bbox = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok
- | QtWidgets.QDialogButtonBox.Cancel)
- self.formwidget.update_buttons.connect(self.update_buttons)
- if self.apply_callback is not None:
- apply_btn = bbox.addButton(QtWidgets.QDialogButtonBox.Apply)
- apply_btn.clicked.connect(self.apply)
-
- bbox.accepted.connect(self.accept)
- bbox.rejected.connect(self.reject)
- layout.addWidget(bbox)
-
- self.setLayout(layout)
-
- self.setWindowTitle(title)
- if not isinstance(icon, QtGui.QIcon):
- icon = QtWidgets.QWidget().style().standardIcon(QtWidgets.QStyle.SP_MessageBoxQuestion)
- self.setWindowIcon(icon)
-
- def register_float_field(self, field):
- self.float_fields.append(field)
-
- def update_buttons(self):
- valid = True
- for field in self.float_fields:
- if not is_edit_valid(field):
- valid = False
- for btn_type in (QtWidgets.QDialogButtonBox.Ok, QtWidgets.QDialogButtonBox.Apply):
- btn = self.bbox.button(btn_type)
- if btn is not None:
- btn.setEnabled(valid)
-
- def accept(self):
- self.data = self.formwidget.get()
- QtWidgets.QDialog.accept(self)
-
- def reject(self):
- self.data = None
- QtWidgets.QDialog.reject(self)
-
- def apply(self):
- self.apply_callback(self.formwidget.get())
-
- def get(self):
- """Return form result"""
- return self.data
-
-
-def fedit(data, title="", comment="", icon=None, parent=None, apply=None):
- """
- Create form dialog and return result
- (if Cancel button is pressed, return None)
-
- data: datalist, datagroup
- title: string
- comment: string
- icon: QIcon instance
- parent: parent QWidget
- apply: apply callback (function)
-
- datalist: list/tuple of (field_name, field_value)
- datagroup: list/tuple of (datalist *or* datagroup, title, comment)
-
- -> one field for each member of a datalist
- -> one tab for each member of a top-level datagroup
- -> one page (of a multipage widget, each page can be selected with a combo
- box) for each member of a datagroup inside a datagroup
-
- Supported types for field_value:
- - int, float, str, unicode, bool
- - colors: in Qt-compatible text form, i.e. in hex format or name (red,...)
- (automatically detected from a string)
- - list/tuple:
- * the first element will be the selected index (or value)
- * the other elements can be couples (key, value) or only values
- """
-
- # Create a QApplication instance if no instance currently exists
- # (e.g., if the module is used directly from the interpreter)
- if QtWidgets.QApplication.startingUp():
- _app = QtWidgets.QApplication([])
- dialog = FormDialog(data, title, comment, icon, parent, apply)
- if dialog.exec_():
- return dialog.get()
-
-
-if __name__ == "__main__":
-
- def create_datalist_example():
- return [('str', 'this is a string'),
- ('list', [0, '1', '3', '4']),
- ('list2', ['--', ('none', 'None'), ('--', 'Dashed'),
- ('-.', 'DashDot'), ('-', 'Solid'),
- ('steps', 'Steps'), (':', 'Dotted')]),
- ('float', 1.2),
- (None, 'Other:'),
- ('int', 12),
- ('font', ('Arial', 10, False, True)),
- ('color', '#123409'),
- ('bool', True),
- ('date', datetime.date(2010, 10, 10)),
- ('datetime', datetime.datetime(2010, 10, 10)),
- ]
-
- def create_datagroup_example():
- datalist = create_datalist_example()
- return ((datalist, "Category 1", "Category 1 comment"),
- (datalist, "Category 2", "Category 2 comment"),
- (datalist, "Category 3", "Category 3 comment"))
-
- #--------- datalist example
- datalist = create_datalist_example()
-
- def apply_test(data):
- print("data:", data)
- print("result:", fedit(datalist, title="Example",
- comment="This is just an example.",
- apply=apply_test))
-
- #--------- datagroup example
- datagroup = create_datagroup_example()
- print("result:", fedit(datagroup, "Global title"))
-
- #--------- datagroup inside a datagroup example
- datalist = create_datalist_example()
- datagroup = create_datagroup_example()
- print("result:", fedit(((datagroup, "Title 1", "Tab 1 comment"),
- (datalist, "Title 2", "Tab 2 comment"),
- (datalist, "Title 3", "Tab 3 comment")),
- "Global title"))
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/qt_editor/formsubplottool.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/qt_editor/formsubplottool.py
deleted file mode 100644
index c48aef6..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/qt_editor/formsubplottool.py
+++ /dev/null
@@ -1,231 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
-formsubplottool.py
-
-backend.qt4 (PyQt4|PySide) independent form of the subplot tool.
-
-"""
-
-__author__ = 'rudolf.hoefler@gmail.com'
-
-from matplotlib.backends.qt_compat import QtCore, QtGui, QtWidgets
-
-
-class UiSubplotTool(QtWidgets.QDialog):
-
- def __init__(self, *args, **kwargs):
- super(UiSubplotTool, self).__init__(*args, **kwargs)
- self.setObjectName('SubplotTool')
- self.resize(450, 265)
-
- gbox = QtWidgets.QGridLayout(self)
- self.setLayout(gbox)
-
- # groupbox borders
- groupbox = QtWidgets.QGroupBox('Borders', self)
- gbox.addWidget(groupbox, 6, 0, 1, 1)
- self.verticalLayout = QtWidgets.QVBoxLayout(groupbox)
- self.verticalLayout.setSpacing(0)
-
- # slider top
- self.hboxtop = QtWidgets.QHBoxLayout()
- self.labeltop = QtWidgets.QLabel('top', self)
- self.labeltop.setMinimumSize(QtCore.QSize(50, 0))
- self.labeltop.setAlignment(
- QtCore.Qt.AlignRight |
- QtCore.Qt.AlignTrailing |
- QtCore.Qt.AlignVCenter)
-
- self.slidertop = QtWidgets.QSlider(self)
- self.slidertop.setMouseTracking(False)
- self.slidertop.setProperty("value", 0)
- self.slidertop.setOrientation(QtCore.Qt.Horizontal)
- self.slidertop.setInvertedAppearance(False)
- self.slidertop.setInvertedControls(False)
- self.slidertop.setTickPosition(QtWidgets.QSlider.TicksAbove)
- self.slidertop.setTickInterval(100)
-
- self.topvalue = QtWidgets.QLabel('0', self)
- self.topvalue.setMinimumSize(QtCore.QSize(30, 0))
- self.topvalue.setAlignment(
- QtCore.Qt.AlignRight |
- QtCore.Qt.AlignTrailing |
- QtCore.Qt.AlignVCenter)
-
- self.verticalLayout.addLayout(self.hboxtop)
- self.hboxtop.addWidget(self.labeltop)
- self.hboxtop.addWidget(self.slidertop)
- self.hboxtop.addWidget(self.topvalue)
-
- # slider bottom
- hboxbottom = QtWidgets.QHBoxLayout()
- labelbottom = QtWidgets.QLabel('bottom', self)
- labelbottom.setMinimumSize(QtCore.QSize(50, 0))
- labelbottom.setAlignment(
- QtCore.Qt.AlignRight |
- QtCore.Qt.AlignTrailing |
- QtCore.Qt.AlignVCenter)
-
- self.sliderbottom = QtWidgets.QSlider(self)
- self.sliderbottom.setMouseTracking(False)
- self.sliderbottom.setProperty("value", 0)
- self.sliderbottom.setOrientation(QtCore.Qt.Horizontal)
- self.sliderbottom.setInvertedAppearance(False)
- self.sliderbottom.setInvertedControls(False)
- self.sliderbottom.setTickPosition(QtWidgets.QSlider.TicksAbove)
- self.sliderbottom.setTickInterval(100)
-
- self.bottomvalue = QtWidgets.QLabel('0', self)
- self.bottomvalue.setMinimumSize(QtCore.QSize(30, 0))
- self.bottomvalue.setAlignment(
- QtCore.Qt.AlignRight |
- QtCore.Qt.AlignTrailing |
- QtCore.Qt.AlignVCenter)
-
- self.verticalLayout.addLayout(hboxbottom)
- hboxbottom.addWidget(labelbottom)
- hboxbottom.addWidget(self.sliderbottom)
- hboxbottom.addWidget(self.bottomvalue)
-
- # slider left
- hboxleft = QtWidgets.QHBoxLayout()
- labelleft = QtWidgets.QLabel('left', self)
- labelleft.setMinimumSize(QtCore.QSize(50, 0))
- labelleft.setAlignment(
- QtCore.Qt.AlignRight |
- QtCore.Qt.AlignTrailing |
- QtCore.Qt.AlignVCenter)
-
- self.sliderleft = QtWidgets.QSlider(self)
- self.sliderleft.setMouseTracking(False)
- self.sliderleft.setProperty("value", 0)
- self.sliderleft.setOrientation(QtCore.Qt.Horizontal)
- self.sliderleft.setInvertedAppearance(False)
- self.sliderleft.setInvertedControls(False)
- self.sliderleft.setTickPosition(QtWidgets.QSlider.TicksAbove)
- self.sliderleft.setTickInterval(100)
-
- self.leftvalue = QtWidgets.QLabel('0', self)
- self.leftvalue.setMinimumSize(QtCore.QSize(30, 0))
- self.leftvalue.setAlignment(
- QtCore.Qt.AlignRight |
- QtCore.Qt.AlignTrailing |
- QtCore.Qt.AlignVCenter)
-
- self.verticalLayout.addLayout(hboxleft)
- hboxleft.addWidget(labelleft)
- hboxleft.addWidget(self.sliderleft)
- hboxleft.addWidget(self.leftvalue)
-
- # slider right
- hboxright = QtWidgets.QHBoxLayout()
- self.labelright = QtWidgets.QLabel('right', self)
- self.labelright.setMinimumSize(QtCore.QSize(50, 0))
- self.labelright.setAlignment(
- QtCore.Qt.AlignRight |
- QtCore.Qt.AlignTrailing |
- QtCore.Qt.AlignVCenter)
-
- self.sliderright = QtWidgets.QSlider(self)
- self.sliderright.setMouseTracking(False)
- self.sliderright.setProperty("value", 0)
- self.sliderright.setOrientation(QtCore.Qt.Horizontal)
- self.sliderright.setInvertedAppearance(False)
- self.sliderright.setInvertedControls(False)
- self.sliderright.setTickPosition(QtWidgets.QSlider.TicksAbove)
- self.sliderright.setTickInterval(100)
-
- self.rightvalue = QtWidgets.QLabel('0', self)
- self.rightvalue.setMinimumSize(QtCore.QSize(30, 0))
- self.rightvalue.setAlignment(
- QtCore.Qt.AlignRight |
- QtCore.Qt.AlignTrailing |
- QtCore.Qt.AlignVCenter)
-
- self.verticalLayout.addLayout(hboxright)
- hboxright.addWidget(self.labelright)
- hboxright.addWidget(self.sliderright)
- hboxright.addWidget(self.rightvalue)
-
- # groupbox spacings
- groupbox = QtWidgets.QGroupBox('Spacings', self)
- gbox.addWidget(groupbox, 7, 0, 1, 1)
- self.verticalLayout = QtWidgets.QVBoxLayout(groupbox)
- self.verticalLayout.setSpacing(0)
-
- # slider hspace
- hboxhspace = QtWidgets.QHBoxLayout()
- self.labelhspace = QtWidgets.QLabel('hspace', self)
- self.labelhspace.setMinimumSize(QtCore.QSize(50, 0))
- self.labelhspace.setAlignment(
- QtCore.Qt.AlignRight |
- QtCore.Qt.AlignTrailing |
- QtCore.Qt.AlignVCenter)
-
- self.sliderhspace = QtWidgets.QSlider(self)
- self.sliderhspace.setMouseTracking(False)
- self.sliderhspace.setProperty("value", 0)
- self.sliderhspace.setOrientation(QtCore.Qt.Horizontal)
- self.sliderhspace.setInvertedAppearance(False)
- self.sliderhspace.setInvertedControls(False)
- self.sliderhspace.setTickPosition(QtWidgets.QSlider.TicksAbove)
- self.sliderhspace.setTickInterval(100)
-
- self.hspacevalue = QtWidgets.QLabel('0', self)
- self.hspacevalue.setMinimumSize(QtCore.QSize(30, 0))
- self.hspacevalue.setAlignment(
- QtCore.Qt.AlignRight |
- QtCore.Qt.AlignTrailing |
- QtCore.Qt.AlignVCenter)
-
- self.verticalLayout.addLayout(hboxhspace)
- hboxhspace.addWidget(self.labelhspace)
- hboxhspace.addWidget(self.sliderhspace)
- hboxhspace.addWidget(self.hspacevalue) # slider hspace
-
- # slider wspace
- hboxwspace = QtWidgets.QHBoxLayout()
- self.labelwspace = QtWidgets.QLabel('wspace', self)
- self.labelwspace.setMinimumSize(QtCore.QSize(50, 0))
- self.labelwspace.setAlignment(
- QtCore.Qt.AlignRight |
- QtCore.Qt.AlignTrailing |
- QtCore.Qt.AlignVCenter)
-
- self.sliderwspace = QtWidgets.QSlider(self)
- self.sliderwspace.setMouseTracking(False)
- self.sliderwspace.setProperty("value", 0)
- self.sliderwspace.setOrientation(QtCore.Qt.Horizontal)
- self.sliderwspace.setInvertedAppearance(False)
- self.sliderwspace.setInvertedControls(False)
- self.sliderwspace.setTickPosition(QtWidgets.QSlider.TicksAbove)
- self.sliderwspace.setTickInterval(100)
-
- self.wspacevalue = QtWidgets.QLabel('0', self)
- self.wspacevalue.setMinimumSize(QtCore.QSize(30, 0))
- self.wspacevalue.setAlignment(
- QtCore.Qt.AlignRight |
- QtCore.Qt.AlignTrailing |
- QtCore.Qt.AlignVCenter)
-
- self.verticalLayout.addLayout(hboxwspace)
- hboxwspace.addWidget(self.labelwspace)
- hboxwspace.addWidget(self.sliderwspace)
- hboxwspace.addWidget(self.wspacevalue)
-
- # button bar
- hbox2 = QtWidgets.QHBoxLayout()
- gbox.addLayout(hbox2, 8, 0, 1, 1)
- self.tightlayout = QtWidgets.QPushButton('Tight Layout', self)
- spacer = QtWidgets.QSpacerItem(
- 5, 20, QtWidgets.QSizePolicy.Expanding,
- QtWidgets.QSizePolicy.Minimum)
- self.resetbutton = QtWidgets.QPushButton('Reset', self)
- self.donebutton = QtWidgets.QPushButton('Close', self)
- self.donebutton.setFocus()
- hbox2.addWidget(self.tightlayout)
- hbox2.addItem(spacer)
- hbox2.addWidget(self.resetbutton)
- hbox2.addWidget(self.donebutton)
-
- self.donebutton.clicked.connect(self.accept)
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/tkagg.py b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/tkagg.py
deleted file mode 100644
index 2a9913d..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/tkagg.py
+++ /dev/null
@@ -1,37 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import tkinter as Tk
-
-from matplotlib.backends import _tkagg
-
-def blit(photoimage, aggimage, bbox=None, colormode=1):
- tk = photoimage.tk
-
- if bbox is not None:
- bbox_array = bbox.__array__()
- else:
- bbox_array = None
- try:
- tk.call("PyAggImagePhoto", photoimage, id(aggimage), colormode, id(bbox_array))
- except Tk.TclError:
- try:
- try:
- _tkagg.tkinit(tk.interpaddr(), 1)
- except AttributeError:
- _tkagg.tkinit(id(tk), 0)
- tk.call("PyAggImagePhoto", photoimage, id(aggimage), colormode, id(bbox_array))
- except (ImportError, AttributeError, Tk.TclError):
- raise
-
-def test(aggimage):
- import time
- r = Tk.Tk()
- c = Tk.Canvas(r, width=aggimage.width, height=aggimage.height)
- c.pack()
- p = Tk.PhotoImage(width=aggimage.width, height=aggimage.height)
- blit(p, aggimage)
- c.create_image(aggimage.width,aggimage.height,image=p)
- blit(p, aggimage)
- while 1: r.update_idletasks()
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/all_figures.html b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/all_figures.html
deleted file mode 100644
index 73c34b4..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/all_figures.html
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
- MPL | WebAgg current figures
-
-
-
-
-
-
-
-
-
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/css/boilerplate.css b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/css/boilerplate.css
deleted file mode 100644
index 2b1535f..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/css/boilerplate.css
+++ /dev/null
@@ -1,77 +0,0 @@
-/**
- * HTML5 ✰ Boilerplate
- *
- * style.css contains a reset, font normalization and some base styles.
- *
- * Credit is left where credit is due.
- * Much inspiration was taken from these projects:
- * - yui.yahooapis.com/2.8.1/build/base/base.css
- * - camendesign.com/design/
- * - praegnanz.de/weblog/htmlcssjs-kickstart
- */
-
-
-/**
- * html5doctor.com Reset Stylesheet (Eric Meyer's Reset Reloaded + HTML5 baseline)
- * v1.6.1 2010-09-17 | Authors: Eric Meyer & Richard Clark
- * html5doctor.com/html-5-reset-stylesheet/
- */
-
-html, body, div, span, object, iframe,
-h1, h2, h3, h4, h5, h6, p, blockquote, pre,
-abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp,
-small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li,
-fieldset, form, label, legend,
-table, caption, tbody, tfoot, thead, tr, th, td,
-article, aside, canvas, details, figcaption, figure,
-footer, header, hgroup, menu, nav, section, summary,
-time, mark, audio, video {
- margin: 0;
- padding: 0;
- border: 0;
- font-size: 100%;
- font: inherit;
- vertical-align: baseline;
-}
-
-sup { vertical-align: super; }
-sub { vertical-align: sub; }
-
-article, aside, details, figcaption, figure,
-footer, header, hgroup, menu, nav, section {
- display: block;
-}
-
-blockquote, q { quotes: none; }
-
-blockquote:before, blockquote:after,
-q:before, q:after { content: ""; content: none; }
-
-ins { background-color: #ff9; color: #000; text-decoration: none; }
-
-mark { background-color: #ff9; color: #000; font-style: italic; font-weight: bold; }
-
-del { text-decoration: line-through; }
-
-abbr[title], dfn[title] { border-bottom: 1px dotted; cursor: help; }
-
-table { border-collapse: collapse; border-spacing: 0; }
-
-hr { display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0; }
-
-input, select { vertical-align: middle; }
-
-
-/**
- * Font normalization inspired by YUI Library's fonts.css: developer.yahoo.com/yui/
- */
-
-body { font:13px/1.231 sans-serif; *font-size:small; } /* Hack retained to preserve specificity */
-select, input, textarea, button { font:99% sans-serif; }
-
-/* Normalize monospace sizing:
- en.wikipedia.org/wiki/MediaWiki_talk:Common.css/Archive_11#Teletype_style_fix_for_Chrome */
-pre, code, kbd, samp { font-family: monospace, sans-serif; }
-
-em,i { font-style: italic; }
-b,strong { font-weight: bold; }
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/css/fbm.css b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/css/fbm.css
deleted file mode 100644
index 0e21d19..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/css/fbm.css
+++ /dev/null
@@ -1,97 +0,0 @@
-
-/* Flexible box model classes */
-/* Taken from Alex Russell http://infrequently.org/2009/08/css-3-progress/ */
-
-.hbox {
- display: -webkit-box;
- -webkit-box-orient: horizontal;
- -webkit-box-align: stretch;
-
- display: -moz-box;
- -moz-box-orient: horizontal;
- -moz-box-align: stretch;
-
- display: box;
- box-orient: horizontal;
- box-align: stretch;
-}
-
-.hbox > * {
- -webkit-box-flex: 0;
- -moz-box-flex: 0;
- box-flex: 0;
-}
-
-.vbox {
- display: -webkit-box;
- -webkit-box-orient: vertical;
- -webkit-box-align: stretch;
-
- display: -moz-box;
- -moz-box-orient: vertical;
- -moz-box-align: stretch;
-
- display: box;
- box-orient: vertical;
- box-align: stretch;
-}
-
-.vbox > * {
- -webkit-box-flex: 0;
- -moz-box-flex: 0;
- box-flex: 0;
-}
-
-.reverse {
- -webkit-box-direction: reverse;
- -moz-box-direction: reverse;
- box-direction: reverse;
-}
-
-.box-flex0 {
- -webkit-box-flex: 0;
- -moz-box-flex: 0;
- box-flex: 0;
-}
-
-.box-flex1, .box-flex {
- -webkit-box-flex: 1;
- -moz-box-flex: 1;
- box-flex: 1;
-}
-
-.box-flex2 {
- -webkit-box-flex: 2;
- -moz-box-flex: 2;
- box-flex: 2;
-}
-
-.box-group1 {
- -webkit-box-flex-group: 1;
- -moz-box-flex-group: 1;
- box-flex-group: 1;
-}
-
-.box-group2 {
- -webkit-box-flex-group: 2;
- -moz-box-flex-group: 2;
- box-flex-group: 2;
-}
-
-.start {
- -webkit-box-pack: start;
- -moz-box-pack: start;
- box-pack: start;
-}
-
-.end {
- -webkit-box-pack: end;
- -moz-box-pack: end;
- box-pack: end;
-}
-
-.center {
- -webkit-box-pack: center;
- -moz-box-pack: center;
- box-pack: center;
-}
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/css/page.css b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/css/page.css
deleted file mode 100644
index d284be1..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/css/page.css
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * Primary styles
- *
- * Author: IPython Development Team
- */
-
-
-body {
- background-color: white;
- /* This makes sure that the body covers the entire window and needs to
- be in a different element than the display: box in wrapper below */
- position: absolute;
- left: 0px;
- right: 0px;
- top: 0px;
- bottom: 0px;
- overflow: visible;
-}
-
-
-div#header {
- /* Initially hidden to prevent FLOUC */
- display: none;
- position: relative;
- height: 40px;
- padding: 5px;
- margin: 0px;
- width: 100%;
-}
-
-span#ipython_notebook {
- position: absolute;
- padding: 2px 2px 2px 5px;
-}
-
-span#ipython_notebook img {
- font-family: Verdana, "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;
- height: 24px;
- text-decoration:none;
- display: inline;
- color: black;
-}
-
-#site {
- width: 100%;
- display: none;
-}
-
-/* We set the fonts by hand here to override the values in the theme */
-.ui-widget {
- font-family: "Lucinda Grande", "Lucinda Sans Unicode", Helvetica, Arial, Verdana, sans-serif;
-}
-
-.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button {
- font-family: "Lucinda Grande", "Lucinda Sans Unicode", Helvetica, Arial, Verdana, sans-serif;
-}
-
-/* Smaller buttons */
-.ui-button .ui-button-text {
- padding: 0.2em 0.8em;
- font-size: 77%;
-}
-
-input.ui-button {
- padding: 0.3em 0.9em;
-}
-
-span#login_widget {
- float: right;
-}
-
-.border-box-sizing {
- box-sizing: border-box;
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
-}
-
-#figure-div {
- display: inline-block;
- margin: 10px;
-}
-
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/ipython_inline_figure.html b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/ipython_inline_figure.html
deleted file mode 100644
index 100a1e7..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/ipython_inline_figure.html
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-bg_flat_0_aaaaaa_40x100.png b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-bg_flat_0_aaaaaa_40x100.png
deleted file mode 100644
index 5b5dab2..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-bg_flat_0_aaaaaa_40x100.png and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-bg_flat_75_ffffff_40x100.png b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-bg_flat_75_ffffff_40x100.png
deleted file mode 100644
index ac8b229..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-bg_flat_75_ffffff_40x100.png and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-bg_glass_55_fbf9ee_1x400.png b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-bg_glass_55_fbf9ee_1x400.png
deleted file mode 100644
index ad3d634..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-bg_glass_55_fbf9ee_1x400.png and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-bg_glass_65_ffffff_1x400.png b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-bg_glass_65_ffffff_1x400.png
deleted file mode 100644
index 42ccba2..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-bg_glass_65_ffffff_1x400.png and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-bg_glass_75_dadada_1x400.png b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-bg_glass_75_dadada_1x400.png
deleted file mode 100644
index 5a46b47..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-bg_glass_75_dadada_1x400.png and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-bg_glass_75_e6e6e6_1x400.png b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-bg_glass_75_e6e6e6_1x400.png
deleted file mode 100644
index 86c2baa..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-bg_glass_75_e6e6e6_1x400.png and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-bg_glass_95_fef1ec_1x400.png b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-bg_glass_95_fef1ec_1x400.png
deleted file mode 100644
index 4443fdc..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-bg_glass_95_fef1ec_1x400.png and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-bg_highlight-soft_75_cccccc_1x100.png
deleted file mode 100644
index 7c9fa6c..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-bg_highlight-soft_75_cccccc_1x100.png and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-icons_222222_256x240.png b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-icons_222222_256x240.png
deleted file mode 100644
index ee039dc..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-icons_222222_256x240.png and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-icons_2e83ff_256x240.png b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-icons_2e83ff_256x240.png
deleted file mode 100644
index 45e8928..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-icons_2e83ff_256x240.png and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-icons_454545_256x240.png b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-icons_454545_256x240.png
deleted file mode 100644
index 7ec70d1..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-icons_454545_256x240.png and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-icons_888888_256x240.png b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-icons_888888_256x240.png
deleted file mode 100644
index 5ba708c..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-icons_888888_256x240.png and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-icons_cd0a0a_256x240.png b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-icons_cd0a0a_256x240.png
deleted file mode 100644
index 7930a55..0000000
Binary files a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/images/ui-icons_cd0a0a_256x240.png and /dev/null differ
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/jquery-ui.min.css b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/jquery-ui.min.css
deleted file mode 100644
index 82752b5..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/css/themes/base/jquery-ui.min.css
+++ /dev/null
@@ -1 +0,0 @@
-.ui-helper-hidden{display:none;}.ui-helper-hidden-accessible{position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none;}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;}.ui-helper-clearfix:after{clear:both;}.ui-helper-clearfix{zoom:1;}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0);}.ui-state-disabled{cursor:default!important;}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat;}.ui-widget-overlay{position:absolute;top:0;left:0;width:100%;height:100%;}.ui-accordion{width:100%;}.ui-accordion .ui-accordion-header{cursor:pointer;position:relative;margin-top:1px;zoom:1;}.ui-accordion .ui-accordion-header-active{border-bottom:0!important;}.ui-accordion .ui-accordion-heading{display:block;font-size:1em;padding:.5em .5em .5em .7em;}.ui-accordion-icons .ui-accordion-heading{padding-left:2.2em;}.ui-accordion .ui-accordion-header .ui-accordion-header-icon{position:absolute;left:.5em;top:50%;margin-top:-8px;}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;margin-top:-2px;position:relative;top:1px;margin-bottom:2px;overflow:auto;display:none;zoom:1;}.ui-accordion .ui-accordion-content-active{display:block;}.ui-autocomplete{position:absolute;cursor:default;}* html .ui-autocomplete{width:1px;}.ui-button{display:inline-block;position:relative;padding:0;margin-right:.1em;text-decoration:none!important;cursor:pointer;text-align:center;zoom:1;overflow:hidden;*overflow:visible;}.ui-button-icon-only{width:2.2em;}button.ui-button-icon-only{width:2.4em;}.ui-button-icons-only{width:3.4em;}button.ui-button-icons-only{width:3.7em;}.ui-button .ui-button-text{display:block;line-height:1.4;}.ui-button-text-only .ui-button-text{padding:.4em 1em;}.ui-button-icon-only .ui-button-text,.ui-button-icons-only .ui-button-text{padding:.4em;text-indent:-9999999px;}.ui-button-text-icon-primary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 1em .4em 2.1em;}.ui-button-text-icon-secondary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 2.1em .4em 1em;}.ui-button-text-icons .ui-button-text{padding-left:2.1em;padding-right:2.1em;}input.ui-button{padding:.4em 1em;}.ui-button-icon-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon,.ui-button-icons-only .ui-icon{position:absolute;top:50%;margin-top:-8px;}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px;}.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-text-icons .ui-button-icon-primary,.ui-button-icons-only .ui-button-icon-primary{left:.5em;}.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em;}.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em;}.ui-buttonset{margin-right:7px;}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em;}button.ui-button::-moz-focus-inner{border:0;padding:0;}.ui-datepicker{width:17em;padding:.2em .2em 0;display:none;}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0;}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em;}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px;}.ui-datepicker .ui-datepicker-prev{left:2px;}.ui-datepicker .ui-datepicker-next{right:2px;}.ui-datepicker .ui-datepicker-prev-hover{left:1px;}.ui-datepicker .ui-datepicker-next-hover{right:1px;}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px;}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center;}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0;}.ui-datepicker select.ui-datepicker-month-year{width:100%;}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:49%;}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em;}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:bold;border:0;}.ui-datepicker td{border:0;padding:1px;}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none;}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0;}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em .6em;width:auto;overflow:visible;}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left;}.ui-datepicker.ui-datepicker-multi{width:auto;}.ui-datepicker-multi .ui-datepicker-group{float:left;}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em;}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%;}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%;}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%;}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header{border-left-width:0;}.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0;}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left;}.ui-datepicker-row-break{clear:both;width:100%;font-size:0;}.ui-datepicker-rtl{direction:rtl;}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto;}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto;}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto;}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto;}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right;}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left;}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current{float:right;}.ui-datepicker-rtl .ui-datepicker-group{float:right;}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header{border-right-width:0;border-left-width:1px;}.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px;}.ui-datepicker-cover{display:none;display:block;position:absolute;z-index:-1;filter:mask();top:-4px;left:-4px;width:200px;height:200px;}.ui-dialog{position:absolute;padding:.2em;width:300px;overflow:hidden;}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative;}.ui-dialog .ui-dialog-title{float:left;margin:.1em 16px .1em 0;}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:19px;margin:-10px 0 0 0;padding:1px;height:18px;}.ui-dialog .ui-dialog-titlebar-close span{display:block;margin:1px;}.ui-dialog .ui-dialog-titlebar-close:hover,.ui-dialog .ui-dialog-titlebar-close:focus{padding:0;}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:none;overflow:auto;zoom:1;}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin:.5em 0 0 0;padding:.3em 1em .5em .4em;}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right;}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer;}.ui-dialog .ui-resizable-se{width:14px;height:14px;right:3px;bottom:3px;}.ui-draggable .ui-dialog-titlebar{cursor:move;}.ui-menu{list-style:none;padding:2px;margin:0;display:block;outline:none;}.ui-menu .ui-menu{margin-top:-3px;position:absolute;}.ui-menu .ui-menu-item{margin:0;padding:0;zoom:1;width:100%;}.ui-menu .ui-menu-item a{text-decoration:none;display:block;padding:2px .4em;line-height:1.5;zoom:1;font-weight:normal;}.ui-menu .ui-menu-item a.ui-state-focus,.ui-menu .ui-menu-item a.ui-state-active{font-weight:normal;margin:-1px;}.ui-menu .ui-state-disabled{font-weight:normal;padding:.0em .4em;margin:.4em 0 .2em;line-height:1.5;}.ui-menu-icons{position:relative;}.ui-menu-icons .ui-menu-item a{position:relative;padding-left:2em;}.ui-menu .ui-icon{position:absolute;top:.2em;left:.2em;}.ui-menu .ui-menu-icon{position:static;float:right;}.ui-menubar{list-style:none;margin:0;padding-left:0;}.ui-menubar-item{float:left;}.ui-menubar .ui-button{float:left;font-weight:normal;border-top-width:0!important;border-bottom-width:0!important;margin:0;outline:none;}.ui-menubar .ui-menubar-link{border-right:1px dashed transparent;border-left:1px dashed transparent;}.ui-menubar .ui-menu{width:200px;position:absolute;z-index:9999;font-weight:normal;}.ui-progressbar{height:2em;text-align:left;overflow:hidden;}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%;}.ui-resizable{position:relative;}.ui-resizable-handle{position:absolute;font-size:.1px;z-index:99999;display:block;}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none;}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0;}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0;}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%;}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%;}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px;}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px;}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px;}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px;}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black;}.ui-slider{position:relative;text-align:left;}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default;}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0;}.ui-slider-horizontal{height:.8em;}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em;}.ui-slider-horizontal .ui-slider-range{top:0;height:100%;}.ui-slider-horizontal .ui-slider-range-min{left:0;}.ui-slider-horizontal .ui-slider-range-max{right:0;}.ui-slider-vertical{width:.8em;height:100px;}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em;}.ui-slider-vertical .ui-slider-range{left:0;width:100%;}.ui-slider-vertical .ui-slider-range-min{bottom:0;}.ui-slider-vertical .ui-slider-range-max{top:0;}.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle;}.ui-spinner-input{border:none;background:none;padding:0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:22px;}.ui-spinner-button{width:16px;height:50%;font-size:.5em;padding:0;margin:0;z-index:100;text-align:center;vertical-align:middle;position:absolute;cursor:default;display:block;overflow:hidden;right:0;}.ui-spinner a.ui-spinner-button{border-top:none;border-bottom:none;border-right:none;}.ui-spinner .ui-icon{position:absolute;margin-top:-8px;top:50%;left:0;}.ui-spinner-up{top:0;}.ui-spinner-down{bottom:0;}span.ui-spinner{background:none;}.ui-spinner .ui-icon-triangle-1-s{background-position:-65px -16px;}.ui-tabs{position:relative;padding:.2em;zoom:1;}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0;}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom:0!important;padding:0;white-space:nowrap;}.ui-tabs .ui-tabs-nav li a{float:left;padding:.5em 1em;text-decoration:none;}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px;}.ui-tabs .ui-tabs-nav li.ui-tabs-active a,.ui-tabs .ui-tabs-nav li.ui-state-disabled a,.ui-tabs .ui-tabs-nav li.ui-tabs-loading a{cursor:text;}.ui-tabs .ui-tabs-nav li a,.ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a{cursor:pointer;}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none;}.ui-tooltip{padding:8px;position:absolute;z-index:9999;-o-box-shadow:0 0 5px #aaa;-moz-box-shadow:0 0 5px #aaa;-webkit-box-shadow:0 0 5px #aaa;box-shadow:0 0 5px #aaa;}* html .ui-tooltip{background-image:none;}body .ui-tooltip{border-width:2px;}.ui-widget{font-family:Verdana,Arial,sans-serif;font-size:1.1em;}.ui-widget .ui-widget{font-size:1em;}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Verdana,Arial,sans-serif;font-size:1em;}.ui-widget-content{border:1px solid #aaa;background:#fff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x;color:#222;}.ui-widget-content a{color:#222;}.ui-widget-header{border:1px solid #aaa;background:#ccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x;color:#222;font-weight:bold;}.ui-widget-header a{color:#222;}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #d3d3d3;background:#e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x;font-weight:normal;color:#555;}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#555;text-decoration:none;}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:1px solid #999;background:#dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x;font-weight:normal;color:#212121;}.ui-state-hover a,.ui-state-hover a:hover{color:#212121;text-decoration:none;}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #aaa;background:#fff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x;font-weight:normal;color:#212121;}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#212121;text-decoration:none;}.ui-widget :active{outline:none;}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #fcefa1;background:#fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x;color:#363636;}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#363636;}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #cd0a0a;background:#fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x;color:#cd0a0a;}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#cd0a0a;}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#cd0a0a;}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold;}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal;}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none;}.ui-icon{width:16px;height:16px;background-image:url(images/ui-icons_222222_256x240.png);}.ui-widget-content .ui-icon{background-image:url(images/ui-icons_222222_256x240.png);}.ui-widget-header .ui-icon{background-image:url(images/ui-icons_222222_256x240.png);}.ui-state-default .ui-icon{background-image:url(images/ui-icons_888888_256x240.png);}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url(images/ui-icons_454545_256x240.png);}.ui-state-active .ui-icon{background-image:url(images/ui-icons_454545_256x240.png);}.ui-state-highlight .ui-icon{background-image:url(images/ui-icons_2e83ff_256x240.png);}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url(images/ui-icons_cd0a0a_256x240.png);}.ui-icon-carat-1-n{background-position:0 0;}.ui-icon-carat-1-ne{background-position:-16px 0;}.ui-icon-carat-1-e{background-position:-32px 0;}.ui-icon-carat-1-se{background-position:-48px 0;}.ui-icon-carat-1-s{background-position:-64px 0;}.ui-icon-carat-1-sw{background-position:-80px 0;}.ui-icon-carat-1-w{background-position:-96px 0;}.ui-icon-carat-1-nw{background-position:-112px 0;}.ui-icon-carat-2-n-s{background-position:-128px 0;}.ui-icon-carat-2-e-w{background-position:-144px 0;}.ui-icon-triangle-1-n{background-position:0 -16px;}.ui-icon-triangle-1-ne{background-position:-16px -16px;}.ui-icon-triangle-1-e{background-position:-32px -16px;}.ui-icon-triangle-1-se{background-position:-48px -16px;}.ui-icon-triangle-1-s{background-position:-64px -16px;}.ui-icon-triangle-1-sw{background-position:-80px -16px;}.ui-icon-triangle-1-w{background-position:-96px -16px;}.ui-icon-triangle-1-nw{background-position:-112px -16px;}.ui-icon-triangle-2-n-s{background-position:-128px -16px;}.ui-icon-triangle-2-e-w{background-position:-144px -16px;}.ui-icon-arrow-1-n{background-position:0 -32px;}.ui-icon-arrow-1-ne{background-position:-16px -32px;}.ui-icon-arrow-1-e{background-position:-32px -32px;}.ui-icon-arrow-1-se{background-position:-48px -32px;}.ui-icon-arrow-1-s{background-position:-64px -32px;}.ui-icon-arrow-1-sw{background-position:-80px -32px;}.ui-icon-arrow-1-w{background-position:-96px -32px;}.ui-icon-arrow-1-nw{background-position:-112px -32px;}.ui-icon-arrow-2-n-s{background-position:-128px -32px;}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px;}.ui-icon-arrow-2-e-w{background-position:-160px -32px;}.ui-icon-arrow-2-se-nw{background-position:-176px -32px;}.ui-icon-arrowstop-1-n{background-position:-192px -32px;}.ui-icon-arrowstop-1-e{background-position:-208px -32px;}.ui-icon-arrowstop-1-s{background-position:-224px -32px;}.ui-icon-arrowstop-1-w{background-position:-240px -32px;}.ui-icon-arrowthick-1-n{background-position:0 -48px;}.ui-icon-arrowthick-1-ne{background-position:-16px -48px;}.ui-icon-arrowthick-1-e{background-position:-32px -48px;}.ui-icon-arrowthick-1-se{background-position:-48px -48px;}.ui-icon-arrowthick-1-s{background-position:-64px -48px;}.ui-icon-arrowthick-1-sw{background-position:-80px -48px;}.ui-icon-arrowthick-1-w{background-position:-96px -48px;}.ui-icon-arrowthick-1-nw{background-position:-112px -48px;}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px;}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px;}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px;}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px;}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px;}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px;}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px;}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px;}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px;}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px;}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px;}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px;}.ui-icon-arrowreturn-1-w{background-position:-64px -64px;}.ui-icon-arrowreturn-1-n{background-position:-80px -64px;}.ui-icon-arrowreturn-1-e{background-position:-96px -64px;}.ui-icon-arrowreturn-1-s{background-position:-112px -64px;}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px;}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px;}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px;}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px;}.ui-icon-arrow-4{background-position:0 -80px;}.ui-icon-arrow-4-diag{background-position:-16px -80px;}.ui-icon-extlink{background-position:-32px -80px;}.ui-icon-newwin{background-position:-48px -80px;}.ui-icon-refresh{background-position:-64px -80px;}.ui-icon-shuffle{background-position:-80px -80px;}.ui-icon-transfer-e-w{background-position:-96px -80px;}.ui-icon-transferthick-e-w{background-position:-112px -80px;}.ui-icon-folder-collapsed{background-position:0 -96px;}.ui-icon-folder-open{background-position:-16px -96px;}.ui-icon-document{background-position:-32px -96px;}.ui-icon-document-b{background-position:-48px -96px;}.ui-icon-note{background-position:-64px -96px;}.ui-icon-mail-closed{background-position:-80px -96px;}.ui-icon-mail-open{background-position:-96px -96px;}.ui-icon-suitcase{background-position:-112px -96px;}.ui-icon-comment{background-position:-128px -96px;}.ui-icon-person{background-position:-144px -96px;}.ui-icon-print{background-position:-160px -96px;}.ui-icon-trash{background-position:-176px -96px;}.ui-icon-locked{background-position:-192px -96px;}.ui-icon-unlocked{background-position:-208px -96px;}.ui-icon-bookmark{background-position:-224px -96px;}.ui-icon-tag{background-position:-240px -96px;}.ui-icon-home{background-position:0 -112px;}.ui-icon-flag{background-position:-16px -112px;}.ui-icon-calendar{background-position:-32px -112px;}.ui-icon-cart{background-position:-48px -112px;}.ui-icon-pencil{background-position:-64px -112px;}.ui-icon-clock{background-position:-80px -112px;}.ui-icon-disk{background-position:-96px -112px;}.ui-icon-calculator{background-position:-112px -112px;}.ui-icon-zoomin{background-position:-128px -112px;}.ui-icon-zoomout{background-position:-144px -112px;}.ui-icon-search{background-position:-160px -112px;}.ui-icon-wrench{background-position:-176px -112px;}.ui-icon-gear{background-position:-192px -112px;}.ui-icon-heart{background-position:-208px -112px;}.ui-icon-star{background-position:-224px -112px;}.ui-icon-link{background-position:-240px -112px;}.ui-icon-cancel{background-position:0 -128px;}.ui-icon-plus{background-position:-16px -128px;}.ui-icon-plusthick{background-position:-32px -128px;}.ui-icon-minus{background-position:-48px -128px;}.ui-icon-minusthick{background-position:-64px -128px;}.ui-icon-close{background-position:-80px -128px;}.ui-icon-closethick{background-position:-96px -128px;}.ui-icon-key{background-position:-112px -128px;}.ui-icon-lightbulb{background-position:-128px -128px;}.ui-icon-scissors{background-position:-144px -128px;}.ui-icon-clipboard{background-position:-160px -128px;}.ui-icon-copy{background-position:-176px -128px;}.ui-icon-contact{background-position:-192px -128px;}.ui-icon-image{background-position:-208px -128px;}.ui-icon-video{background-position:-224px -128px;}.ui-icon-script{background-position:-240px -128px;}.ui-icon-alert{background-position:0 -144px;}.ui-icon-info{background-position:-16px -144px;}.ui-icon-notice{background-position:-32px -144px;}.ui-icon-help{background-position:-48px -144px;}.ui-icon-check{background-position:-64px -144px;}.ui-icon-bullet{background-position:-80px -144px;}.ui-icon-radio-on{background-position:-96px -144px;}.ui-icon-radio-off{background-position:-112px -144px;}.ui-icon-pin-w{background-position:-128px -144px;}.ui-icon-pin-s{background-position:-144px -144px;}.ui-icon-play{background-position:0 -160px;}.ui-icon-pause{background-position:-16px -160px;}.ui-icon-seek-next{background-position:-32px -160px;}.ui-icon-seek-prev{background-position:-48px -160px;}.ui-icon-seek-end{background-position:-64px -160px;}.ui-icon-seek-start{background-position:-80px -160px;}.ui-icon-seek-first{background-position:-80px -160px;}.ui-icon-stop{background-position:-96px -160px;}.ui-icon-eject{background-position:-112px -160px;}.ui-icon-volume-off{background-position:-128px -160px;}.ui-icon-volume-on{background-position:-144px -160px;}.ui-icon-power{background-position:0 -176px;}.ui-icon-signal-diag{background-position:-16px -176px;}.ui-icon-signal{background-position:-32px -176px;}.ui-icon-battery-0{background-position:-48px -176px;}.ui-icon-battery-1{background-position:-64px -176px;}.ui-icon-battery-2{background-position:-80px -176px;}.ui-icon-battery-3{background-position:-96px -176px;}.ui-icon-circle-plus{background-position:0 -192px;}.ui-icon-circle-minus{background-position:-16px -192px;}.ui-icon-circle-close{background-position:-32px -192px;}.ui-icon-circle-triangle-e{background-position:-48px -192px;}.ui-icon-circle-triangle-s{background-position:-64px -192px;}.ui-icon-circle-triangle-w{background-position:-80px -192px;}.ui-icon-circle-triangle-n{background-position:-96px -192px;}.ui-icon-circle-arrow-e{background-position:-112px -192px;}.ui-icon-circle-arrow-s{background-position:-128px -192px;}.ui-icon-circle-arrow-w{background-position:-144px -192px;}.ui-icon-circle-arrow-n{background-position:-160px -192px;}.ui-icon-circle-zoomin{background-position:-176px -192px;}.ui-icon-circle-zoomout{background-position:-192px -192px;}.ui-icon-circle-check{background-position:-208px -192px;}.ui-icon-circlesmall-plus{background-position:0 -208px;}.ui-icon-circlesmall-minus{background-position:-16px -208px;}.ui-icon-circlesmall-close{background-position:-32px -208px;}.ui-icon-squaresmall-plus{background-position:-48px -208px;}.ui-icon-squaresmall-minus{background-position:-64px -208px;}.ui-icon-squaresmall-close{background-position:-80px -208px;}.ui-icon-grip-dotted-vertical{background-position:0 -224px;}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px;}.ui-icon-grip-solid-vertical{background-position:-32px -224px;}.ui-icon-grip-solid-horizontal{background-position:-48px -224px;}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px;}.ui-icon-grip-diagonal-se{background-position:-80px -224px;}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{-moz-border-radius-topleft:4px;-webkit-border-top-left-radius:4px;-khtml-border-top-left-radius:4px;border-top-left-radius:4px;}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{-moz-border-radius-topright:4px;-webkit-border-top-right-radius:4px;-khtml-border-top-right-radius:4px;border-top-right-radius:4px;}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{-moz-border-radius-bottomleft:4px;-webkit-border-bottom-left-radius:4px;-khtml-border-bottom-left-radius:4px;border-bottom-left-radius:4px;}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{-moz-border-radius-bottomright:4px;-webkit-border-bottom-right-radius:4px;-khtml-border-bottom-right-radius:4px;border-bottom-right-radius:4px;}.ui-widget-overlay{background:#aaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x;opacity:.3;filter:Alpha(Opacity=30);}.ui-widget-shadow{margin:-8px 0 0 -8px;padding:8px;background:#aaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x;opacity:.3;filter:Alpha(Opacity=30);-moz-border-radius:8px;-khtml-border-radius:8px;-webkit-border-radius:8px;border-radius:8px;}
\ No newline at end of file
diff --git a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/js/jquery-1.7.1.min.js b/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/js/jquery-1.7.1.min.js
deleted file mode 100644
index 198b3ff..0000000
--- a/dist.mac/AttributionReport.app/Contents/Resources/lib/python2.7/matplotlib/backends/web_backend/jquery/js/jquery-1.7.1.min.js
+++ /dev/null
@@ -1,4 +0,0 @@
-/*! jQuery v1.7.1 jquery.com | jquery.org/license */
-(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"":"")+""),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){if(c!=="border")for(;g=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;ca",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o=""+"",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};
-f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&i.push({elem:this,matches:d.slice(e)});for(j=0;j0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/",""],legend:[1,"