Changes

Jump to navigation Jump to search
2,255 bytes added ,  12:48, 17 March 2016
example using PsychoPy to display matplotlib images without writing to file
Matplotlib does not have a (documented) way of exporting an image other than writing to file or screen.
PsychoPy does not have a documented way of importing images other than reading from file. The following
example shows how to use the undocumented features in both libraries.

A matplotlib graph is made, written to file and shown in a PsychoPy ImageStim. Then the graph is updated
and send directly to the ImageStim object to replace the old image. On the labcomputer this runs smoothly
at 60Hz.

<syntaxhighlight lang="python" line="1" >
#!/usr/bin/python
from __future__ import print_function
from psychopy import visual, event
import pyglet.gl as GL
import numpy as np
import matplotlib.pyplot as plt # default backend TkAgg is ok
import math
import sys, time
#for optimalization: http://bastibe.de/2013-05-30-speeding-up-matplotlib.html

# make initial image
t = np.linspace(0, 4*np.pi, 1000) # horizontal axis
fig, ax = plt.subplots() # create new figure
fig.set_size_inches([8,6]) # yuck
line, = ax.plot(t, np.sin(t)) # initial plot
fig.savefig('img.png', dpi=80) # must be set to 80, this is what tostring_rgb does also
ncols, nrows = fig.canvas.get_width_height()

# put it in an ImageStim
win = visual.Window(monitor='testMonitor')
img = visual.ImageStim(win, 'img.png', units='pix', interpolate=False, flipVert=True)

# change it
x = t0 = t1 = 0
while not event.getKeys():
ax.draw_artist(ax.patch) # faster than redrawing the canvas
ax.draw_artist(line) # faster than redrawing the canvas
buf = fig.canvas.tostring_rgb() # make a bitmap
# convert bitmap to correct format for GL texture
tex = np.fromstring(buf, dtype=np.uint8).reshape(nrows, ncols, 3).astype(np.float32)/255
img._createTexture(tex, img._texID, GL.GL_RGB, img, forcePOW2=False) # set texture in video mem
img.draw()
t1 = win.flip() # mark time on screen
print("{:.3f} s/frame".format(t1-t0), end='\r') # show frame time
sys.stdout.flush() # write text immediately
t0 = t1 # prepare for next iteration
x += 0.01 # change graph
line.set_ydata(np.sin(2*t+x)) # change graph, faster than ax.clear, ax.plot

</syntaxhighlight>

Navigation menu