Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Improve virtualenv and framework builds #7022

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Sep 5, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/faq/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ The Matplotlib FAQ
troubleshooting_faq.rst
environment_variables_faq.rst
virtualenv_faq.rst
osx_framework.rst
130 changes: 130 additions & 0 deletions doc/faq/osx_framework.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
.. _osxframework-faq:

******************************
Working with Matplotlib on OSX
******************************

.. contents::
:backlinks: none


.. _osxframework_introduction:

Introduction
============

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 the ``macosx`` backend
checks that a framework build is available and fails if a non framework
build is found. WX has a similar check build in.

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.

Short version
=============

VirtualEnv
----------

If you are on Python 3, use
`venv <https://docs.python.org/3/library/venv.html>`_
instead of `virtualenv <https://virtualenv.pypa.io/en/latest/>`_::

python -m venv my-virtualenv
source my-virtualenv/bin/activate

Otherwise you will need one of the workarounds below.

Conda
-----

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``


Long version
============

Unfortunately virtualenv creates a non
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth another mention of venv here in case someone skipped straight to the long version?

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
<https://github.com/pypa/virtualenv/issues/54>`__ and `here
<https://github.com/pypa/virtualenv/issues/609>`__

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

.. code:: bash

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`` Script
^^^^^^^^^^^^^^^^^^^^^

An alternative work around borrowed from the `WX wiki
<http://wiki.wxpython.org/wxPythonVirtualenvOnMac>`_, 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``

.. code:: bash

#!/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

PythonW Compiler
^^^^^^^^^^^^^^^^

In addition
`virtualenv-pythonw-osx <https://github.com/gldnspud/virtualenv-pythonw-osx>`_
provides an alternative workaround which may be used to solve the issue.
100 changes: 5 additions & 95 deletions doc/faq/virtualenv_faq.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Working with Matplotlib in Virtual environments
:backlinks: none


.. _introduction:
.. _virtualenv_introduction:

Introduction
============
Expand All @@ -25,6 +25,9 @@ If you only use the ``IPython/Jupyter Notebook``'s ``inline`` and ``notebook``
backends and non interactive backends you should not have any issues and can
ignore everything below.

If you are using Matplotlib on OSX you may also want to consider the
:ref:`OSX framework FAQ <osxframework-faq>`.

GUI Frameworks
==============

Expand All @@ -40,8 +43,7 @@ exist. Some of these are given here:
* The ``TKAgg`` backend doesn't require any external dependencies and is
normally always available.
* The ``QT4`` framework ``PySide`` is pip installable.
* The upcoming `WX Phoenix <http://wiki.wxpython.org/ProjectPhoenix>`_ toolkit
is ``pip`` installable.
* ``PYQT5`` is pip installable on Python 3.5.

Other frameworks are harder to install into a virtual environment. There are at
least two possible ways to get access to these in a virtual environment.
Expand All @@ -58,95 +60,3 @@ Alternatively, you can manually symlink the GUI frameworks into the environment.
I.e. to use PyQt5, you should symlink ``PyQt5`` and ``sip`` from your system
site packages directory into the environment taking care that the environment
and the systemwide install use the same python version.

OSX
===

Short version
-------------

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.

Long version
------------

On OSX, two different types of Python Builds exist: a regular build and a
framework build. In order to interact correctly with OSX through some
GUI frameworks you need a framework build of Python.
At the time of writing the ``macosx``, ``WX`` and ``WXAgg`` backends require a
framework build to function correctly. Unfortunately virtualenv creates a non
framework build even if created from a framework build of Python. Conda
environments are framework builds. From
Matplotlib 1.5 onwards the ``macosx`` backend checks that a framework build is
available and fails if a non framework build is found.
WX has a similar check build in.

The issue has been reported on the virtualenv bug tracker `here
<https://github.com/pypa/virtualenv/issues/54>`__ and `here
<https://github.com/pypa/virtualenv/issues/609>`__

Until this is fixed, one of the following workarounds must be used:

``PYTHONHOME`` Script
^^^^^^^^^^^^^^^^^^^^^

The best known workaround,
borrowed from the `WX wiki
<http://wiki.wxpython.org/wxPythonVirtualenvOnMac>`_, 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``

.. code:: bash

#!/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`` 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`` Function
^^^^^^^^^^^^^^^^^^^^^^^

Alternatively you can define a function in your ``.bashrc`` using

.. code:: bash

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.

PythonW Compiler
^^^^^^^^^^^^^^^^

In addition
`virtualenv-pythonw-osx <https://github.com/gldnspud/virtualenv-pythonw-osx>`_
provides an alternative workaround which may be used to solve the issue.
5 changes: 3 additions & 2 deletions src/_macosx.m
Original file line number Diff line number Diff line change
Expand Up @@ -3092,8 +3092,9 @@ static bool verify_framework(void)
"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 "
"Working with Matplotlib in a virtual enviroment see 'Working with "
"Matplotlib in Virtual environments' in the Matplotlib FAQ");
"using (Ana)Conda please install python.app and replace the use of 'python' "
"with 'pythonw'. See 'Working with Matplotlib on OSX' "
"in the Matplotlib FAQ for more information.");
return false;
}

Expand Down