Contents
On OSX, two different types of Python builds exist: a regular build and a
framework build. In order to interact correctly with OSX through the native
GUI frameworks you need a framework build of Python. At the time of writing
the macosx
and WXAgg
backends require a framework build to function
correctly. This can result in issues for a Python installation not build as a
framework and may also happen in virtual envs and when using (Ana)Conda. From
Matplotlib 1.5 onwards, both backends check that a framework build is available
and fail if a non framework build is found.
Without this check a partially functional figure is created. Among the issues with it is that it is produced in the background and cannot be put in front of any other window. Several solutions and work arounds exist see below.
If you are on Python 3, use venv instead of virtualenv:
python -m venv my-virtualenv
source my-virtualenv/bin/activate
Otherwise you will need one of the workarounds below.
If you are using pyenv and virtualenv you can enable your python version to be installed as a framework:
PYTHON_CONFIGURE_OPTS="--enable-framework" pyenv install x.x.x
The default python provided in (Ana)Conda is not a framework
build. However, the Conda developers have made it easy to install
a framework build in both the main environment and in Conda envs.
To use this install python.app conda install python.app
and
use pythonw
rather than python
Unfortunately virtualenv creates a non framework build even if created from a framework build of Python. As documented above you can use venv as an alternative on Python 3.
The issue has been reported on the virtualenv bug tracker here and here
Until this is fixed, one of the following workarounds can be used:
PYTHONHOME
Function¶The best known work around is to use the non
virtualenv python along with the PYTHONHOME environment variable.
This can be done by defining a function in your .bashrc
using
function frameworkpython {
if [[ ! -z "$VIRTUAL_ENV" ]]; then
PYTHONHOME=$VIRTUAL_ENV /usr/local/bin/python "$@"
else
/usr/local/bin/python "$@"
fi
}
This function can then be used in all of your virtualenvs without having to fix every single one of them.
With this in place you can run frameworkpython
to get an interactive
framework build within the virtualenv. To run a script you can do
frameworkpython test.py
where test.py
is a script that requires a
framework build. To run an interactive IPython
session with the framework
build within the virtual environment you can do frameworkpython -m IPython
PYTHONHOME
and Jupyter¶This approach can be followed even if using Jupyter
notebooks: you just need to setup a kernel with the suitable PYTHONHOME
definition. The jupyter-virtualenv-osx
script automates the creation of such a kernel.
PYTHONHOME
Script¶An alternative work around borrowed from the WX wiki, is to use the non
virtualenv python along with the PYTHONHOME environment variable. This can be
implemented in a script as below. To use this modify PYVER
and
PATHTOPYTHON
and put the script in the virtualenv bin directory i.e.
PATHTOVENV/bin/frameworkpython
#!/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 "$@"
With this in place you can run frameworkpython
as above but will need to add this script
to every virtualenv
In addition virtualenv-pythonw-osx provides an alternative workaround which may be used to solve the issue.