Defining plots in function results in world problem

I just stumbled across the following behaviour:
This code works

using Plots

x = range(0, 2 * pi, length=200)
Plots.pyplot()
p1 = plot(x, cos.(x))
display(p1)
savefig(p1, "test.pdf")
println("success")

while this code

using Plots

function main()
    x = range(0, 2 * pi, length=200)
    Plots.pyplot()
    p1 = plot(x, cos.(x))
    display(p1)
    savefig(p1, "test.pdf")
    println("success")
end

main()

gives the following error msg:

ERROR: LoadError: MethodError: no method matching _show(::IOStream, ::MIME{Symbol("application/pdf")}, ::Plots.Plot{Plots.PyPlotBackend})
The applicable method may be too new: running in world age 27217, while current world is 27298.
Closest candidates are:
  _show(::IO, ::MIME{Symbol("application/pdf")}, ::Plots.Plot{Plots.PyPlotBackend}) at /home/user/.julia/packages/Plots/vAz7I/src/backends/pyplot.jl:1428 (method too new to be called from this world context.)
  _show(::IO, ::MIME{Symbol("text/html")}, ::Plots.Plot) at /home/user/.julia/packages/Plots/vAz7I/src/output.jl:166
  _show(::IO, ::MIME{Symbol("text/plain")}, ::Plots.Plot) at /home/user/.julia/packages/Plots/vAz7I/src/output.jl:225
  ...
Stacktrace:
 [1] show(::IOStream, ::MIME{Symbol("application/pdf")}, ::Plots.Plot{Plots.PyPlotBackend}) at /home/user/.julia/packages/Plots/vAz7I/src/output.jl:215
 [2] pdf(::Plots.Plot{Plots.PyPlotBackend}, ::String) at /home/user/.julia/packages/Plots/vAz7I/src/output.jl:23
 [3] _show_pdfbackends(::IOContext{Base64.Base64EncodePipe}, ::MIME{Symbol("image/png")}, ::Plots.Plot{Plots.PyPlotBackend}) at /home/user/.julia/packages/Plots/vAz7I/src/fileio.jl:11
 [4] _show(::IOContext{Base64.Base64EncodePipe}, ::MIME{Symbol("image/png")}, ::Plots.Plot{Plots.PyPlotBackend}) at /home/user/.julia/packages/Plots/vAz7I/src/init.jl:89
 [5] _showjuno(::IOContext{Base64.Base64EncodePipe}, ::MIME{Symbol("image/png")}, ::Plots.Plot{Plots.PyPlotBackend}) at /home/user/.julia/packages/Plots/vAz7I/src/output.jl:284
 [6] showjuno(::IOContext{Base64.Base64EncodePipe}, ::MIME{Symbol("image/png")}, ::Plots.Plot{Plots.PyPlotBackend}) at /home/user/.julia/packages/Plots/vAz7I/src/output.jl:266
 [7] show(::IOContext{Base64.Base64EncodePipe}, ::MIME{Symbol("image/png")}, ::Plots.Plot{Plots.PyPlotBackend}) at /home/user/.julia/packages/Plots/vAz7I/src/output.jl:212
 [8] base64encode(::Function, ::MIME{Symbol("image/png")}, ::Vararg{Any,N} where N; context::IOContext{Base.GenericIOBuffer{Array{UInt8,1}}}) at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.4/Base64/src/encode.jl:208
 [9] _binstringmime(::MIME{Symbol("image/png")}, ::Plots.Plot{Plots.PyPlotBackend}, ::IOContext{Base.GenericIOBuffer{Array{UInt8,1}}}) at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.4/Base64/src/Base64.jl:46
 [10] stringmime(::MIME{Symbol("image/png")}, ::Plots.Plot{Plots.PyPlotBackend}; context::IOContext{Base.GenericIOBuffer{Array{UInt8,1}}}) at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.4/Base64/src/Base64.jl:43
 [11] stringmime(::String, ::Plots.Plot{Plots.PyPlotBackend}; context::IOContext{Base.GenericIOBuffer{Array{UInt8,1}}}) at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.4/Base64/src/Base64.jl:44
 [12] displayinplotpane(::Plots.Plot{Plots.PyPlotBackend}) at /home/user/.julia/packages/Atom/9h5Up/src/display/showdisplay.jl:84
 [13] display(::Atom.JunoDisplay, ::Plots.Plot{Plots.PyPlotBackend}) at /home/user/.julia/packages/Atom/9h5Up/src/display/showdisplay.jl:118
 [14] display(::Any) at ./multimedia.jl:323
 [15] main() at ...
 [16] top-level scope at ...
in expression starting at ...

I did a little research on the world problem, but couldn’t find any immediate solutions. I’m on Julia 1.4.2. The whole world thing seemed kind of strange to me to be honest.
The second version works in juno, when you run it a second time, but never on the first run when julia is started.

Edit: The problem also occurs when running from terminal and not in juno. For one I am interested in understanding the error, but mainly want to be able to wrap the plotting into a function.

Try taking Plots.pyplot() out of the function.

2 Likes

Solved my problem, thanks a lot!

1 Like