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 an psynet.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 write final_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 called cx and cy.

  • 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 of psynet.graphic.Object objects to include in the frame.

  • duration (Optional[float]) – The duration of the frame, in seconds. If None, 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 the media slot of the parent psynet.graphic.GraphicMixin.

  • activate_control_response (bool) – If True, then activate responses for the page’s psynet.modular_page.Control object once this frame is reached.

  • activate_control_submit (bool) – If True, then enable response submission for the page’s psynet.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 and Control.

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 as blobs and metadata.

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 of psynet.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]) – Optional psynet.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 of psynet.graphic.Animation objects .

  • loop_animations (bool) – If True, 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) – If True, the response interface in the psynet.modular_page.Control object is not activated until explicitly instructed by one of the psynet.graphic.Frame objects.

  • prevent_control_submit (bool) – If True, participants are not allowed to submit responses until explicitly instructed by one of the psynet.graphic.Frame objects.

  • **kwargs – Parameters passed to GraphicMixin and Prompt.

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. If None, the height is set automatically with reference to width.

  • 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 the transform 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 the transform 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:
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.