gnu: Add python-upsetplot.
[jackhill/guix/guix.git] / gnu / packages / python-science.scm
1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2015, 2016, 2020, 2021 Ricardo Wurmus <rekado@elephly.net>
3 ;;; Copyright © 2015 Federico Beffa <beffa@fbengineering.ch>
4 ;;; Copyright © 2016 Ben Woodcroft <donttrustben@gmail.com>
5 ;;; Copyright © 2016 Hartmut Goebel <h.goebel@crazy-compilers.com>
6 ;;; Copyright © 2016 Efraim Flashner <efraim@flashner.co.il>
7 ;;; Copyright © 2016, 2017, 2018, 2019, 2020 Marius Bakke <mbakke@fastmail.com>
8 ;;; Copyright © 2019 Tobias Geerinckx-Rice <me@tobias.gr>
9 ;;; Copyright © 2019 Maxim Cournoyer <maxim.cournoyer@gmail.com>
10 ;;; Copyright © 2019 Giacomo Leidi <goodoldpaul@autistici.org>
11 ;;; Copyright © 2020 Pierre Langlois <pierre.langlois@gmx.com>
12 ;;; Copyright © 2020 Vinicius Monego <monego@posteo.net>
13 ;;; Copyright © 2021 Greg Hogan <code@greghogan.com>
14 ;;;
15 ;;; This file is part of GNU Guix.
16 ;;;
17 ;;; GNU Guix is free software; you can redistribute it and/or modify it
18 ;;; under the terms of the GNU General Public License as published by
19 ;;; the Free Software Foundation; either version 3 of the License, or (at
20 ;;; your option) any later version.
21 ;;;
22 ;;; GNU Guix is distributed in the hope that it will be useful, but
23 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
24 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 ;;; GNU General Public License for more details.
26 ;;;
27 ;;; You should have received a copy of the GNU General Public License
28 ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
29
30 (define-module (gnu packages python-science)
31 #:use-module ((guix licenses) #:prefix license:)
32 #:use-module (gnu packages)
33 #:use-module (gnu packages base)
34 #:use-module (gnu packages check)
35 #:use-module (gnu packages gcc)
36 #:use-module (gnu packages maths)
37 #:use-module (gnu packages perl)
38 #:use-module (gnu packages python)
39 #:use-module (gnu packages python-web)
40 #:use-module (gnu packages python-xyz)
41 #:use-module (gnu packages sphinx)
42 #:use-module (gnu packages time)
43 #:use-module (gnu packages xdisorg)
44 #:use-module (gnu packages xml)
45 #:use-module (gnu packages xorg)
46 #:use-module (guix packages)
47 #:use-module (guix download)
48 #:use-module (guix utils)
49 #:use-module (guix build-system python))
50
51 (define-public python-scipy
52 (package
53 (name "python-scipy")
54 (version "1.6.0")
55 (source
56 (origin
57 (method url-fetch)
58 (uri (pypi-uri "scipy" version))
59 (sha256
60 (base32 "0rh5b1rwdcvvagld8vpxnpaibszy1skpx39a0fwzd5gx5pwcjvfb"))))
61 (build-system python-build-system)
62 (propagated-inputs
63 `(("python-numpy" ,python-numpy)
64 ("python-matplotlib" ,python-matplotlib)
65 ("python-pyparsing" ,python-pyparsing)))
66 (inputs
67 `(("lapack" ,lapack)
68 ("openblas" ,openblas)
69 ("pybind11" ,pybind11)))
70 (native-inputs
71 `(("python-cython" ,python-cython)
72 ("python-pytest" ,python-pytest)
73 ("python-sphinx" ,python-sphinx)
74 ("python-numpydoc" ,python-numpydoc)
75 ("gfortran" ,gfortran)
76 ("perl" ,perl)
77 ("which" ,which)))
78 (outputs '("out" "doc"))
79 (arguments
80 `(#:phases
81 (modify-phases %standard-phases
82 (add-before 'build 'change-home-dir
83 (lambda _
84 ;; Change from /homeless-shelter to /tmp for write permission.
85 (setenv "HOME" "/tmp")
86 #t))
87 (add-after 'unpack 'disable-broken-tests
88 (lambda _
89 (substitute* "scipy/sparse/linalg/dsolve/tests/test_linsolve.py"
90 (("^( +)def test_threads_parallel\\(self\\):" m indent)
91 (string-append indent
92 "@pytest.mark.skip(reason=\"Disabled by Guix\")\n"
93 m)))
94 (substitute* "scipy/sparse/linalg/eigen/arpack/tests/test_arpack.py"
95 (("^def test_parallel_threads\\(\\):" m)
96 (string-append "@pytest.mark.skip(reason=\"Disabled by Guix\")\n"
97 m)))
98 #t))
99 (add-before 'build 'configure-openblas
100 (lambda* (#:key inputs #:allow-other-keys)
101 (call-with-output-file "site.cfg"
102 (lambda (port)
103 (format port
104 "[blas]
105 libraries = openblas
106 library_dirs = ~a/lib
107 include_dirs = ~a/include
108
109 # backslash-n to make emacs happy
110 \n[atlas]
111 library_dirs = ~a/lib
112 atlas_libs = openblas
113 "
114 (assoc-ref inputs "openblas")
115 (assoc-ref inputs "openblas")
116 (assoc-ref inputs "openblas"))))
117 #t))
118 (add-after 'install 'install-doc
119 (lambda* (#:key inputs outputs #:allow-other-keys)
120 (let* ((data (string-append (assoc-ref outputs "doc") "/share"))
121 (doc (string-append data "/doc/" ,name "-" ,version))
122 (html (string-append doc "/html"))
123 (pyver ,(string-append "PYVER=" (version-major+minor
124 (package-version python))))
125 ;; By default it tries to run sphinx-build through the Python
126 ;; interpreter which won't work with our shell wrapper.
127 (sphinxbuild "SPHINXBUILD=LANG=C sphinx-build"))
128 ;; Make installed package available for building the
129 ;; documentation
130 (add-installed-pythonpath inputs outputs)
131 (with-directory-excursion "doc"
132 ;; Fix generation of images for mathematical expressions.
133 (substitute* (find-files "source" "conf\\.py")
134 (("pngmath_use_preview = True")
135 "pngmath_use_preview = False"))
136 (mkdir-p html)
137 (invoke "make" "html" pyver sphinxbuild)
138 (with-directory-excursion "build/html"
139 (for-each (lambda (file)
140 (let* ((dir (dirname file))
141 (tgt-dir (string-append html "/" dir)))
142 (install-file file html)))
143 (find-files "." ".*")))))
144 #t))
145 ;; Tests can only be run after the library has been installed and not
146 ;; within the source directory.
147 (delete 'check)
148 (add-after 'install 'check
149 (lambda* (#:key inputs outputs #:allow-other-keys)
150 (add-installed-pythonpath inputs outputs)
151 (with-directory-excursion "/tmp"
152 (invoke "python" "-c"
153 "import scipy; scipy.test(verbose=2)")))))))
154 (home-page "https://www.scipy.org/")
155 (synopsis "The Scipy library provides efficient numerical routines")
156 (description "The SciPy library is one of the core packages that make up
157 the SciPy stack. It provides many user-friendly and efficient numerical
158 routines such as routines for numerical integration and optimization.")
159 (properties `((python2-variant . ,(delay python2-scipy))))
160 (license license:bsd-3)))
161
162 ;; Version 1.2.2 is the last version to support Python 2
163 (define-public python2-scipy
164 (package
165 (inherit (package-with-python2
166 (strip-python2-variant python-scipy)))
167 (version "1.2.2")
168 (source
169 (origin
170 (method url-fetch)
171 (uri (pypi-uri "scipy" version))
172 (sha256
173 (base32
174 "1cgvgin8fvckv96hjh3ikmwkra5rif51bdb75ifzf7xbil5iwcx4"))))))
175
176 (define-public python2-weave
177 (package
178 (name "python2-weave")
179 (version "0.16.0")
180 (source
181 (origin
182 (method url-fetch)
183 (uri (pypi-uri "weave" version))
184 (sha256
185 (base32 "0jnm3584mfichgwgrd1gk5i42ll9c08nkw9716n947n4338f6ghs"))))
186 (build-system python-build-system)
187 (arguments
188 `(#:python ,python-2
189 #:phases
190 (modify-phases %standard-phases
191 (replace 'check
192 (lambda _
193 (invoke "nosetests" "-v"
194 "--exclude"
195 "test_(user|incorrect_ownership|char_fail|obj_fail)"))))))
196 (propagated-inputs
197 `(("python-numpy" ,python2-numpy)))
198 (native-inputs
199 `(("python-nose" ,python2-nose)))
200 (home-page "https://www.scipy.org/")
201 (synopsis "Tools for including C/C++ code within Python code")
202 (description "Weave is the stand-alone version of the obsolete Scipy
203 submodule @code{scipy.weave}. It is Python 2.x only, and is provided for
204 users that need new versions of Scipy but have existing code that still
205 depends on @code{scipy.weave}. For new code, users are recommended to use
206 Cython.")
207 (license license:bsd-3)))
208
209 (define-public python-scikit-fuzzy
210 (package
211 (name "python-scikit-fuzzy")
212 (version "0.4.2")
213 (source
214 (origin
215 (method url-fetch)
216 (uri (pypi-uri "scikit-fuzzy" version))
217 (sha256
218 (base32 "0bp1n771fj44kdp7a00bcvfwirvv2rc803b7g6yf3va7v0j29c8s"))))
219 (build-system python-build-system)
220 (arguments
221 `(#:phases
222 (modify-phases %standard-phases
223 (replace 'check
224 (lambda _
225 (invoke "nosetests" "-s" "-v" "skfuzzy")
226 #t)))))
227 (native-inputs
228 `(("python-nose" ,python-nose)))
229 (propagated-inputs
230 `(("python-networkx" ,python-networkx)
231 ("python-numpy" ,python-numpy)
232 ("python-scipy" ,python-scipy)))
233 (home-page "https://github.com/scikit-fuzzy/scikit-fuzzy")
234 (synopsis "Fuzzy logic toolkit for SciPy")
235 (description
236 "This package implements many useful tools for projects involving fuzzy
237 logic, also known as grey logic.")
238 (license license:bsd-3)))
239
240 (define-public python-scikit-image
241 (package
242 (name "python-scikit-image")
243 (version "0.17.2")
244 (source
245 (origin
246 (method url-fetch)
247 (uri (pypi-uri "scikit-image" version))
248 (sha256
249 (base32 "1cyqqbcbrg3prc36wis0sm3q5rjhd7h9bp33jwfyixzhi02lr5dx"))))
250 (build-system python-build-system)
251 (arguments
252 ;; TODO: Some tests require running X11 server. Disable them?
253 '(#:tests? #f))
254 ;; See DEPENDS.txt for the list of build and run time requiremnts
255 (propagated-inputs
256 `(("python-cloudpickle" ,python-cloudpickle)
257 ("python-dask" ,python-dask)
258 ("python-imageio" ,python-imageio)
259 ("python-matplotlib" ,python-matplotlib)
260 ("python-networkx" ,python-networkx)
261 ("python-numpy" ,python-numpy)
262 ("python-pillow" ,python-pillow)
263 ("python-pywavelets" ,python-pywavelets)
264 ("python-scipy" ,python-scipy)
265 ("python-six" ,python-six)
266 ("python-tifffile" ,python-tifffile)))
267 (native-inputs
268 `(("python-cython" ,python-cython)))
269 (home-page "https://scikit-image.org/")
270 (synopsis "Image processing in Python")
271 (description
272 "Scikit-image is a collection of algorithms for image processing.")
273 (license license:bsd-3)))
274
275 (define-public python-sgp4
276 (package
277 (name "python-sgp4")
278 (version "2.12")
279 (source
280 (origin
281 (method url-fetch)
282 (uri (pypi-uri "sgp4" version))
283 (sha256
284 (base32 "0dncp9i5b6afkg7f8mj9j0qzsp008b8v73yc0qkmizhpns7mvwvx"))))
285 (build-system python-build-system)
286 (propagated-inputs
287 `(("python-numpy" ,python-numpy)))
288 (home-page "https://github.com/brandon-rhodes/python-sgp4")
289 (synopsis "Track earth satellite TLE orbits using SGP4")
290 (description
291 "This package provides a Python implementation of the most recent version
292 of the SGP4 satellite tracking algorithm.")
293 (license license:expat)))
294
295 (define-public python-pandas
296 (package
297 (name "python-pandas")
298 (version "1.0.5")
299 (source
300 (origin
301 (method url-fetch)
302 (uri (pypi-uri "pandas" version))
303 (sha256
304 (base32 "1a2gv3g6jr6vb5ca43fkwjl5xf86wpfz8y3zcy787adjl0hdkib9"))))
305 (build-system python-build-system)
306 (arguments
307 `(#:modules ((guix build utils)
308 (guix build python-build-system)
309 (ice-9 ftw)
310 (srfi srfi-26))
311 #:phases (modify-phases %standard-phases
312 (add-after 'unpack 'patch-which
313 (lambda* (#:key inputs #:allow-other-keys)
314 (let ((which (assoc-ref inputs "which")))
315 (substitute* "pandas/io/clipboard/__init__.py"
316 (("^WHICH_CMD = .*")
317 (string-append "WHICH_CMD = \"" which "\"\n"))))
318 #t))
319 (add-before 'check 'prepare-x
320 (lambda _
321 (system "Xvfb &")
322 (setenv "DISPLAY" ":0")
323 ;; xsel needs to write a log file.
324 (setenv "HOME" "/tmp")
325 #t))
326 (replace 'check
327 (lambda _
328 (let ((build-directory
329 (string-append
330 (getcwd) "/build/"
331 (car (scandir "build"
332 (cut string-prefix? "lib." <>))))))
333 ;; Disable the "strict data files" option which causes
334 ;; the build to error out if required data files are
335 ;; not available (as is the case with PyPI archives).
336 (substitute* "setup.cfg"
337 (("addopts = --strict-data-files") "addopts = "))
338 (with-directory-excursion build-directory
339 (invoke "pytest" "-vv" "pandas" "--skip-slow"
340 "--skip-network"))))))))
341 (propagated-inputs
342 `(("python-jinja2" ,python-jinja2)
343 ("python-numpy" ,python-numpy)
344 ("python-openpyxl" ,python-openpyxl)
345 ("python-pytz" ,python-pytz)
346 ("python-dateutil" ,python-dateutil)
347 ("python-xlrd" ,python-xlrd)))
348 (inputs
349 `(("which" ,which)
350 ("xclip" ,xclip)
351 ("xsel" ,xsel)))
352 (native-inputs
353 `(("python-cython" ,python-cython)
354 ("python-beautifulsoup4" ,python-beautifulsoup4)
355 ("python-lxml" ,python-lxml)
356 ("python-html5lib" ,python-html5lib)
357 ("python-nose" ,python-nose)
358 ("python-pytest" ,python-pytest)
359 ("python-pytest-mock" ,python-pytest-mock)
360 ;; Needed to test clipboard support.
361 ("xorg-server" ,xorg-server-for-tests)))
362 (home-page "https://pandas.pydata.org")
363 (synopsis "Data structures for data analysis, time series, and statistics")
364 (description
365 "Pandas is a Python package providing fast, flexible, and expressive data
366 structures designed to make working with structured (tabular,
367 multidimensional, potentially heterogeneous) and time series data both easy
368 and intuitive. It aims to be the fundamental high-level building block for
369 doing practical, real world data analysis in Python.")
370 (properties `((python2-variant . ,(delay python2-pandas))))
371 (license license:bsd-3)))
372
373 (define-public python-pandas-0.25
374 (package
375 (inherit python-pandas)
376 (version "0.25.3")
377 (source (origin
378 (method url-fetch)
379 (uri (pypi-uri "pandas" version))
380 (sha256
381 (base32
382 "191048m6kdc6yfvqs9w412lq60cfvigrsb57y0x116lwibgp9njj"))))
383 (arguments
384 (substitute-keyword-arguments (package-arguments python-pandas)
385 ((#:phases phases)
386 `(modify-phases ,phases
387 (replace 'patch-which
388 (lambda* (#:key inputs #:allow-other-keys)
389 (let ((which (assoc-ref inputs "which")))
390 (substitute* "pandas/io/clipboard/__init__.py"
391 (("^CHECK_CMD = .*")
392 (string-append "CHECK_CMD = \"" which "\"\n"))))
393 #t))
394 (delete 'prepare-x)))))))
395
396 ;; Pandas 0.24.x are the last versions that support Python 2.
397 (define-public python2-pandas
398 (let ((pandas (package-with-python2
399 (strip-python2-variant python-pandas-0.25))))
400 (package
401 (inherit pandas)
402 (version "0.24.2")
403 (source (origin
404 (method url-fetch)
405 (uri (pypi-uri "pandas" version))
406 (sha256
407 (base32
408 "18imlm8xbhcbwy4wa957a1fkamrcb0z988z006jpfda3ki09z4ag"))
409 (modules '((guix build utils)))
410 (snippet
411 '(begin
412 ;; Adjust for renamed error message in Python 2.7.17. Taken
413 ;; from <https://github.com/pandas-dev/pandas/pull/29294>.
414 (substitute* "pandas/io/parsers.py"
415 (("if 'NULL byte' in msg:")
416 "if 'NULL byte' in msg or 'line contains NUL' in msg:"))
417 #t)))))))
418
419 (define-public python-bottleneck
420 (package
421 (name "python-bottleneck")
422 (version "1.3.2")
423 (source
424 (origin
425 (method url-fetch)
426 (uri (pypi-uri "Bottleneck" version))
427 (sha256
428 (base32 "0wz5320jx3n4q2nsvwvc7cpi66b46qbals9v53m955rmcq5ry5r0"))))
429 (build-system python-build-system)
430 (arguments
431 `(#:phases
432 (modify-phases %standard-phases
433 (replace 'check
434 (lambda _
435 (invoke "python" "setup.py" "pytest"))))))
436 (native-inputs
437 `(("python-hypothesis" ,python-hypothesis)
438 ("python-pytest" ,python-pytest)
439 ("python-pytest-runner" ,python-pytest-runner)))
440 (propagated-inputs
441 `(("python-numpy" ,python-numpy)))
442 (home-page "https://github.com/pydata/bottleneck")
443 (synopsis "Fast NumPy array functions written in C")
444 (description
445 "Bottleneck is a collection of fast, NaN-aware NumPy array functions
446 written in C.")
447 (license license:bsd-2)))
448
449 (define-public python-baycomp
450 (package
451 (name "python-baycomp")
452 (version "1.0.2")
453 (source
454 (origin
455 (method url-fetch)
456 (uri (pypi-uri "baycomp" version))
457 (sha256
458 (base32 "1c1354a7b3g8slychjgyjxqdm8z40z9kviyl9n4g9kfpdg0p4d64"))))
459 (build-system python-build-system)
460 (propagated-inputs
461 `(("python-matplotlib" ,python-matplotlib)
462 ("python-numpy" ,python-numpy)
463 ("python-scipy" ,python-scipy)))
464 (home-page "https://github.com/janezd/baycomp")
465 (synopsis "Library for comparison of Bayesian classifiers")
466 (description
467 "Baycomp is a library for Bayesian comparison of classifiers. Functions
468 in the library compare two classifiers on one or on multiple data sets. They
469 compute three probabilities: the probability that the first classifier has
470 higher scores than the second, the probability that differences are within the
471 region of practical equivalence (rope), or that the second classifier has
472 higher scores.")
473 (license license:expat)))
474
475 (define-public python-xarray
476 (package
477 (name "python-xarray")
478 (version "0.15.1")
479 (source (origin
480 (method url-fetch)
481 (uri (pypi-uri "xarray" version))
482 (sha256
483 (base32
484 "1yx8j66b7rn10m2l6gmn8yr9cn38pi5cj0x0wwpy4hdnhy6i7qv4"))))
485 (build-system python-build-system)
486 (native-inputs
487 `(("python-setuptools-scm" ,python-setuptools-scm)
488 ("python-pytest" ,python-pytest)))
489 (propagated-inputs
490 `(("python-numpy" ,python-numpy)
491 ("python-pandas" ,python-pandas)))
492 (arguments
493 `(#:phases
494 (modify-phases %standard-phases
495 (replace 'check
496 (lambda _
497 (invoke "pytest"))))))
498 (home-page "https://github.com/pydata/xarray")
499 (synopsis "N-D labeled arrays and datasets")
500 (description "Xarray (formerly xray) makes working with labelled
501 multi-dimensional arrays simple, efficient, and fun!
502
503 Xarray introduces labels in the form of dimensions, coordinates and attributes
504 on top of raw NumPy-like arrays, which allows for a more intuitive, more
505 concise, and less error-prone developer experience. The package includes a
506 large and growing library of domain-agnostic functions for advanced analytics
507 and visualization with these data structures.")
508 (license license:asl2.0)))
509
510 (define-public python-msgpack-numpy
511 (package
512 (name "python-msgpack-numpy")
513 (version "0.4.6.post0")
514 (source
515 (origin
516 (method url-fetch)
517 (uri (pypi-uri "msgpack-numpy" version))
518 (sha256
519 (base32
520 "0syzy645mwcy7lfjwz6pc8f9p2vv1qk4limc8iina3l5nnf0rjyz"))))
521 (build-system python-build-system)
522 (propagated-inputs
523 `(("python-msgpack" ,python-msgpack)
524 ("python-numpy" ,python-numpy)))
525 (home-page "https://github.com/lebedov/msgpack-numpy")
526 (synopsis
527 "Numpy data serialization using msgpack")
528 (description
529 "This package provides encoding and decoding routines that enable the
530 serialization and deserialization of numerical and array data types provided
531 by numpy using the highly efficient @code{msgpack} format. Serialization of
532 Python's native complex data types is also supported.")
533 (license license:bsd-3)))
534
535 (define-public python-statannot
536 (package
537 (name "python-statannot")
538 (version "0.2.3")
539 (source
540 (origin
541 (method url-fetch)
542 (uri (pypi-uri "statannot" version))
543 (sha256
544 (base32
545 "1f8c2sylzr7lpjbyqxsqlp9xi8rj3d8c9hfh98x4jbb83zxc4026"))))
546 (build-system python-build-system)
547 (propagated-inputs
548 `(("python-numpy" ,python-numpy)
549 ("python-seaborn" ,python-seaborn)
550 ("python-matplotlib" ,python-matplotlib)
551 ("python-pandas" ,python-pandas)
552 ("python-scipy" ,python-scipy)))
553 (home-page
554 "https://github.com/webermarcolivier/statannot")
555 (synopsis "Add annotations to existing plots generated by seaborn")
556 (description
557 "This is a Python package to compute statistical test and add statistical
558 annotations on an existing boxplots and barplots generated by seaborn.")
559 (license license:expat)))
560
561 (define-public python-upsetplot
562 (package
563 (name "python-upsetplot")
564 (version "0.4.1")
565 (source
566 (origin
567 (method url-fetch)
568 (uri (pypi-uri "UpSetPlot" version))
569 (sha256
570 (base32
571 "0kwljcmsvrxm33y3ssham2bwv4a5m31mv96y9h18va0cv7s3mqn1"))))
572 (build-system python-build-system)
573 (arguments
574 `(#:phases
575 (modify-phases %standard-phases
576 (add-after 'unpack 'fix-versioning
577 (lambda _
578 (substitute* "setup.py"
579 (("pytest-cov<2.6") "pytest-cov"))))
580 (replace 'check
581 (lambda* (#:key inputs outputs #:allow-other-keys)
582 (add-installed-pythonpath inputs outputs)
583 (invoke "pytest" "-v" "--doctest-modules"))))))
584 (propagated-inputs
585 `(("python-matplotlib" ,python-matplotlib)
586 ("python-pandas" ,python-pandas)))
587 (native-inputs
588 `(("python-pytest-runner" ,python-pytest-runner)
589 ("python-pytest-cov" ,python-pytest-cov)))
590 (home-page "https://upsetplot.readthedocs.io")
591 (synopsis "Draw UpSet plots with Pandas and Matplotlib")
592 (description
593 "This is a Python implementation of UpSet plots by Lex et al.
594 UpSet plots are used to visualize set overlaps; like Venn diagrams but more
595 readable.")
596 (license license:bsd-3)))