Julia on MyBinder with pyplot

Hi,

I hope this is the correct place to ask this question.

I’m trying to set up a binder at mybinder.org to run some Julia notebooks. So far this worked very well using Project.toml and Manifest.toml. The only thing I can’t get to work is plotting with the pyplot backend of Plots.jl.
In a MWE, the Project.toml contains just the Plots and PyPlot packages and looks like this:

[deps]
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
PyPlot = "d330b81b-6aea-500a-939a-2ce795aea3ee"

When running a notebook on binder, using Plots and plotting with gr works well, but running pyplot() throws the following error:

InitError: PyError (PyImport_ImportModule

The Python package matplotlib could not be found by pyimport. Usually this means
that you did not install matplotlib in the Python version being used by PyCall.

PyCall is currently configured to use the Python version at:

/srv/conda/envs/notebook/bin/python3

and you should use whatever mechanism you usually use (apt-get, pip, conda,
etcetera) to install the Python package containing the matplotlib module.

One alternative is to re-configure PyCall to use a different Python
version on your system: set ENV["PYTHON"] to the path/name of the python
executable you want to use, run Pkg.build("PyCall"), and re-launch Julia.

Another alternative is to configure PyCall to use a Julia-specific Python
distribution via the Conda.jl package (which installs a private Anaconda
Python distribution), which has the advantage that packages can be installed
and kept up-to-date via Julia.  As explained in the PyCall documentation,
set ENV["PYTHON"]="", run Pkg.build("PyCall"), and re-launch Julia. Then,
To install the matplotlib module, you can use `pyimport_conda("matplotlib", PKG)`,
where PKG is the Anaconda package the contains the module matplotlib,
or alternatively you can use the Conda package directly (via
`using Conda` followed by `Conda.add` etcetera).

) <class 'ModuleNotFoundError'>
ModuleNotFoundError("No module named 'matplotlib'")

during initialization of module PyPlot

Stacktrace:
 [1] pyimport(::String) at /srv/julia/pkg/packages/PyCall/zqDXB/src/PyCall.jl:536
 [2] pyimport_conda(::String, ::String, ::String) at /srv/julia/pkg/packages/PyCall/zqDXB/src/PyCall.jl:694
 [3] pyimport_conda at /srv/julia/pkg/packages/PyCall/zqDXB/src/PyCall.jl:693 [inlined]
 [4] __init__() at /srv/julia/pkg/packages/PyPlot/XHEG0/src/init.jl:179
 [5] _include_from_serialized(::String, ::Array{Any,1}) at ./loading.jl:697
 [6] _require_search_from_serialized(::Base.PkgId, ::String) at ./loading.jl:781
 [7] _require(::Base.PkgId) at ./loading.jl:1006
 [8] require(::Base.PkgId) at ./loading.jl:927
 [9] require(::Module, ::Symbol) at ./loading.jl:922
 [10] top-level scope at /srv/julia/pkg/packages/Plots/FYxdA/src/backends.jl:508
 [11] eval at ./boot.jl:331 [inlined]
 [12] _initialize_backend(::Plots.PyPlotBackend) at /srv/julia/pkg/packages/Plots/FYxdA/src/backends.jl:507
 [13] backend at /srv/julia/pkg/packages/Plots/FYxdA/src/backends.jl:176 [inlined]
 [14] pyplot(; kw::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}) at /srv/julia/pkg/packages/Plots/FYxdA/src/backends.jl:33
 [15] pyplot() at /srv/julia/pkg/packages/Plots/FYxdA/src/backends.jl:33
 [16] top-level scope at In[3]:1

Is there anything I need to do to setup the python environment correctly on binder?

1 Like

By default, I believe that PyPlot will try to use whichever version of Python is in the system PATH.

The way I got this working was by just adding a requirements.txt file which tells binder to install matplotlib on whichever Python version it uses by default.

Feel free to have a look at my repository for an example:

In particular the requirements.txt file:

For more complex set-ups, you might be interested in this example repository:

2 Likes