Friday, September 26, 2014

Matplotlib Animation Save with FFmpeg Freezes After N Frames

Matplotlib is a go-to plotting tool in Python, which has a lot of useful features, like compatibility with the Scipy/Numpy stack. Sometimes it's useful to visualize time-series data temporally.

One very useful feature that Matplotlib has is the animations module, which allows you to animate plots with changing data [over time, for example], and save the data as a video file using FFmpeg. There's a great tutorial for Matplotlib animations here.

My only complaint about the Matplotlib animations, is that the documentation and examples are not super-comprehensive. I might create a follow-up post with some sample programs, to add to the documented examples floating around the interwebs.

In any case, once I got the animations working, I wanted to save them as a video for later on-demand viewing. I set up an animation writer with ffmpeg, x264, and let it run. Each time I ran the script, and the video saving would freeze after 820 frames.

It took a fair amount of online searching to find the answer here. It turns out that the stock Ubuntu/Debian FFmpeg and LibAV have branched apart at some point. You can obtain the "real" FFmpeg here. Once you install this, the Matplotlib animations save videos just fine.


Sunday, September 14, 2014

USB Serial COM Ports and Python

I was working with a simple device that provides data via USB Serial COM. For whatever reason, the C++ library I was using to read from the device was not working consistently on different machines.

USB Serial COM is akin to socket programming. The routines are somewhat platform-dependent, and today's developer doesn't usually care about the details. Just give me an abstraction that lets me communicate!

Then I realized that Python has PySerial. Using this library, I was easily able to communicate with the device, and send it via localhost socket to my C++ program. Done and done.

Check out the super simple source code:

 import serial  
 import socket  
   
 IP="127.0.0.1"  
 PORT=3001  
 sock=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #Sending data to localhost via UDP  
   
 ser= serial.Serial(2,timeout=2) #COM3 is port number 2.  
 print ser.name  
 line=''  
 while (True):  
      line=ser.readline()  
      print line  
      sock.sendto(line,(IP,PORT))  

Python for the win.