Pyenv and matplotlib on MacOS High Sierra

1 minute read

Pyenv and matplotlib on MacOS High Sierra

Have you seen this error when trying to use matplotlib (or ggplot for that matter…)?

from matplotlib.backends import _macosx
RuntimeError: Python is not installed as a framework. The Mac OS X backend will not be able to function correctly if Python is not installed as a framework. See the Python documentation for more information on installing Python as a framework on Mac OS X. Please either reinstall Python as a framework, or try one of the other backends. If you are using (Ana)Conda please install and replace the use of 'python' with 'pythonw'. See 'Working with Matplotlib on OSX' in the Matplotlib FAQ for more information.

Frameworks is it? I’ll give ye frameworks…

The combination of Pyenv and virtualenv is the only sensible approach to Python development (for me). Imagine the deep sighs followed by gut-wrenching sobs when I was innocently trying to plot some data and saw the above error. The first thing to do is remove your virtualenv and delete the version of pyenv managed Python you were using (make sure you pip freeze before hand!)

It is possible to provide environment variables that are specific to the command being run simply by prefixing the command. In this case we want to install Python 3.x as a framework.

PYTHON_CONFIGURE_OPTS="--enable-framework" pyenv install 3.6.5

Sadly, I discovered, as I was nodding, almost napping - upon my keyboard a tapping - that this will complain; zlib is not installed, then openssl is problematic and on and on.

Apparently this is an issue with MacOS High Sierra not referencing various libraries, nor compiling openssl properly. There is a solution involving homebrew (assuming you have installed pyenv etc through homebrew) and setting various compiler flags that facilitate compiling openssl properly:

PYTHON_CONFIGURE_OPTS="--enable-framework" CFLAGS="-I$(brew --prefix openssl)/include" LDFLAGS="-L$(brew --prefix openssl)/lib" pyenv install 3.6.5

This will take a few minutes to complete but hopefully you should then be able to output matplotlib charts to your hearts content