Adventure with matplotlib, virtualenv and MacOS

Recently I've developed passion for machine learning. Which includes many hours of fun with various modeling and plotting libraries.

Yesterday I was playing around with Multidimensional scaling in jupyter notebook. But when I tried to render a chart it just didn't work. Engine got stuck and I had to restart it. At first I though that the rendering is too complicated, but even simple example didn't work.

Problem was as I later discovered caused by a bug in virtualenv. I managed to get it working using workaround described on matplotlib's FAQ.

First install python and create virtualenv.

brew install python --framework # install python 2.7 framework build
virtualenv env # create virtualenv

Then create bash script called frameworkpython in bin folder of your environment, in my case it's env/bin/frameworkpython with following content.

#!/bin/bash

# what real Python executable to use
PYVER=2.7
PATHTOPYTHON=/usr/local/bin/
PYTHON=${PATHTOPYTHON}python${PYVER}

# find the root of the virtualenv, it should be the parent of the dir this script is in
ENV=`$PYTHON -c "import os; print os.path.abspath(os.path.join(os.path.dirname(\"$0\"), '..'))"`

# now run Python with the virtualenv set as Python's HOME
export PYTHONHOME=$ENV
exec $PYTHON "$@"

Make the scipt executable and install libraries.

chmod +x env/bin/frameworkpython # make it executable
source env/bin/activate # activate environment
pip install matplotlib jupyter notebook # install matplotlib and jupyter notebook

Only one problem was ahed of me. How to start the notebook from this script. It was pretty simple in the end frameworkpython env/bin/jupyter-notebook.

You can use this code to test it. Don't forget to use %matplotlib inline in your notebook to prevent window popping up.

%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np

t = np.arange(0.0, 2.0, 0.01)
s = np.sin(2*np.pi*t)
plt.plot(t, s)

plt.grid(True)
plt.show()

I hope this article will save you some hours of your life I spent with this. You can see the result on my github.