Search code examples
linuxbatch-fileanimationplotxmgrace

How to make proper animated graph in xmgrace?


I have a series of data files and I just simply want to show them in a movie file where for each data file color, legends will change. So I tried something like below:

for i in *dat; do gracebat $i -batch setup.batch -printfile fig-$i.png -hdevice PNG -hardcopy; done

after that I use usual convert command to make a movie out of the PNG files using:

convert -delay 50 fig-*.png animation.gif

This produces a movie like below:

Now I want to change the colour and as well as legend in each frame according to the data point. I know there needs to be changed something in the setup.batch file but I couldn't figure it out what should I write there? Can anyone please help me a bit?

The setup.batch file looks like:

TITLE "Energy barrier"
WORLD XMIN 0
WORLD XMAX 2
WORLD YMIN 0
WORLD YMAX 0.6
XAXIS TICK MAJOR 0.5
XAXIS TICK MINOR 0.25
YAXIS TICK MAJOR 0.1
YAXIS TICK MINOR 0.05
s0 LINE LINEWIDTH 2.0

It would be really helpful if someone has idea about keeping the plots in each frame instead of showing only one plot at a frame. As an example, now it shows only one line at each step but what would be the way If I keep the previous plots so then at the 8th frame I can shown all the 8 plots?


Solution

  • One option is to make as many batch files as the number of data files. The following bash script will automatically generate batch files.

    #!/bin/bash
    rm -f temp.batch
    c=0;
    for fullname in `find . -name "*.dat"`; do
      # Extract filename without extension
      fname=$(basename "$fullname")
      fname="${fname%.*}"
    
      # Keeping the plots in each frame
      echo READ BLOCK \"${fname}.dat\" >> temp.batch
      echo BLOCK xy \"1:2\" >> temp.batch
      echo s$c LINE LINEWIDTH 2.0 >> temp.batch
      echo s$c LINE COLOR $((c+1)) >> temp.batch          # change the colour
      echo >> temp.batch  # a blank line for readability
    
      cat temp.batch >> plot${fname}.batch
    
      # Set formatting and other global options
      echo WORLD XMIN 0 > plot${fname}.batch                # create or overwrite file
      echo WORLD XMAX 2 >> plot${fname}.batch
      echo WORLD YMIN 0 >> plot${fname}.batch
      echo WORLD YMAX 0.6 >> plot${fname}.batch
      echo XAXIS TICK MAJOR 0.5 >> plot${fname}.batch
      echo XAXIS TICK MINOR 0.25 >> plot${fname}.batch
      echo YAXIS TICK MAJOR 0.1 >> plot${fname}.batch
      echo YAXIS TICK MINOR 0.05 >> plot${fname}.batch
      echo PRINT TO \"${fname}.png\" >> plot${fname}.batch
      echo HARDCOPY DEVICE \"PNG\" >> plot${fname}.batch
      echo PRINT >> plot${fname}.batch
      ((c++));
    done
    rm -f temp.batch
    

    Followed by calls to gracebat to create the .png image sequence.

    for fullname in `find . -name "*.dat"`; do
      fname=$(basename "$fullname")
      fname="${fname%.*}"  
      gracebat -batch plot${fname}.batch -nosafe 
    done
    

    Then use the convert command to make the movie with a unique color for each data-set, keeping old plots in each new frame.

    Ofcourse, if you just want to change the color and not keep the old plots, replace temp.batch with plot${fname}.batch in the bash script and get rid of the concatenation line.