I recorded a phenomenon using video capturing (phen.avi, imported into Mathematica) and simultaneous measurement of some electrical properties of that phenomenon (a list with values). For every frame, there is a corresponding value, which I would like to

a) overlay directly on each frame (is it possible to convert numbers into graphics and then use ImageCompose[]?); and

b) animate these values in an "electrocardiogram"-style, so values vs. "rolling time".

This should be possible with Animate[], but do I have to split this animation into single images in order to overlay it onto phen.avi, or is there a more direct way?

  • $\begingroup$ You should be able to use something like `Animate[Show[frameofavi[[t]],Graphics[Text[ToString[the number you want to overlay],{xposition,yposition}]]],{t,1,Length[frameofavi},1]' $\endgroup$ – Jonathan Shock May 1 '13 at 23:26

If you import the avi using the option GraphicsList then you immediately have a variable which is a list with all the frames. For instance:

imagelist = Import["...file.avi","GraphicsList"]

You can then create an animation with this imagelist and superpose the frame numbers (or whatever other numbers you want using Show inside the Animate function):

Animate[Show[imagelist[[t]], Graphics[Text[ToString[t],{10,10}]]],{t,1,Length[imagelist], 1}]

The {10,10} alters where in the frame the text will appear. You can alter the Style of the text as you want. In this example the text which will appear is simply the frame number (ToString[t]) and you can alter this however you need.

| improve this answer | |
  • $\begingroup$ Thanks that works! I just replaced the t in ToString[t] with code that selects the proper values. Nice! $\endgroup$ – R.S. May 1 '13 at 23:53
k = Import["traffic.avi", "ImageList"];
a = RandomReal[{0, 1}, 10];
s[n_] := ListLinePlot[a[[1 ;; n]], PlotStyle ->{Thick, White}, PlotRange ->{{1, 10}, {0, 1}}]
Table[ImageCompose[k[[n]], s[n]], {n, 10}]

enter image description here

| improve this answer | |
  • $\begingroup$ Thanks, your code (and particularly the PlotStyle) is very close to what I was looking for. I think for the animation style I tried to describe (regarding oscilloscopes, it's also called roll mode), a full range plot should be slided under a fixed-width time window. $\endgroup$ – R.S. May 2 '13 at 0:20

I present a solution qualitatively similar to belisarius's, but done somewhat differently:

(* import an AVI frame-by-frame *)
imgs = ExampleData /@ ExampleData[{"TestAnimation", "ToyVehicles"}, "Frames"];

(* some plots *)
plots = Table[Plot[Sin[x], {x, -$MachineEpsilon, u}, Axes -> None, Frame -> True,
                   Epilog -> {Directive[AbsolutePointSize[6], Orange], 
                              Point[{u, Sin[u]}]},
                   FrameTicks -> {{All, None}, {None, All}},
                   PlotRange -> {{0, 2 π}, {-1, 1}}, PlotStyle -> Orange],
              {u, 0, 2 π, 2 π/9}];

(* finished product *)
  Graphics[Inset[plots[[k]], {1, 0}, {2 π + π/15, -1 - 1/8}], 
           PlotRange -> {{0, 1}, {0, 1}}, 
           Prolog -> {Texture[imgs[[k]]], 
                      Polygon[Scaled /@ {{0, 0}, {1, 0}, {1, 1}, {0, 1}}, 
                          VertexTextureCoordinates -> {{0, 0}, {1, 0}, {1, 1}, {0, 1}}]}],
        {k, Length[imgs]}]

some cartoon with a plot

Here, I took care to match the aspect ratio of the enclosing Graphics[] with the aspect ratio of the animation; you can skip this calibration if you don't mind a few distortions. After this, I used Inset[] so that the graph is displayed, but does not cover up the animation. If need be, one can also use directives like Text[] or options like PlotLabel along with each frame of the final animation.

| improve this answer | |
  • $\begingroup$ That Jeep is mine $\endgroup$ – Dr. belisarius May 3 '13 at 18:22
  • $\begingroup$ @bel, sorry, but I didn't like Walter Cronkite, and the chemical plants remind me too much of my job. Thus... $\endgroup$ – J. M.'s technical difficulties May 3 '13 at 18:27

To get a rolling plot you can change the PlotRange with time, something like this:

(* fake movie frames *)
image[t_] := RandomImage[{0, 1}, {150, 150}]~Blur~3

(* make up some data to plot *)
data = Accumulate[RandomReal[{-1, 1}, {100}]];
range = {Min[data], Max[data]};

(* define the rolling plot *)
rollingplot[t_, n_] := ListLinePlot[data[[;; t]],
  PlotRange -> {{Max[t, n] - n + 1, Max[t, n]}, range}, 
  BaseStyle -> {FontFamily -> "Courier", 10, White},
  PlotStyle -> Directive[Thick, Green],
  Frame -> True, Axes -> False, ImagePadding -> 15]

Animate[ImageCompose[image[t], rollingplot[t, 25]], {t, 1, 100, 1}]

enter image description here

| improve this answer | |
  • $\begingroup$ ur cable provider is worst than mine $\endgroup$ – Dr. belisarius May 4 '13 at 3:32
  • $\begingroup$ This is what I meant with "rolling time" - thanks! I will try to modify it, so that the graph also starts coming from the right side. $\endgroup$ – R.S. May 5 '13 at 14:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.