问题
I have a program in Fortran that calculates a file, say, named wvfunc3d.dat which I want to visualize with Gnuplot in real time during the execution of my program. After the code that creates this file, I put in my program a string
jret=SYSTEM('gnuplot wf3d.plt')
the script file wf3d.plt has the only string and looks like:
splot 'wvfunc3d.dat' w l
All of this really draws a plot I want to see, but, as is well known, it immediately disappears. I know, there is an option to avoid the closing of the window,
jret=SYSTEM('gnuplot -persist wf3d.plt')
that lets my plot not to disappear, but then the execution of the Fortran program also freezes until I close the window with the graph.
So, I want the plot to persist until I have new data, to be automatically updated after a new call of a command in Fortran, but I also need my program to run calculations! Is there a way to solve this problem? I use Windows XP.
回答1:
I think you may be able to use EXECUTE_COMMAND_LINE
instead of system
to achieve what you want. This allows you to include a wait
option which when set to .false.
allows the fortran code to keep running. You can then add a sleep and reread to your gnuplot script (e.g. sleep 1
and reread
) as suggested in this post.
If this doesn't work, you could consider a multi-threaded strategy ( openMP or mpi in fortran). Personally, I usually just run gnuplot at the same time and trigger an update of the plotted data by pressing the a
key. I use linux so cannot test it for windows but a minimal example which works for me is,
program gnuplot
implicit none
logical :: gnuplot_open = .false.
integer :: i,t,N,redraw
real(kind(0.d0)),dimension(:),allocatable :: x,y
real(kind(0.d0)),parameter:: pi=4.d0*atan(1.d0)
N = 1000
allocate(x(N),y(N))
redraw = 100
do t = 1,300000
do i=1,N
x(i) = 6.d0*i/N*pi
y(i) = sin(x(i)+t*0.2)
enddo
if (mod(t,redraw) .eq. 0) then
open(1,FILE='./tempout',status='replace')
do i=1,N
write(1,*) x(i),y(i)
enddo
close(1,status='keep')
endif
if (.not. gnuplot_open) then
call execute_command_line('gnuplot --persist plot_tempout', wait=.false.)
gnuplot_open = .true.
endif
enddo
end program gnuplot
and plot_tempout
is,
plot 'tempout' u 1:2 w l
pause 0.1
reread
回答2:
Ed, thank you very much for your thorough reply. I will try to work on it.
Before encountering this problem I was able to easily draw the plots of small enough files using a cycle directly in gnuplot. Something like this:
do for [i=1:100500] {plot 'littldat.dat' w l; pause 3}
that did it well. But when I tried to do this with large file, it was very often caught read by gnuplot in the moment it was not completed yet: I had either a full plot or a plot of a part of my data, and it was not good. Because of this I began to seek for the way to do it by the means of programming language.
Before you answered I finally found a very simply, though not very elegant solution: you write data to a temporary file and then, once it is completed, give it the final name to be read by gnuplot. So, gnuplot reads either old data, or new ones, but never an incomplete file. It results to be something like this in Fortran:
open(1,file='donnees_temp.dat')
write(1,*)x,y,z
close(1)
call rename ('donnees_temp.dat','donnees.dat')
and, in Gnuplot I used a cycle like the one above:
do for [i=1:100500] {splot 'donnees.dat' w l; pause 5}
so it works, and the program executes.
来源:https://stackoverflow.com/questions/31386567/how-to-let-gnuplot-window-persist-and-the-main-program-not-freeze