How to let gnuplot window persist and the main program not freeze

穿精又带淫゛_ 提交于 2019-12-11 12:34:51

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!