Errors Using PythonCall.jl and PythonPlot.jl with a Python Virtual Environment

I really have been struggling with this issue and not sure what to do. For context, I have a brand-new Windows PC, and I have Julia 1.11.2 and Python 3.13.1 installed on it. I did the following:

I created a Python virtual environment (in a PowerShell Terminal with PowerShell version 5.1.22621.4391) called venv_1 with venv (the virtual environment manager that comes with Python) in the following directory:

"C:\Research Software\Python\Virtual Environments\venv_1"

I then activated the Python virtual environment and did:

pip install numpy
pip install matplotlib

When I do pip list in the Python virtual environment, I get the following output:

Package         Version
--------------- -----------
contourpy       1.3.1
cycler          0.12.1
fonttools       4.55.3
kiwisolver      1.4.7
matplotlib      3.10.0
numpy           2.2.1
packaging       24.2
pillow          11.0.0
pip             24.3.1
pyparsing       3.2.0
python-dateutil 2.9.0.post0
six             1.17.0

I then created a Julia virtual environment called venv_1 in the following directory:

"C:\Research Software\Julia\Virtual Environments\venv_1"

I then activated the Julia virtual environment and did:

Pkg.add("Plots.jl")
Pkg.add("PythonCall.jl")
Pkg.add("PythonPlot.jl")

I then added the following lines of code to my startup.jl file located at "~\.julia\config\startup.jl":

ENV["JULIA_CONDAPKG_BACKEND"]="Null"
ENV["JULIA_PYTHONCALL_EXE"]=raw"C:/Research Software/Python/Virtual Environments/venv_1/Scripts/python.exe"

Here is where the issue arises. When I run the following Julia script (called test_script.jl):

using Plots
pythonplot()

x = [1,2,3,4,5]
y = x

plot(x,y)

I get the following error:

ERROR: InitError: PythonCall.Core.PyException(PythonCall.Core.Py(Ptr{PythonCall.C.PyObject} @0x00007ffe22ec7f20), PythonCall.Core.Py(Ptr{PythonCall.C.PyObject} @0x000002d8339cd6c0), PythonCall.Core.Py(Ptr{PythonCall.C.PyObject} @0x000002d833a24480), false)
Stacktrace:
  [1] pythrow()
    @ PythonCall.Core C:\Users\ericd\.julia\packages\PythonCall\Nr75f\src\Core\err.jl:92
  [2] errcheck
    @ C:\Users\ericd\.julia\packages\PythonCall\Nr75f\src\Core\err.jl:10 [inlined]
  [3] pyimport(m::String)
    @ PythonCall.Core C:\Users\ericd\.julia\packages\PythonCall\Nr75f\src\Core\builtins.jl:1561
  [4] __init__()
    @ PythonPlot C:\Users\ericd\.julia\packages\PythonPlot\469aA\src\init.jl:150
  [5] run_module_init(mod::Module, i::Int64)
    @ Base .\loading.jl:1378
  [6] register_restored_modules(sv::Core.SimpleVector, pkg::Base.PkgId, path::String)
    @ Base .\loading.jl:1366
  [7] _include_from_serialized(pkg::Base.PkgId, path::String, ocachepath::String, depmods::Vector{…}, ignore_native::Nothing; register::Bool)
    @ Base .\loading.jl:1254
  [8] _include_from_serialized (repeats 2 times)
    @ .\loading.jl:1210 [inlined]
  [9] _require_search_from_serialized(pkg::Base.PkgId, sourcepath::String, build_id::UInt128, stalecheck::Bool; reasons::Dict{…}, DEPOT_PATH::Vector{…})
    @ Base .\loading.jl:2057
 [10] _require(pkg::Base.PkgId, env::String)
    @ Base .\loading.jl:2527
 [11] __require_prelocked(uuidkey::Base.PkgId, env::String)
    @ Base .\loading.jl:2388
 [12] #invoke_in_world#3
    @ .\essentials.jl:1089 [inlined]
 [13] invoke_in_world
    @ .\essentials.jl:1086 [inlined]
 [14] _require_prelocked(uuidkey::Base.PkgId, env::String)
    @ Base .\loading.jl:2375
 [15] macro expansion
    @ .\loading.jl:2314 [inlined]
 [16] macro expansion
    @ .\lock.jl:273 [inlined]
 [17] __require(into::Module, mod::Symbol)
    @ Base .\loading.jl:2271
 [18] #invoke_in_world#3
    @ .\essentials.jl:1089 [inlined]
 [19] invoke_in_world
    @ .\essentials.jl:1086 [inlined]
 [20] require(into::Module, mod::Symbol)
    @ Base .\loading.jl:2260
 [21] top-level scope
    @ C:\Users\ericd\.julia\packages\Plots\Ec1L1\src\backends.jl:1074
