0

I am using matlibplot to plot a 3d graph of scatter points as shown in below code.

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

plt.ion()
plt.show()

ax.set_xlim([0.,13.])
ax.set_ylim([-1.5,1.5])
ax.set_zlim([-1.5,1.5])

def plotPoint(x,y,z):
    ax.scatter(x, y, z)

In above code plotPoint(x,y,z) is called in while True loop after very Serial.readLine()

With out this plot I was able to log data in console for every 20 mill seconds.But after started plotting those in graph it become very slow.

How to make this fast? Are there any other python libraries that can help me to visualize 3d points in plots.I am using OpenCV also in my project.I case if there are any solution for my problem with opencv.

Edited code as suggested by unutbu:

list_data = []

xdata = []
ydata = []
zdata = []
def update_graph(i):
    global xdata
    global ydata
    global zdata
    global list_data

    print i, list_data

    for x in list_data:
        xdata.append(x[0][0])
        ydata.append(x[1][0])
        zdata.append(x[2][0])
        graph.set_data (xdata, ydata)
        graph.set_3d_properties(zdata)
        title.set_text('3D Test')
    return title, graph, 



fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
title = ax.set_title('3D Test')
graph, = ax.plot(xdata, ydata, zdata, linestyle="", marker="o")
ani = matplotlib.animation.FuncAnimation(fig, update_graph,
                           interval=100, blit=True)
plt.show()
djkpA
  • 1,224
  • 2
  • 27
  • 57
  • The key is to avoid calling `ax.scatter` multiple times. Instead, modify one scatter plot by calling its pathcollection's [`set_offsets` method](https://matplotlib.org/api/collections_api.html#matplotlib.collections.PathCollection.set_offsets). There is an [example here](http://stackoverflow.com/q/31303105/190597). You could modify the `update` function to use the log data coming in every 20 ms. – unutbu May 10 '17 at 11:39
  • What does `set_offsets()` do(Set the offsets for the collection). And I didn't get what `update` in that example does. could you please elaborate. Thanks. Sry I am new to python – djkpA May 10 '17 at 11:51
  • The `set_offsets` function modifies the underlying data in the `pathcollection`. matplotlib is faster at rendering lots of data in one pathcollection than it is at rendering lots of pathcollections which each contain a single data point. That's why you want to call `set_offsets` instead of calling `ax.scatter` multiple times. The `update` function is called by `animation.FuncAnimation` multiple times -- once for each frame of the animation. You can learn more about how `FuncAnimation` works from this [tutorial](https://jakevdp.github.io/blog/2012/08/18/matplotlib-animation-tutorial/). – unutbu May 10 '17 at 11:56
  • Correction: for 3d scatter plots, the attribute to modify is `_offsets3d`, not `set_offsets`. See [here](http://stackoverflow.com/a/41609238/190597) for an example. Note that the underscore in `_offsets3d` indicates it is a private, undocumented attribute. While modifying it works in the current version of matplotlib, it is not part of the official API, so there is no guarantee it will continue to work in future versions of matplotlib. – unutbu May 10 '17 at 12:14
  • While edited the code as you said, its blocking the main code to run. Updated edited code – djkpA May 10 '17 at 14:43

0 Answers0