Hey guys, so I have this case; I am running a simulation program which at every time steps outputs a data file, which I then strip for data - I would like to do this and showcase it with a live plot but I am struggling a bit to find a way to update x and y values, so do anyone happen to have some very basic examples of how to proceed with this? Currently I have:
Function to check if new files are added at every 5 seconds
If new files are added then read this data in and put it into x and y array
Then plot
Of course I could just rerun these 3 steps again, but the problem with that is that I would have to reread all the data, instead of just reading the new data added in the folder, so I would rather have it like:
Function to check if new files are added at every 5 seconds
2a. If new files are added then read this data in and put it into x and y array
2b. If new files are added after first creation, then update these arrays by appending new data
Since you have a possible strategy laid out, did you just try to implement it? It should be pretty straightforward to keep a list of files that have already been processed and update the data arrays and the plot only when new data shows up.
If you have concrete questions in the process, we’ll be here to help!
So this picture shows the new files which are read each 5 seconds. The problem is that it is not reading “Part_0000.bi4”, “Part_0001.bi4” etc., so I am having some trouble in my first iteration of how to tell my program, that in the first iteration, do not use my function, just read the files which are available right now.
I assume you know when the first iteration is taking place? If so, you can just code that case manually
How do you check if a file has been read? My first idea would be a list (or a set) of paths which you have loaded already. If the a path is already in there, don’t load it. If you run your program for the first time, that list should be empty and all files should be loaded.
function test()
i = 1
while true
if i == 1
difFiles = _dirFiles()
println(difFiles)
i = 0
else
curFiles = _dirFiles()
sleep(2.5)
newFiles = _dirFiles()
difFiles = setdiff(newFiles,curFiles)
println(difFiles)
end
end
end
Where sleep is a parameter currently set by the user and “_dirFiles” is my implementation of readdir in my case. So now I get an array only having the new names of data to be read.
I think you should be able to simplify it like this, which also avoids calling _dirFiles() back to back:
function test()
already_loaded = String[] # the files you have loaded, none in the beginning
while true
all_files = _dirFiles()
new_files = setdiff(all_files, already_loaded)
println(new_files)
already_loaded = all_files
sleep(2.5)
end
end
This assumes _dirFiles() returns an array of Strings, otherwise you have to change the arrays type.
If you want to update your plot, use plot!(...) instead of plot(...). However, I think that the whole image is re-rendered anyways. If you use something like GR for plotting, that should be pretty quick though.
It is constantly adding new legend entries, which I do not want, and it is not continuing the previous lines, ie. I expected a straight line but it is constantly starting from one again. Any suggestions?
The code:
function test()
i = 1
while true
if i == 1
difFiles = _dirFiles()
i = 0
else
curFiles = _dirFiles()
sleep(2.5)
newFiles = _dirFiles()
difFiles = setdiff(newFiles,curFiles)
end
data = readBi4Body(MovingSquare,Points,difFiles)
y = getindex.(mean.(data),1)[:]
pp = plot!(y)
display(pp)
end
end
And you currently only provide y values, but I assume you have some x values as well? Maybe just time, on that axis? This is what you would need to modify. This shows what you are currently doing:
plot()
for i in 1:10
plot!(i:i+5, label = "")
end
But you’d need to provide information about the x values as well:
plot()
for i in 1:10
plot!(i:i+5, i:i+5, label = "")
end
This should give you something like you are looking for.
(If you are using Juno, add a plot!() at the end to show the plot.)
You can’t not have x-axis values. If you don’t provide them, Plots invents them for you (otherwise, all y points would land on the same x point, and a vertical line is not what you want either). If you try
a = [1, 2, 4]
plot(a)
this gets expanded to
plot(1:length(a), a)
If you really don’t want to provide x-axis values, you can mix old and new data together and then plot that.
Thanks for the suggestion, my case is a bit more intricate right now, so that solution is not working properly. Will try again in the future, when Julia plotting becomes a bit faster to start up as well.