17

So I have some phone accelerometry data and I would like to basically make a video of what the motion of the phone looked like. So I used matplotlib to create a 3D graph of the data:

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import pandas as pd
import pickle
def pickleLoad(pickleFile):
    pkl_file = open(pickleFile, 'rb')
    data = pickle.load(pkl_file)
    pkl_file.close()
    return data
data = pickleLoad('/Users/ryansaxe/Desktop/kaggle_parkinsons/accelerometry/LILY_dataframe')
data = data.reset_index(drop=True)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
xs = data['x.mean']
ys = data['y.mean']
zs = data['z.mean']
ax.scatter(xs, ys, zs)
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
ax.set_zlabel('Z Label')
plt.show()

Now time is important and is actually also a factor that I only see one point at a time because time is also a factor and it lets me watch the progression of the accelerometry data!

What can I do with this to make it a live updating graph?

Only thing I can think of is to have a loop that goes through row by row and makes the graph from the row, but that will open so many files that it would be insane because I have millions of rows.

So how can I create a live updating graph?

Ryan Saxe
  • 17,123
  • 23
  • 80
  • 128

2 Answers2

39

Here is a bare-bones example that updates as fast as it can:

import pylab as plt
import numpy as np

X = np.linspace(0,2,1000)
Y = X**2 + np.random.random(X.shape)

plt.ion()
graph = plt.plot(X,Y)[0]

while True:
    Y = X**2 + np.random.random(X.shape)
    graph.set_ydata(Y)
    plt.draw()

The trick is not to keep creating new graphs as this will continue to eat up memory, but to change the x,y,z-data on an existing plot. Use .ion() and .draw() setup the canvas for updating like this.

Addendum: A highly ranked comment below by @Kelsey notes that:

You may need a plt.pause(0.01) after the plt.draw() line to get the refresh to show

Hooked
  • 84,485
  • 43
  • 192
  • 261
  • @RyanSaxe What OS and what version of `matplotlib` are you using? Are you saying that _nothing_ shows up with this example? – Hooked May 08 '13 at 18:17
  • I use linux on osx 10.8. And whatever the most recent version is of matplotlib because I downloaded it 2 weeks ago. And when I run this, it opens up a console but the graph never laods or shows – Ryan Saxe May 08 '13 at 18:26
  • @RyanSaxe I wonder if it's a problem with the backend on OSX, as it works for me on Ubuntu. Try adding a file in the script directory `matplotlibrc` with the contents `backend: MacOSX` and see if that changes anything (try other backends too to see if it helps). – Hooked May 08 '13 at 18:52
  • it's fine, I was able to figure it out on my own, but I came across a new problem...you can find a new question for that problem [here](http://stackoverflow.com/questions/16447812/make-matplotlib-draw-only-show-new-point) – Ryan Saxe May 08 '13 at 18:57
  • @RyanSaxe If you've found a new solution, please post it as an answer to your own question! If not accept this one so it looks like it's closed. – Hooked May 08 '13 at 19:06
  • 19
    This is the right way to do it without issuing multiple plotting commands. You may need a `plt.pause(0.01)` after the `plt.draw()` line to get the refresh to show. – Kelsey May 08 '13 at 20:33
  • Is there a way to do it and not freeze the PC while – reox Jan 09 '15 at 12:53
  • Nothing appeared until I added a `plt.pause(0.01)`, as per @Kelsey's suggestion, at which point everything worked as expected. – sevko Feb 22 '15 at 18:36
  • 1
    PyLab takes forever to import. For me it loads much quicker using `import matplotlib.pyplot as plt` (and renaming `pl` to `plt`, of course). – Lenar Hoyt Sep 02 '17 at 17:11
1

I was able to create live updating with draw() and a while loop here is the code I used:

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from pylab import *
import time
import pandas as pd
import pickle
def pickleLoad(pickleFile):
    pkl_file = open(pickleFile, 'rb')
    data = pickle.load(pkl_file)
    pkl_file.close()
    return data
data = pickleLoad('/Users/ryansaxe/Desktop/kaggle_parkinsons/accelerometry/LILY_dataframe')
data = data.reset_index(drop=True)
df = data.ix[0:,['x.mean','y.mean','z.mean','time']]
ion()
fig = figure()
ax = fig.add_subplot(111, projection='3d')
count = 0
plotting = True
while plotting:
    df2 = df.ix[count]
    count += 1
    xs = df2['x.mean']
    ys = df2['y.mean']
    zs = df2['z.mean']
    t = df2['time']
    ax.scatter(xs, ys, zs)
    ax.set_xlabel('X Label')
    ax.set_ylabel('Y Label')
    ax.set_zlabel('Z Label')
    ax.set_title(t)
    draw()
    pause(0.01)
    if count > 50:
        plotting = False
ioff()
show()
Ryan Saxe
  • 17,123
  • 23
  • 80
  • 128