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