Understanding the retina screen scaling of stimuli

I am working on a retina screen macbook (1440 x 900). I wanted to draw a stimulus containing a luminance ramp that’s the same size as the window. Code snippet:

from __future__ import division
from psychopy import visual, core, event
import numpy as np

win_x = 800
win_y = 600
win = visual.Window([win_x, win_y], units='pix')

# create a floating point high precision numpy ramp:
xvals = np.linspace(-1, 1, win_x)
yvals = np.ones(win_y)
xv, yv = np.meshgrid(xvals, yvals)

im = visual.ImageStim(win=win,
                      name='ramp',
                      image=xv,
                      # size=(win_x, win_y),
                      size=(1600, 1200),
                      interpolate=False)

im.draw()
win.flip()

event.waitKeys()

win.close()
core.quit()

If size=(win_x, win_y) then the stimulus appears at half the window size; if size=(1600, 1200) then it appears the same size as the opened window.

I get that retina screens are doing a funny double-pixel scaling thing, but why should this have a different effect for the opened window object than for the presented stimulus?

I’m using the current development version of PsychoPy (forked from Github; psychopy.__version__ Out[4]: '1.90.0'
).

As per the API:

http://www.psychopy.org/api/visual/window.html

useRetina : True or False
In PsychoPy >1.85.3 this should always be True as pyglet (or Apple) no longer allows us to create a non-retina display. NB when you use Retina display the initial win size request will be in the larger pixels but subsequent use of units=’pix’ should refer to the tiny Retina pixels. Window.size will give the actual size of the screen in Retina pixels

1 Like

I have the same problem. Stimuli appear twice as small as they should be. Working on Mac OS X (El Capitain), Psychopy 1.85.6. The doRetina is by default always True, so explicitly setting it to true does not help. I am wondering, does this now mean that on Mac OS X we have to multiply all sizes by 2 (also defaults, e.g., font sizes), since this will only occur on Mac OS X, and not on Windows?

Great, thanks Michael. Well that was a “read the docs” fail on my part.

thjor: You can get the new window size after opening the window, then use that for subsequent needs. For example, I’ve modified the script above with the following line:

win_x = 800
win_y = 600
win = visual.Window([win_x, win_y], units='pix')
# get real size in px:
win_x, win_y = win.size

On your retina display,win_x, win_y should be 1600 by 1200, but on other displays it will remain as 800 by 600.

2 Likes

I think units like deg and cm should be converting correctly but do just check!

Hi there, I’m also experiencing problems with the screen scaling, working on a retina screen macbook pro (1440 x 900) using pyglet.

All stimuli are half sized and occupy the left bottom part of the window. Here is a code snipped that demonstrates the problem:

win = visual.Window(size=(400, 400), units='pix')
mytext = visual.TextStim(win=win, text="test")
mytext.draw()
win.flip()

Changing the units or manually increasing the size of the stimulus don’t seem to make a difference. Note that winType=‘pygame’ solves the problem, but I need to use pyglet for other reasons. I’m using psychopy version ‘1.85.3’

Any help would be appreciated!

Please update to a newer version of PsychoPy and this should be fixed

Yes, it worked! Thanks

I’m using PsychoPy 3.1, but this problem still exists.

win = visual.Windows(size=(800,600), …)
print(win.size)

–> results in (1600, 1200)

if I specify “useRetina=False”, I get runtime error.

So, it is a little awkward, because:

win = visual.Windows(size=(1000, 1000), …)
print(win.size)  # array([2000., 2000.])
print(win.winHandle.width, win.winHandle, height)  # array([800., 600.])
s = visual.rect.Rect(win, size=(1000, 1000), pos=(0, 0), fillColor=(0.8, 0.2, 0.7))
s.draw()
win.flip()  # pink rectangle fills entire window
print(s.size)  # array([1000., 1000.])

So, if you wanted to use win.size to calculate the size you should pass to Rect, then you need to be Retina-aware.