6

Snippet:

ax = Axes3D(self.fig)

u = np.linspace(0, 2 * np.pi, 100)
v = np.linspace(0, np.pi, 100)

x = self.prop * np.outer(np.cos(u), np.sin(v))
y = self.prop * np.outer(np.sin(u), np.sin(v))
z = self.prop * np.outer(np.ones(np.size(u)), np.cos(v))

t = ax.plot_surface(x, y, z, rstride=6, cstride=6,color='lightgreen',linewidth=0)
self.canvas.draw()

The above snippet graphs a sphere in tkinter using matplotlib. I've found that higher rstride and cstride values allow the graph to have a bit better performance. However, they give the sphere a weird ribbed shape. I was wondering what other things could be adjusted in the above code to help improve performance.

3 Answers 3

13

Really, the problem is more within plot_surface. There are a lot of things that can be done to improve it. For instance, the shading takes a lot of time and just by changing one line:

colors = [color * (0.5 + norm(v) * 0.5) for v in shade]

to

colors = np.outer(0.5+norm(shade)*0.5,color)

within one of the functions used by plot_surface, I got a reduction of about 28% in the overall runtime. Why? The norm function (well, class kind of) is set-up for vectorization, but wasn't being used in that manner. I know that there are many such things within these functions that aren't very optimal. Changing the two lines:

for rs in np.arange(0, rows-1, rstride):
    for cs in np.arange(0, cols-1, cstride):

to

for rs in xrange(0,rows-1,rstride):
    for cs in xrange(0,cols-1,cstride):

in the plot_surface function itself gives another substantial improvement - now we're down 33% from the original runtime.

From what I've seen, the code isn't really written for efficiency so much as to just get it working from what I can tell - there are plenty of places where things which could be made to be more vectorized using Numpy and aren't. I'm afraid that what really is needed is some optimization of the matplotlib functions.

Sign up to request clarification or add additional context in comments.

4 Comments

These seem like really good fixes which file is the plot_surface function in?
It is in the mpl_toolkits/mplot3d/axes3d.py file. The second change is actually within plot_surface. The first change is within a function called _shade_colors which plot_surface calls. I'm working on submitting these changes back to the source.
Messing around with it, I noticed that the shaded surfaces became less opaque with your first change. Any Idea why that is? It looks really cool!
@Aneaster7171 I hadn't noticed that. Did you change something else? For instance if you changed the line color[3] = 1 that comes right before that part so that it sets the alpha value (4th value of the color) to something less than 1 then there will be less opacity. By the way, I decided to look into whether using a different backend would make any difference. The GTK was much faster than the Tk and PyQT4 backends (which were essentially equivalent).
1

At this point is the visualization package that has the bottleneck. The number of points are defined and constant.

Try if using psyco can speed up it (is only 32bit though).

Comments

0

I'm not sure if it would help, but maybe you could try a different rendering backend for matplotlib. But maybe one of them will give you better performance.

http://matplotlib.sourceforge.net/faq/installing_faq.html#what-is-a-backend

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.