Plotting directly to movie with numpy and mencoder
Question: So, this should be a comment to [this
thread](http://stackoverflow.com/questions/4092927/generating-movie-from-
python-without-saving-individual-frames-to-files), but it's apparently closed,
so here it goes. I've been playing around quite successfully with matplotlib
and numpy and mencoder, as has been suggested around here. I have since
adopted [Voki Codder buffer to stdin
solution](https://github.com/vokimon/freenect_python_processing/blob/master/src/videosink.py),
which speeds the whole process up considerably. The thing is, I couldn't find
any documentation on the -format="bgra" part of the command. This means that
the bytes are from right to left blue green red alpha, right. Do they have to
be uint32, or something else. The problem is I'm plotting colormaps of floats,
so I'm trying to convert them to grayscale, but I'm getting lots of weird
patterns which make me strongly believe I'm doing something wrong. I wrote
this function to convert from floats to uint32 within a range. But the result
is not why I expected, am I doing something terribly stupid?

    
    
    def grayscale(x, min, max):
      return np.uint32((x-min)/(max-min)*0xffffff)
    


Answer: I think you're getting confused on what the `uint32` represents. It's 4 bands
of `uint8` integers.

If you have floating point data, and want to represent it in grayscale, you
don't want to rescale it to a full 32 bit range, you want to rescale it to an
8-bit range, and repeat that for the red, green, and blue bands (and then
presumably put in a constant alpha band).

You could also just use a different byteorder. `Y8` is just a single
grayscale, 8-bit band, and `Y16` is a single, grayscale 16-bit band. (Have a
look at the output of `mencoder -rawvideo format=help` for a full (though
somewhat confusing) listing.)

Just to illustrate using numpy for view a 32-bit integer as four bands of
8-bit integers:

    
    
    import numpy as np
    height, width = 20,20
    
    # Make an array with 4 bands of uint8 integers
    image = np.zeros((height, width, 4), dtype=np.uint8)
    
    # Filling a single band (red) 
    b,g,r,a = image.T
    r.fill(255) 
    
    # Fill the image with yellow and leave alpha alone
    image[...,:3] = (255, 255, 0) 
    
    # Then when we want to view it as a single, 32-bit band:
    image32bit = image.reshape(-1).view(np.uint32).reshape(height, width)
    # (Note that this is a view. In other words,  we could change "b" above 
    #  and it would change "image32bit")
    

In your case, however, you probably want to do something more like this:

    
    
    import numpy as np
    from videosink import VideoSink
    
    height, width = 20,20
    numframes = 1000
    data = np.random.random((height, width, numframes))
    
    # Rescale your data into 0-255, 8-bit integers 
    # (This could be done in-place if you need to conserve memory)
    d    ata_rescaled = 255.0 / (data.max() - data.min()) * (data - data.min())
    data_rescaled = data_rescaled.astype(np.uint8)
    
    # The key here is the "Y8" format. It's 8-bit grayscale.
    video = VideoSink((height,width), "test", rate=20, byteorder="Y8")
    
    # Iterate over last axis
    for frame in data.T:
        video.run(frame.T)
    video.close()
    

