Skip to content

Instantly share code, notes, and snippets.

Last active July 25, 2023 07:14
Show Gist options
  • Save jbilcke/5405777 to your computer and use it in GitHub Desktop.
Save jbilcke/5405777 to your computer and use it in GitHub Desktop.
How to create a video using Gephi + Scripting plugin + ffmpeg
ts_min=1352261778000, # "from" timestamp..
ts_max=1352262378000, # .."to" timestamp
frames=20, # number of images in the video. eg 200 frames for a video at 20 frames per seconds = 10 seconds of video
output_prefix="/path/to/output/dir/frame_", # path where to write the png. images will be prefixed with "frame_"
output_format=".png" # you probably want to leave png here
# not tested - of course you need to change this to your settings
# here this will generate a 20 frame/sec video of 1024x1024 pixels. Not standard for a video, but computers can deal with it :)
# the duration of the video is controlled by the number of images. ffmpeg will automatically stop when it reaches the end.
# tip:
# frame_%d.png will count from 1 to N
# frame_%02d.png will count from 01 to N
# frame_%03d.png will count from 001 to N.. you get the point
ffmpeg -r 20 -f image2 -i /path/to/output/dir/frame_%d.png -y -s 1024x1024 out.mp4
# videomaker assumes each node has a "timestamp" numeric that can be compared
def videomaker(ts_min, ts_max, frames, output_prefix, output_format):
length = ts_max - ts_min # duration between min and max. these can Integers or Double - just use the same unit everywhere
interval = length / float(frames) # time interval between each frame
t = ts_min # set the cursor to the beginning
for i in range(0, frames): # let's start to count from image 0 to image FRAMES
t += i * interval
setVisible(g.filter(timestamp < t)) # filter using the "timestamp" node attribute. We keep nodes *before* the time cursor
exportGraph("%s%s%s" % (output_prefix, i, output_format)) # export. maybe put more parameters here?
Copy link

Can you detail a bit more about the Gephi part in the Python script? Sounds excellent :)

Copy link

So much needed, great!
I'd like to test it and put it in the tuto I am writing on dynamics. Question: I suppose the shell part should look the same in the Windows command line?

Copy link

jbilcke commented Apr 17, 2013

Okay so I tried it in production. It works! png compress well ("clean" images, good compression ratio in mp4)
I only have two issues:

  • gephi automatically "center" the png output (it seems to try to fit the graph in a canvas, using barycenter + zoom), so some frames can "jump" from one position to another: can be a problem if you want to a smooth video.
  • memory issues past 150+ images? I will need to double-check this
  • I need to figure out how to configure the export. Maybe try to setup the PNG settings in the Gephi UI, before running the video export?

Anyway, here are some explanations:

  1. This is a workflow to generate a video from a temporal graph
  2. First you need the latest version of Gephi, and the Python Scripting Plugin
  3. Download the file somewhere. It is a very basic script.
  4. If you want, you can modify this script to do additional steps (eg. a layout pass at each iteration)
  5. Then prepare a graph (eg. GEXF) with a "timestamp" attribute (if you need another name, you must change the script accordingly). This must be a number, so the filter operation can work.
  6. For the moment this is manual.. you need to know the begin timestamp and the end timestamp in your data. This can be the oldest or youngest, or any other interval. Note the values somewhere, you will need them later.
  7. Load the graph, then open the Gephi scripting console
  8. call "execfile" to load the small script: execfile("/your/path/to/") on Windows you will need to escape thigns, use backslashes etc..
  9. Configure the Preview: colors, background etc.. (I recommend to save the preset), since it will export PNG images from the Preview
  10. call videomaker using the begin timestamp, end timestamp, and the number of frames you want (number of images in the video)
  11. Gephi will freeze during the export procedure: should not be an issue, just check the output dir, you should see the PNG files being generated. If Gephi crashes, kill it. It should be possible to extend the videomaker script to support "interrupted" exports, by replacing the first value of the range(...) function by the id of the last image you generated.
  12. done! now, open a terminal, and run ffmpeg. Ffmpeg has many features, including the ability to generate a video from still images. You can customize everything: you can speedup or slow down things by adjusting the frame per seconds, the delays.. see this StackOverflow comment post for instance: (he explains how to use the file name pattern under Windows)
  13. post on youtube and enjoy the glory

It is not easy to create a generic plugin, because I think most people may want to do something between each iteration.

It should be possible, anyway, to have a better version of videomaker with support for callbacks (you would then put your layout etc.. in the callback). I think it is possible in Jython (?).

Copy link

jbilcke commented Apr 17, 2013

I've documented the code a bit more

Copy link

It worked like a charm! I probably will use it in order to improve my degree's final project presentation. Thanks!

Copy link

Thanks Julian for setting us on the right path! I got up and running pretty quickly, but then found a minor but fundamental bug in the time calculation.

See line 7 of t should be incremented by the interval, not interval * frame number (or t could be assigned t =ts_min + i * interval)

Hoping this helps others!

Copy link

Thanks for sharing this, Julian! Much appreciated!

Copy link

Hi there. I've been looking for this for a while, thanks for pulling it together!
Sadly, having followed these instructions I get what appears to be a JS error -- I realise this post is coming nearly 4 years after development of this script, so wholly expect that updates to both Gephi (using 0.9.2) and JS (v8u144) on macOS 12.6.
I get the following error when running the script:
TypeError: unsupported operator for attribute type 'class java.lang.Integer'

Any thoughts? help appreciated

Copy link

in the script, timestamp is an attribute of the nodes, right? Which attribute is g in g.filter? I'm trying to use this code, but in my graph, the time parameter belongs to the edges (the animation shows the edges being added..), not to the nodes...How can I edit this code to that?
Thanks in advance!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment