PythonPlot.streamplot error

Hello, I was trying to generate a stream plot using PythonPlot.jl like this example: Julia_Examples/pyplot_streamplot.jl at master · gizmaa/Julia_Examples · GitHub

However, I was encounter an error while running the following code. I would like to know how to correctly call streamplot() under PythonPlot.jl .

using PythonPlot

## This works
x = range(0; stop=2*pi, length=1000)
y = sin.(3 * x + 4 * cos.(2 * x))
plot(x, y, color="red", linewidth=2.0, linestyle="--")
title("A sinusoidally modulated sinusoid")
gcf()

#---
minval = -3
maxval = 3
steps = 100
X = repeat(range(minval,stop=maxval,length=steps)',steps)
Y = repeat(range(minval,stop=maxval,length=steps),1,steps)
U = -1 .- X.^2 .+ Y
V = 1 .+ X .- Y.^2
speed = sqrt.(U.^2 .+ V.^2)

fig = figure("pyplot_streamplot",figsize=(10,10))
subplot(311)
streamplot(X,Y,U,V) ## This line gives error

Error message:

ERROR: Python: Julia: an error occurred while setting an error
Python stacktrace:
 [1] __getitem__
   @ C:\Users\sosiristseng\.julia\packages\PythonCall\83z4q\src\JlWrap\array.jl:350
 [2] __init__
   @ matplotlib.streamplot d:\github\mmsb-bebi-5009\.CondaPkg\.pixi\envs\default\Lib\site-packages\matplotlib\streamplot.py:329
 [3] streamplot
   @ matplotlib.streamplot d:\github\mmsb-bebi-5009\.CondaPkg\.pixi\envs\default\Lib\site-packages\matplotlib\streamplot.py:91
 [4] inner
   @ matplotlib d:\github\mmsb-bebi-5009\.CondaPkg\.pixi\envs\default\Lib\site-packages\matplotlib\__init__.py:1524
 [5] streamplot
   @ matplotlib.pyplot d:\github\mmsb-bebi-5009\.CondaPkg\.pixi\envs\default\Lib\site-packages\matplotlib\pyplot.py:4141
Stacktrace:
 [1] pythrow()
   @ PythonCall.Core C:\Users\sosiristseng\.julia\packages\PythonCall\83z4q\src\Core\err.jl:77
 [2] errcheck
   @ C:\Users\sosiristseng\.julia\packages\PythonCall\83z4q\src\Core\err.jl:10 [inlined]
 [3] pycallargs(f::PythonCall.Py, args::PythonCall.Py)
   @ PythonCall.Core C:\Users\sosiristseng\.julia\packages\PythonCall\83z4q\src\Core\builtins.jl:194
 [4] pycall(::PythonCall.Py, ::Matrix{Float64}, ::Vararg{Matrix{Float64}}; kwargs::@Kwargs{})
   @ PythonCall.Core C:\Users\sosiristseng\.julia\packages\PythonCall\83z4q\src\Core\builtins.jl:213
 [5] pycall(::PythonCall.Py, ::Matrix{Float64}, ::Vararg{Matrix{Float64}})
   @ PythonCall.Core C:\Users\sosiristseng\.julia\packages\PythonCall\83z4q\src\Core\builtins.jl:203
 [6] streamplot(::Matrix{Float64}, ::Vararg{Matrix{Float64}}; kws::@Kwargs{})
   @ PythonPlot C:\Users\sosiristseng\.julia\packages\PythonPlot\oS8x4\src\PythonPlot.jl:179
 [7] streamplot(::Matrix{Float64}, ::Vararg{Matrix{Float64}})
   @ PythonPlot C:\Users\sosiristseng\.julia\packages\PythonPlot\oS8x4\src\PythonPlot.jl:175
 [8] top-level scope
   @ d:\github\mmsb-bebi-5009\test.jl:22

System info

Julia Version 1.12.5
OS: Windows 11 24H2

Installed packages

  [274fc56d] + PythonPlot v1.0.6

Manifest

  [3da002f7] + ColorTypes v0.12.1
  [5ae59095] + Colors v0.13.1
  [992eb4ea] + CondaPkg v0.2.34
  [9a962f9c] + DataAPI v1.16.0
  [e2d170a0] + DataValueInterfaces v1.0.0
  [53c48c17] + FixedPointNumbers v0.8.5
  [82899510] + IteratorInterfaceExtensions v1.0.0
  [692b3bcd] + JLLWrappers v1.7.1
  [682c06a0] + JSON v1.4.0
  [b964fa9f] + LaTeXStrings v1.4.0
  [1914dd2f] + MacroTools v0.5.16
  [0b3b1443] + MicroMamba v0.1.15
  [bac558e1] + OrderedCollections v1.8.1
  [69de0a69] + Parsers v2.8.3
  [fa939f87] + Pidfile v1.3.0
  [aea7be01] + PrecompileTools v1.3.3
  [21216c6a] + Preferences v1.5.2
  [6099a3de] + PythonCall v0.9.31
  [274fc56d] + PythonPlot v1.0.6
  [189a3867] + Reexport v1.2.2
  [6c6a2e73] + Scratch v1.3.0
  [10745b16] + Statistics v1.11.1
  [ec057cc2] + StructUtils v2.7.1
  [3783bdb8] + TableTraits v1.0.1
  [bd369af6] + Tables v1.12.1
  [e17b2a0c] + UnsafePointers v1.0.0
  [81def892] + VersionParsing v1.3.0
  [f8abcde7] + micromamba_jll v2.3.1+0
  [4d7b5844] + pixi_jll v0.41.3+0
  [0dad84c5] + ArgTools v1.1.2
  [56f22d72] + Artifacts v1.11.0
  [2a0f44e3] + Base64 v1.11.0
  [ade2ca70] + Dates v1.11.0
  [f43a241f] + Downloads v1.7.0
  [7b1f6079] + FileWatching v1.11.0
  [b77e0a4c] + InteractiveUtils v1.11.0
  [ac6e5ff7] + JuliaSyntaxHighlighting v1.12.0
  [4af54fe1] + LazyArtifacts v1.11.0
  [b27032c2] + LibCURL v0.6.4
  [76f85450] + LibGit2 v1.11.0
  [8f399da3] + Libdl v1.11.0
  [37e2e46d] + LinearAlgebra v1.12.0
  [56ddb016] + Logging v1.11.0
  [d6f4376e] + Markdown v1.11.0
  [ca575930] + NetworkOptions v1.3.0
  [44cfe95a] + Pkg v1.12.1
  [de0858da] + Printf v1.11.0
  [9a3f8284] + Random v1.11.0
  [ea8e919c] + SHA v0.7.0
  [9e88b42a] + Serialization v1.11.0
  [6462fe0b] + Sockets v1.11.0
  [f489334b] + StyledStrings v1.11.0
  [fa267f1f] + TOML v1.0.3
  [a4e569a6] + Tar v1.10.0
  [8dfed614] + Test v1.11.0
  [cf7118a7] + UUIDs v1.11.0
  [4ec0a83e] + Unicode v1.11.0
  [e66e0078] + CompilerSupportLibraries_jll v1.3.0+1
  [deac9b47] + LibCURL_jll v8.15.0+0
  [e37daf67] + LibGit2_jll v1.9.0+0
  [29816b5a] + LibSSH2_jll v1.11.3+1
  [14a3606d] + MozillaCACerts_jll v2025.11.4
  [4536629a] + OpenBLAS_jll v0.3.29+0
  [458c3c95] + OpenSSL_jll v3.5.4+0
  [83775a58] + Zlib_jll v1.3.1+2
  [8e850b90] + libblastrampoline_jll v5.15.0+0
  [8e850ede] + nghttp2_jll v1.64.0+1
  [3f19e933] + p7zip_jll v17.7.0+0
1 Like

streamplot seems to be erroring at array slicing for checking row equality in a matrix (elif np.ndim(x) == 2: x_row = x[0] at line 329 of streamplot.py), which is fairly concerning for PythonCall.ArrayValue wrapping a plain Matrix{Float64}. Not sure how that’s going wrong, maybe somewhere translating the array indices from Python to Julia.

streamplot used to only support 1D arrays, which should dodge that particular check. Try these edits, maybe nothing else goes wrong:

Xrange = range(minval,stop=maxval,length=steps)
X = Xrange'
Y = range(minval,stop=maxval,length=steps)

and:

streamplot(Xrange, Y, U, V)

EDIT: Looked into this a bit further, and the indexing issue is an intentional limitation. The automatic juliacall.ArrayValue on the Python side does adjust Python’s 0-based indexing and slicing syntax for the wrapped Julia AbstractArray; for example, @pyexec X => "print(X[0,:])" works and indexes X[1,:]. However, wrapping a Julia AbstractArray cannot be entirely the same as a NumPy array; in this case, Julia AbstractArrays and NumPy arrays disagree on omitted trailing indices and linear indexing, so @pyexec X => "print(X[0])" fails. Not sure how that script worked before, but in the general case, you need to rewrap in a NumPy array.

1 Like

@Benny Thank you for your clear explanation. Your solution works!