Show PyPlot

Hello everyone! Please, I need help with a simple task:
x = plot(…); …; close()
How to show the graph again using x?
I use Julia 1.8.3 e PyPlot

display(x) should show the plot again.

This text appears in the terminal:
1-element Vector{PyCall.PyObject}:
PyObject <matplotlib.lines.Line2D object at 0x7f6dbc6dadd0>
But it does not show the graph window.

Note: I had to install PyCall with the ENV[“PYTHON”]=“” option

If you are calling your plotting code directly in Python, I think you could do something like:

using PyCall

plt=pyimport("matplotlib.pyplot")
plt.show(x)

Which should work as your plot looks like it’s a PyObject.

p.s. I would recommend looking into using Plots.jl instead, as you can use the PyPlot backend easily:

using Plots
pyplot()

plt = plot(...)
display(plt)

And you can also switch to other backends if you need, usually without changing any of your code.

using PyPlot # At the REPL
x = plot(rand(10), rand(10))

My question is more to understand than to do. I found that show(x) or display(x) could redisplay a graph from the variable x. I think I already did it using PyPlot, but I don’t remember exactly. I used Plots when I started in Julia, today I prefer not to use it anymore. Thank you so much.

With PyPlot, you need to call display on the figure object, which is not what is returned by plot in Matplotlib. You can get the current figure with gcf(), for example.

2 Likes

I will answer a little later.

I updated to Fedora 37 and it looks like PyCall can’t use python 3.11 so I did the ENV[“PYTHON”] = “” procedure, suggested by ufechner7 (PyPlot stopped working when upgrading to Fedora 37 - #2 by ufechner7) and it worked. Then I noticed that show() didn’t redisplay graphs. I don’t know if it’s related!

# at the bash terminal
using PyPlot

# try 1
plot( collect(1:100), rand(100) .^ 50 )
# close the figure manually
# I type show(): blank line

# try 2
x = plot( collect(1:100), rand(100) .^ 50 )
# close the figure manually
# I type show(), ans: blank line
# I type show(x), ans: PyCall.PyObject[PyObject <matplotlib.lines.Line2D object at 0x7f9f4eed92d0>]
# I type display(x), ans: 1-element Vector{PyObject}: \n PyObject <matplotlib.lines.Line2D object at 0x7f9f4eed92d0>

# try 3
x = figure()
plot( collect(1:100), rand(100) .^ 50 )
# close the figure manually
# I type display(x), show(x), show(), ans: almost the same, but no figure

# a curious fact (for me)
using Serialization

x = plot( collect(1:100), rand(100) .^ 50 )
data = (text="tests", img=x)
serialize("data.bin", data)
# close the figure manually
data = deserialize("data.bin")
# The figure is redisplayed, without any other command!

I know you can use Python 3.11 at least with PythonCall.jl (it downloads it for you by default, you can also point to it). I would use it for most everything now, unless some package uses PyCall (you can use both).

PythonPlot.jl uses PythonCall.jl, and it’s a fork of PyCall.jl, and apparently the future too. I tried plotting, with it it worked for me.