3
votes

From a function in C++ I get in a file the coordinates of the centers of a chain of spheres (of constant radius r). I would like to plot this chain with gnuplot. How can I represent the spheres with the true radius? This solution actually does not work, since the unit of pointsize is not the same as that of the axis (and is also changing with the axis limits).

1
You want this in 2D or 3D? - Karl
I want spheres, in 3D - David
You could try to calibrate gnuplot's pointsizes, but all in all, you'll be better off with some 3D rendering software. Or write "Sphere sizes are not to scale" under your graph. ;-) - Karl
I also tought about scaling, but the problem is when I change axis limits, this scale also changes ;) At the end I switched to Matlab, thanks anyway. If someone know a solution I'm always interested - David

1 Answers

5
votes

This a slightly dirty solution which uses parametric (and some commands from Unix). For each line of the following data, we will plot a sphere with radius r, and centered at (x,y,z):

# points.dat :
# x y z radius 
0 0 0 0.5
1 2 2 1.0
3 4 5 0.7
2 5 7 1.0
1 3 4 0.75
2 0 1 1.5

In other words, we will run commands with the form:

splot x1+r1*cos(v)*cos(u), y1+r1*cos(v)*sin(u), z1+r1*sin(v) title "line 1",\
      x2+r2*cos(v)*cos(u), y2+r2*cos(v)*sin(u), z2+r2*sin(v) title "line 2", ...

The following code will do the trick (comments through the script):

set view equal xyz           # to scale the axes of the plot
set hidden3d front           # draw opaque spheres
set parametric               # enable parametric mode with angles (u,v)
set urange [0:2*pi]          
set vrange [-pi/2.0:pi/2.0]

filename = 'spheres.dat'

# get number of data-lines in filename
nlines   = system(sprintf('grep -v ^# %s | wc -l', filename))

# this will save the plot commands
commands = 'splot '
do for [i=1:nlines] {
   # get the i-th line
   line = system( sprintf('grep -v ^# %s | awk "NR == %i {print; exit}" ', filename, i) )

   # extract the data
   x = word(line,1)
   y = word(line,2)
   z = word(line,3)
   r = word(line,4)

   # and save the instructions to plot the corresponding sphere 
   commands = commands . sprintf('%s + %s*cos(v)*cos(u), %s + %s*cos(v)*sin(u), %s + %s*sin(v)  t "line %i"', x, r, y, r, z, r, i)

   # if not EOF, add a comma to commands
   if(i<nlines) { commands = commands . ',  ' }
}

# commands is a string. We can run it into the command line through macros
set macros
@commands

This is the output I obtain:

chain of spheres