Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to clean Plots (GR) without closing Julia environment

Tags:

julia

plots.jl

I'm debugging a script (which use Plots.jl with GKS QtTerm backend). So I run the script many times. When I run it from terminal like bash> julia pointPlacement.jl it takes for ages to initialize Julia and Plots.jl (this is one big inconvenience in comparison to python). Therefore I rather keep Julia open and run the script from within, like julia> include( "pointPlacement.jl" )

grid = [ [ix*0.01 iy*0.01] for ix=1:100, iy=1:100 ]
grid = vcat(ps...)

centers = hexGrid( 2, 0.2 )

using Plots
display(scatter!( grid[:,1], grid[:,2], markersize = 1, markerstrokewidth = 0, aspect_ratio=:equal ))
display(scatter!( centers[:,1], centers[:,2], markersize = 2, markerstrokewidth = 0, aspect_ratio=:equal ))

The problem is that the plots accumulate. This is after 9 runs. There should be just 2 datasets, not 18:

enter image description here

I want to close (kill,destroy) them

If I remove ! like this, it helps

display(scatter( grid[:,1], grid[:,2], markersize = 1, markerstrokewidth = 0, aspect_ratio=:equal ))
display(scatter!( centers[:,1], centers[:,2], markersize = 2, markerstrokewidth = 0, aspect_ratio=:equal ))

but still, I worry that some junk (previous figures) stay allocated in memory and Julia will crash after I run the script 100x. Therefore I would like to call some function like clear(),flush(),closeAll() ... or something ... everytime I run the script

like image 218
Prokop Hapala Avatar asked Oct 16 '19 14:10

Prokop Hapala


2 Answers

Removing the ! has the effect that you want - the plot is gone if you call scatter again and it doesn't live somewhere in the background.

If you want you can store the plot in a variable and overwrite it "to be safe", i.e.

p = scatter(...)
scatter!(p, ...)

, where ... are your plotting arguments. This will explicitly overwrite p on every include.

like image 58
carstenbauer Avatar answered Sep 18 '22 13:09

carstenbauer


This is a long comment on crstnbr's excellent answer. If you want to make a new plot, but it shares similarities with the previous one, you can define a "canvas" (for want of a better word) in a function, which I have named new_plot(), and reuse the canvas. This is particularly useful if you have long labels and titles that you do not want to keep copying from plot to plot:

using Plots

function new_plot()
    plot(xlabel = "x", ylabel = "f(x)",
        xlims = (0,Inf), ylims = (-Inf, 1))
end 

p = new_plot()
plot!(p, x -> x^2, 0, 1)
plot!(p, x -> x^3, 0, 1)

enter image description here

p = new_plot()
plot!(p, x -> 2^x, 0, 1)
plot!(p, x -> 3^x, 0, 1)

enter image description here

Edit: Not directly related to the OP anymore, but note that, as pointed out by Benoît Pasquier in a comment, you can set default options with:

default(xlabel = "x", ylabel = "f(x)", 
        xlims = (0,:auto), ylims = (:auto, 1))

but you'll still need to create a new plot to "overwrite" the previous one, as explained by crstnbr. Consider this:

using Plots
p = plot()
for i in 1:5
    plot!(p, x -> x^i, 0, 1)
end

Nothing happened? Now try this:

p  # after a loop, you must call the plot object to display it
like image 32
PatrickT Avatar answered Sep 18 '22 13:09

PatrickT