during initialization of module PythonPlot
Some type information was truncated. Use `show(err)` to see complete types.

When I then type show(err), the following is displayed:

1-element ExceptionStack:
LoadError: InitError: Python: ImportError: Error importing numpy: you should not try to import numpy from
        its source directory; please exit the numpy source tree, and relaunch
        your python interpreter from there.
Python stacktrace:
 [1] <module>
   @ C:\Research Software\Python\Virtual Environments\venv_1\Lib\site-packages\numpy\__init__.py:132
 [2] <module>
   @ C:\Research Software\Python\Virtual Environments\venv_1\Lib\site-packages\matplotlib\cbook.py:24
 [3] <module>
   @ C:\Research Software\Python\Virtual Environments\venv_1\Lib\site-packages\matplotlib\__init__.py:161
Stacktrace:
  [1] pythrow()
    @ PythonCall.Core C:\Users\ericd\.julia\packages\PythonCall\Nr75f\src\Core\err.jl:92
  [2] errcheck
    @ C:\Users\ericd\.julia\packages\PythonCall\Nr75f\src\Core\err.jl:10 [inlined]
  [3] pyimport(m::String)
    @ PythonCall.Core C:\Users\ericd\.julia\packages\PythonCall\Nr75f\src\Core\builtins.jl:1561
  [4] __init__()
    @ PythonPlot C:\Users\ericd\.julia\packages\PythonPlot\469aA\src\init.jl:150
  [5] run_module_init(mod::Module, i::Int64)
    @ Base .\loading.jl:1378
  [6] register_restored_modules(sv::Core.SimpleVector, pkg::Base.PkgId, path::String)
    @ Base .\loading.jl:1366
  [7] _include_from_serialized(pkg::Base.PkgId, path::String, ocachepath::String, depmods::Vector{Any}, ignore_native::Nothing; register::Bool)
    @ Base .\loading.jl:1254
  [8] _include_from_serialized (repeats 2 times)
    @ .\loading.jl:1210 [inlined]
  [9] _require_search_from_serialized(pkg::Base.PkgId, sourcepath::String, build_id::UInt128, stalecheck::Bool; reasons::Dict{String, Int64}, DEPOT_PATH::Vector{String})
    @ Base .\loading.jl:2057
 [10] _require(pkg::Base.PkgId, env::String)
    @ Base .\loading.jl:2527
 [11] __require_prelocked(uuidkey::Base.PkgId, env::String)
    @ Base .\loading.jl:2388
 [12] #invoke_in_world#3
    @ .\essentials.jl:1089 [inlined]
 [13] invoke_in_world
    @ .\essentials.jl:1086 [inlined]
 [14] _require_prelocked(uuidkey::Base.PkgId, env::String)
    @ Base .\loading.jl:2375
 [15] macro expansion
    @ .\loading.jl:2314 [inlined]
 [16] macro expansion
    @ .\lock.jl:273 [inlined]
 [17] __require(into::Module, mod::Symbol)
    @ Base .\loading.jl:2271
 [18] #invoke_in_world#3
    @ .\essentials.jl:1089 [inlined]
 [19] invoke_in_world
    @ .\essentials.jl:1086 [inlined]
 [20] require(into::Module, mod::Symbol)
    @ Base .\loading.jl:2260
 [21] top-level scope
    @ C:\Users\ericd\.julia\packages\Plots\Ec1L1\src\backends.jl:1074
 [22] eval
    @ .\boot.jl:430 [inlined]
 [23] _initialize_backend(pkg::Plots.PythonPlotBackend)
    @ Plots C:\Users\ericd\.julia\packages\Plots\Ec1L1\src\backends.jl:1073
 [24] backend(pkg::Plots.PythonPlotBackend)
    @ Plots C:\Users\ericd\.julia\packages\Plots\Ec1L1\src\backends.jl:245
 [25] pythonplot()
    @ Plots C:\Users\ericd\.julia\packages\Plots\Ec1L1\src\backends.jl:86
 [26] top-level scope
    @ c:\Examples\test_script.jl:2
 [27] eval
    @ .\boot.jl:430 [inlined]
 [28] include_string(mapexpr::typeof(identity), mod::Module, code::String, filename::String)
    @ Base .\loading.jl:2734
 [29] include_string(m::Module, txt::String, fname::String)
    @ Base .\loading.jl:2744
 [30] invokelatest(::Any, ::Any, ::Vararg{Any}; kwargs::@Kwargs{})
    @ Base .\essentials.jl:1055
 [31] invokelatest(::Any, ::Any, ::Vararg{Any})
    @ Base .\essentials.jl:1052
 [32] inlineeval(m::Module, code::String, code_line::Int64, code_column::Int64, file::String; softscope::Bool)
    @ VSCodeServer c:\Users\ericd\.vscode\extensions\julialang.language-julia-1.127.2\scripts\packages\VSCodeServer\src\eval.jl:271
 [33] (::VSCodeServer.var"#69#74"{Bool, Bool, Bool, Module, String, Int64, Int64, String, VSCodeServer.ReplRunCodeRequestParams})()
    @ VSCodeServer c:\Users\ericd\.vscode\extensions\julialang.language-julia-1.127.2\scripts\packages\VSCodeServer\src\eval.jl:181
 [34] withpath(f::VSCodeServer.var"#69#74"{Bool, Bool, Bool, Module, String, Int64, Int64, String, VSCodeServer.ReplRunCodeRequestParams}, path::String)
    @ VSCodeServer c:\Users\ericd\.vscode\extensions\julialang.language-julia-1.127.2\scripts\packages\VSCodeServer\src\repl.jl:276
 [35] (::VSCodeServer.var"#68#73"{Bool, Bool, Bool, Module, String, Int64, Int64, String, VSCodeServer.ReplRunCodeRequestParams})()
    @ VSCodeServer c:\Users\ericd\.vscode\extensions\julialang.language-julia-1.127.2\scripts\packages\VSCodeServer\src\eval.jl:179
 [36] hideprompt(f::VSCodeServer.var"#68#73"{Bool, Bool, Bool, Module, String, Int64, Int64, String, VSCodeServer.ReplRunCodeRequestParams})
    @ VSCodeServer c:\Users\ericd\.vscode\extensions\julialang.language-julia-1.127.2\scripts\packages\VSCodeServer\src\repl.jl:38
 [37] #67
    @ c:\Users\ericd\.vscode\extensions\julialang.language-julia-1.127.2\scripts\packages\VSCodeServer\src\eval.jl:150 [inlined]
 [38] with_logstate(f::VSCodeServer.var"#67#72"{Bool, Bool, Bool, Module, String, Int64, Int64, String, VSCodeServer.ReplRunCodeRequestParams}, logstate::Base.CoreLogging.LogState)
    @ Base.CoreLogging .\logging\logging.jl:522
 [39] with_logger
    @ .\logging\logging.jl:632 [inlined]
 [40] (::VSCodeServer.var"#66#71"{VSCodeServer.ReplRunCodeRequestParams})()
    @ VSCodeServer c:\Users\ericd\.vscode\extensions\julialang.language-julia-1.127.2\scripts\packages\VSCodeServer\src\eval.jl:263
 [41] #invokelatest#2
    @ .\essentials.jl:1055 [inlined]
 [42] invokelatest(::Any)
    @ Base .\essentials.jl:1052
 [43] (::VSCodeServer.var"#64#65")()
    @ VSCodeServer c:\Users\ericd\.vscode\extensions\julialang.language-julia-1.127.2\scripts\packages\VSCodeServer\src\eval.jl:34
