Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

gnuplot from fortran

2,172 views
Skip to first unread message

Arjan

unread,
Mar 11, 2015, 4:01:44 PM3/11/15
to
Hi!

In my program I iteratively fit a set of model-parameters by comparing model and measured values (Windows-7, MinGW/MSYS, gfortran). Every iteration, a gnuplot file is written that can show observations and numerical model estimates. A system call from FORTRAN to gnuplot then reads the gnuplot file and shows the plot comparing measurements and the current parameterization of the model in a window. In this way I hoped to see the model fit better and better the observations (or not, which is then a sign that my algorithm is not okay).

It works, but you have to look very fast, since each plot is shown during only a fraction of a second... Does anyone know how to modify the gnuplot file such that the plot remains visible until the next iteration of the model? The gnuplot help-function for "set terminal windows" suggests "unless you specify - as the last command line option", and something is written about an option -persist, but I have no clue where to put either of these. Just at the end of the file does not work. Nor does putting it at the end of the plot-command or at the end of the set-terminal command.

In fact this whole question is off-topic, since the problem also shows when I run gnuplot straight from the command-line in MinGW/MSYS with the gnuplot-file as its single parameter. Nevertheless, I hope that you are willing to help me out. If this works, then gnuplot can provide a very easily programmed form of graphical feedback while a FORTRAN-program runs.

Regards,


Arjan

GianLuigi Piacentini

unread,
Mar 11, 2015, 4:09:55 PM3/11/15
to
Have a look at http://gnuplotfortran.sourceforge.net/, may be you find the
solution. Anyway, I found that library useful, although I'm using a Linux
box.

Gigi

Beliavsky

unread,
Mar 11, 2015, 4:11:03 PM3/11/15
to
On Wednesday, March 11, 2015 at 4:01:44 PM UTC-4, Arjan wrote:

> In fact this whole question is off-topic, since the problem also shows when I run gnuplot straight from the command-line in MinGW/MSYS with the gnuplot-file as its single parameter. Nevertheless, I hope that you are willing to help me out. If this works, then gnuplot can provide a very easily programmed form of graphical feedback while a FORTRAN-program runs.
>

Adding a "pause -1" at the end of a gnuplot script causes the plot to persist. I also call gnuplot from Fortran programs.

Arjan

unread,
Mar 11, 2015, 5:42:54 PM3/11/15
to
gnuplotfortran seems not to have been developed for Windows. Pause -1 does allow to take a longer peek at the plot, but I would prefer the program to continue and see the plot get automagically updated as the solution converges, as a sort of poor-man's animation.

mencaraglia

unread,
Mar 12, 2015, 6:12:29 AM3/12/15
to

entropy

unread,
Mar 12, 2015, 6:27:12 AM3/12/15
to
On Wednesday, March 11, 2015 at 9:42:54 PM UTC, Arjan wrote:
> gnuplotfortran seems not to have been developed for Windows. Pause -1 does allow to take a longer peek at the plot, but I would prefer the program to continue and see the plot get automagically updated as the solution converges, as a sort of poor-man's animation.

Off the top of my head. Why don't you use the "pause -1" statement in your gnuplot script and then, when the data for the next picture are ready to be displayed, you execute a system call to stop gnuplot and finally re-run it with the new data?

Arjan

unread,
Mar 12, 2015, 1:05:13 PM3/12/15
to
Thanks for the suggestions so far. Problem does not seem to be solved yet. The code for "gnufor", suggested by Mencaraglia Francesco, gave me the correct hint of where to place the -persist option: in the call to the gnuplot executable. The result is similar to putting pause -1 in the gnuplot command-file: the plot is not closed anymore. This gives me time to contemplate the thing, but the computational FORTRAN-model now does the same: contemplate the beautiful plot and not proceed calculating the next step. I have to either close the plot (if -persist was used) or press a button in the pause pop-up to let my FORTRAN-program proceed with the calculation. A suggestion that was forwarded to me via the mail is

http://techthat.net/2014/01/29/incremental-plotting-in-gnuplot/

here the suggestion is made to run gnuplot not from FORTRAN, but from a script that runs in a loop:

script="plot 'data-file.dat'"

mkfifo $$.gnuplot-pipe
gnuplot -p <$$.gnuplot-pipe & pid=$! exec 3>$$.gnuplot-pipe
echo "$script" >&3

running=1
trap 'running=0' SIGINT
while [[ $running -eq 1 && $(lsof "$1" | wc -l) -gt 0 ]]; do
echo "replot" >&3
sleep .5s
done

exec 3>&-
rm $$.gnuplot-pipe
wait $pid

I am not sure if this is going to work on my Windows/MinGW/MSYS box, but I'll plod on and try it out. Alternatives are still welcome! ;-)


Arjan

Geico Caveman

unread,
Mar 12, 2015, 2:40:35 PM3/12/15
to
Amazing that it is still in use. I wrote it almost 11 years ago.

Never for windows though.

Walt Brainerd

unread,
Mar 12, 2015, 4:31:21 PM3/12/15
to
I have a little program that displays the "heat"
spreading over a plate. It displays a plot every few
iterations.

I put this in the plot file:

write(unit=11, fmt="(a)") &
"set terminal wxt", &
"set pm3d", &
"set palette", &
"set ticslevel 0", &
"set view 0,0"
write(unit=11, fmt="(a, i0)") &
"pause_seconds=", pause_time

Then generate some data to be plotted at each iteration.
Then put this in the gnuplot file for each iteration:

write (unit=11, fmt="(a)") &
"splot """ // trim(filename) // """ matrix pt 0", &
"pause pause_seconds"

Then at the end, execute wgnuplot as follows:

