GUI to edit matrix in Julia?

I would like to ask a similar question to Stack Overflow’s GUI to Create Table in Julia. Is there any Pkg in Julia that has a GUI like uitable in Matlab or similar that allows editing interactively a matrix/table? And once done with the edits, continue the normal flow of the program.

1 Like

check if https://github.com/JuliaComputing/TableView.jl meets your needs

1 Like

Thanks for the pointer but after some investigation it seems that it is still work in progress to edit cells in place? See post: Edit a cell in TableView.
So with a code example, the question is how to edit matrix in-place in a GUI:

using DataFrames, TableView
mat = [1 4.0 7; 2 5.0 8; 3 6.0 9]
matdf = DataFrame(mat)
showtable(matdf)
# Is there anything like **edittable**?

I know this does not answer your quetion, but

  1. if it is just a few entries, you can just use setindex! (mat[2, 3] = 42) from the REPL,

  2. if you need to edit a lot of data, presumably you have it in some external format so you can edit that using the appropriate external tool.

2 Likes

I am not aware that such a package exists, but agree that it would be very helpful.
Ideally, it would be a html / js frontend coupled to a Julia Tables.jl compatible data structure, like a DataFrame. This way, it could be used in Pluto or Julia web applications (e.g. with Genie).

For the frontend, there are already solutions available like

(this may not be the best choice because the repo is not active anymore).

It would be a nice project to wrap something like it into a Julia library, but unfortunately I do not have any JS knowledge :frowning:

Related is the following discussion for displaying tabular data:

1 Like

Not that I intend to say that this is an actual solution, but depending on the use case it is a pretty practical workaround (I have used it sometimes):

julia>using DelimitedFiles
      function ed!(M)
         tmp_file_name = tempname()
         writedlm(tmp_file_name,M)
         InteractiveUtils.edit(tmp_file_name)
         readM = readdlm(tmp_file_name)
         @. M = readM
         rm(tmp_file_name)
       end
ed! (generic function with 1 method)

julia> M = zeros(4,4)
4×4 Array{Float64,2}:
 0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0

# This will open vim and you can edit the data 
# Here I changed the first element to 1.0
julia> ed!(M)  

julia> M
4×4 Array{Float64,2}:
 1.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0

julia>
4 Likes

You can definitely use TableView for this, it just needs a bit of plumbing:

using Blink, TableView
w = Blink.Window();
x = rand(10,10)
function update_cell(arr, msg)
    row = msg["row"] + 1 # zero-indexed in JS
    col = parse(Int, match(r"Column(\d+)", msg["col"])[1])
    arr[row, col] = parse(eltype(arr), msg["new"])
end
body!(w, TableView.showtable(x, cell_changed = msg -> update_cell(x, msg)))

This will obviously only work for concretely-typed arrays of numbers, but you can of course adjust it to whatever you want.

Feel free open an issue or PR at https://github.com/JuliaComputing/TableView.jl if you have ideas on how to make the whole experience smoother.

Edit: Fixed the row indexing.

7 Likes

Wow! This is great, thank you @pfitzseb for the magic.
For some reason, I had to increase row by 1 in the function to avoid 0 indexes. Tested your solution beautifully in loop below.
PS: a minor recommendation would be to add an OK button to close the GUI window when done with editing.

using Blink, TableView

function update_cell(arr, msg)
    row = msg["row"] + 1
    col = parse(Int, match(r"Column(\d+)", msg["col"])[1])
    arr[row, col] = parse(eltype(arr), msg["new"])
end

x = rand(10,10)

# mock-up loop of Julia program not terminating to the REPL until user decides so
leave = false
while !leave
    w = Blink.Window();
    body!(w, TableView.showtable(x, cell_changed = msg -> update_cell(x, msg)))
    println("Enter to continue or Y to leave: ")
    str = readline()
    if str == "y" || str == "Y"
       leave = true
    end
end
2 Likes