⚠️ Warning: This article is obsolete.
Articles typically receive this designation when the technology they describe is no longer relevant, code provided is later deemed to be of poor quality, or the topics discussed are better presented in future articles. Articles like this are retained for the sake of preservation, but their content should be critically assessed.
Posted on June 24th, 2010
Fast TK Pixelmap generation from 2D Numpy Arrays in Python
I had TKinter all wrong! While my initial tests with PyGame's rapid ability to render Numpy arrays in the form of pixel maps proved impressive, it was only because I was comparing it to poor TK code. I don't know what I was doing wrong, but when I decided to give TKinter one more shot I was blown away -- it's as smooth or smoother as PyGame. Forget PyGame! I'm rendering everything in raw TK from now on. This utilizes the Python Imaging Library (PIL) so it's EXTREMELY flexible (supports fancy operations, alpha channels, etc).
The screenshot shows me running the script (below) generating random noise and "scrolling" it horizontally (like my spectrograph software does) at a fast rate smoothly (almost 90 FPS!). Basically, it launches a window, creates a canvas widget (which I'm told is faster to update than a label and reduces flickering that's often associated with rapid redraws because it uses double-buffering). Also, it uses threading to handle the calculations/redraws without lagging the GUI. The code speaks for itself.
from PIL import Image, ImageTk
times = 1
timestart = time.clock()
data = numpy.array(numpy.random.random((400, 500))*100, dtype=int)
self.root = Tkinter.Tk()
self.frame = Tkinter.Frame(self.root, width=500, height=400)
self.canvas = Tkinter.Canvas(self.frame, width=500, height=400)
self.root.after(0, self.start) # INCREASE THE 0 TO SLOW IT DOWN
self.im = Image.fromstring('L', (self.data.shape,
self.photo = ImageTk.PhotoImage(image=self.im)
self.canvas.create_image(0, 0, image=self.photo, anchor=Tkinter.NW)
self.times += 1
if self.times % 33 == 0:
print "%.02f FPS" % (self.times/(time.clock()-self.timestart))
self.data = numpy.roll(self.data, -1, 1)
if __name__ == '__main__':
x = mainWindow()
This article's source
was last edited on September 10, 2020.
Have something to say about this article? Let me know