JuliaGizmos / Interact.jl

Interactive widgets to play with your Julia code
Other
525 stars 76 forks source link

Saving the state of a variable for use outside of widget doesn't seem to work #393

Closed antoinerincent closed 3 years ago

antoinerincent commented 3 years ago

Hi! If this is the wrong place to ask, I'll be happy to move my issue/question to where it's better suited if you could point me in the right direction! I'm very much new to Julia and using Interact to make a neat little interface in Jupyter (using Julia 1.5.3), but I'd like to be able to save the state of different variables (sliders and dicts), in another cell of the jupyter notebook, how can I go around saving the state of the selected variable? I tried creating the variable outside of the @manipulate macro, and saving the state this way, but it doesn't change the value of the outside variable, for example :

valstate = 0 @manipulate for state=1:1:10 valstate = state end print(valstate)

Will return 0, how can I make it return the single value between 1 and 10 that was the last state of the slider? Thanks a lot!

twavv commented 3 years ago

In this case you'll need to use the global keyword I believe (search for Julia soft global scope).

Generally, you should put the code that uses the variables inside of the manipulate block if possible. :)

antoinerincent commented 3 years ago

Thanks for your answer! Here's the code I'm using :

muval = 0
solveurval = 0
@manipulate for x1=2:1:31, x2=2:1:31, Solveur=Dict("Linéaire avec IpOpt"=>1, "Linéaire avec RipQP"=>2, "Linéaire avec Tulip"=>3, "Linéaire avec Knitro"=>4, "Quadratique avec IpOpt"=>5, "Quadratique avec RipQP"=>6, "Quadratique avec Knitro"=>7), μ=0:0.001:1
    # Résoudre système
    if Solveur==1
        w, γ = LinIpOpt(mtrain, ktrain, 0)
    elseif Solveur==2
        w, γ = LinRipQP(mtrain, ktrain, 0)
    elseif Solveur==3
        w, γ = LinTulip(mtrain, ktrain, 0)
    elseif Solveur==4
        w, γ = LinKnitro(mtrain, ktrain, 0)
    elseif Solveur==5
        w, γ = QuadIpOpt(μ, mtrain, ktrain, 0)
    elseif Solveur==6
        w, γ = QuadRipQP(μ, mtrain, ktrain, 0)
    elseif Solveur==7
        w, γ = QuadKnitro(μ, mtrain, ktrain, 0)
    end

    muval = μ
    solveurval = Solveur

    # Print résultat
    titrestats, PerrorMalignant, PerrorBenign = accuracygraph(mtest, ktest, Mtest, Btest, w, γ, n, ntrain, ntest)
    s = ["Malignant classified as benign", "Benign classified as malignant"]
    barx = [PerrorMalignant, PerrorBenign]
    bar(barx, xticks=(1:2, s), legend=false)
    ylabel!("%")
    title!(titrestats)

    # Graphique avec interactivité
    titre = string("Caractéristiques ", string(x1), " et ", string(x2))

    plot(Mtest[:,x1], Mtest[:,x2], seriestype = :scatter, color= :red, label="Malignant Cancer", title=titre)
    plot!(Btest[:,x1], Btest[:,x2], seriestype = :scatter, color= :blue, label="Benign Cancer")

    xlabel!(labels[x1-1])
    ylabel!(labels[x2-1])

end

I want to use the values of mu and the choice of solver in the next block :

if Solveur==1
    w, γ = LinIpOpt(mtrain, ktrain, 1)
elseif Solveur==2
    w, γ = LinRipQP(mtrain, ktrain, 1)
elseif Solveur==3
    w, γ = LinTulip(mtrain, ktrain, 1)
elseif Solveur==4
    w, γ = LinKnitro(mtrain, ktrain, 1)
elseif Solveur==5
    w, γ = QuadIpOpt(μ, mtrain, ktrain, 1)
elseif Solveur==6
    w, γ = QuadRipQP(μ, mtrain, ktrain, 1)
elseif Solveur==7
    w, γ = QuadKnitro(μ, mtrain, ktrain, 1)
end

titrestats, PerrorMalignant, PerrorBenign = accuracygraph(mtest, ktest, Mtest, Btest, w, γ, n, ntrain, ntest)
s = ["Malignant classified as benign", "Benign classified as malignant"]
barx = [PerrorMalignant, PerrorBenign]
bar(barx, xticks=(1:2, s), legend=false)
ylabel!("%")
title!(titrestats)

I looked up (and tried) to use soft global scopes, but I'm not sure how it applies to Jupyter, since from my understanding all the blocks of the given jupyter notebook behave as a single module, no?

Thanks again, it's very much appreciated! :)

antoinerincent commented 3 years ago

Finally found the fix, which is quite dumb, but in case someone else stumbles upon this one day, simply using global outside and inside the @manipulate did the trick! For example :

global muval = 0
@manipulate ...
    global muval = \mu

print(muval)

Will return the last value of \mu, even if it's in another cell of the Jupyter notebook!