Plots & PyPlot?

Plots vs. PyPlot seems to have changed…

In the past, the following worked (Julia 1.1.0):

using Plots
pyplot()

This doesn’t work any more – if I do this, I get a lengthy error message:

┌ Warning: Error requiring PyPlot from Plots:
│ LoadError: MethodError: no method matching getproperty(::PyCall.PyObject, ::String)
│ Closest candidates are:
│   getproperty(::Any, !Matched::Symbol) at sysimg.jl:18
│ Stacktrace:
│  [1] top-level scope at none:0
│  [2] include at .\boot.jl:326 [inlined]
│  [3] include_relative(::Module, ::String) at .\loading.jl:1038
│  [4] include at .\sysimg.jl:29 [inlined]
│  [5] include(::String) at C:\Users\my-user-name\.julia\packages\Plots\47Tik\src\Plots.jl:1
│  [6] top-level scope at none:0
│  [7] eval at .\boot.jl:328 [inlined]
│  [8] eval at C:\Users\my-user-name\.julia\packages\Plots\47Tik\src\Plots.jl:1 [inlined]
│  [9] (::getfield(Plots, Symbol("##294#321")))() at C:\Users\my-user-name\.julia\packages\Requires\9Jse8\src\require.jl:67
│  [10] err(::getfield(Plots, Symbol("##294#321")), ::Module, ::String) at C:\Users\my-user-name\.julia\packages\Requires\9Jse8\src\require.jl:38
│  [11] #293 at C:\Users\my-user-name\.julia\packages\Requires\9Jse8\src\require.jl:66 [inlined]
│  [12] withpath(::getfield(Plots, Symbol("##293#320")), ::String) at C:\Users\my-user-name\.julia\packages\Requires\9Jse8\src\require.jl:28
│  [13] (::getfield(Plots, Symbol("##292#319")))() at C:\Users\my-user-name\.julia\packages\Requires\9Jse8\src\require.jl:65
│  [14] #invokelatest#1 at .\essentials.jl:742 [inlined]
│  [15] invokelatest at .\essentials.jl:741 [inlined]
│  [16] #3 at C:\Users\my-user-name\.julia\packages\Requires\9Jse8\src\require.jl:19 [inlined]
│  [17] iterate at .\generator.jl:47 [inlined]
│  [18] _collect(::Array{Function,1}, ::Base.Generator{Array{Function,1},getfield(Requires, Symbol("##3#4"))}, ::Base.EltypeUnknown, ::Base.HasShape{1}) at .\array.jl:619
│  [19] map at .\array.jl:548 [inlined]
│  [20] loadpkg(::Base.PkgId) at C:\Users\my-user-name\.julia\packages\Requires\9Jse8\src\require.jl:19
│  [21] #invokelatest#1 at .\essentials.jl:742 [inlined]
│  [22] invokelatest at .\essentials.jl:741 [inlined]
│  [23] require(::Base.PkgId) at .\loading.jl:861
│  [24] require(::Module, ::Symbol) at .\loading.jl:853
│  [25] top-level scope at C:\Users\my-user-name\.julia\packages\Plots\47Tik\src\backends.jl:486
│  [26] eval at .\boot.jl:328 [inlined]
│  [27] _initialize_backend(::Plots.PyPlotBackend) at C:\Users\my-user-name\.julia\packages\Plots\47Tik\src\backends.jl:485
│  [28] backend(::Plots.PyPlotBackend) at C:\Users\my-user-name\.julia\packages\Plots\47Tik\src\backends.jl:182
│  [29] #pyplot#253 at C:\Users\my-user-name\.julia\packages\Plots\47Tik\src\backends.jl:33 [inlined]
│  [30] pyplot() at C:\Users\my-user-name\.julia\packages\Plots\47Tik\src\backends.jl:33
│  [31] top-level scope at In[1]:2
│  [32] eval at .\boot.jl:328 [inlined]
│  [33] softscope_include_string(::Module, ::String, ::String) at C:\Users\my-user-name\.julia\packages\SoftGlobalScope\cSbw5\src\SoftGlobalScope.jl:218
│  [34] execute_request(::ZMQ.Socket, ::IJulia.Msg) at C:\Users\my-user-name\.julia\packages\IJulia\gI2uA\src\execute_request.jl:67
│  [35] #invokelatest#1 at .\essentials.jl:742 [inlined]
│  [36] invokelatest at .\essentials.jl:741 [inlined]
│  [37] eventloop(::ZMQ.Socket) at C:\Users\my-user-name\.julia\packages\IJulia\gI2uA\src\eventloop.jl:8
│  [38] (::getfield(IJulia, Symbol("##15#18")))() at .\task.jl:259
│ in expression starting at C:\Users\my-user-name\.julia\packages\Plots\47Tik\src\backends\pyplot.jl:24
└ @ Requires C:\Users\my-user-name\.julia\packages\Requires\9Jse8\src\require.jl:40