during initialization of module PythonPlot
in expression starting at c:\Examples\test_script.jl:2

If I run test_script.jl again in the same Julia session, the following error is returned:

┌ Warning: You are using Matplotlib 0.0.0, which is no longer
│ officially supported by the Plots community. To ensure smooth Plots.jl
│ integration update your Matplotlib library to a version ≥ 3.4.0
└ @ Plots C:\Users\ericd\.julia\packages\Plots\Ec1L1\src\backends\pythonplot.jl:12
┌ Warning: You are using Matplotlib 0.0.0, which is no longer
│ officially supported by the Plots community. To ensure smooth Plots.jl
│ integration update your Matplotlib library to a version ≥ 3.4.0
└ @ Plots C:\Users\ericd\.julia\packages\Plots\Ec1L1\src\backends\pythonplot.jl:12
ERROR: Python: ImportError: Error importing numpy: you should not try to import numpy from
        its source directory; please exit the numpy source tree, and relaunch
        your python interpreter from there.
Python stacktrace:
 [1] <module>
   @ C:\Research Software\Python\Virtual Environments\venv_1\Lib\site-packages\numpy\__init__.py:132
 [2] <module>
   @ C:\Research Software\Python\Virtual Environments\venv_1\Lib\site-packages\matplotlib\cbook.py:24
 [3] <module>
   @ C:\Research Software\Python\Virtual Environments\venv_1\Lib\site-packages\matplotlib\__init__.py:161
