我在Fortran中有一个程序来计算一个文件,比如名字 wvfunc3d.dat 我希望在程序执行期间实时显示Gnuplot。在创建此文件的代码之后,我在程序中添加了一个字符串
jret=SYSTEM('gnuplot wf3d.plt')
脚本文件wf3d.plt具有唯一的字符串,如下所示:
splot 'wvfunc3d.dat' w l
所有这些都是我想要看到的情节,但众所周知,它会立即消失。我知道,有一个选项可以避免关闭窗口,
jret=SYSTEM('gnuplot -persist wf3d.plt')
让我的情节不会消失,但Fortran程序的执行也会冻结,直到我用图形关闭窗口。
所以,我希望情节持续到我有新数据,在Fortran中新命令调用后自动更新,但我还需要我的程序来运行计算!有没有办法解决这个问题?我使用的是Windows XP。
答案 0 :(得分:1)
我认为您可以使用EXECUTE_COMMAND_LINE
代替system
来实现您想要的效果。这允许您添加wait
选项,当set到.false.
允许fortran代码继续运行时。然后,您可以按照post中的建议添加睡眠并重新读取您的gnuplot脚本(例如sleep 1
和reread
)。
如果这不起作用,您可以考虑多线程策略(fortran中的openMP或mpi)。就个人而言,我通常只是同时运行gnuplot并通过按a
键触发更新绘制的数据。我使用linux所以不能测试它的窗口,但一个适合我的最小例子是,
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
和plot_tempout
是,
plot 'tempout' u 1:2 w l
pause 0.1
reread
答案 1 :(得分:0)
在遇到这个问题之前,我能够直接在gnuplot中使用循环轻松绘制足够小的文件图。像这样:
do for [i=1:100500] {plot 'littldat.dat' w l; pause 3}
做得很好。但是当我尝试用大文件做这个时,gnuplot在它尚未完成的那一刻就经常被读取:我有一个完整的情节或我的数据的一部分情节,并且它不好。因此,我开始寻求通过编程语言来实现它的方法。
在您回答之前,我终于找到了一个非常简单但不是很优雅的解决方案:您将数据写入临时文件,然后,一旦完成,将其命名为gnuplot读取的最终名称。因此,gnuplot读取旧数据或新数据,但从不读取不完整的文件。在Fortran中会出现类似的结果:
open(1,file='donnees_temp.dat')
write(1,*)x,y,z
close(1)
call rename ('donnees_temp.dat','donnees.dat')
并且,在Gnuplot中我使用了一个类似上面的循环:
do for [i=1:100500] {splot 'donnees.dat' w l; pause 5}
所以它可以正常运行。