I have updated PyPlot.

If I forget about pyplot() and default to gr() (i.e., don’t specify the backend), then I avoid the error messages. However, gr() produces substandard plots for my use – (i) gr doesn’t have complete support for LaTeX, and (ii) it sometimes does something strange wrt. scaling: here is what I try to do…

using Plots
using LaTeXStrings
# function
f(x,u) = -exp(-1/u)*x^2 + 0.1*exp(-2/u)*x
x = range(0,5,length=25)
u=range(0.01,0.1,length=25)
f3d = plot(u,x,f,st=:surface,c=:blues,colorbar=:none)
plot!(f3d,xlabel=L"u", ylabel=L"c_A",zlabel=L"dc_A/dt")
#plot!(f3d,xlabel=L"u", ylabel=L"c_\mathrm{A}",zlabel=L"\frac{d c_\mathrm{A}}{dt}")
fc =plot(u,x,f,st=:contour,c=:blues)
plot!(fc,xlabel=L"u", ylabel=L"c_A")
#plot!(fc,xlabel=L"u", ylabel=L"c_\mathrm{A}")

plot(f3d,fc,layout=(2,1))

I’ve had to comment out things that give error messages with gr() – but that should work with pyplot(). Even without error messages, gr() (i) does not add labels to f3d, and (ii) messes up the scaling of f3d:

Any ideas on how to fix this? Have I done anything wrong?

The point is, that \mathrm is not defined in the LaTeX prologue using within GR. I’ll see how this can be fixed …

1 Like

Thanks, Josef. Although PyPlot is still more complete, I notice that GR produces a “crisper” / “cleaner” plot, which is nice.

Notice: in addition to “\mathrm”, I think there was also a problem with ,“\frac”.

Btw: any idea why the 3D surface plot doesn’t rescale when stacked with the contour plot?

You need to ]up PyPlot.

What is ]up PyPlot? Update? (I probably should know this, but I use using Pkg and Pkg.update("PyPlot")… reason: this can be put in a file together with other commands and run as script file…)

Note: I did update PyPlot before I submitted the question, with no effect.

I gave your code a try, but inserted pyplot() after using.... It works well on my win10 machine, Julia 1.10, latest Plots&PyPlot.

Weird.

Some 1-2 month ago, there was also a problem with Plots and PyPlot. I was then adviced to “lock” PyPlot (?) to an older, working version. Don’t recall the command… after that, I uninstalled and reinstalled PyPlot…

Could it be that that “lock” persists? If so, what is the command for removing such a “lock” to a specific version?

] free PyPlot perhaps?

Thanks! I just checked again 30 minutes ago, doing ] status, and found a suspicious symbol next to PyPlot and PyCall … something that looked like a key. So I dug around in the documentation, and found precisely the ] free command (actually, not in the manual, but in the REPL/package manager).

When freeing the too packages, and running update, it seems like PyCall gets updated from v. 1.18.5 to v. 1.91.2, while PyPlot gets updated from v. 2.7.0 to v. 2.8.1.

“Seems like” in the sense that it takes “forever” to do the update… it’s still running.

Yes! Thanks! It works…

Only one thing:

Why do I get this warning? Why are the “rainbow” colors defined two places? This error message does not show up if I use c = :blues or c= :grays

That’s something to watch out for in PlotUtils. Since a miscellaneous set of colours (misc) was added for testing and giggles, and the ‘default’ library with which to handle this hasn’t been defined by you, PlotUtils will show a warning. You can squelch this by including the statement uselibrary(:misc) or uselibrary(:colorcet) somewhere above it.

Thanks. But you do not say where to include the statement uselibrary(:misc). I tried to include it in my Julia code, after I have done using Plots, and then I get an error message:

UndefVarError: uselibrary not defined

Stacktrace:
 [1] top-level scope at In[3]:2

Shit, wrong function :slight_smile: it’s actually clibrary, sorry about that!

Yup! clibrary(:colorcet) works! Thanks!

…and now I get a strange warning for a contour plot…

fc =plot(x,u,f,st=:contour,c=:rainbow)
plot!(fc,ylabel=L"u", xlabel=L"c_\mathrm{A}")

leads to the plot:


and the warning:

C:\Users\user_name\.julia\conda\3\lib\site-packages\matplotlib\contour.py:1000: UserWarning: The following kwargs were not used by contour: 'label'
  s)

Am I supposed to use a label? What is the label? The z-value??

That might just be a matplotlib/pyplot thing - I don’t even know if Plots supports contour labels…

Have you tried using the GR backend?