abarbu / matplotlib-haskell

Haskell bindings for Python's Matplotlib
Other
85 stars 12 forks source link

Changes needed to run on Windows #3

Closed LukaHorvat closed 7 years ago

LukaHorvat commented 7 years ago

This is surely not the only way but it works for me. The requirement is msys2 (the one shipped with stack probably works fine)

Then inside of the msys environment (always use the msys console) you do this

pacman -S mingw64/mingw-w64-x86_64-python3
pacman -S mingw64/mingw-w64-x86_64-python3-matplotlib
pacman -S mingw64/mingw-w64-x86_64-python3-numpy

Make sure where python3 reports /mingw64/bin/python3 before anything else. If not, add /mingw64/bin/ to the front of your PATH variable. When running the functions from this library, make sure you're using the msys console.

These are the changes I needed to make to the code

diff --git a/src/Graphics/Matplotlib/Internal.hs b/src/Graphics/Matplotlib/Internal.hs
index 33f5683..08471f9 100644
--- a/src/Graphics/Matplotlib/Internal.hs
+++ b/src/Graphics/Matplotlib/Internal.hs
@@ -303,7 +303,7 @@ python codeStr =
          (\codeFile codeHandle -> do
              forM_ codeStr (hPutStrLn codeHandle)
              hClose codeHandle
-             Right <$> readProcess "/usr/bin/env" ["python3", codeFile] ""))
+             Right <$> readProcess "env" ["python3", codeFile] ""))
          (\e -> return $ Left $ show (e :: IOException))

 pyBackend backend = "matplotlib.use('" ++ backend ++ "')"
@@ -332,13 +332,16 @@ pyIncludes backend = ["import matplotlib"
                      ,"axes = [plot.gca()]"
                      ,"ax = axes[0]"]

+flipSlashes :: [Char] -> [Char]
+flipSlashes = map (\c -> if c == '\\' then '/' else c)
+
 -- | The python command that reads external data into the python data array
 pyReadData :: [Char] -> [[Char]]
-pyReadData filename = ["data = json.loads(open('" ++ filename ++ "').read())"]
+pyReadData filename = ["data = json.loads(open('" ++ flipSlashes filename ++ "').read())"]

 -- | The python command that reads an image into the img variable
 pyReadImage :: [Char] -> [[Char]]
-pyReadImage filename = ["img = mpimg.imread('" ++ filename ++ "')"]
+pyReadImage filename = ["img = mpimg.imread('" ++ flipSlashes filename ++ "')"]

 -- | Detach python so we don't block (TODO This isn't working reliably)
 pyDetach :: [[Char]]
@@ -385,4 +388,3 @@ minimum2 l = minimum $ minimum l
 -- | Largest element of a list of lists
 maximum2 :: (Ord (t a), Ord a, Foldable t1, Foldable t) => t1 (t a) -> a
 maximum2 l = maximum $ maximum l

So basically /usr/bin/env doesn't work on Windows but env does (also using msys). The backslashes also need to be converted to slashes.

abarbu commented 7 years ago

That's great. I put in the env change but I'm a little confused about the slashes. If the platform is windows isn't it correctly producing forward slashes? Why flip them back into the unix direction?

LukaHorvat commented 7 years ago

Forward slashes have worked on Windows for a while now. In fact, I don't really remember them ever not working. The problem seems to be that these "system specific" functions, like the temp file one, return paths with backslashes and then this gets into the Python file unescaped. The error complains about bad escape sequences. If you want you can keep backslashes and escape them instead of flipping them. I think it's pretty much the same.

abarbu commented 7 years ago

Oh I see! I guess this never happens on *nix since the temp directory is just /tmp and there are no spaces but it's a problem everywhere. Did the last push help?

LukaHorvat commented 7 years ago

Yup, it works

abarbu commented 7 years ago

Great! Thanks for the help in figuring this out :)