Random Hacks‎ > ‎

Text-mode 2D-Graphics for Fortran

What is this all about?

Sometimes you need some simple and fast optical feedback to know,whether your simulation is doing the right thing or going into a bad direction. You can write out intermediate data and use a visualization tool of your choice, or you can have some visual feedback included into your software. Now, in most programming languages that is a fairly straightforward operation using one of the available graphics libraries. When you're stuck with programming Fortran, the options are limited, and often it is not worth the overhead.

The forgotten art of ASCII graphics and ANSI-escapes

But a graphical display is not really needed. A fairly good approximation can often be achieved with simple text mode (ASCII) characters. You have to have a thing for historical computer equipment or be over 50 years old to remember to recall that graphics was not always a given with computers and people were quite creative using text mode output. Most computer terminals were text mode terminals that understood a magical thing called ANSI escape sequences that would allow to control positioning the cursor and writing text into (almost) arbitrary locations and changing text attributes. Combine this with using different characters to represent different shades of grey and you have a low resolution graphics display.

How to use this? What can it do?

In the files section below, you find a fortran source file that implements a module for simple 2d-text "images" as plain Fortran code without any external dependencies. To not interfere with the layout, it is important use the write() command with the option ADVANCE='NO', so that no newline is appended to the output as it is otherwise the default in Fortran. The following subroutines are included:


integer, intent(in) :: x,y

This subroutine initializes the module. It turns off the cursor to reduce flicker and records the dimensions of the intended dimension (in character cells) of the graphic output area.


This subroutine clears the entire terminal screen


integer, intent(in) :: x,y

This subroutine positions the cursor to the location given by the x and y arguments. Any subsequent write will start from this location. The top left of the screen is position (1,1).


integer, intent(in) :: nx,ny
real, intent(in) :: array(nx,ny)
real, intent(in),optional :: vmax

This is the heart of the module. It takes a 2d-array of real numbers and plots it into the destined screen area. The plot library support 10 levels of intensity using 10 different characters and the space character to represent zero. Positive and negative values are represented by colors (black and red for positive, blue and cyan for negative). The plot is usually scaled by the absolute maximum value, but this number can also be set as an optional argument. The picture in the top right corner shows two gaussians.


This subroutine positions the cursor back to the bottom of the screen, tries to reset the original status and issues one newline.


Here is a simple example program showing the use of the module:
PROGRAM test_viz
  USE text_viz

  INTEGER, PARAMETER :: nx = 200, ny = 200
  REAL :: val(nx,ny)
  INTEGER :: i,j

  CALL viz_init(48,24)
  CALL viz_clear

  DO j=1,ny ! fill array with data
      DO i=1,nx
          val(i,j) = SIN(REAL(i)*0.05)*SIN(REAL(j)*0.033)
      END DO

  CALL viz_plot(val,nx,ny)
  CALL viz_done
END PROGRAM test_viz
Axel Kohlmeyer,
Jun 24, 2013, 3:45 AM