From: Josh Vermaas (vermaas2_at_illinois.edu)
Date: Thu Sep 25 2014 - 11:29:14 CDT

Hi Thomas,

For these kinds of things, I tend to prefer outputting the frames
individually, editing the frames with a python script to insert the text
(that way I can use prettier fonts for the labels), and stitching the
frames together with ffmpeg. If you want to use VMD, you'll need to use
the graphics commands to write arbitrary text
(http://www.ks.uiuc.edu/Research/vmd/current/ug/node128.html). To
control it on a frame by frame basis, you'd need to make a user-defined
movie script (see
http://www.ks.uiuc.edu/Research/vmd/plugins/vmdmovie/usermoviefade.tcl
for an example) and use that as your controller program for making the
movie itself. I've done both methods, and I GREATLY prefer option #1.

-Josh Vermaas

Here is my example of adding text using python. I had many frames (all
called frameXXXX.png), and wanted to sequentially go through them and
label them according to how far along they were in the trajectory
(between 0 and 300 ns). It requires the python image library (PIL), but
to me this was alot less work than working out the TCL to get it right.

#!/usr/bin/env python
from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw
import math
import numpy as np
import glob
font =
ImageFont.truetype("/usr/share/fonts/truetype/liberation/LiberationSerif-Bold.ttf",84)

fixedpoint = (183,13)

point = "."
nstext = "ns"
images = sorted(glob.glob("frame*png"))

for i, ns in enumerate(np.linspace(0,300,len(images))):
         print ns
         img = Image.open(images[i])
         draw = ImageDraw.Draw(img)
         tenths = "%1d" % ((10*ns % 10))
         ones = "%d" % math.floor(ns)
         w1, h1 = draw.textsize(ones, font=font)
         w2, h2 = draw.textsize(point, font=font)
         w3, h3 = draw.textsize(tenths, font=font)
         #No way of getting a thin-space (PIL doesn't believe in letting
LaTeX do the typesetting). Do it by drawing two things close together
         draw.text((fixedpoint[0] -w2 - w1,fixedpoint[1]),"%s" %
ones,(0,0,0), font=font)
         draw.text((fixedpoint[0] -w2,fixedpoint[1]),"%s" %
point,(0,0,0), font=font)
         draw.text((fixedpoint[0] ,fixedpoint[1]),"%s" % tenths,(0,0,0),
font=font)
         draw.text((fixedpoint[0]+48,fixedpoint[1]),"%s" %
nstext,(0,0,0), font=font)
         img.save("images%04d.png" % i)

On 09/25/2014 10:28 AM, Thomas Sexton wrote:
> Hello,
>
> I have been using VMD to make movies of chemical reactions for a
> presentation, and it has been very useful. Now, I would like to place
> a title at the top of the movie, where the text displayed depends on
> the frame. For example, I would like the label to say, "Before
> Transition State" or "After Transition State" depending on the frame
> number. I already know how to use the GUI to place bond length and
> angle labels, but it seems that these labels can't be used to write a
> title.
>
> I think that I need to know two things:
> 1) How do I display arbitrary text in an arbitrary location?
> 2) How do I change the displayed text based on frame number?
>
> Thanks for the great software,
> Thomas Sexton