psychopy.org | Reference | Downloads | Github

Setting a variable image position

Hello,

I built an experiment in which different pictures have different positions is Psychopy 1.84.2.
I updated to 1.85 so I can post my experiment online. Problem is it stopped recognizing the position coordinates in my excel file.
I tried different combinations (ie: 0.5 instead of (0.5, 0.5), and (-0.5) instead of (0.5, -0.5), I tried (0.5,0.5) instead of (0.5, 0.5), I tried seperating the number as in a column by coordinate so I inserted in the builder ($PX,$PY) )… None worked
I tried converting it into CSV, didn’t work either.
Here’s the error message I get

Any help would be much appreciated.

I’m using builder, OS: windows 7.

Cordially,
Joseph

So the exact same experiment worked before and now it doesn’t in the new version? One thing I might try is deleting any .pyc files that are in the experiment folder.

Other than that we would need more information. Is this in the builder? Show a screenshot or include the code where the positions are set, that would be a start.

Hi Daniel,

Thanks for your answer.
Indeed, it worked and still works in 1.84.2, but not in 1.85.0. Given that I want it online, the package psychojs doesn’t exist in 1.84.2 as far as I know (tried it…) unless there’s a way to import it.
You’ll find attached a screenshot of my excel sheet, a screenshot of the builder & the image’s position as defined in the builder.
For instance for the image TLV1Essai, it recognises the image and displays it correctly according to the image defined in my excel sheet. Given that the position is constant it is able to place it correctly.
However, for the IndiceV text and the other images that have placements defined in the excel sheet, it doesn’t recognize the position. So the program crashes when the positions change at every frame (starting from the 2nd routine of my first loop)
The code component that shows in the builder is for the mouse command & trial counts.
I forgot to mention that I also made copies and loaded the program on different computers with different OS to see if it works (Ubuntu, Windows 7, MacOS Sierra 10.12)
EDIT: Deleting .pyc files didn’t change a thing.
Thanks in advance.

Cordially,
Joseph

I’m not aware of anything changing on this lately. I would do it as $(PX, PY) and set PX, PY as separate columns in your conditions file. If that doesn’t work could you let us know the error message you get for it?

For using 1.85 and online experiments, please be warned that this is in very early stages of development. We’re making it available for people to play with but it REALLY is only meant as a proof of principle. Don’t use it for anything serious right now.

Hi All,
I have the exact same problem as Joseph. Same error message, still works on 1.84.2, but not 1.85. I’d love to hear if someone figures this out.
Thanks,
Dave

Hi Again,
The first time I tried Jon’s suggestion it didn’t work, but I just tried again (I must have done something different, but I don’t know what it was) and it works! So in the image properties > position field I have $(px, py) and in my Excel file I have columns labels px and py.
Thank you Jon, much appreciated.
Dave

Hi all,

I’m trying to do something similar to @JosephA: adding a variable in the image position, but instead of having a single value as a variable (e.g. [0.5, 0.5]), I’d like to have a string of values for x (e.g. [0.5, 0.4, 0.3, 0.2…]) that get updated on every frame, so that the image moves from 0.5 to 0.4 to 0.3 in each frame. So basically, I’d like my image to move from left to right (only x values) at a given speed (which will be determined by the x values). I don’t know if this is possible to do with the Builder, or do I need to add something to the code component (a loop for ex.?)

Thanks!

You need to evaluate the variable to turn it into a list object, and then extract items from within it. e.g. something like this in your position field (assuming a constant y value of 0):

[eval(your_x_variable).pop(), 0]

But a more general solution is to use a mathematical expression incorporating Builder’s variable t, representing the time in seconds since the routine started. e.g. if your window units are pixels, then this would move your stimulus around the perimeter of a circle of radius 50 pixels:

[cos(t) * 50, sin(t) * 50]

Use whatever expression suits your desired motion, and avoid the clunky specification of individual points in your conditions file (making it much easier to change the motion, or you can use your conditions file to specify parameters, like velocity, that change from trial to trial). In your case:

[start_position + t * some_velocity_multiplier, 0]

Hi @Michael. Thanks a lot! This is definitely very helpful, in particular the possibility of evaluating the variable to turn it into a list object, and then extract the items of the list (the first solution you suggested). This is precisely what I need. However, when I run the code in my experiment I keep getting the following error:

polygon.setPos([eval(px).pop(), 0], log=False)
TypeError: eval() arg 1 must be a string, bytes or code object

px corresponds to the name of the Excel column with the different x locations (e.g. [-0.5], [-0.4]).
Any idea of how to deal with this error?

Insert a code component (from the “custom” component panel) and make sure it goes above your polygon component so it gets executed before the error occurs. In the “begin routine” tab, put this:

print(px)
print(type(x))

and look for the output window after the experiment runs to help us debug what is happening.

Hi @Michael. This is what I get:

[-0.5]
<class 'list'>

I added " " to each value in the Excel file, and this is what I see now:

"[-0.5]"
<class 'str'>

However, even when doing this (turning the list into string) I get an error:

value = numpy.array(value, float)
ValueError: could not convert string to float: '[-0.5]'

OK, there are a few things going on here.

  • if px is of type list, then it doesn’t need to be evaluated (i.e. coerced from a string to a Python expression - it is already a Python object of the sort you want). So you could just drop the eval() in that case, and things should just work. Perhaps vela() has already been applied to it earlier on?
  • in the second case, px is a string, so then it does need to be evaluated, as somewhere along the line a function is trying to use it as a numeric (floating point) value. There are a couple of things going on there - wherever that error is occurring, the function expects a number and is probably trying itself to force a non-numeric string into a number, but gets thrown because the string contains brackets and so on. I’m not sure where this error is coming from in your code, and why is isn’t tripped earlier on, when presumably the list would have had more than just one entry (-0.5), or how entries could have been removed from it if is a string representation of a list rather than an actual list.
1 Like

Hi @Michael. Thanks again for taking your time to answer my questions.
Now that I know that px is a list, and therefore doesn’t need to be evaluated with eval(), I tried two things:

  • Setting the position of the image with the variable px, next to a 0 as constant y value: [px, 0]. When doing this I get the following error:
value = numpy.array(value, float)
ValueError: setting an array element with a sequence.
  • I edited the Excel file. Now I have two columns: px and py, and changed the position to [px,py]. But again, I get an error:
raise ValueError(msg % (str(length), str(len(value))))
ValueError: Invalid parameter. Should be length 2 but got length 2.

Ok. I finally figured out what the error was. I removed the brackets from each cell in the Excel file, and now it works :grinning: