Fortran plots with gnuplot

2,557 views
Skip to first unread message

Evangelos Bertakis

unread,
Jan 7, 2007, 11:17:13 AM1/7/07
to fortran thermo math
Hello everyone!

First, I would like to wish to you all a happy New Year, with lots of
health, happiness and inspiration!

Second, I would like to share a new idea that came to me today.

During the past few months (those that know me better would say
years), I've spent many hours of my free time playing around with the
visualization problems of Fortran. As you all know, Fortran has a hard
time doing graphics, which are necessary for visualizing curves and
data. Since this is of vital importance in our field, I've taken up
the task of finding workarounds for improving the I/O (Input/Output)
of Fortran.

However, I haven't thought of gnuplot since this morning. Although I
knew of it's existence, I haven't thought of a way to couple it with
Fortran. I thought that since gnuplot is a separate platform, it would
be a great hassle to combine it with a programming language that
didn't support it by default. Nevertheless, working with other
platforms for doing various things (SVG graphics etc.) taught me
several simple tricks that can be applied in circumstances like this
one.

What do you need:
1. A copy of gnuplot. This can be obtained here:
http://sourceforge.net/project/showfiles.php?group_id=2055&package_id=1996&release_id=231440
At the download page that will show up, choose the right package for
your system. For MS Windows users, the right file is: gp400win32.zip.
After you download the file, unzip it and you're good to go!
2. A Fortran compiler that supports the system() function. As far as I
know, the Compaq compiler as well as the open source G95 compiler
support this function.
3. Your favourite text editor.

What I will present here is for MS Windows. Nevertheless, everything
is valid also for UNIX/Linux systems.

The whole idea is to set up a gnuplot input-graph file and then invoke
gnuplot from the command line to plot the graph on screen or as a
file. Since this idea is really fresh, I haven't gone a long way in
implementing it, so this email is bound to be more descriptive than
detailed.

First of all, let's have a look at a simple gnuplot input file (let's
name it "input.txt") that can be created with a text editor:

# file start
set xrange [-pi:pi]
set grid
set title "My first graph"
set xlabel "Angle in degrees"
set ylabel "sin(angle)"
plot sin(x)
# file end

This file plots the function sin(x) from -pi to +pi. As you can easily
guess from looking the commands above, besides the line plot it has a
title, axes labels and a grid. You can have numerous other options,
like defining colors, ticks, multiple curves etc. I will keep things
simple for the sake of clarity. What applies for one, applies for all.

Now, the following DOS command line:

wgnuplot -persist input.txt

will read the input file "input.txt" and plot the graph on your
screen. You can define the wgnuplot path in your Windows PATH
variable, or you can give the path of the wgnuplot executable in the
DOS command. The same can be done for file input.txt for not having to
put it in the wgnuplot bin folder. The -persist option will keep the
plot window on screen until you close it. Otherwise, it will flash on
and off instantaneously, which is terrible for viewing, but rather
helpfull for making automated tasks (nice!!).

What is missing? Something to do this whole thing with Fortran. By
using the system() function the last part of calling gnuplot is
covered. Now we need to create the plot file. Here is how:

1. Convert all user-defined parts of the gnuplot commands into Fortran
variables. For example:
CHARACTER*(50):: GraphTitle, XLabel, YLabel
REAL:: XUpperLimit, XLoweLimit
LOGICAL:: DrawGrid

2. Create a function (or several functions, according to your
programming style), that will get these variables as argument input
variables. Additional to that, an input variable should define the
name of the gnuplot input file.

3. The subroutines should print these data to form the input file:

WRITE(1,*)"set xrange [",XLoweLimit,":",XUpperLimit,"]"
IF (DrawGrid) WRITE(1,*)"set grid"
WRITE(1,*)'set title "',TRIM(XLabel),'"'
WRITE(1,*)'set xlabel "',TRIM(XLabel),'"'
WRITE(1,*)'set ylabel "',TRIM(YLabel),'"'
WRITE(1,*)"plot sin(x)"

Now, all you have to do is to call the function(s) for defining the
gnuplot options and then the system() function for calling gnuplot!
Then, as your Fortran program runs, a plot window will pop up before
your eyes with your data plot. Nifty huh?
Note: I haven't really tried writting such functions, but it should
work as described. In addition, the Fortran lines above may have
syntax errors in them.

Of course, being able to plot a few functions is not that big a deal.
But gnuplot can also plot data scatters, just like MS Excel. All you
have to do is to create the appropriate input file(s) using Fortran as
explained above. What is really nice about all this, is that it
requires very little effort and once you code it, you have it forever.
You will never again have to move your data to and from some plotting
software every time you run your Fortran program thus wasting an awful
amount of time.

Do you want more? gnuplot can also do 3D-plots, bar-charts,
automatically save the plots as image files (PNG, which is web-browser
friendly, SVG that everyone likes, PDF that everyone is addicted to,
and several other beloved formats), it can do least squares
approximations, animations, you name it!

Have fun!

Vangelis

P.S. The Compaq compiler has a built-in library for graphics. However,
it is only usable with that specific compiler. Now, you wouldn't want
to write Fortran code that is not portable, would you?
P.S.S. Use the mailing list if you have any questions!

Dimitrios Papadopoulos

unread,
Jan 8, 2007, 9:39:21 AM1/8/07
to Fortran Thermodynamics Mathematics
Happy New Year!!!

A good idea, but in order to avoid writing some code already written
try this:
http://gnuplotfortran.sourceforge.net/
and this:
http://www.csit.fsu.edu/~burkardt/g_src/gnufor/gnufor.html
For more "hardcore" graphics you could also try:
http://math.nist.gov/f90gl/
which is unfortunately only for Fortran 90.

Evangelos Bertakis

unread,
Jan 8, 2007, 3:41:42 PM1/8/07
to fortran-t...@googlegroups.com
Thanks for the feedback Dimitris!

I think that my Plot() subroutine for SVG that I wrote last summer has
just been rendered obsolete (*sigh*!). But I earned useful experience,
right? Now I have to think of new tricks to put up my sleeve...

For those that are interested, here is the gnuplot homepage:
http://www.gnuplot.info/
There you can also find links to tutorials (good starting points), the
manual (for the more advanced) etc. I found out that it has a really
steep learning curve.

Vangelis

Dimitrios Papadopoulos

unread,
Jan 17, 2007, 4:46:15 AM1/17/07
to Fortran Thermodynamics Mathematics
There is a little problem with using a system call in fortran. One
cannot make a diagram refresh, lets say every five seconds, because the
system does not return handle to fortran if the process which has
iniciated does not return. Is there any idea how to overcome this
problem? One way in Unix would be to use the fork C function in order
to create to processes, one that handles computation and the other
doing plotting. But this seems quite complecated.

Best,
Dimitris

Evangelos Bertakis

unread,
Jan 17, 2007, 5:33:05 AM1/17/07
to fortran-t...@googlegroups.com
Good morning!

Dimitris, try using Python's SPAWN* function with the P_NOWAIT mode
(where * should probably be the "p" variant, but I'm not sure - read
the manual...). Now, be cautious because some of the variants are not
portable on MS Windows (but I guess that you don't really care, do
you?).

The SPAWN function will launch a new process using the operating
system. It also supports command-line arguments. The P_NOWAIT mode
will cause the python program to continue execution withoud waiting
for return data from the spawned process. It will just return the new
process ID (as soon as the new process is launched), and the two
applications will go separate ways.

The idea is that you just make a little program in Python that will
handle gnuplot (or any other program) in this way. Then, use the
system() function in Fortran to call the python program. Python will
launch your diagram, and it will end, thus returning control to
Fortran, which will go on with the number crunching.

You will find SPAWN in module OS. The section in the Python v2.5
manual is "14.1.5 Process Management".

This is just an idea. If you fix it, let me know, because I'm
interested as well!

Vangelis

Evangelos Bertakis

unread,
Jan 18, 2007, 1:20:13 PM1/18/07
to fortran-t...@googlegroups.com
Hello everyone!

Here is the complete solution to the problem that Dimitris suggested
last time, although I still haven't tried it with gnuplot. I'll leave
that as an exercise to the reader...

The target is to make a Fortran program launch another program (in
Dimitris' case, gnuplot) and not wait for the that program to return
in order to go on with the calculations. I've tried this in MS
Windows, but it should work anywhere because Python is portable.

What you need:
1) A Fortran compiler that supports the system() function
2) The Python platform (at least version 1.6, I've used version 2.5)
3) Your favourite text editor

First let's make ourselves a working directory, let's say
"C:\Sandbox". Now, let's make in there a small program, let's call it
"a.exe". This program may be something like this:

program a
integer:: err
do
write(*,*)'program a start'
err=system('C:/b.exe')
if (err/=0) pause 'system error'
write(*,*)'program a end'
end do
end program a

Note that program a.exe is running in an infinite loop. It is designed
so that it will:
1) print "program a start" on screen
2) launch program b.exe that exists in C:/
3) print "program a end " on screen
4) loop steps 1-3

Program b.exe should look like this:

program b
write(*,*) "program b"
read(*,*)
end program b

Note that program b.exe does nothing else that writing something on
screen and then waiting for the user to press ENTER in order to end.
This is the process that we want to launch using program a.exe, but we
don't want a.exe to wait for the user to press ENTER.

If we execute program a.exe we will get in our command promt:

program a start
program b
(program halts, user presses ENTER)
program a end
... (loop)

This is NOT what we want! OK, now, let's make in C:\Sandbox a text
file named "b.py". In this we write the following Python program:

import os
os.spawnl(os.P_NOWAIT,'C:/b')

Long huh? This program uses the Python module OS to launch program "b"
(the .exe ending is added internally). P_NOWAIT means that b.exe will
be launched and then ignored. Now, let's go back to the source code of
the program a.exe and substitute the line:

err=system('C:/b.exe')

with the line:

err=system('b.py')

Now, the program b.exe will be executed through the Python program.
After building and executing program a.exe we get on screen:

program a start
program b
program a end
... (loops continuously without interference)

There you go! Problem solved.

Now, let's redefine the program and make it (a lot) more perverse and
therefore interesting: change the Python program into:

import os
os.spawnl(os.P_NOWAIT,'a')

Now, execute program a.exe. Note that it executes itself and the
*whole* of the program is being executed every time. This is different
than changing program a.exe so that the system command is:

err=system('a.exe')

In this case you will only get the output line "program a start" on
screen and the line "program a end" will *never* show up. Now, I don't
have any use of this, but it is fairly interesting to mention (I
discovered it by accident). Any ideas where this can be useful?

Have fun,

Vangelis

P.S. Attention: in both the Fortran and the Python programs, use only
the forward slash "/" for defining paths. Do NOT use backslash "\"
that is commonly used in DOS.

Reply all
Reply to author
Forward
0 new messages