Graphics¶
PsyNet contains sophisticated functionality for constructing and displaying animated graphics to the participant. These graphics can be used to generate engaging instruction pages, but they can also be used to construct highly visual experiment trials.
Under the hood, PsyNet uses the Javascript library Raphaël for displaying graphics. You typically won’t have to learn much about this library. However, PsyNet does expose certain aspects of this library to the user, for example when adding customized object attributes. In these cases, we refer you to the Raphaël documentation for details about the available options.
Quick introduction¶
There are several ways of introducing a graphic into a PsyNet timeline.
Here we will focus on the simplest of these, the GraphicPage
.
However, what you learn here will generalize naturally to the modular page
versions of the GraphicPage
, namely the
GraphicPrompt
and the
GraphicControl
.
A GraphicPage
presents a single graphic canvas to
the participant, which the participant can either watch passively or respond
to by clicking on the canvas.
Each graphic is defined by a collection of Frame
objects.
These frames are shown in sequence to the participant.
Each frame contains a number of GraphicObject
instances
which are drawn simultaneously and shown to the participant.
For example, we might write something like this:
from psynet.graphics import (
GraphicPage,
Frame,
Text
)
page = GraphicPage(
"my_graphic_page",
time_estimate=3,
dimensions=[100, 100],
auto_advance_after=3,
frames=[
Frame([
Text("number", "3", x=50, y=50)
], duration=1),
Frame([
Text("number", "2", x=50, y=50)
], duration=1),
Frame([
Text("number", "1", x=50, y=50)
], duration=1)
]
)
Here we have three frames. Each frame contains a text object, drawing a number.
These numbers are drawn in the centre of the canvas (the x
and y
locations
are expressed relative to the dimensions
argument).
Each frame lasts 1 second, then once the final frame finishes, the page
automatically advances to the next page.
Alternatively, we might design a page such that the participant responds by clicking. Here is an example:
from psynet.graphics import (
GraphicPage,
Frame,
Text
)
page = GraphicPage(
"my_graphic_page",
time_estimate=3,
dimensions=[200, 200],
frames=[
Frame([
Text("question", "Choose a number", x=100, y=100)
], duration=1),
Frame([
Text("n1", "1", x=50, y=100, click_to_answer=True),
Text("n2", "2", x=100, y=100, click_to_answer=True),
Text("n3", "3", x=150, y=100, click_to_answer=True)
])
]
)
If click_to_answer=True
, this means that the participant can respond
by clicking on the object. In this case the page returns a dict containing
two variables: clicked_object
, corresponding to the object ID of the
clicked object, and click_coordinates
, corresponding to the exact location
of the mouse click.
Often we want to customize the objects that we display to the user. A large amount of customization can be achieved by passing attributes to the objects. For example, the following code adds colors to the text displayed to the participant:
from psynet.graphics import (
GraphicPage,
Frame,
Text
)
page = GraphicPage(
"my_graphic_page",
time_estimate=3,
dimensions=[100, 100],
auto_advance_after=3,
frames=[
Frame([
Text("number", "3", x=50, y=50, attributes={"fill": "blue"})
], duration=1),
Frame([
Text("number", "2", x=50, y=50, attributes={"fill": "green"})
], duration=1),
Frame([
Text("number", "1", x=50, y=50, attributes={"fill": "red"})
], duration=1)
]
)
See https://dmitrybaranovskiy.github.io/raphael/reference.html#Element.attr and https://www.w3.org/TR/SVG/ for details about valid attributes.
PsyNet also makes it easy to add animations to these objects. An animation works by setting the object’s initial attributes, then setting the object’s final attributes, then setting the duration of the transition between the two. Complex animations can be constructed by chaining multiple simple animations. See below for an example:
from psynet.graphics import (
GraphicPage,
Frame,
Text,
Image,
Animation
)
page = GraphicPage(
label="animation",
dimensions=[100, 100],
viewport_width=0.5,
time_estimate=5,
auto_advance_after=5,
frames=[
Frame(
[
Image("logo", media_id="logo", x=45, y=25, width=75, loop_animations=True,
animations=[
Animation({"x": 55, "y": 75}, duration=1),
Animation({"width": 100}, duration=1),
Animation({"x": 45, "y": 25, "width": 75}, duration=1),
])
], duration=1
),
],
media=MediaSpec(image=dict(logo="/static/images/logo.svg"))
)
Note that here we also introduced the Image
object. To use an image in a graphic,
you must introduce it as part of the page’s media
argument. That way the image
is loaded once before the graphic is drawn, and can be reused multiple times.
A similar approach is used to play audio as part of the graphic.
You should now have a good high-level perspective on PsyNet’s graphics functionality.
To gain more of an insight into how to use these features, we recommend
that you explore the graphic
demo and its source code,
as well as looking through the low-level documentation below.
Further reading¶
Low-level documentation¶
- class psynet.graphics.Animation(final_attributes, duration, easing='linear')[source]¶
Bases:
object
An
psynet.graphic.Animation
can be added to anpsynet.graphic.Object
to provide motion.- Parameters:
final_attributes (
dict
) – The final set of attributes that the object should attain by the end of the animation. Only animated attributes need to be mentioned. For example, to say that the object should reach an x position of 60 by the end of the animation, we writefinal_attributes={"x": 60}
. See https://dmitrybaranovskiy.github.io/raphael/reference.html#Element.attr and https://www.w3.org/TR/SVG/ for available attributes. Note that the x and y coordinates for circles and ellipses are calledcx
andcy
.duration (
float
) – The time that the animation should take to complete, in seconds.easing (
str
) – Determines the dynamics of the transition between initial and final attributes. Permitted values are"linear"
,"ease-in"
,"ease-out"
,"ease-in-out"
,"back-in"
,"back-out"
,"elastic"
, and"bounce"
.
- class psynet.graphics.Circle(id_, x, y, radius, **kwargs)[source]¶
Bases:
GraphicObject
A circle object.
- Parameters:
id – A unique identifier for the object.
x (
int
) – x coordinate.y (
int
) – y coordinate.radius (
int
) – The circle’s radius.**kwargs – Additional parameters passed to
GraphicObject
.
- class psynet.graphics.Ellipse(id_, x, y, radius_x, radius_y, **kwargs)[source]¶
Bases:
GraphicObject
An ellipse object. Note that for a rotated ellipse you should use the
transform
attribute.- Parameters:
id – A unique identifier for the object.
x (
int
) – x coordinate.y (
int
) – y coordinate.radius_x (
int
) – The ellipse’s x radius.radius_y (
int
) – The ellipses’s y radius.**kwargs – Additional parameters passed to
GraphicObject
.
- class psynet.graphics.Frame(objects, duration=None, audio_id=None, activate_control_response=False, activate_control_submit=False)[source]¶
Bases:
object
A
psynet.graphic.Frame
defines an image to show to the participant.- Parameters:
objects (
List
[GraphicObject
]) – A list ofpsynet.graphic.Object
objects to include in the frame.duration (
Optional
[float
]) – The duration of the frame, in seconds. IfNone
, then the frame lasts forever.audio_id (
Optional
[str
]) – An optional ID for an audio file to play when the frame starts. This audio file must be provided in themedia
slot of the parentpsynet.graphic.GraphicMixin
.activate_control_response (
bool
) – IfTrue
, then activate responses for the page’spsynet.modular_page.Control
object once this frame is reached.activate_control_submit (
bool
) – IfTrue
, then enable response submission for the page’spsynet.modular_page.Control
object once this frame is reached.
- class psynet.graphics.GraphicControl(auto_advance_after=None, **kwargs)[source]¶
Bases:
GraphicMixin
,Control
A graphic control for use in
psynet.modular_page.ModularPage
.- Parameters:
auto_advance_after (float) – If not
None
, a time in seconds after which the page will automatically advance to the next page.**kwargs – Parameters passed to
GraphicMixin
andControl
.
- get_bot_response(experiment, bot, page, prompt)[source]¶
This function is used when a bot simulates a participant responding to a given page. In the simplest form, the function just returns the value of the answer that the bot returns. For more sophisticated treatment, the function can return a
BotResponse
object which contains other parameters such asblobs
andmetadata
.
- class psynet.graphics.GraphicMixin(id_, frames, dimensions, viewport_width=0.6, loop=False, media=None, *args, **kwargs)[source]¶
Bases:
object
A mix-in corresponding to a graphic panel.
- Parameters:
id – An identifier for the graphic, should be parsable as a valid variable name.
frames (
List
[Frame
]) – List ofpsynet.graphic.Frame
objects. These frames will be displayed in sequence to the participant.dimensions (
List
) – A list containing two numbers, corresponding to the x and y dimensions of the graphic. The ratio of these numbers determines the aspect ratio of the graphic. They define the coordinate system according to which objects are plotted. However, the absolute size of the graphic is independent of the size of these numbers (i.e. a 200x200 graphic occupies the same size on the screen as a 100x100 graphic).viewport_width (
float
) – The width of the graphic display, expressed as a fraction of the browser window’s width. The default value (0.6) means that the graphic occupies 60% of the window’s width.loop (
bool
) – Whether the graphic should loop back to the first frame once the last frame has finished.media (
Optional
[MediaSpec
]) – Optionalpsynet.timeline.MediaSpec
object providing audio and image files to be used within the graphic.**kwargs – Additional parameters passed to parent classes.
-
border_color:
str
= '#cfcfcf'¶ CSS border-color property for the graphic panel.
-
border_style:
str
= 'solid'¶ CSS border-style property for the graphic panel.
-
border_width:
str
= '1px'¶ CSS border-width property for the graphic panel.
-
margin:
str
= '25px'¶ CSS margin property for the graphic panel.
- class psynet.graphics.GraphicObject(id_, click_to_answer=False, persist=False, attributes=None, animations=None, loop_animations=False)[source]¶
Bases:
object
An object that is displayed as part of a
psynet.graphic.Frame
.- Parameters:
id – A unique identifier for the object. This should be parsable as a valid variable name.
click_to_answer (
bool
) – Whether clicking on the object constitutes a valid answer, thereby advancing to the next page.persist (
bool
) – Whether the object should persist into successive frames. In this case, the object must not share an ID with any objects in these successive frames.attributes (
Optional
[dict
]) – A collection of attributes to give the object. See https://dmitrybaranovskiy.github.io/raphael/reference.html#Element.attr for valid attributes, and https://www.w3.org/TR/SVG/ for further details. For example, one might write{"fill": "red", "opacity" = 0.5}
.animations (
Optional
[List
]) – A list ofpsynet.graphic.Animation
objects .loop_animations (
bool
) – IfTrue
, then the object’s animations will be looped back to the beginning once they finish.
- class psynet.graphics.GraphicPage(label, *, time_estimate, **kwargs)[source]¶
Bases:
ModularPage
A page that contains a single graphic.
- Parameters:
label – A label for the page.
time_estimate – A time estimate for the page (seconds).
**kwargs – Parameters passed to
GraphicControl
.
- class psynet.graphics.GraphicPrompt(*, prevent_control_response=False, prevent_control_submit=False, **kwargs)[source]¶
Bases:
GraphicMixin
,Prompt
A graphic prompt for use in
psynet.modular_page.ModularPage
.- Parameters:
prevent_control_response (
bool
) – IfTrue
, the response interface in thepsynet.modular_page.Control
object is not activated until explicitly instructed by one of thepsynet.graphic.Frame
objects.prevent_control_submit (
bool
) – IfTrue
, participants are not allowed to submit responses until explicitly instructed by one of thepsynet.graphic.Frame
objects.**kwargs – Parameters passed to
GraphicMixin
andPrompt
.
- class psynet.graphics.Image(id_, media_id, x, y, width, height=None, anchor_x=0.5, anchor_y=0.5, **kwargs)[source]¶
Bases:
GraphicObject
An image object.
- Parameters:
id – A unique identifier for the object.
media_id (
str
) – The ID for the media source, which will be looked up in the graphic’s :class:`psynet.timeline.MediaSpec object.x (
int
) – x coordinate.y (
int
) – y coordinate.width (
int
) – Width of the drawn image.height (
Optional
[int
]) – Height of the drawn image. IfNone
, the height is set automatically with reference towidth
.anchor_x (
float
) – Determines the x-alignment of the image. A value of 0.5 (default) means that the image is center-aligned. This alignment is achieved using thetransform
attribute of the image, bear this in mind when overriding this attribute.anchor_y (
float
) – Determines the y-alignment of the image. A value of 0.5 (default) means that the image is center-aligned. This alignment is achieved using thetransform
attribute of the image, bear this in mind when overriding this attribute.**kwargs – Additional parameters passed to
GraphicObject
.
- class psynet.graphics.Path(id_, path_string, **kwargs)[source]¶
Bases:
GraphicObject
A path object. Paths provide the most flexible way to draw arbitrary vector graphics.
- Parameters:
id – A unique identifier for the object.
path_string (
str
) – The object’s path string. This should be in SVG format, see https://dmitrybaranovskiy.github.io/raphael/reference.html#Paper.path and https://www.w3.org/TR/SVG/paths.html#PathData for information.**kwargs – Additional parameters passed to
GraphicObject
.
- class psynet.graphics.Rectangle(id_, x, y, width, height, corner_radius=0, **kwargs)[source]¶
Bases:
GraphicObject
A rectangle object.
- Parameters:
id – A unique identifier for the object.
x (
int
) – x coordinate.y (
int
) – y coordinate.width (
int
) – Width.height (
int
) – Height.corner_radius (
int
) – Radius of the rounded corners, defaults to zero (no rounding).**kwargs – Additional parameters passed to
GraphicObject
.
- class psynet.graphics.Text(id_, text, x, y, **kwargs)[source]¶
Bases:
GraphicObject
A text object.
- Parameters:
id – A unique identifier for the object.
text (
str
) – Text to display.x (
int
) – x coordinate.y (
int
) – y coordinate.**kwargs – Additional parameters passed to
GraphicObject
.