Thursday, July 14, 2016

3D Gnuplot Gif

I needed to make a rotating graph in gnuplot. The plot itself was a 3d plot with one axis being time, one being a server name, and one being a mail count. The graph was fine and all but due to using the heat surface look, it was hard to see some things in the back of the graph. So I wanted to make a gif that simply rotated it.


I did some research and this ended up seeming nigh impossible to do within gnuplot alone. I was able to plot the graph how I wanted by controlling the viewpoint. So I figured if there is a way I can make a ton of output png files, I could use those to create a gif. Turns out this method works quite well. And the best part is that it can all be automated with a script needing no human interaction. The only downside is if you want a small gif at the end, you need to resize/resample it. The final gif I use is a rofling 30 megs. It's 360 frames at a full 1400 by 700 a frame. But on an internal network, this is perfectly fine. You can adjust resolution of the individual graphs in the gnuplot config file.




#! /bin/bash

# Script for creating a gif from the gnuplot pics.

# You need this for fonts: sudo apt-get -y install libgd2-xpm-dev build-essential

#This was for starting out without any residual files

rm /var/www/Servers/test/*.png /var/www/Servers/test/*animation*gif


# All the counters and such initiated

count=0

rotation=0

gifnum=0

gifchunk=0

fullcount=0



while [ $fullcount -lt 360 ] # Main loop; 360 degrees for a perfect spin gif

do



# 'convert' is used to make the gif and it uses globbing

# more than 10 pics at a time will mean they get out of order

while [ $count -lt 10 ]

do


# see the gnuplot config file below


# These sed statemnts are adjusting the output picture number and angle per rep through the 10 count 'while' statement

sed s/XNUMX/$count/ /var/www/Servers/test/3dgnuplot.cfg > /var/www/Servers/test/3dgnuplot.cfg.tmp

sed -i s/XVIEWX/$rotation/ /var/www/Servers/test/3dgnuplot.cfg.tmp


# mmake 1 graph

gnuplot /var/www/Servers/test/3dgnuplot.cfg.tmp



# increment the while10 count, full count (up to 360) and rotation degree (last two interchangable really)

count=$(echo $(($count + 1)))

rotation=$(echo $(($rotation + 1)))

fullcount=$(echo $(($fullcount + 1)))

done


# so after making 10 pictures, use convert to make a gif, keeping it at 10 means globbing works fine

# gifnum is just referencing the while10 gif number so I can glob those later

convert -delay 20 -loop 0 /var/www/Servers/test/*.png /var/www/Servers/test/$gifnum.animation.gif

# after making the gif, remove the png's

rm /var/www/Servers/test/*.png

# reset the while10 counter

count=0

# increment the gif counter

gifnum=$(echo $(($gifnum + 1)))



#####################################

# When you get 10 gifs that the while10 loop made, it globs them together for a larger gif

if [[ $gifnum -eq 9 ]]

then


convert -delay 20 -loop 0 /var/www/Servers/test/*animation.gif /var/www/Servers/test/animation.$gifchunk.gif

gifchunk=$(echo $(($gifchunk + 1)))

gifnum=0

rm /var/www/Servers/test/*.animation.gif

fi

#####################################


done

# After all is said and done and you get the 360 degrees (360 pics made),

# remove all gifs except your larger gif chunks you made

# then use convert to combine all your gifs together in to a mega gif

rm /var/www/Servers/test/*.animation.gif

convert -delay 10 -loop 0 /var/www/Servers/test/animation.* /var/www/Servers/test/myfinalform.gif

# myfinalform.gif is the finished product



## gnuplot config used; you can adjust these to adjust the final gnuplot form

#set term png

#set output '/var/www/Servers/test/XNUMXdgraph.png'

#set terminal png size 1400,700

#set title "Messages processed each hour"

#unset border

#unset surface

#set pm3d at bs

#set hidden3d

#set ylabel "Server"

#set xlabel "Time"

#set dgrid3d 100,100,2

#set samples 50

#set isosamples 50

#set view ,XVIEWX

#splot '/var/www/Servers/3dgnuplot.dat' using 2:1:4:xtic(2):ytic(3) title "Message Counts"







So it may seem like a lot but most of that code is purely to get globbing to work. Without it, you get a schizophrenic gif due to the normal ordering of files (1,12,2,22,3,37,etc). So here's a simple breakdown of what's going on.

Make 10 graphs at incrementing angles

Take those 10 graphs and make a gif

Rinse and repeat above

If you get 10 gifs, combine to larger gif

Once 360 pics are made in to 10-at-a-time gifs, combine all of those gifs in to the final product

Here's a trimmed down sample of it.


No comments:

Post a Comment