Drawing with mouse, saving a ShapeStim to file

Hello everybody!

I’m asking for some suggestions on how I might save a ShapeStim to a file. I adapted some code I found on a different post so that participants can use the mouse to draw on the screen by continually updating a ShapeStim, and I would like to save their drawing to a file. I’m thinking a png so I could later open it and see what they drew.

I have plenty of coding experience but not much in manipulating image files, so I’m just wondering if you all had a suggestion for a place to look, or if there were a format or data container that would be a flexible way of storing the data. Can I convert the ShapeStim to an object that can be handed to a different library or something?

Thanks in advance, I’d be happy to post any working solutions here for those who might find this interesting in the future. Hope you’re all doing great.

Dan

Actually now that I’m looking at my code again, they can actually draw several ShapeStims, but I’m having them draw it in a specified area of the screen.

Two solutions:

  • certainly you could take a copy of the window when the shape has been drawn using Window.getMovieFrame() (one or more times) and Window.saveMovieFrames() to save all captured frames since last save
  • but I’d have thought you can do more by extracting the ShapeStim.vertices values and saving those rather than the image they represent. Knowing the vertices seems to provide more analysis options to my mind, but it depends what you need I guess.

Of course, you can do both of the above to be extra safe!

That’s pretty much the plan, I figured saving the vertices will ultimately be more programmatically flexible. But I didn’t know about Window.getMovieFrame() and Window.saveMovieFrames(), so that was the other piece of the puzzle. Thanks Jon! Of course if anyone else has any other thoughts I’d be happy to hear them.

Ticking “solved” is best way to indicate the solution is what you’re looking for :slight_smile:

I think Jon presented the obvious solutions, so make sure to tick “solved” on his answer. If you want a total overkill, you can get the code to create an identical ShapeStim using my_shape.__str__(). For example, if you want to know which units the vertices are represented in, the line color etc. But these are probably stable across participants, hence the overkill.

Thanks, sorry I missed that you can mark things as solved in the new discourse app (which is a great thing, btw). I think I’ve marked Jon’s answer as the accepted solution. Hopefully it’s not a problem if I post a minimal working example with some code after marking this as solved.

Not a problem at all. To the contrary: encouraged and much appreciated!

Here’s an example of what I ended up doing. In this example, the user can draw an arbitrary number of lines to the screen. These drawings are saved as png files, and they are also pickled (saved to file as binary python objects). A “drawing” here is a list of ShapeStims.

Note that since the “win” property on the ShapeStim can’t be pickled, “win” is set to None before saving, and when it’s read back in it is given a reference to a window object again. I don’t know if that little hack will work for all other stims, I’ve only done it with ShapeStim so far.

Also, be warned that this example does nothing with management of reaction times or basic experiment housekeeping.

Lastly, the drawWithMouse method was adapted from code posted to the psychopy-users group by Gary Strangman here, which was improved by Jeremy Gray (@jeremygray) . Many thanks to them!

I hope someone finds this useful! Talk to you all later, thanks again!

Dan

drawAndSaveExample.py (7.4 KB)

1 Like

One more note for those who might not know, is that this example uses the default relative window units, so if you were to unpickle the objects, the window will have to have the same dimensions as the one that the user drew on, or its shape could be distorted.

Hey! I’m creating an experiment right now that involves a similar response to yours: the participants must use a mouse to draw a few lines over a period of time. I’m relatively new to PsychoPy and Python, would you be able to let me know where you found the code mentioned? I pretty much have no idea how to put this together.

Thanks!