animating surfaces

I'd like to plot a 3D surface and its contours as the surface evolves. When I do it by simply calling plot_surface and/or contour3D multiple times, the plot doesn't clear the old surface before plotting the new one, so I get a whole bunch of surfaces accumulating in the same plot:

<snip>
import pylab as P
import matplotlib.axes3d as P3

    # bad: plots multiple surfaces on top of each other
    def animatePlot():

        P.ion() fig = P.gcf()
        ax3d = P3.Axes3D(self.fig)
               for i in xrange(100):
            x, y, z = getLatestData(i)
            ax3d.plot_surface( x, y, z )
            ax3d.contour3D( x, y, z )
            P.draw()
</snip>

The one workaround I've found so far is to recreate the entire Axes3D object at each iteration:

<snip>
import pylab as P
import matplotlib.axes3d as P3

    # Better: clears previous surface & contours before re-plotting
    # Slower.
    def animatePlot():

        P.ion() fig = P.gcf()
        ax3d = P3.Axes3D(self.fig)
               for i in xrange(100):

            # P.clf() # uncomment to speed up, introduces flicker
            self.fig = P.gcf()
            self.ax3d = P3.Axes3D(self.fig)

            x, y, z = getLatestData(i)
            ax3d.plot_surface( x, y, z )
            ax3d.contour3D( x, y, z )
            P.draw()
</snip>

... but this is significantly slower than the first method. If I uncomment the P.clf() call above, it actually gets faster (??), but there's some unpleasant screen flicker. What's the Right Way to replot a changing surface+contour plot?

Thanks,
-- Matt

Matthew Koichi Grimes wrote:

I'd like to plot a 3D surface and its contours as the surface evolves. When I do it by simply calling plot_surface and/or contour3D multiple times, the plot doesn't clear the old surface before plotting the new one, so I get a whole bunch of surfaces accumulating in the same plot:

<snip>
import pylab as P
import matplotlib.axes3d as P3

    # bad: plots multiple surfaces on top of each other
    def animatePlot():

        P.ion() fig = P.gcf()
        ax3d = P3.Axes3D(self.fig)
               for i in xrange(100):
            x, y, z = getLatestData(i)
            ax3d.plot_surface( x, y, z )
            ax3d.contour3D( x, y, z )
            P.draw()

Try putting "ax3d.hold(False)" before the plot_surface, and "ax3d.hold(True)" after it.

I haven't tried it, but I think this should accomplish what you want.

Eric

Hmm, I tried that but it didn't work.

I also tried just using ax3d.hold(False), and also tried pylab.hold(False), but both times I still kept on getting multiple surfaces.

-- Matt

Eric Firing wrote:

···

Matthew Koichi Grimes wrote:

I'd like to plot a 3D surface and its contours as the surface evolves. When I do it by simply calling plot_surface and/or contour3D multiple times, the plot doesn't clear the old surface before plotting the new one, so I get a whole bunch of surfaces accumulating in the same plot:

<snip>
import pylab as P
import matplotlib.axes3d as P3

    # bad: plots multiple surfaces on top of each other
    def animatePlot():

        P.ion() fig = P.gcf()
        ax3d = P3.Axes3D(self.fig)
               for i in xrange(100):
            x, y, z = getLatestData(i)
            ax3d.plot_surface( x, y, z )
            ax3d.contour3D( x, y, z )
            P.draw()

Try putting "ax3d.hold(False)" before the plot_surface, and "ax3d.hold(True)" after it.

I haven't tried it, but I think this should accomplish what you want.

Eric