1{ 2 lib, 3 stdenv, 4 fetchPypi, 5 writeText, 6 buildPythonPackage, 7 isPyPy, 8 pythonOlder, 9 10 # build-system 11 certifi, 12 pkg-config, 13 pybind11, 14 setuptools, 15 setuptools-scm, 16 17 # native libraries 18 ffmpeg-headless, 19 freetype, 20 qhull, 21 22 # propagates 23 contourpy, 24 cycler, 25 fonttools, 26 kiwisolver, 27 numpy, 28 packaging, 29 pillow, 30 pyparsing, 31 python-dateutil, 32 33 # optional 34 importlib-resources, 35 36 # GTK3 37 enableGtk3 ? false, 38 cairo, 39 gobject-introspection, 40 gtk3, 41 pycairo, 42 pygobject3, 43 44 # Tk 45 # Darwin has its own "MacOSX" backend, PyPy has tkagg backend and does not support tkinter 46 enableTk ? (!stdenv.isDarwin && !isPyPy), 47 tcl, 48 tk, 49 tkinter, 50 51 # Ghostscript 52 enableGhostscript ? true, 53 ghostscript, 54 55 # Qt 56 enableQt ? false, 57 pyqt5, 58 59 # Webagg 60 enableWebagg ? false, 61 tornado, 62 63 # nbagg 64 enableNbagg ? false, 65 ipykernel, 66 67 # darwin 68 Cocoa, 69 70 # required for headless detection 71 libX11, 72 wayland, 73 74 # Reverse dependency 75 sage, 76}: 77 78let 79 interactive = enableTk || enableGtk3 || enableQt; 80in 81 82buildPythonPackage rec { 83 version = "3.8.4"; 84 pname = "matplotlib"; 85 pyproject = true; 86 87 disabled = pythonOlder "3.8"; 88 89 src = fetchPypi { 90 inherit pname version; 91 hash = "sha256-iqw5fV6ewViWDjHDgcX/xS3dUr2aR3F+KmlAOBZ9/+o="; 92 }; 93 94 env.XDG_RUNTIME_DIR = "/tmp"; 95 96 # Matplotlib tries to find Tcl/Tk by opening a Tk window and asking the 97 # corresponding interpreter object for its library paths. This fails if 98 # `$DISPLAY` is not set. The fallback option assumes that Tcl/Tk are both 99 # installed under the same path which is not true in Nix. 100 # With the following patch we just hard-code these paths into the install 101 # script. 102 postPatch = 103 let 104 tcl_tk_cache = ''"${tk}/lib", "${tcl}/lib", "${lib.strings.substring 0 3 tk.version}"''; 105 in 106 '' 107 substituteInPlace pyproject.toml \ 108 --replace-fail '"numpy>=2.0.0rc1,<2.3",' "" 109 '' 110 + lib.optionalString enableTk '' 111 sed -i '/self.tcl_tk_cache = None/s|None|${tcl_tk_cache}|' setupext.py 112 '' 113 + lib.optionalString (stdenv.isLinux && interactive) '' 114 # fix paths to libraries in dlopen calls (headless detection) 115 substituteInPlace src/_c_internal_utils.c \ 116 --replace libX11.so.6 ${libX11}/lib/libX11.so.6 \ 117 --replace libwayland-client.so.0 ${wayland}/lib/libwayland-client.so.0 118 ''; 119 120 nativeBuildInputs = [ pkg-config ] ++ lib.optionals enableGtk3 [ gobject-introspection ]; 121 122 buildInputs = 123 [ 124 ffmpeg-headless 125 freetype 126 qhull 127 ] 128 ++ lib.optionals enableGhostscript [ ghostscript ] 129 ++ lib.optionals enableGtk3 [ 130 cairo 131 gtk3 132 ] 133 ++ lib.optionals enableTk [ 134 libX11 135 tcl 136 tk 137 ] 138 ++ lib.optionals stdenv.isDarwin [ Cocoa ]; 139 140 # clang-11: error: argument unused during compilation: '-fno-strict-overflow' [-Werror,-Wunused-command-line-argument] 141 hardeningDisable = lib.optionals stdenv.isDarwin [ "strictoverflow" ]; 142 143 build-system = [ 144 certifi 145 numpy 146 pybind11 147 setuptools 148 setuptools-scm 149 ]; 150 151 dependencies = 152 [ 153 # explicit 154 contourpy 155 cycler 156 fonttools 157 kiwisolver 158 numpy 159 packaging 160 pillow 161 pyparsing 162 python-dateutil 163 ] 164 ++ lib.optionals (pythonOlder "3.10") [ importlib-resources ] 165 ++ lib.optionals enableGtk3 [ 166 pycairo 167 pygobject3 168 ] 169 ++ lib.optionals enableQt [ pyqt5 ] 170 ++ lib.optionals enableWebagg [ tornado ] 171 ++ lib.optionals enableNbagg [ ipykernel ] 172 ++ lib.optionals enableTk [ tkinter ]; 173 174 passthru.config = { 175 directories = { 176 basedirlist = "."; 177 }; 178 libs = { 179 system_freetype = true; 180 system_qhull = true; 181 # LTO not working in darwin stdenv, see #19312 182 enable_lto = !stdenv.isDarwin; 183 }; 184 }; 185 186 passthru.tests = { 187 inherit sage; 188 }; 189 190 env.MPLSETUPCFG = writeText "mplsetup.cfg" (lib.generators.toINI { } passthru.config); 191 192 # Encountering a ModuleNotFoundError, as describved and investigated at: 193 # https://github.com/NixOS/nixpkgs/issues/255262 . It could be that some of 194 # which may fail due to a freetype version that doesn't match the freetype 195 # version used by upstream. 196 doCheck = false; 197 198 meta = with lib; { 199 description = "Python plotting library, making publication quality plots"; 200 homepage = "https://matplotlib.org/"; 201 changelog = "https://github.com/matplotlib/matplotlib/releases/tag/v${version}"; 202 license = with licenses; [ 203 psfl 204 bsd0 205 ]; 206 maintainers = with maintainers; [ 207 lovek323 208 veprbl 209 ]; 210 }; 211}