Stacktrace:
 [1] pythrow()
   @ PythonCall.Core C:\Users\ericd\.julia\packages\PythonCall\Nr75f\src\Core\err.jl:92
 [2] errcheck
   @ C:\Users\ericd\.julia\packages\PythonCall\Nr75f\src\Core\err.jl:10 [inlined]
 [3] pyimport(m::String)
   @ PythonCall.Core C:\Users\ericd\.julia\packages\PythonCall\Nr75f\src\Core\builtins.jl:1561
 [4] top-level scope
   @ C:\Users\ericd\.julia\packages\Plots\Ec1L1\src\backends.jl:1055

To see if the issue was (exclusively) with my Python installation, I created the following Python script called test_script.py and ran it with the Python interpreter found in the venv_1 python virtual environment:

import numpy as np
import matplotlib.pyplot at plt

x = np.array([1,2,3,4,5])
y = x 

plt.plot(x,y)

plt.show()

This script ran perfectly fine. I am not sure what the issue is. I specifically would like to understand the following and how it can be resolved.

Error importing numpy: you should not try to import numpy from
        its source directory; please exit the numpy source tree, and relaunch
        your python interpreter from there.

Any help is greatly appreciated!

(I recently posted another post with respect to PyCall.jl and PyPlot.jl. This issue is similar but not identical, so I figured this post was warranted.)

Hi,

the PythonCall.jl equivalent of the explicit adding of site-packages also seems to work here:

ENV["JULIA_PYTHONCALL_EXE"] = "C:/Research Software/Python/Virtual Environments/venv_1/Scripts/python.exe"
ENV["JULIA_CONDAPKG_BACKEND"] = "Null"
using Pkg
Pkg.add("PythonCall")
using PythonCall
pyimport("site").addsitedir("C:/Research Software/Python/Virtual Environments/venv_1/Lib/site-packages")
# Alternatively, pyimport("sys").path.insert(0, "C:/Research Software/Python/Virtual Environments/venv_1/Lib/site-packages") also seems to work.
# It's probably safest to add to both site and path.
Pkg.add("PythonPlot")
Pkg.add("Plots")


using Plots
pythonplot()

x = [1,2,3,4,5]
y = x

plot(x,y)
1 Like

Thank you very much. This worked for me.

1 Like