py2ls 0.2.5.8__tar.gz → 0.2.5.10__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/PKG-INFO +1 -1
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/ips.py +349 -90
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/plot.py +65 -56
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/pyproject.toml +1 -1
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/README.md +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.DS_Store +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/.DS_Store +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/COMMIT_EDITMSG +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/FETCH_HEAD +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/HEAD +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/config +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/description +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/hooks/applypatch-msg.sample +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/hooks/commit-msg.sample +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/hooks/fsmonitor-watchman.sample +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/hooks/post-update.sample +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/hooks/pre-applypatch.sample +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/hooks/pre-commit.sample +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/hooks/pre-merge-commit.sample +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/hooks/pre-push.sample +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/hooks/pre-rebase.sample +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/hooks/pre-receive.sample +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/hooks/prepare-commit-msg.sample +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/hooks/push-to-checkout.sample +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/hooks/update.sample +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/index +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/info/exclude +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/logs/HEAD +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/logs/refs/heads/main +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/logs/refs/remotes/origin/HEAD +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/logs/refs/remotes/origin/main +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/.DS_Store +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/01/d5bd8065e6860c0bd23ff9fa57161806a099e1 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/09/08da26de58c114225ad81f484b80bf5d351b34 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/0b/409e1bc918277010f5679b402d1d1dda53e15c +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/12/c2808a1b3a4d0892a4154dfba1e2ae3770fa73 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/14/449a0e6ba4ea2f1a73acf63ef91c9c6193f9ed +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/15/a8e468aacfcb440e090020f36d0b985d45da23 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/1a/b4585881a6a42889f01aa0cfe25fd5acfaf46f +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/1c/3f92adda34344bcbbbf9d409c79855ae2aaea8 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/1c/9314c5f69b9390068a2a8616875d974849d71f +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/1d/fe9d9633b24ea560354f4f93d39c6e5f163ea0 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/20/72c28e83f4347959d29f7b3a6c1fc3e4ee6b59 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/24/6b368b986f758630c46dc02b7fa512b53422f7 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/25/b796accd261b9135fd32a2c00785f68edf6c46 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/27/aa6074f652bc6f7078f8647489d9ee8e24f0e2 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/28/c2969d785c1b892c2a96b3f00eba63a59811b3 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/2a/ae95d517d213b660bf4f65a4e0cfae7bb893eb +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/2a/fdf45791a26d42ccead35ace76a8f0b2a56561 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/30/a2f8da47ee947811dc8d993f5a06a45de374f4 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/32/fd627b62fad7cf3b2f9e34ab9777126a0987ad +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/34/9e31b6a3634cea102ce5588b98c11cc1738605 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/34/b6f3a2ee84f39bed4eee57f2c0e0afb994feb1 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/35/1a5f491ab97eee9d1ee699478d75a8bb5d3dc2 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/36/b4a1b7403abc6c360f8fe2cb656ab945254971 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/36/e56a361f526eafa59c5235a5c990bf288b5f9c +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/36/ef43e50009e59db11812c258846d9e38718173 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/39/7ead045fbbcfb17c62019eb18fe21ed05dbee5 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/39/b13be65125556784e44c7a1d9821703c7ab67e +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/3b/507acc7f23391644cc0b824b1e79fd2677a362 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/3b/bd972aa7ad680858f8dfbd0f7fcd97756f0d6f +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/3c/bbe5f4173d165127b9ad96119f1ec24c306ffc +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/3d/9d10d27724657a436c65a6254bfd213d4b3562 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/3f/d6561300938afbb3d11976cf9c8f29549280d9 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/41/dcf4b3bf0460946b2da93776cf9e836d62178f +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/43/dbd49b2ee367c5434dd545e3b5795434f2ef0b +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/45/b1b6178bacbfc997811a998b5cc60c1ea7fac8 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/47/6cbd5a7c5e35cddef2f8a38bdc4896d403b095 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/48/a88fc5806305d0bb0755ee6801161b79696972 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/4f/7afb40dff2153d857fc85748c2eecb85125042 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/50/08ddfcf53c02e82d7eee2e57c38e5672ef89f6 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/53/e0deb1cb4c2c606bced6e7f9a66b0fda60980d +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/56/e4e8b2d5545e0256090f45aa8fc42c5fe067d0 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/57/63d0c52f5c9c69e89d514a1f96034947abe21a +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/57/bd1c0199483ab316235b094543b85edec6c35e +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/58/20a729045d4dc7e37ccaf8aa8eec126850afe2 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/59/380c4c26bdcd4d9b71ae3e2e35f05b3f26c5ab +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/5a/192565abf89c9d765af846ce6d53a92b1ce7ad +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/60/f273eb1c412d916fa3f11318a7da7a9911b52a +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/61/570cec8c061abe74121f27f5face6c69b98f99 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/62/4488173ed2c8936fa5cea3cf5dd3f26a30b86e +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/62/7c81b23b4e56e87b042b650b0103653cc9e34a +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/62/d90ccf8cbefdc2e4fd475e7c6f4f76e9fdf801 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/63/100154b27846e8010e55b6bf4b3d7762c14c5f +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/64/27a4edff08f93d98f511418423f09f2ab90bcd +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/66/6227eeeba24073e63811e89f1449f3d958f183 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/66/c998778721d424bd0aae80602dabbffa93af2e +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/68/6df3072c8b025fb18106ed2df505994ad062a9 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/69/13c452ca319f7cbf6a0836dc10a5bb033c84e4 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/6a/52e747a2b349b128d1490d9e896d2323818eb7 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/6b/7fde264d93a7a0986d394c46c7650d0ce2ab92 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/6c/cebb29b7f3f5b0c889f6dadbf9ff066554587d +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/6d/c2cdf4a84e538e5d4777486aeff87e42f41799 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/6d/ee29dbdcc84edeeacede105110446f3ccac963 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/71/36b2074a2754be8b58127d82250e5b37e3c373 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/72/245a05b0966011cb381e6b32b0465000e969ab +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/72/e4179337639859678ddaecf38b16f33aaec8e1 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/78/063f4c863fc371ec0313303c0a81283b35d9b6 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/78/3d4167bc95c9d2175e0df03ef1c1c880ba75ab +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/79/7ae089b2212a937840e215276005ce76881307 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/7e/5956c806b5edc344d46dab599dec337891ba1f +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/81/8f26b7bf042269729020cf944fc362d66ba27e +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/82/70b319ce4046854fbe7dc41054b6c2d112dab2 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/84/59071b722a255b774a80b27746033f8141ab39 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/85/aee46f478e9afdb84d50a05242c53b04ed2e21 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/86/e288b46f8fe179907e4413f665aeb5053fddb1 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/87/ef1fc3f7f1ddc4d0ab9b3e65381ce9f3388621 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/8b/84f56978e1de8f2ae82abce5f8b3e182d365cd +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/8e/55a7d2b96184030211f20c9b9af201eefcac82 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/91/c69ad88fe0ba94aa7859fb5f7edac5e6f1a3f7 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/94/74152b4b463d70ae5ad07f0c658be3e296026b +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/94/f7dbe88e80c4205a901b71eb8f181974376bba +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/97/1aef09ea939f46b60b9646f8d524c78a9220f4 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/9b/ec5ee2236ee2d5532c36bfd132e23c58fdb69c +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/9d/0df52899fe95279059286d9c0ec42287edc168 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/a1/5389729850729fc7bd78a54f26fce77f30be12 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/a1/906da89d1174f74867800c74c43af36253bd5e +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/a4/63fdd23e5efd713db8a71f316f3a1c7bd60916 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/a5/ec8f74642fbba27f7ea78c53b372ae0c7dedce +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/a7/3e13eafee65c5b8d73ad2d3ea46d0eee82f0d3 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/b0/56be4be89ba6b76949dd641df45bb7036050c8 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/b0/9cd7856d58590578ee1a4f3ad45d1310a97f87 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/b2/18e6a0f0f1c4df8cdefa9852058348abc713b7 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/b3/4f7f271c6d6105e35a6556ffda71d03afe8c96 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/b3/69579064bde9de9a19d114fc33e4e48cc8c0e4 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/b5/61831c7dce8ea51e7ee6b6fa35745f14d8242d +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/b7/2c9e75ab7d0afe594664650aa8f6c772f5ac64 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/bb/81ccc0513f18fc160b54a82861e9a80d23f4f6 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/bb/934eb33bc1a8b85630bf680caffd99560c1b8f +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/bf/67907e337021ebff434e02b19b30a741c144af +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/bf/b54d65922ce1dfda1aaa014913a54e7172d0bc +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/c1/20fc812b9ad311c34a3608512d6a9d976bb48e +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/c1/397c6ed72c4e20ef6b9ab83163e9a6baba5b45 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/c4/cba65f1163661999ee4b8ed23342b63bc1300c +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/c6/7f17e5707313600efcb85e9a3fedea35dba591 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/c6/f32aced880bd165a251cb52b26b0c1107e2141 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/cc/45df1d317a2eb63ff1ff3a5f3b4a9f98fd92b5 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/cd/822b3574a88ebdd1ed82fd6983f37e626d52b4 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/cf/0c0d9c6fb09473aaeb7f7e2edbd770c3f2ef3d +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/d2/992df305f4b56a466a2f221aeb182ddd20f418 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/d6/39e8af592cd75a318d8affddd1bcc70c2095f2 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/d6/9ab1c4aadf279936dd778e8346ba60f74705b6 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/d8/4688b54c0040a30976b3a6540bc47adf7ce680 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/d9/005f2cc7fc4e65f14ed5518276007c08cf2fd0 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/d9/c2403fd166ce791b4e9d0c6792ed8342c71fcd +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/d9/dfa5aee51e92a541b707e8e7baea6f06deff98 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/db/141dbaa93594df2a8156182f361ee4db829359 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/db/3f2cd643292057936230b95cf7ec3046affe11 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/db/ffa8ea7bda721d0cee7b9e4ce5b2ef927733ff +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/dc/c2bdbafb3296e09d9ee4955cfa55d275825f94 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/dc/cdbd4266765d840be2ae35ab1752a0fa312c16 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/dd/87fb5f606fe380d81e6fe3a2c98f9f99e3e09b +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/de/214c626ac2dd2685bfaa0bc0fc20f528d014d7 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/df/e0770424b2a19faf507a501ebfc23be8f54e7b +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/e2/f2f8f4c25e62a297fc55f36acc6b01cfbab76f +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/e3/1356f90ea6dd0577b5e0b40b206319adcbf085 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/e3/5a4dafc50850cacac7bf76c56db2715cbda2c4 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/e4/6c715352db9fe3c887a635f1916df4ca1f4ff9 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/e5/0580a0bd1e1b3d29f834382b80fceb61d5cf0c +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/e9/391ffe371f1cc43b42ef09b705d9c767c2e14f +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/ea/3a18cc75e53792744ef754e05d3f4481768c13 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/ec/40fd8bf8e4c342534a9fc020289e402ba6bc9d +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/ec/d980279432b13f0374b90ca439a6329cdece0f +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/ee/cee64eacaff022dcdc509c0c2b1da492f21060 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/f1/e50757fddc28b445545dc7e2759b54cdd0f42e +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/f4/b64d3107b39e3ad6f540c6607004ea34e6c024 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/f4/ba7f815b886797b73fede071d86e0c134d2bc7 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/f5/61c3c1bf1c9ea9c9d1f556a7be2869f71f3bdf +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/f6/44a8ff56fa035105fc517cbb1ac46c3d8e349a +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/f7/c98ba5c2f903e603b1f5e63d49fbc8a43815cc +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/f9/045a08e96eb76848fc4d68e3e3e687cca39a2d +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/fa/147e6bb78a2e8db241d231295fd7f1ed061af8 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/objects/fc/292e793ecfd42240ac43be407023bd731fa9e7 +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/refs/.DS_Store +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/refs/heads/main +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/refs/remotes/origin/HEAD +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.git/refs/remotes/origin/main +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.gitattributes +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/.gitignore +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/LICENSE +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/README.md +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/__init__.py +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/batman.py +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/bio.py +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/brain_atlas.py +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/chat.py +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/corr.py +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/correlators.py +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/.DS_Store +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/db2ls_sql_chtsht.json +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/docs_links.json +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/email/email_html_template.html +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/hyper_param_autogluon_zeroshot2024.json +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/hyper_param_tabrepo_2024.py +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/lang_code_iso639.json +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/mygenes_fields_241022.txt +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/sns_info.json +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/.DS_Store +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/example/.DS_Store +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/example/style1.pdf +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/example/style2.pdf +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/example/style3.pdf +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/example/style4.pdf +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/example/style5.pdf +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/example/style6.pdf +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/example/style7.pdf +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/example/style8.pdf +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/example/style9.pdf +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/style1.json +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/style10.json +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/style11.json +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/style12.json +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/style2.json +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/style3.json +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/style4.json +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/style5.json +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/style6.json +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/style7.json +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/style8.json +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/style9.json +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/stylelib/.DS_Store +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/stylelib/grid.mplstyle +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/stylelib/high-contrast.mplstyle +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/stylelib/high-vis.mplstyle +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/stylelib/ieee.mplstyle +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/stylelib/light.mplstyl +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/stylelib/muted.mplstyle +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/stylelib/nature-reviews-latex.mplstyle +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/stylelib/nature-reviews.mplstyle +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/stylelib/nature.mplstyle +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/stylelib/no-latex.mplstyle +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/stylelib/notebook.mplstyle +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/stylelib/paper.mplstyle +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/stylelib/retro.mplstyle +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/stylelib/sans.mplstyle +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/stylelib/scatter.mplstyle +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/stylelib/science.mplstyle +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/stylelib/std-colors.mplstyle +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/styles/stylelib/vibrant.mplstyle +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/tiles.csv +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/usages_pd.json +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/data/usages_sns.json +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/db2ls.py +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/doc.py +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/ec2ls.py +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/export_requirements.py +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/fetch_update.py +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/freqanalysis.py +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/ich2ls.py +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/ml2ls.py +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/mol.py +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/netfinder.py +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/nl2ls.py +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/ocr.py +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/setuptools-70.1.0-py3-none-any.whl +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/sleep_events_detectors.py +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/stats.py +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/translator.py +0 -0
- {py2ls-0.2.5.8 → py2ls-0.2.5.10}/py2ls/wb_detector.py +0 -0
@@ -3,7 +3,7 @@ import pandas as pd
|
|
3
3
|
import sys
|
4
4
|
import os
|
5
5
|
from IPython.display import display
|
6
|
-
from typing import List, Optional, Union,Any
|
6
|
+
from typing import Dict,List, Optional, Union,Any
|
7
7
|
|
8
8
|
from regex import X
|
9
9
|
|
@@ -3589,6 +3589,7 @@ def fload(fpath, kind=None, **kwargs):
|
|
3589
3589
|
|
3590
3590
|
# https://github.com/eyurtsev/fcsparser
|
3591
3591
|
meta, data = fcsparser.parse(fpath, reformat_meta=True)
|
3592
|
+
print("meta, data = fload(*.fcs)")
|
3592
3593
|
return meta, data
|
3593
3594
|
|
3594
3595
|
elif kind == "mplstyle":
|
@@ -5245,63 +5246,169 @@ def split_path(fpath):
|
|
5245
5246
|
dir_ch = "".join(fpath.split(f_slash)[-1:])
|
5246
5247
|
return dir_par, dir_ch
|
5247
5248
|
|
5249
|
+
from pathlib import Path
|
5250
|
+
import matplotlib.pyplot as plt
|
5251
|
+
from PIL import Image
|
5252
|
+
import numpy as np
|
5253
|
+
import cv2
|
5248
5254
|
|
5249
|
-
def figsave(*args, dpi=300):
|
5250
|
-
|
5251
|
-
|
5255
|
+
def figsave(*args, dpi=300, **kwargs):
|
5256
|
+
bbox_inches = kwargs.pop("bbox_inches", "tight")
|
5257
|
+
pad_inches = kwargs.pop("pad_inches", 0)
|
5258
|
+
facecolor = kwargs.pop("facecolor", "white")
|
5259
|
+
edgecolor = kwargs.pop("edgecolor", "auto")
|
5252
5260
|
|
5253
5261
|
dir_save = None
|
5254
5262
|
fname = None
|
5255
5263
|
img = None
|
5256
|
-
|
5264
|
+
|
5257
5265
|
for arg in args:
|
5258
5266
|
if isinstance(arg, str):
|
5259
|
-
|
5260
|
-
|
5267
|
+
path = Path(arg)
|
5268
|
+
if path.suffix: # Has file extension
|
5269
|
+
fname = path.name
|
5270
|
+
dir_save = path.parent
|
5261
5271
|
else:
|
5262
|
-
|
5272
|
+
dir_save = path
|
5263
5273
|
elif isinstance(arg, (Image.Image, np.ndarray)):
|
5264
|
-
img = arg # Store
|
5274
|
+
img = arg # Store PIL image or numpy array
|
5265
5275
|
|
5266
|
-
|
5267
|
-
|
5276
|
+
# Set default save directory
|
5277
|
+
dir_save = Path(dir_save) if dir_save else Path(".")
|
5278
|
+
dir_save.mkdir(parents=True, exist_ok=True)
|
5279
|
+
|
5280
|
+
# Handle filename and extension
|
5281
|
+
if fname is None:
|
5282
|
+
fname = "figure"
|
5283
|
+
fname = dir_save / fname
|
5284
|
+
if fname.suffix == "":
|
5285
|
+
fname = fname.with_suffix(".pdf") # Default format
|
5268
5286
|
|
5269
|
-
|
5270
|
-
|
5271
|
-
|
5272
|
-
if
|
5273
|
-
|
5287
|
+
ftype = fname.suffix.lstrip(".").lower()
|
5288
|
+
|
5289
|
+
# Save figure based on file type
|
5290
|
+
if ftype == "eps":
|
5291
|
+
plt.savefig(fname, format="eps", bbox_inches=bbox_inches)
|
5292
|
+
plt.savefig(fname.with_suffix(".pdf"), format="pdf", dpi=dpi,
|
5293
|
+
pad_inches=pad_inches, bbox_inches=bbox_inches,
|
5294
|
+
facecolor=facecolor, edgecolor=edgecolor)
|
5295
|
+
elif ftype == "pdf":
|
5296
|
+
plt.savefig(fname, format="pdf", dpi=dpi, pad_inches=pad_inches,
|
5297
|
+
bbox_inches=bbox_inches, facecolor=facecolor, edgecolor=edgecolor)
|
5298
|
+
elif ftype in ["jpg", "jpeg", "png", "tiff", "tif"]:
|
5299
|
+
if img is not None: # If an image is provided
|
5300
|
+
if isinstance(img, Image.Image):
|
5301
|
+
img = img.convert("RGB") if img.mode == "RGBA" else img
|
5302
|
+
img.save(fname, format=ftype.upper(), dpi=(dpi, dpi))
|
5303
|
+
elif isinstance(img, np.ndarray):
|
5304
|
+
if img.ndim == 2:
|
5305
|
+
Image.fromarray(img).save(fname, format=ftype.upper(), dpi=(dpi, dpi))
|
5306
|
+
elif img.ndim == 3:
|
5307
|
+
if img.shape[2] == 3:
|
5308
|
+
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
|
5309
|
+
elif img.shape[2] == 4:
|
5310
|
+
img = cv2.cvtColor(img, cv2.COLOR_BGRA2RGBA)
|
5311
|
+
Image.fromarray(img).save(fname, format=ftype.upper(), dpi=(dpi, dpi))
|
5312
|
+
else:
|
5313
|
+
raise ValueError("Unexpected image dimensions.")
|
5314
|
+
else:
|
5315
|
+
plt.savefig(fname, format=ftype, dpi=dpi, pad_inches=pad_inches,
|
5316
|
+
bbox_inches=bbox_inches, facecolor=facecolor, edgecolor=edgecolor)
|
5317
|
+
elif ftype == "ico":
|
5318
|
+
if img is None:
|
5319
|
+
plt.savefig(fname, dpi=dpi, pad_inches=pad_inches,
|
5320
|
+
bbox_inches=bbox_inches, facecolor=facecolor, edgecolor=edgecolor)
|
5321
|
+
img = Image.open(fname)
|
5322
|
+
img = img.convert("RGBA")
|
5323
|
+
icon_sizes = [(32, 32), (64, 64), (128, 128), (256, 256)]
|
5324
|
+
img.save(fname, format="ICO", sizes=icon_sizes)
|
5325
|
+
print(f"Icon saved @: {fname} with sizes: {icon_sizes}")
|
5326
|
+
else:
|
5327
|
+
raise ValueError(f"Unsupported file format: {ftype}")
|
5328
|
+
|
5329
|
+
print(f"\nSaved @ {fname} (dpi={dpi})")
|
5330
|
+
|
5331
|
+
def figsave(*args, dpi=300, **kwargs):
|
5332
|
+
"""
|
5333
|
+
Save a Matplotlib figure or image file in various formats.
|
5334
|
+
|
5335
|
+
This function automatically determines whether to save a Matplotlib figure
|
5336
|
+
or an image (PIL or NumPy array) and handles different file formats, including:
|
5337
|
+
- PDF, EPS, PNG, JPG, TIFF, ICO, EMF
|
5338
|
+
|
5339
|
+
Parameters:
|
5340
|
+
-----------
|
5341
|
+
*args : str, PIL.Image, np.ndarray
|
5342
|
+
- File path (directory and/or filename) to save the figure.
|
5343
|
+
- If an image is provided (PIL or NumPy), it will be saved accordingly.
|
5344
|
+
|
5345
|
+
dpi : int, optional (default=300)
|
5346
|
+
- Resolution (dots per inch) for saved figures.
|
5347
|
+
|
5348
|
+
**kwargs : dict
|
5349
|
+
- Additional keyword arguments for `matplotlib.pyplot.savefig()`, including:
|
5350
|
+
- bbox_inches (str, default="tight"): Bounding box for figure.
|
5351
|
+
- pad_inches (float, default=0): Padding around figure.
|
5352
|
+
- facecolor (str, default="white"): Background color.
|
5353
|
+
- edgecolor (str, default="auto"): Edge color.
|
5354
|
+
|
5355
|
+
Supported Formats:
|
5356
|
+
------------------
|
5357
|
+
- Vector: `pdf`, `eps`, `emf`
|
5358
|
+
- Raster: `png`, `jpg`, `jpeg`, `tiff`, `tif`, `ico`
|
5359
|
+
|
5360
|
+
Example Usage:
|
5361
|
+
--------------
|
5362
|
+
>>> figsave("output_plot.pdf")
|
5363
|
+
>>> figsave("figs/plot.png", dpi=600)
|
5364
|
+
>>> figsave("./results/figure", format="pdf")
|
5365
|
+
>>> figsave("icons/logo.ico", image) # Save an image file as an icon
|
5366
|
+
|
5367
|
+
Returns:
|
5368
|
+
--------
|
5369
|
+
None
|
5370
|
+
"""
|
5371
|
+
import matplotlib.pyplot as plt
|
5372
|
+
from PIL import Image
|
5373
|
+
from pathlib import Path
|
5374
|
+
|
5375
|
+
bbox_inches=kwargs.pop("bbox_inches","tight")
|
5376
|
+
pad_inches=kwargs.pop("pad_inches",0)
|
5377
|
+
facecolor=kwargs.pop("facecolor",'white')
|
5378
|
+
edgecolor=kwargs.pop("edgecolor",'auto')
|
5379
|
+
|
5380
|
+
dir_save = None
|
5381
|
+
fname = None
|
5382
|
+
img = None
|
5383
|
+
for arg in args:
|
5384
|
+
if isinstance(arg, str):
|
5385
|
+
path = Path(arg)
|
5386
|
+
if path.suffix: # Has file extension
|
5387
|
+
fname = path.name
|
5388
|
+
dir_save = path.parent
|
5389
|
+
else:
|
5390
|
+
dir_save = path
|
5391
|
+
elif isinstance(arg, (Image.Image, np.ndarray)):
|
5392
|
+
img = arg # Store PIL image or numpy array
|
5274
5393
|
|
5394
|
+
dir_save = Path(dir_save) if dir_save else Path(".")
|
5395
|
+
dir_save.mkdir(parents=True, exist_ok=True)
|
5396
|
+
# Handle filename and extension
|
5275
5397
|
if fname is None:
|
5276
|
-
fname =
|
5277
|
-
mkdir(dir_par)
|
5278
|
-
ftype = fname.split(".")[-1]
|
5279
|
-
if len(fname.split(".")) == 1:
|
5280
|
-
ftype = "nofmt"
|
5281
|
-
fname = dir_par + fname + "." + ftype
|
5398
|
+
fname = dir_save
|
5282
5399
|
else:
|
5283
|
-
fname =
|
5400
|
+
fname = dir_save / fname
|
5401
|
+
if fname.suffix == "":
|
5402
|
+
fname = fname.with_suffix(".pdf") # Default format
|
5403
|
+
|
5404
|
+
ftype = fname.suffix.lstrip(".").lower()
|
5284
5405
|
|
5285
5406
|
# Save figure based on file type
|
5286
|
-
if ftype
|
5287
|
-
plt.savefig(fname, format="eps", bbox_inches=
|
5288
|
-
plt.savefig(
|
5289
|
-
|
5290
|
-
|
5291
|
-
bbox_inches="tight",
|
5292
|
-
dpi=dpi,
|
5293
|
-
pad_inches=0,
|
5294
|
-
)
|
5295
|
-
elif ftype.lower() == "nofmt": # default: both "tif" and "pdf"
|
5296
|
-
fname_corr = fname.replace("nofmt", "pdf")
|
5297
|
-
plt.savefig(
|
5298
|
-
fname_corr, format="pdf", bbox_inches="tight", dpi=dpi, pad_inches=0
|
5299
|
-
)
|
5300
|
-
fname = fname.replace("nofmt", "tif")
|
5301
|
-
plt.savefig(fname, format="tiff", dpi=dpi, bbox_inches="tight", pad_inches=0)
|
5302
|
-
print(f"default saving filetype: both 'tif' and 'pdf")
|
5303
|
-
elif ftype.lower() == "pdf":
|
5304
|
-
plt.savefig(fname, format="pdf", bbox_inches="tight", dpi=dpi, pad_inches=0)
|
5407
|
+
if ftype == "eps":
|
5408
|
+
plt.savefig(fname, format="eps", bbox_inches=bbox_inches)
|
5409
|
+
plt.savefig(fname.with_suffix(".pdf"), format="pdf", dpi=dpi,
|
5410
|
+
pad_inches=pad_inches, bbox_inches=bbox_inches,
|
5411
|
+
facecolor=facecolor, edgecolor=edgecolor)
|
5305
5412
|
elif ftype.lower() in ["jpg", "jpeg", "png", "tiff", "tif"]:
|
5306
5413
|
if img is not None: # If a PIL image is provided
|
5307
5414
|
if isinstance(img, Image.Image):
|
@@ -5310,63 +5417,46 @@ def figsave(*args, dpi=300):
|
|
5310
5417
|
img.save(fname, format=ftype.upper(), dpi=(dpi, dpi))
|
5311
5418
|
elif isinstance(img, np.ndarray):
|
5312
5419
|
import cv2
|
5313
|
-
|
5314
|
-
# Check the shape of the image to determine color mode
|
5315
5420
|
if img.ndim == 2:
|
5316
5421
|
# Grayscale image
|
5317
|
-
Image.fromarray(img).save(
|
5318
|
-
fname, format=ftype.upper(), dpi=(dpi, dpi)
|
5319
|
-
)
|
5422
|
+
Image.fromarray(img).save(fname, format=ftype.upper(), dpi=(dpi, dpi))
|
5320
5423
|
elif img.ndim == 3:
|
5321
5424
|
if img.shape[2] == 3:
|
5322
5425
|
# RGB image
|
5323
5426
|
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
|
5324
|
-
Image.fromarray(img).save(
|
5325
|
-
fname, format=ftype.upper(), dpi=(dpi, dpi)
|
5326
|
-
)
|
5427
|
+
Image.fromarray(img).save(fname, format=ftype.upper(), dpi=(dpi, dpi))
|
5327
5428
|
elif img.shape[2] == 4:
|
5328
5429
|
# RGBA image
|
5329
|
-
img = cv2.cvtColor(
|
5330
|
-
|
5331
|
-
) # Convert BGRA to RGBA
|
5332
|
-
Image.fromarray(img).save(
|
5333
|
-
fname, format=ftype.upper(), dpi=(dpi, dpi)
|
5334
|
-
)
|
5430
|
+
img = cv2.cvtColor(img, cv2.COLOR_BGRA2RGBA) # Convert BGRA to RGBA
|
5431
|
+
Image.fromarray(img).save(fname, format=ftype.upper(), dpi=(dpi, dpi))
|
5335
5432
|
else:
|
5336
|
-
raise ValueError(
|
5337
|
-
"Unexpected number of channels in the image array."
|
5338
|
-
)
|
5433
|
+
raise ValueError("Unexpected number of channels in the image array.")
|
5339
5434
|
else:
|
5340
|
-
raise ValueError(
|
5341
|
-
"Image array has an unexpected number of dimensions."
|
5342
|
-
)
|
5435
|
+
raise ValueError("Image array has an unexpected number of dimensions.")
|
5343
5436
|
else:
|
5344
|
-
plt.savefig(
|
5345
|
-
|
5346
|
-
|
5347
|
-
dpi=dpi,
|
5348
|
-
bbox_inches="tight",
|
5349
|
-
transparent=True,
|
5350
|
-
pad_inches=0,
|
5351
|
-
)
|
5352
|
-
elif ftype.lower() == "emf":
|
5353
|
-
plt.savefig(fname, format="emf", dpi=dpi, bbox_inches="tight", pad_inches=0)
|
5354
|
-
elif ftype.lower() == "fig":
|
5355
|
-
plt.savefig(fname, format="pdf", bbox_inches="tight", dpi=dpi, pad_inches=0)
|
5356
|
-
|
5437
|
+
plt.savefig(fname,format=ftype.lower(),dpi=dpi,pad_inches=pad_inches,bbox_inches=bbox_inches,facecolor=facecolor,edgecolor=edgecolor)
|
5438
|
+
elif ftype.lower() in ["emf","pdf","fig"]:
|
5439
|
+
plt.savefig(fname,format=ftype.lower(),dpi=dpi,pad_inches=pad_inches,bbox_inches=bbox_inches,facecolor=facecolor,edgecolor=edgecolor)
|
5357
5440
|
elif ftype.lower() == "ico":
|
5358
5441
|
# Ensure the image is in a format that can be saved as an icon (e.g., 32x32, 64x64, etc.)
|
5359
5442
|
if img is None: # If no image is provided, use the matplotlib figure
|
5360
|
-
img = plt.figure()
|
5361
|
-
|
5443
|
+
img = plt.figure()
|
5444
|
+
print(fname)
|
5445
|
+
img.savefig(fname,
|
5446
|
+
format="png",
|
5447
|
+
dpi=dpi,
|
5448
|
+
pad_inches=pad_inches,
|
5449
|
+
bbox_inches=bbox_inches,
|
5450
|
+
facecolor=facecolor,
|
5451
|
+
edgecolor=edgecolor )
|
5362
5452
|
img = Image.open(fname) # Load the saved figure image
|
5363
5453
|
|
5364
5454
|
# Resize the image to typical icon sizes and save it as .ico
|
5365
5455
|
icon_sizes = [(32, 32), (64, 64), (128, 128), (256, 256)]
|
5366
|
-
img = img.convert("RGBA")
|
5456
|
+
img = img.convert("RGBA")
|
5367
5457
|
img.save(fname, format="ICO", sizes=icon_sizes)
|
5368
5458
|
print(f"Icon saved @: {fname} with sizes: {icon_sizes}")
|
5369
|
-
print(f"\
|
5459
|
+
print(f"\n✅ Saved @: dpi={dpi}\n{fname}")
|
5370
5460
|
|
5371
5461
|
|
5372
5462
|
def is_str_color(s):
|
@@ -8022,21 +8112,20 @@ def format_excel(
|
|
8022
8112
|
pil_img=img_path = None
|
8023
8113
|
if isinstance(img_data, dict):
|
8024
8114
|
if "path" in img_data:
|
8025
|
-
|
8026
|
-
img_ = drawing.image.Image(img_path)
|
8115
|
+
img_ = drawing.image.Image(img_data["path"])# File path
|
8027
8116
|
elif "image" in img_data:
|
8028
|
-
|
8117
|
+
img_ = drawing.image.Image(img_data["image"])# PIL Image object
|
8029
8118
|
elif "array" in img_data:
|
8030
|
-
|
8119
|
+
img_ = drawing.image.Image(Image.fromarray(img_data["array"]))# Convert NumPy array to PIL Image
|
8031
8120
|
|
8032
8121
|
img_width = img_data.get("width", None)
|
8033
8122
|
img_height = img_data.get("height", None)
|
8034
8123
|
elif isinstance(img_data, str):
|
8035
|
-
|
8124
|
+
img_ = drawing.image.Image(img_data)# Direct file path
|
8036
8125
|
elif isinstance(img_data, (PIL.Image.Image,PIL.PngImagePlugin.PngImageFile)):
|
8037
|
-
|
8126
|
+
img_ = drawing.image.Image(img_data)# Direct PIL Image object
|
8038
8127
|
elif isinstance(img_data, np.ndarray):
|
8039
|
-
|
8128
|
+
img_ = drawing.image.Image(Image.fromarray(img_data))# Convert NumPy array to PIL Image
|
8040
8129
|
elif pil_img:
|
8041
8130
|
img_ = drawing.image.Image(pil_img)
|
8042
8131
|
|
@@ -8230,7 +8319,89 @@ def _df_outlier(
|
|
8230
8319
|
|
8231
8320
|
return processed_data
|
8232
8321
|
|
8322
|
+
def df_group(
|
8323
|
+
data: pd.DataFrame,
|
8324
|
+
columns: Union[str, list, None] = None,
|
8325
|
+
by: str = None,
|
8326
|
+
param: Dict[str, Any] = None,
|
8327
|
+
sep: Union[str, list] = [", ",","],
|
8328
|
+
dropna: bool = True,
|
8329
|
+
unique: bool = False,
|
8330
|
+
astype: type = str,
|
8331
|
+
merge: List[str] = None,
|
8332
|
+
merge_symbo_column:str=' & ',
|
8333
|
+
merge_symbo_cell:str='[]',# ["{}","()","[]"]
|
8334
|
+
) -> pd.DataFrame:
|
8335
|
+
"""
|
8336
|
+
Groups a dataframe based on a specified column and applies aggregation functions dynamically.
|
8337
|
+
|
8338
|
+
Parameters:
|
8339
|
+
data (pd.DataFrame): The dataframe to be grouped.
|
8340
|
+
columns (Union[str, list, None]): Columns to select; if None, all columns are selected.
|
8341
|
+
by (str): The column name to group by.
|
8342
|
+
param (dict): A dictionary specifying aggregation rules.
|
8343
|
+
sep (Union[str, list]): Separator for concatenated values. when sep is a list, then sep[0] used for general, sep[1] used in the merging
|
8344
|
+
dropna (bool): Whether to drop NaN values before aggregation.
|
8345
|
+
unique (bool): Whether to apply uniqueness before concatenation.
|
8346
|
+
astype (type): Data type to cast values before aggregation.
|
8347
|
+
merge (List[str]): List of columns to merge into a single paired column.
|
8348
|
+
merge_symbo_column:str: indicate in the columns, default ("&")
|
8349
|
+
merge_symbo_cell:str=default: '{}' or can select from ["{}","()","[]"]
|
8233
8350
|
|
8351
|
+
Usage:
|
8352
|
+
data = pd.DataFrame({
|
8353
|
+
"Cage Tag": [1, 1, 2, 2, 3],
|
8354
|
+
"Physical Tag": ["A1", "A2", "B1", "B2", "C1"],
|
8355
|
+
"Sex": ["M", "F", "M", "M", "F"],
|
8356
|
+
"Date of Birth": ["2021-06-01", "2021-06-02", "2021-07-01", "2021-07-02", "2021-08-01"],
|
8357
|
+
"Age": [34, 35, 30, 31, 29],
|
8358
|
+
"State": ["Mating", "Resting", "Mating", "Resting", "Mating"],
|
8359
|
+
"Owner": ["Dr. Smith", "Dr. Smith", "Dr. Brown", "Dr. Brown", "Dr. Lee"],
|
8360
|
+
})
|
8361
|
+
display(data)
|
8362
|
+
result = df_group(data,
|
8363
|
+
# columns=["Sex", "Date of Birth", "Age", "State"],
|
8364
|
+
by="Cage Tag",
|
8365
|
+
merge=["Age", "State"],
|
8366
|
+
merge_symbo_column="|",
|
8367
|
+
# astype=str
|
8368
|
+
# sep=[',', '_'],
|
8369
|
+
merge_symbo_cell=None
|
8370
|
+
)
|
8371
|
+
result
|
8372
|
+
|
8373
|
+
|
8374
|
+
"""
|
8375
|
+
if param is None:
|
8376
|
+
param = {}
|
8377
|
+
if columns is None:
|
8378
|
+
columns = data.columns.tolist()
|
8379
|
+
elif isinstance(columns, str):
|
8380
|
+
columns = [columns]
|
8381
|
+
if not isinstance(sep, list):
|
8382
|
+
sep = [sep]
|
8383
|
+
sep.extend(sep) if len(sep)==1 else None
|
8384
|
+
|
8385
|
+
# Merge specified columns into a single column
|
8386
|
+
if merge:
|
8387
|
+
merge_col_name = merge_symbo_column.join(merge)
|
8388
|
+
# data[merge_col_name] = data[merge].apply(lambda row: tuple(map(astype, row.dropna() if dropna else row)), axis=1)
|
8389
|
+
if merge_symbo_cell is None:
|
8390
|
+
data[merge_col_name] = data[merge].apply(lambda row: f"{sep[1].join(map(astype, row.dropna()))}" if dropna else f"{sep[1].join(map(astype, row))}", axis=1)
|
8391
|
+
elif len(merge_symbo_cell)==2:
|
8392
|
+
data[merge_col_name] = data[merge].apply(lambda row: f"{merge_symbo_cell[0]}{sep[1].join(map(astype, row.dropna()))}{merge_symbo_cell[1]}" if dropna else f"{merge_symbo_cell[0]}{sep[1].join(map(astype, row))}{merge_symbo_cell[1]}", axis=1)
|
8393
|
+
else:
|
8394
|
+
data[merge_col_name] = data[merge].apply(lambda row: f"[{sep[1].join(map(astype, row.dropna()))}]" if dropna else f"[{sep[1].join(map(astype, row))}]", axis=1)
|
8395
|
+
columns.append(merge_col_name)
|
8396
|
+
|
8397
|
+
default_aggregations = {
|
8398
|
+
col: (lambda x: sep[0].join(map(astype, x.dropna().unique() if unique else x.dropna())) if dropna else sep[0].join(map(astype, x.unique() if unique else x)))
|
8399
|
+
for col in columns if col != by and (merge is None or col not in merge)
|
8400
|
+
}
|
8401
|
+
aggregation_rules = {**default_aggregations, **param}
|
8402
|
+
|
8403
|
+
grouped_df = data.groupby(by).agg(aggregation_rules).reset_index()
|
8404
|
+
return grouped_df
|
8234
8405
|
def df_outlier(
|
8235
8406
|
data,
|
8236
8407
|
columns=None,
|
@@ -10208,11 +10379,19 @@ def get_df_format(data, threshold_unique=0.5, verbose=False):
|
|
10208
10379
|
from sklearn.cluster import AgglomerativeClustering
|
10209
10380
|
from sklearn.preprocessing import StandardScaler
|
10210
10381
|
|
10211
|
-
long_score = 0
|
10212
|
-
wide_score = 0
|
10213
|
-
|
10382
|
+
long_score,wide_score,fs = 0,0,500
|
10214
10383
|
n_rows, n_cols = data.shape
|
10215
|
-
|
10384
|
+
# -----to reduce memory, only check 500 rows/columns----
|
10385
|
+
if n_rows > fs:
|
10386
|
+
if verbose:
|
10387
|
+
print(f"Sampling {fs} rows from {n_rows} rows.")
|
10388
|
+
data = data.sample(n=fs, random_state=1)
|
10389
|
+
if n_cols > fs:
|
10390
|
+
if verbose:
|
10391
|
+
print(f"Using first {fs} columns out of {n_cols} columns.")
|
10392
|
+
data = data.iloc[:, :fs]
|
10393
|
+
n_rows, n_cols = data.shape
|
10394
|
+
|
10216
10395
|
# Step 1: Row-Column Ratio Heuristic
|
10217
10396
|
if n_rows > 3 * n_cols:
|
10218
10397
|
long_score += 2
|
@@ -12520,3 +12699,83 @@ def py2installer(
|
|
12520
12699
|
raise
|
12521
12700
|
|
12522
12701
|
print("\nPackaging complete. Check the output directory for the executable.")
|
12702
|
+
|
12703
|
+
|
12704
|
+
def set_theme(
|
12705
|
+
context="paper",
|
12706
|
+
style="whitegrid",
|
12707
|
+
palette="deep",
|
12708
|
+
font="sans-serif",
|
12709
|
+
font_scale=1.0,
|
12710
|
+
color_codes=True,
|
12711
|
+
grid_alpha=0.5,
|
12712
|
+
grid_linewidth=0.8,
|
12713
|
+
grid_linestyle="--",
|
12714
|
+
tick_direction="out",
|
12715
|
+
# tick_length=4,
|
12716
|
+
spine_visibility=False,
|
12717
|
+
# figsize=(8, 6),
|
12718
|
+
# linewidth=2,
|
12719
|
+
dpi=100,
|
12720
|
+
rc=None,
|
12721
|
+
):
|
12722
|
+
"""
|
12723
|
+
to configure Seaborn theme with maximum flexibility.
|
12724
|
+
|
12725
|
+
# Example Usage
|
12726
|
+
set_sns_theme(font_scale=1.2, grid_alpha=0.8, tick_direction="in", dpi=150)
|
12727
|
+
|
12728
|
+
Parameters:
|
12729
|
+
- context: Plotting context ('notebook', 'paper', 'talk', 'poster')
|
12730
|
+
- style: Style of the plot ('darkgrid', 'whitegrid', 'dark', 'white', 'ticks')
|
12731
|
+
- palette: Color palette (string or list of colors)
|
12732
|
+
- font: Font family ('sans-serif', 'serif', etc.)
|
12733
|
+
- font_scale: Scaling factor for fonts
|
12734
|
+
- color_codes: Boolean, whether to use seaborn color codes
|
12735
|
+
- grid_alpha: Opacity of the grid lines
|
12736
|
+
- grid_linewidth: Thickness of grid lines
|
12737
|
+
- grid_linestyle: Style of grid lines ('-', '--', '-.', ':')
|
12738
|
+
- tick_direction: Direction of ticks ('in', 'out', 'inout')
|
12739
|
+
- tick_length: Length of ticks
|
12740
|
+
- spine_visibility: Whether to show plot spines (True/False)
|
12741
|
+
- figsize: Default figure size as tuple (width, height)
|
12742
|
+
- linewidth: Default line width for plots
|
12743
|
+
- dpi: Resolution of the figure
|
12744
|
+
- rc: Dictionary of additional rc settings
|
12745
|
+
"""
|
12746
|
+
import seaborn as sns
|
12747
|
+
import matplotlib.pyplot as plt
|
12748
|
+
|
12749
|
+
# Define additional rc parameters for fine-tuning
|
12750
|
+
rc_params = {
|
12751
|
+
# "axes.grid": True,
|
12752
|
+
"grid.alpha": grid_alpha,
|
12753
|
+
"grid.linewidth": grid_linewidth,
|
12754
|
+
"grid.linestyle": grid_linestyle,
|
12755
|
+
"xtick.direction": tick_direction,
|
12756
|
+
"ytick.direction": tick_direction,
|
12757
|
+
# "xtick.major.size": tick_length,
|
12758
|
+
# "ytick.major.size": tick_length,
|
12759
|
+
# "axes.linewidth": linewidth,
|
12760
|
+
# "figure.figsize": figsize,
|
12761
|
+
"figure.dpi": dpi,
|
12762
|
+
"axes.spines.top": spine_visibility,
|
12763
|
+
"axes.spines.right": spine_visibility,
|
12764
|
+
"axes.spines.bottom": spine_visibility,
|
12765
|
+
"axes.spines.left": spine_visibility,
|
12766
|
+
}
|
12767
|
+
|
12768
|
+
# Merge user-provided rc settings
|
12769
|
+
if rc:
|
12770
|
+
rc_params.update(rc)
|
12771
|
+
|
12772
|
+
# Apply the theme settings
|
12773
|
+
sns.set_theme(
|
12774
|
+
context=context,
|
12775
|
+
style=style,
|
12776
|
+
palette=palette,
|
12777
|
+
font=font,
|
12778
|
+
font_scale=font_scale,
|
12779
|
+
color_codes=color_codes,
|
12780
|
+
rc=rc_params,
|
12781
|
+
)
|