call execute_command_line &
("C:\FortranTools\gnuplot\binary\wgnuplot" &
// " -persist ""heat.gp""")

Is this what you want to do? I will put the whole program at
www.fortran.com/heat.f90

but wait a bit, as I can't get my ftp working right now.


Arjan

unread,
Mar 13, 2015, 4:47:08 AM3/13/15
to
Walt, thanks! Your example works and looks like the solution to my problem! It is all in the subtle details. Somehow the gnuplot manual does not seem to yield this type of crucial info to its users. I had a big smile when I saw your heat equation gradually converge to its solution. This sort of swift, elegant visual feedback, that does not come at the price of huge programming overhead, is what I miss in the usual black-box type of modelling work, where you press enter on the command line and all you can do is wait until the prompt returns. Thanks again!

entropy

unread,
Mar 13, 2015, 7:52:36 AM3/13/15
to
To run your code in parallel while gnuplot is displaying your plot (using "pause -1") you need to append the command line call with a final ampersand "&" (not 100% sure if it works also with MSYS). Then, when you have the data of the new iteration available, you need to kill (or, better, close gracefully) gnuplot and restart it again.

Walt's solution is interesting but it seems to me that it does not respond exactly to your request concerning the concurrent execution of your program and the display of results.

Arjan

unread,
Mar 13, 2015, 11:57:44 AM3/13/15
to
> Walt's solution is interesting but it seems to me that it does not respond exactly to your request concerning the concurrent execution of your program and the display of results.



Walts solution gives me an animation that runs smoothly on the screen without any gap, so somehow the solver of the differential equation manages to iterate while the plot is shown simultaneously by Gnuplot.

entropy

unread,
Mar 13, 2015, 12:32:01 PM3/13/15
to
On Friday, March 13, 2015 at 3:57:44 PM UTC, Arjan wrote:
> > Walt's solution is interesting but it seems to me that it does not respond exactly to your request concerning the concurrent execution of your program and the display of results.
>
>
>
> Walts solution gives me an animation that runs smoothly on the screen without any gap, so somehow the solver of the differential equation manages to iterate while the plot is shown simultaneously by Gnuplot.

No. Walt's program solves the differential equation first, stores all data in output files and *at the end of the solving sequence* (i.e. at convergence) calls automatically gnuplot to show the plots with 1 second of pause between them (1 second could be changed to any value changing the variable pause_time). There is no concurrence of solving and plotting, it's purely done in series.

Arjan

unread,
Mar 13, 2015, 1:27:53 PM3/13/15
to
> No. Walt's program solves the differential equation first, [...] There is no concurrence of solving and plotting, it's purely done in series.



Hm. You are right. I misread the code. Thanks for pointing this out. Going to check the other suggestions!

Arjan

unread,
Mar 13, 2015, 2:40:51 PM3/13/15
to
What does seem to more or less work is:
- generate a .png-file via gnuplot, called from within the FORTRAN program
- update this file every N iterations of the numerical solver
- while the program runs, open the .png-file(s) separately under Windows.

Now Windows does the multitasking and shows updated plots while the solver runs. Sometimes, the plot flashes a bit. Not a perfect solution, but workable.

James Van Buskirk

unread,
Mar 13, 2015, 5:10:08 PM3/13/15
to
"Arjan" wrote in message
news:06fa7113-2a51-4d55...@googlegroups.com...
The natural way to do animation in Windows is to write a full Windows
program
with message loop. A couple of examples:
http://home.comcast.net/~kmbtib/Fortran_stuff/example2.zip
http://home.comcast.net/~kmbtib/Fortran_stuff/example3.zip

ali.gods...@gmail.com

unread,
Sep 13, 2019, 4:46:57 PM9/13/19
to
Hi Arjan,
Please, can you send an example of what you said in this comment?
Thanks in advance

Jeff Ryman

unread,
Sep 13, 2019, 9:10:48 PM9/13/19
to
I couldn't find either example. When clicked on, the first link resolves to https://my.xfinity.com/~kmbtib/Fortran_stuff/example2.zip and gives the error message:

"Sorry, we couldn't find that page.
The page you are looking for may have been moved, updated or deleted."

urba...@comcast.net

unread,
Sep 16, 2019, 11:59:34 PM9/16/19
to
Not sure if your programming environment supports popen(3c) and other POSIX C routines, but a really flexible way to call gnuplot is via popen(3). I put a quick hack together temporarily at http://www.urbanjost.altervista.org/hack.f90 for you to see if it works in your PE. It draws a sin wave animation with fixed ends to keep the scale constant just to do something. If that works there is a commented module on the Fortran Wiki for reading and writing from processes that I hacked this from, and there are functions you can call that will read mouse events so you can interrupt the animation and pause and enter gnuplot commands or otherwise interact with your program that can make this a flexible interface. I did some fancier similar interfaces in the past I can dredge up if this works and you are interested, but if this basic approach does not work in your PE that is pointless.
I use a graphics library for similar reasons myself so it has been a while since I went this route.

urba...@comcast.net

unread,
Sep 17, 2019, 10:32:18 PM9/17/19
to


module M_process
use, intrinsic :: iso_c_binding
implicit none
private
public :: process_open_write ! (cmd,fp,ierr) ! open process to write to
public :: process_close ! (fp,ierr) ! close process
public :: process_writeline ! (string,fp,ierr) ! write line to process
private :: process_open ! (fp,ierr) ! open process
type, public :: streampointer
type (c_ptr) :: handle = c_null_ptr
end type streampointer
interface process_writeline
module procedure process_writeline_scalar, process_writeline_array
end interface
!-----------------------------------------------------------------------------------------------------------------------------------
interface
function system_popen(path, mode) bind(C, name='popen')
use, intrinsic :: iso_c_binding
character(kind=c_char), dimension(*) :: path, mode
type (c_ptr) :: system_popen
end function
function system_pclose(handle) bind(C, name='pclose')
use, intrinsic :: iso_c_binding
integer(c_int) :: system_pclose
type (c_ptr), value :: handle
end function
function system_fputs(buf, handle) bind(C, name='fputs')
use, intrinsic :: iso_c_binding
integer(c_int) :: system_fputs
character(kind=c_char), dimension(*) :: buf
type (c_ptr), value :: handle
end function
function fflush(handle) bind(C, name='fflush')
use, intrinsic :: ISO_C_BINDING
integer(c_int) :: fflush
type (c_ptr), value :: handle
end function
end interface
!-----------------------------------------------------------------------------------------------------------------------------------
contains
!-----------------------------------------------------------------------------------------------------------------------------------
subroutine process_open_write(cmd,fp,ierr)
character(len=*),intent(in) :: cmd ! shell command to start process with
type(streampointer),intent(out) :: fp ! file pointer returned for process
integer,intent(out) :: ierr ! status for attempt to open process (0= no error)
ierr=0
call process_open(cmd,fp,ierr)
end subroutine process_open_write
!-----------------------------------------------------------------------------------------------------------------------------------
subroutine process_open(cmd,fp,ierr)
character(len=*),intent(in) :: cmd ! shell command to start process with
type(streampointer),intent(out) :: fp ! file pointer returned for process
integer,intent(out) :: ierr ! status for attempt to open process (0= no error)
ierr=0
fp%handle = system_popen(trim(cmd) // C_NULL_CHAR, 'w'// C_NULL_CHAR)
if (.not.c_associated(fp%handle)) then
write(*,*) '*process_open_write* ERROR: Could not open pipe!'
ierr=-1
endif
end subroutine process_open
!-----------------------------------------------------------------------------------------------------------------------------------
subroutine process_close(fp,ierr)
type(streampointer) :: fp ! file pointer returned for process
integer(c_int) :: ios
integer :: ierr
ierr=fflush(fp%handle)
ios=0
if (.not.c_associated(fp%handle)) then
write(*,*)'*process_close* process not found'
else
ios=system_pclose(fp%handle)
endif
ierr=min(-1_c_int,ios)
end subroutine process_close
!-----------------------------------------------------------------------------------------------------------------------------------
subroutine process_writeline_scalar(writefrom,fp,ierr)
character(len=*),intent(in) :: writefrom
type(streampointer),intent(in) :: fp
integer,intent(out) :: ierr
integer :: ios
ierr=system_fputs(trim(writefrom)//C_NEW_LINE//C_NULL_CHAR,fp%handle)
if(ierr.ne.0)then
ios = system_pclose(fp%handle)
ierr=min(-1,ios)
endif
if(ierr.eq.0)then
ierr=fflush(fp%handle)
endif
end subroutine process_writeline_scalar
!-----------------------------------------------------------------------------------------------------------------------------------
subroutine process_writeline_array(writefrom,fp,ierr)
character(len=*),intent(in) :: writefrom(:)
type(streampointer),intent(in) :: fp
integer,intent(out) :: ierr
integer :: i
ierr=0
do i=1,size(writefrom,dim=1)
call process_writeline_scalar(writefrom(i),fp,ierr)
if(ierr.ne.0)exit
enddo
end subroutine process_writeline_array
!-----------------------------------------------------------------------------------------------------------------------------------
end module M_process
!-==================================================================================================================================
program gnuplotExample
use M_process ,only: process_open_write, process_writeline
use M_process ,only: streampointer, process_close
implicit none
character(len=4096) :: line !*! line of data to write (assumed long enough to hold any command line)
type(streampointer) :: fp !*! C file pointer returned by process_open()
integer :: ierr !*! check status of calls to process module routines
integer :: i !*! DO loop counter
integer,parameter :: n=300 !*! number of points to put into curve to be plotted
real :: x(n),y(n) !*! arrays to fill with curve data to be plotted
integer :: ios
integer :: j
call process_open_write('gnuplot',fp,ierr) !*! open process to write to (ie. start gnuplot(1) program)
!*! Define sample X,Y array.
do j=1,300,3
do i=1,n !*! set X() values as whole numbers 1 to N
x(i)=i
y(i)=sin(x(i)/25.0+j/40.0)
enddo
call plotit() !*! plot the data
write(*,*)' RETURNED TO MAIN PROGRAM',j
enddo
write(*,'(a)')'enter gnuplot commands or "." to exit' !*! Additional gnuplot commands; in this case interactively entered
do
write(*,'(a)',advance='no')'gnu>>'
read(*,'(a)',iostat=ios)line
if(line.eq.'.')exit
call process_writeline(trim(line),fp,ierr)
enddo
call process_close(fp,ierr)
write(*,*)'CLOSED THE PROCESS. RETURNING TO PROGRAM'
contains
subroutine plotit()
!===================================================================================================================================
call process_writeline('$SET1 <<EOD',fp,ierr) !*! create in-line dataset $SET1
do i=1,n
write(line,'(2(f10.3,1x))')x(i),y(i) !*! Write the X,Y array as coordinates to be plotted.
call process_writeline(line,fp,ierr)
enddo
call process_writeline([character(len=128) :: & !*! plot the data using gnuplot(1)
&'EOD ', &
&'set title " Example of GNUPlot data and command file generation"', &
&'set nokey' , &
&'plot $SET1 with lines' , &
&''],fp,ierr)
end subroutine plotit
!===================================================================================================================================
end program gnuplotExample
!-==================================================================================================================================
Message has been deleted

L Godioleskky

unread,
Sep 25, 2019, 8:23:08 PM9/25/19
to
Could the author of this file explain what coding it contains ??
When I try to compile in Windows MinGW as gfortran -o a gnu_plot_ex.f94
I get "format not recognized errors"

l:/$_gcc/bin/../lib/gcc/i686-pc-mingw32/7.4.0/../../../../i686-pc-mingw32/bin/ld.exe:gnu_plot_ex.f94: file format not recognized; treating as linker script
l:/$_gcc/bin/../lib/gcc/i686-pc-mingw32/7.4.0/../../../../i686-pc-mingw32/bin/ld.exe:gnu_plot_ex.f94:1: syntax error
collect2.exe: error: ld returned 1 exit status


urba...@comcast.net

unread,
Sep 25, 2019, 9:38:30 PM9/25/19
to
It looks like your compiler does not recognize the suffix ".f94". Perhaps .f90 or .f95 is what you intended.

The program shows how a program can write to a process such as gnuplot directly,
and how you can then pass your calculated values as input to the process and then return to your program for further computation. This provides the functionality requested in the Original Post without using external files, an API interface, or other arguably more complex methods. This essentially shows how a Fortran program can call the C popen(3c) procedure.

At the end the program lets you directly enter gnuplots to enter gnuplot modes and then optionally reruns the computations showing how this method can let you essentially create a customized shell around gnuplot.

L Godioleskky

unread,
Sep 26, 2019, 8:29:08 AM9/26/19
to
==================================
Thank You for helping me

.f95 works except for the line

program gnuplotExample
use M_process ,only: process_open_write, process_writeline

which gives fatal error message:

use M_process ,only: process_open_write, process_writeline
1
Fatal Error: Can't open module file 'm_process.mod' for reading at (1): No such file or directory
compilation terminated

Can I substitute something to replace m_process.mod ??

urba...@comcast.net

unread,
Sep 26, 2019, 6:05:22 PM9/26/19
to



> Can I substitute something to replace m_process.mod ??

module M_process source is actually included in the file (from the lines "module M_process" to "end M_process" inclusive). I am surprised that is a problem. I would suspect you had a very old version of gfortran(1) but it is apparently new enough to recognize the ISO_C_BINDING intrinsic module, which means I would expect what you already did to work. So ..

1) Add "-J." to your gfortran(1) command to explicitly tell it to search the current directory for .mod files.

2) Is there a file in the directory where you did the compile called something like "m_process.mod"? If not, split the source file into two files. One has the module M_process in it. Call it "M_process.f90". Leave the remainder (the main program) in the original file. A variety of things should work, but I would recommend trying

gfortran -c M_process.f95
gfortran -J. gnu_plot_ex.f95 M_process.o -o a

and then run your executable. As long as the gnuplot command is in your search path it should run.


0 new messages