7
# -*- coding: utf-8 -*-
"""
slider 3D numpy array

"""

import numpy
import pylab
from matplotlib.widgets import Slider

data = numpy.random.rand(100,256,256) #3d-array with 100 frames 256x256

ax = pylab.subplot(111)
pylab.subplots_adjust(left=0.25, bottom=0.25)

frame = 0
l = pylab.imshow(data[frame,:,:]) #shows 256x256 image, i.e. 0th frame

axcolor = 'lightgoldenrodyellow'
axframe = pylab.axes([0.25, 0.1, 0.65, 0.03], axisbg=axcolor)
sframe = Slider(axframe, 'Frame', 0, 100, valinit=0)

def update(val):
    frame = numpy.around(sframe.val)
    pylab.subplot(111)
    pylab.subplots_adjust(left=0.25, bottom=0.25)
    pylab.imshow(data[frame,:,:])

sframe.on_changed(update)

pylab.show()

I have a 3D-numpy-array, that actually contains images of size 256x256. Now I want to show these frames on after another using a slider. It appears to be really slow. Is there a better way to do that?

ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
feinmann
  • 1,060
  • 1
  • 14
  • 20

2 Answers2

7

Try re-writing the update function as

def update(val):
    frame = numpy.around(sframe.val)
    l.set_data(data[frame,:,:])

so that you do not need to re-create all of the matplotlib objects every update

tacaswell
  • 84,579
  • 22
  • 210
  • 199
  • do you think, it is a good way to do that? do you know if it would be more efficient with PIL? – feinmann Jul 19 '12 at 15:02
  • Don't quite understand what you are asking. I think you can throw PIL object at `imshow` (and `set_data`) without converting them at arrays first and updating the existing `AxisImage` object will always be faster than creating a new one. – tacaswell Jul 19 '12 at 15:07
0

Seems like you need to cast frame number to int

def update(val):
    frame = numpy.around(sframe.val)
    l.set_data(data[int(frame),:,:])

otherwise it will throw an error:

l.set_data(data[frame,:,:])
IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices