Warning "Error requiring PyPlot from Plots" in compiled julia program

Hi all! I am trying to compile my julia project using PackageCompiler v. 2.1.0. My julia version is 1.8.2, Plots is v. 1.35.8, PyCall 1.94.1 and, PyPlot 2.11.0. Compilation works, at least it doesn’t error in the middle. But when I start my compiled program, I get the following warning:

Warning: Error requiring `PyPlot` from `Plots`
│   exception =
│    LoadError: ArgumentError: ref of NULL PyObject
│    Stacktrace:
│      [1] _getproperty(o::PyCall.PyObject, s::String)
│        @ PyCall ~/.julia/packages/PyCall/ygXW2/src/PyCall.jl:299
│      [2] __getproperty
│        @ ~/.julia/packages/PyCall/ygXW2/src/PyCall.jl:312 [inlined]
│      [3] getproperty(o::PyCall.PyObject, s::String)
│        @ PyCall ~/.julia/packages/PyCall/ygXW2/src/PyCall.jl:317
│      [4] top-level scope
│        @ ~/.julia/packages/Plots/qgrW8/src/backends/pyplot.jl:25
│      [5] include(mod::Module, _path::RelocatableFolders.Path)
│        @ Base ./Base.jl:419
│      [6] include(x::RelocatableFolders.Path)
│        @ Plots ~/.julia/packages/Plots/qgrW8/src/Plots.jl:1
│      [7] top-level scope
│        @ ~/.julia/packages/Plots/qgrW8/src/init.jl:96
│      [8] eval
│        @ ./boot.jl:368 [inlined]
│      [9] eval
│        @ ~/.julia/packages/Plots/qgrW8/src/Plots.jl:1 [inlined]
│     [10] (::Plots.var"#378#423")()
│        @ Plots ~/.julia/packages/Requires/Z8rfN/src/require.jl:101
│     [11] macro expansion
│        @ ./timing.jl:382 [inlined]
│     [12] err(f::Any, listener::Module, modname::String, file::String, line::Any)
│        @ Requires ~/.julia/packages/Requires/Z8rfN/src/require.jl:47
│     [13] (::Plots.var"#377#422")()
│        @ Plots ~/.julia/packages/Requires/Z8rfN/src/require.jl:100
│     [14] withpath(f::Any, path::String)
│        @ Requires ~/.julia/packages/Requires/Z8rfN/src/require.jl:37
│     [15] (::Plots.var"#376#421")()
│        @ Plots ~/.julia/packages/Requires/Z8rfN/src/require.jl:99
│     [16] listenpkg(f::Any, pkg::Base.PkgId)
│        @ Requires ~/.julia/packages/Requires/Z8rfN/src/require.jl:20
│     [17] macro expansion
│        @ ~/.julia/packages/Requires/Z8rfN/src/require.jl:98 [inlined]
│     [18] __init__()
│        @ Plots ~/.julia/packages/Plots/qgrW8/src/init.jl:95
│    in expression starting at /home/clara/.julia/packages/Plots/qgrW8/src/backends/pyplot.jl:25
└ @ Requires ~/.julia/packages/Requires/Z8rfN/src/require.jl:51

It is still possible to call the help menu of my program though. But does anyone know how to avoid the warning shown above? Thanks a lot!

It looks like there might br a pointer that is trying to be serialized and deserialized, but it ends up being null since you cannot really save pointers.

The situation also appears complicated by the use of Requires.jl. Since you are compiling anyways there is no need for Requires.jl. Just include Plots.jl directly.

Okay… Thanks! I’m not really including Requires though, it comes in the Plots dependencies. But maybe then I just have to live with the warning…

@stevengj , any thoughts about what might be happening here?

A test might be to use PyPlot.jl directky rather than through Plots.jl.

This probably means that PyPlot had an error loading matplotlib, maybe because it’s missing from your Python install.

You may get a more detailed error message if you do using PyPlot directly.

Would any of the Python environment be captured during compilation?

The location of libpython and the Python path are set when you build PyCall. If you change these, you should re-run

pkg> build PyCall

at the package prompt.

This is via the depsutils.jl file, right?

I’m just thinking if PyCall.jl still knows where to look if it is compiled into the system image.

The other thing to mention here is that the system image itself is not meant to be fully portable at the moment. You may not be able to compile the system image on one computer and use it on another computer.

Let us know if any of this helps @clarakoehne .