pm3d in gnuplot with binary data

binary, binary-data, fortran, gnuplot

Solution

Great question, and thanks for posting it. This is a corner of gnuplot I hadn't spent much time with before. First, I need to generate a little test data -- I used python, but you could use `fortran` just as easily:

Note that my input array (`b`) is just a 10x10 array. The first two "columns" in the datafile are just the index (i,j), but you could use anything.

>>> import numpy as np
>>> a = np.arange(10)
>>> b = a[None,:]+a[:,None]
>>> b
array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9],
       [ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10],
       [ 2,  3,  4,  5,  6,  7,  8,  9, 10, 11],
       [ 3,  4,  5,  6,  7,  8,  9, 10, 11, 12],
       [ 4,  5,  6,  7,  8,  9, 10, 11, 12, 13],
       [ 5,  6,  7,  8,  9, 10, 11, 12, 13, 14],
       [ 6,  7,  8,  9, 10, 11, 12, 13, 14, 15],
       [ 7,  8,  9, 10, 11, 12, 13, 14, 15, 16],
       [ 8,  9, 10, 11, 12, 13, 14, 15, 16, 17],
       [ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]])
>>> with open('foo.dat','wb') as foo:
...     for (i,j),dat in np.ndenumerate(b):
...         s = struct.pack('4f',i,j,dat,dat)
...         foo.write(s)
... 

So here I just write 4-floating point values to the file for each data-point. Again, this is what you've already done using `fortran`. Now for plotting it:

splot 'foo.dat' binary record=(10,-1) format='%float' u 1:2:3:4 w pm3d

I believe that this specifies that each "scan" is a "record". Since I know that each scan will be 10 floats long, that becomes the first index in the `record` list. The `-1` indicates that gnuplot should keep reading records until it finds the end of the file.

Problem

I have some data files with content ``` a1 b1 c1 d1 a1 b2 c2 d2 ... [blank line] a2 b1 c1 d1 a2 b2 c2 d2 ... ``` I plot this with gnuplot using ``` splot 'file' u 1:2:3:4 w pm3d. ``` Now, I want to use a binary file. I created the file with Fortran using unformatted stream-access (direct or sequential access did not work directly). By using gnuplot with ``` splot 'file' binary format='%float%float%float%float' u 1:2:3 ``` I get a normal 3D-plot. However, the pm3d-command does not work as I don't have the blank lines in the binary file. I get the error message: ``` >splot 'file' binary format='%float%float%float%float' u 1:2:3:4 w pm3d Warning: Single isoline (scan) is not enough for a pm3d plot. Hint: Missing blank lines in the data file? See 'help pm3d' and FAQ. ``` According to the demo script in http://gnuplot.sourceforge.net/demo/image2.html, I have to specify the record length (which I still don't understand right). However, using this script from the demo page and the command with pm3d obtains the same error message: ``` splot 'scatter2.bin' binary record=30:30:29:26 u 1:2:3 w pm3d ``` So how is it possible to plot this four dimensional data from a binary file correctly? Edit: Thanks, mgilson. Now it works fine. Just for the record: My fortran code-snippet: ``` open(unit=83,file=fname,action='write',status='replace',access='stream',form='unformatted') a= 0.d0 b= 0.d0 do i=1,200 do j=1,100 write(83)real(a),real(b),c(i,j),d(i,j) b = b + db end do a = a + da b = 0.d0 end do close(83) ``` The gnuplot commands: ``` set pm3d map set contour set cntrparam levels 20 set cntrparam bspline unset clabel splot 'fname' binary record=(100,-1) format='%float' u 1:2:3:4 t 'd as pm3d-projection, c as contour' ```

Original source