Plotting with user input

Hi, I am very new to Julia and am looking for advice/information on plotting.
I am trying to visualise my model fits for multiple instances and would like to visualise the plot and then give user input, perhaps like a 0 or 1 so that after the visualisation I can easily select the fits that I deem acceptable. Is there a standard way to do this or is there perhaps another way this kind of operation is commonly done?

Hello and welcome to the community!

What does “give some user input” mean?

Hi thank you for responding!

As with user input I was hoping it was possible to pass a boolean is some kind of way so that I can divide the plots into two groups that I want to keep and one that I do not want

Do you have something like this in mind?

# manually inspect the result
acceptable_fits = [1, 2, 3, 5, 8]


Yes something like that, where if possible I would like to loop through plotting all the fits and give a boolean which is stored and then it presents me with the next plot. so something like

order = []
for i in 1:number_fits
    model = models[i]
    parameters = parameter_sets[i]

    fit = output(model, parameters)

    u = user_input()

I just have no idea if doing this with a user_input is at all possible.

are you looking to accept user input from the REPL in the loop there? You could do this with

help?> readline
search: readline readlines readlink

  readline(io::IO=stdin; keep::Bool=false)
  readline(filename::AbstractString; keep::Bool=false)

  Read a single line of text from the given I/O stream or file (defaults to stdin). When reading from a file, the text is assumed to be encoded in UTF-8. Lines
  in the input end with '\n' or "\r\n" or the end of an input stream. When keep is false (as it is by default), these trailing newline characters are removed
  from the line before it is returned. When keep is true, they are returned as part of the line.

together with parse(Int, user_input) or parse(Bool, user_input) where user_input is the string returned by readline

julia> user_input = readline()
true # I typed this

julia> parse(Bool, user_input)

Hi! This looks like an ideal use case for a Pluto notebook. Here is a notebook I made for a similar idea (source in this repo).

Take a look at the PlutoUI package: it facilitates using UI elements like dropdown menus, checkboxes, radio buttons, text fields, sliders, etc. (demo here). In your case, you could have a multicheckbox for your fits and collect the boolean values of all checkboxes to select what you want to plot.

1 Like

It can also be fun to do something like this with a small GLMakie GUI. Here’s a mockup where the “fit” is just a line from first to last point of random data, but you get the gist. Afterwards you have your acceptance results in the accepted Observable and can process that further.

using GLMakie

struct Fit

n = 100
fits = [Fit(cumsum(randn(n))) for _ in 1:n]
accepted = Observable(zeros(Bool, length(fits)))

f = Figure()
ax = Axis(f[1, 1])

i = Observable(1)

lines!(ax, @lift(fits[$i].y))

pseudofit_points = lift(i) do i
    f = fits[i]
    len = length(f.y)
    [Point2(1, f.y[1]), Point2(len, f.y[end])]

lines!(ax, pseudofit_points, color = @lift($accepted[$i] ? :lightgreen : :red), linestyle = :dash, linewidth = 3)

subgl = GridLayout(f[2, 1], tellwidth = false)

prevbutton = Button(subgl[1, 1], label = "Prev")
on(prevbutton.clicks) do _
    i[] = mod1(i[] - 1, n)

Label(subgl[1, 2], @lift("Fit $($i)"))

nextbutton = Button(subgl[1, 3], label = "Next")
on(nextbutton.clicks) do _
    i[] = mod1(i[] + 1, n)

togglebutton = Button(subgl[1, 4], label = @lift($accepted[$i] ? "Reject" : "Accept"))
on(togglebutton.clicks) do _
    accepted.val[i[]] =! accepted.val[i[]]


Thank you everyone for responding and giving ideas!

I ended up using the GLMakie method suggested by Jules as I was using Makie for other plotting aswell and it worked very nicely!

1 Like