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.
check if https://github.com/JuliaComputing/TableView.jl meets your needs
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
-
if it is just a few entries, you can just use
setindex!
(mat[2, 3] = 42
) from the REPL, -
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.
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
Related is the following discussion for displaying tabular data:
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>
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.
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