Skip to content

Instantly share code, notes, and snippets.

@nathanielvirgo
Created February 5, 2020 08:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nathanielvirgo/d74ebef1462c68b2e0d6539a9e48e9e2 to your computer and use it in GitHub Desktop.
Save nathanielvirgo/d74ebef1462c68b2e0d6539a9e48e9e2 to your computer and use it in GitHub Desktop.
# This is simple Python code for displaying a numpy array as pixels and updating it
# with reasonable speed.
#
# The code is by Nathaniel Virgo and is in the public domain - you can do what you
# want with it.
#
# I don't tend to use jupyter for this kind of thing, so it displays in a window.
#
# It gets about 60 fps with a 500x300 array on my machine, and about 40 fps for
# 1000x1000. OpenGL would most likely be much faster, but this is not unreasonable
# for Python.
#
# It works correctly on a retina display (in that the pixels are sharp and not
# blurred), but unfortunately it doesn't display at retina resolution.
#
# to use it, just insert your own code to update 'buf' inside the loop. buf is
# in RGBX format, meaning it's a w*h*4 array of uint8s, but the 4th value is not
# used, it's just padding. (This seemed to be very slightly faster than using RGB.)
import numpy as np
import tkinter as tk
from PIL import Image, ImageTk
from timeit import default_timer as timer
root = tk.Tk()
w = 500
h = 300
buf = np.zeros((w,h,4), dtype=np.uint8)
imgbuf = Image.frombuffer('RGBX', (w,h), buf, 'raw', 'RGBX', 0, 1)
img = ImageTk.PhotoImage(image=imgbuf)
canvas = tk.Canvas(root,width=w,height=h)
canvas.pack()
canvas_img = canvas.create_image(0,0, anchor="nw", image=img)
frames_displayed = 0
while True:
# code to update the image buffer. (Here we only update one pixel, so we're
# testing the rendering time, not the time taken to compute the next image)
buf[np.random.randint(w),np.random.randint(h),:] = np.ones(4)*255
imgbuf = Image.frombuffer('RGBX', (w,h), buf, 'raw', 'RGBX', 0, 1)
img = ImageTk.PhotoImage(image=imgbuf)
canvas.itemconfig(canvas_img, image=img)
root.update_idletasks()
root.update()
if frames_displayed==0:
init_time = timer()
frames_displayed+=1
if frames_displayed%100==0:
print("average frame rate:", frames_displayed/(timer()-init_time), "fps")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment