Canvas functions
class Canvas
The Canvas
class is used to present visual stimuli. You generally
create a Canvas
object with the Canvas()
factory function, as
described in the section Creating a Canvas.
Example:
# Create and show a canvas with a central fixation dot
my_canvas = Canvas()
my_canvas.fixdot()
my_canvas.show()
Example:
As of OpenSesame 3.2, you can also add Canvas
elements as objects.
See also the section on Naming, accessing, and modifying elements.
# Create a canvas with a fixation dot and a rectangle
my_canvas = Canvas()
my_canvas['my_fixdot'] = FixDot()
my_canvas.show()
- class Canvas
- Things to know
- function Canvas.arrow(sx, sy, ex, ey, body_length=0.8, body_width=0.5, head_width=30, **style_args)
- property Canvas.bottom
- function Canvas.circle(x, y, r, **style_args)
- function Canvas.clear(**style_args)
- function Canvas.copy(canvas)
- function Canvas.elements_at(x, y)
- function Canvas.ellipse(x, y, w, h, **style_args)
- function Canvas.fixdot(x=None, y=None, style=u'default', **style_args)
- function Canvas.gabor(x, y, orient, freq, env=u'gaussian', size=96, stdev=12, phase=0, col1=u'white', col2=u'black', bgmode=u'avg')
- property Canvas.height
- function Canvas.image(fname, center=True, x=None, y=None, scale=None, rotation=None)
- property Canvas.left
- function Canvas.line(sx, sy, ex, ey, **style_args)
- function Canvas.lower_to_bottom(element)
- function Canvas.noise_patch(x, y, env=u'gaussian', size=96, stdev=12, col1=u'white', col2=u'black', bgmode=u'avg')
- function Canvas.polygon(vertices, **style_args)
- function Canvas.raise_to_top(element)
- function Canvas.rect(x, y, w, h, **style_args)
- property Canvas.right
- function Canvas.show()
- property Canvas.size
- function Canvas.text(text, center=True, x=None, y=None, max_width=None, **style_args)
- function Canvas.text_size(text, center=True, max_width=None, **style_args)
- property Canvas.top
- property Canvas.width
Things to know
Creating a Canvas
You generally create a Canvas
with the Canvas()
factory function:
my_canvas = Canvas()
Optionally, you can pass Style keywords to Canvas()
to set the default style:
my_canvas = Canvas(color='green')
my_canvas.fixdot() # Will be green
Style keywords
All functions that accept **style_args
take the following keyword
arguments:
color
specifies the foreground color. For valid color specifications, see colors.background_color
specifies the background color. For valid color specifications, see colors.fill
indicates whether rectangles, circles, polygons, and ellipses are filled (True
), or drawn as an outline (False
).penwidth
indicates a penwidth in pixels and should beint
orfloat
.html
indicates whether HTML-tags are interpreted, and should beTrue
orFalse
. For supported tags, see /usage/text/.font_family
is the name of a font family, such as 'sans'.font_size
is a font size in pixels.font_italic
indicates whether text should italics, and should beTrue
orFalse
.font_bold
indicates whether text should bold, and should beTrue
orFalse
.font_underline
indicates whether text should underlined, and should beTrue
orFalse
.
# Draw a green fixation dot
my_canvas = Canvas()
my_canvas.fixdot(color='green')
my_canvas.show()
Style keywords only affect the current drawing operation (except when
passed to Canvas()
while creating the Canvas
). To change the style
for all subsequent drawing operations, set style properties, such as
canvas.color
, directly:
# Draw a red cross with a 2px penwidth
my_canvas = Canvas()
my_canvas.color = u'red'
my_canvas.penwidth = 2
my_canvas.line(-10, -10, 10, 10)
my_canvas.line(-10, 10, 10, -10)
my_canvas.show()
Or pass the style properties to Canvas()
:
# Draw a red cross with a 2px penwidth
my_canvas = Canvas(color=u'red', penwidth=2)
my_canvas.line(-10, -10, 10, 10)
my_canvas.line(-10, 10, 10, -10)
my_canvas.show()
Colors
You can specify colors in the following ways. This includes CSS3-type color specifications, but also supports some extra specifications, such as CIE l* a* b* color space.
Version note: The hsv
, hsl
, and lab
color spaces are new in
v3.3.0.
- Color names: 'red', 'black', etc. A full list of valid color names can be found here.
- Seven-character hexadecimal strings:
#FF0000
,#000000
, etc. Here, values range from00
toFF
, so that#FF0000
is bright red. - Four-character hexadecimal strings:
#F00
,#000
, etc. Here, values range from '0' to 'F' so that#F00
is bright red. - RGB strings:
rgb(255,0,0)
,rgb(0,0,0)
, etc. Here, values range from 0 to 255 so thatrgb(255,0,0)
is bright red. - RGB percentage strings:
rgb(100%,0%,0%)
,rgb(0%,0%,0%)
, etc. Here, values range from 0% to 100% so thatrgb(100%,0%,0%)
is bright red. - RGB tuples:
(255, 0, 0)
,(0, 0 ,0)
, etc. Here, values range from0
to255
so that `(255,0,0)' is bright red. - HSV strings:
hsv(120, 100%, 100%)
. In the HSV color space, the hue parameter is an angle from 0 to 359, and the saturation and value parameters are percentages from 0% to 100%. - HSL strings:
hsl(120, 100%, 50%)
. In the HSL color space, the hue parameter is an angle from 0 to 359, and the saturation and lightness parameters are percentages from 0% to 100%. - LAB strings:
lab(53, -20, 0)
. In the CIELAB color space, the parameters reflect lightness (l*
), green-red axis (a*
, negative is green), and blue-yellow axis (b*
, negative is blue). This uses the D65 white point and the sRGB transfer function, as implemented here. - Luminance values:
255
,0
, etc. Here, values range from0
to255
so that255
is white.
# Various ways to specify green
my_canvas.fixdot(color='green') # Dark green
my_canvas.fixdot(color='#00ff00')
my_canvas.fixdot(color='#0f0')
my_canvas.fixdot(color='rgb(0, 255, 0)')
my_canvas.fixdot(color='rgb(0%, 100%, 0%)')
my_canvas.fixdot(color='hsl(100, 100%, 50%)')
my_canvas.fixdot(color='hsv(0, 100%, 100%)')
my_canvas.fixdot(color='lab(53, -20, 0)') # Dark green
my_canvas.fixdot(color=(0, 255, 0))
# Specify a luminance value (white)
my_canvas.fixdot(color=255)
Naming, accessing, and modifying elements
As of OpenSesame 3.2, the Canvas
supports an object-based interface
that allows you to name elements, and to access and modify elements
individually, without having to redraw the entire Canvas
.
For example, the following will first add a red Line
element to a
Canvas
and show it, then change the color of the line to green and
show it again, and then finally delete the line and show the canvas
again (which is now blank). The name of the element (my_line
) is used
to refer to the element for all the operations.
my_canvas = Canvas()
my_canvas['my_line'] = Line(-100, -100, 100, 100, color='red')
my_canvas.show()
clock.sleep(1000)
my_canvas['my_line'].color = 'green'
my_canvas.show()
clock.sleep(1000)
del my_canvas['my_line']
my_canvas.show()
You can also add an element without explicitly providing a name for it.
In that case, a name is generated automatically (e.g. stim0
).
my_canvas = Canvas()
my_canvas += FixDot()
my_canvas.show()
If you add a list of elements, they will be automatically grouped together, and you can refer to the entire group by name.
my_canvas = Canvas()
my_canvas['my_cross'] = [
Line(-100, 0, 100, 0),
Line(0, -100, 0, 100)
]
my_canvas.show()
To check whether a particular x,y
coordinate falls within the bounding
rectangle of an element, you can use in
:
my_mouse = Mouse(visible=True)
my_canvas = Canvas()
my_canvas['rect'] = Rect(-100, -100, 200, 200)
my_canvas.show()
button, (x, y), time = my_mouse.get_click()
if (x, y) in my_canvas['rect']:
print('Clicked in rectangle')
else:
print('Clicked outside of rectangle')
You can also get a list of the names of all elements that contain an
x,y
coordinate, using the Canvas.elements_at()
function, documented
below.
function Canvas.arrow(sx, sy, ex, ey, body_length=0.8, body_width=0.5, head_width=30, **style_args)
Draws an arrow. An arrow is a polygon consisting of 7 vertices, with an arrowhead pointing at (ex, ey).
Arguments:
sx
-- The X coordinate of the arrow's base.- Type: int
sy
-- The Y coordinate of the arrow's base.- Type: int
ex
-- The X coordinate of the arrow's tip.- Type: int
ey
-- The Y coordinate of the arrow's tip..- Type: int
Keywords:
body_length
-- Proportional length of the arrow body relative to the full arrow [0-1].- Type: float
- Default: 0.8
body_width
-- Proportional width (thickness) of the arrow body relative to the full arrow [0-1].- Type: float
- Default: 0.5
head_width
-- Width (thickness) of the arrow head in pixels.- Type: float
- Default: 30
Keyword dict:
**style_args
: No description.
property Canvas.bottom
The y coordinate of the bottom edge of the display. This is a read-only property.
function Canvas.circle(x, y, r, **style_args)
Draws a circle.
Example:
my_canvas = Canvas()
# Function interface
my_canvas.circle(100, 100, 50, fill=True, color='red')
# Element interface
my_canvas['my_circle'] = Circle(100, 100, 50, fill=True, color='red')
Arguments:
x
-- The center X coordinate of the circle.- Type: int
y
-- The center Y coordinate of the circle.- Type: int
r
-- The radius of the circle.- Type: int
Keyword dict:
**style_args
: Optional style keywords that specify the style of the current drawing operation. This does not affect subsequent drawing operations.
function Canvas.clear(**style_args)
Clears the canvas with the current background color. Note that it is generally faster to use a different canvas for each experimental display than to use a single canvas and repeatedly clear and redraw it.
Example:
my_canvas = Canvas()
my_canvas.fixdot(color='green')
my_canvas.show()
clock.sleep(1000)
my_canvas.clear()
my_canvas.fixdot(color='red')
my_canvas.show()
Keyword dict:
**style_args
: Optional style keywords that specify the style of the current drawing operation. This does not affect subsequent drawing operations.
function Canvas.copy(canvas)
Turns the current Canvas
into a copy of the passed Canvas
.
Warning:
Copying Canvas
objects can result in unpredictable behavior. In
many cases, a better solution is to recreate multiple Canvas
objects from scratch, and/ or to use the element interface to
update Canvas
elements individually.
Example:
my_canvas = Canvas()
my_canvas.fixdot(x=100, color='green')
my_copied_canvas = Canvas()
my_copied_canvas.copy(my_canvas)
my_copied_canvas.fixdot(x=200, color="blue")
my_copied_canvas.show()
Arguments:
canvas
-- TheCanvas
to copy.- Type: canvas
function Canvas.elements_at(x, y)
New in v3.2.0
Gets the names of elements that contain a particular x, y
coordinate.
Example:
# Create and show a canvas with two partly overlapping rectangles
my_canvas = Canvas()
my_canvas['right_rect'] = Rect(x=-200, y=-100, w=200, h=200, color='red')
my_canvas['left_rect'] = Rect(x=-100, y=-100, w=200, h=200, color='green')
my_canvas.show()
# Collect a mouse click and print the names of the elements that
# contain the clicked point
my_mouse = Mouse(visible=True)
button, pos, time = my_mouse.get_click()
if pos is not None:
x, y = pos
print('Clicked on elements: %s' % my_canvas.elements_at(x, y))
Arguments:
x
-- An X coordinate.- Type: int, float
y
-- A Y coordinate.- Type: int, float
Returns:
A list
of element names that contain the coordinate x, y
.
- Type: list
function Canvas.ellipse(x, y, w, h, **style_args)
Draws an ellipse.
Example:
my_canvas = Canvas()
# Function interface
my_canvas.ellipse(-10, -10, 20, 20, fill=True)
# Element interface
my_canvas['my_ellipse'] = Ellipse(-10, -10, 20, 20, fill=True)
Arguments:
x
-- The left X coordinate.- Type: int
y
-- The top Y coordinate.- Type: int
w
-- The width.- Type: int
h
-- The height.- Type: int
Keyword dict:
**style_args
: Optional style keywords that specify the style of the current drawing operation. This does not affect subsequent drawing operations.
function Canvas.fixdot(x=None, y=None, style=u'default', **style_args)
Draws a fixation dot. The default style is medium-open.
- 'large-filled' is a filled circle with a 16px radius.
- 'medium-filled' is a filled circle with an 8px radius.
- 'small-filled' is a filled circle with a 4px radius.
- 'large-open' is a filled circle with a 16px radius and a 2px hole.
- 'medium-open' is a filled circle with an 8px radius and a 2px hole.
- 'small-open' is a filled circle with a 4px radius and a 2px hole.
- 'large-cross' is 16px cross.
- 'medium-cross' is an 8px cross.
- 'small-cross' is a 4px cross.
Example:
my_canvas = Canvas()
# Function interface
my_canvas.fixdot()
# Element interface
my_canvas['my_fixdot'] = FixDot()
Keywords:
x
-- The X coordinate of the dot center, or None to draw a horizontally centered dot.- Type: int, NoneType
- Default: None
y
-- The Y coordinate of the dot center, or None to draw a vertically centered dot.- Type: int, NoneType
- Default: None
style
-- The fixation-dot style. One of: default, large-filled, medium-filled, small-filled, large-open, medium-open, small-open, large-cross, medium-cross, or small-cross. default equals medium-open.- Type: str, unicode
- Default: 'default'
Keyword dict:
**style_args
: Optional style keywords that specify the style of the current drawing operation. This does not affect subsequent drawing operations.
function Canvas.gabor(x, y, orient, freq, env=u'gaussian', size=96, stdev=12, phase=0, col1=u'white', col2=u'black', bgmode=u'avg')
Draws a Gabor patch. Note: The exact rendering of the Gabor patch depends on the back-end.
Example:
my_canvas = Canvas()
# Function interface
my_canvas.gabor(100, 100, 45, .05)
# Element interface
my_canvas['my_gabor'] = Gabor(100, 100, 45, .05)
Arguments:
x
-- The center X coordinate.- Type: int
y
-- The center Y coordinate.- Type: int
orient
-- Orientation in degrees [0 .. 360]. This refers to a clockwise rotation from a vertical.
Version note: In version 3.2.6 and earlier, the
orientation was counterclockwise for the legacy and
xpyriment backends, and clockwise for the psycho
backends. As of 3.2.7, the orientation is clockwise
for all backends.
- Type: float, int
- freq
-- Frequency in cycles/px of the sinusoid.
- Type: float, int
Keywords:
env
-- The envelope that determines the shape of the patch. Can be "gaussian", "linear", "circular", or "rectangular".- Type: str, unicode
- Default: 'gaussian'
size
-- A size in pixels.- Type: float, int
- Default: 96
stdev
-- Standard deviation in pixels of the gaussian. Only applicable to gaussian envelopes.- Type: float, int
- Default: 12
phase
-- Phase of the sinusoid [0.0 .. 1.0].- Type: float, int
- Default: 0
col1
-- A color for the peaks.- Type: str, unicode
- Default: 'white'
col2
-- A color for the troughs. Note: The psycho back-end ignores this parameter and always uses the inverse ofcol1
for the throughs.- Type: str, unicode
- Default: 'black'
bgmode
-- Specifies whether the background is the average of col1 col2 ('avg', corresponding to a typical Gabor patch), or equal to col2 ('col2'), useful for blending into the background. Note: this parameter is ignored by the psycho backend, which uses increasing transparency for the background.- Type: str, unicode
- Default: 'avg'
property Canvas.height
The height of the canvas. This is a read-only property.
function Canvas.image(fname, center=True, x=None, y=None, scale=None, rotation=None)
Draws an image from file. This function does not look in the file pool, but takes an absolute path.
Example:
my_canvas = Canvas()
# Determine the absolute path:
path = exp.pool[u'image_in_pool.png']
# Function interface
my_canvas.image(path)
# Element interface
my_canvas['my_image'] = Image(path)
Arguments:
fname
-- The filename of the image. When using Python 2, this should be eitherunicode
or a utf-8-encodedstr
. When using Python 3, this should be eitherstr
or a utf-8-encodedbytes
.- Type: str, unicode
Keywords:
center
-- A bool indicating whether coordinates indicate the center (True) or top-left (False).- Type: bool
- Default: True
x
-- The X coordinate, orNone
to draw a horizontally centered image.- Type: int, NoneType
- Default: None
y
-- The Y coordinate, orNone
to draw a vertically centered image.- Type: int, NoneType
- Default: None
scale
-- The scaling factor of the image.None
or 1 indicate the original size. 2.0 indicates a 200% zoom, etc.- Type: float, int, NoneType
- Default: None
rotation
-- The rotation of the imageNone
or 0 indicate the original rotation. Positive values indicate a clockwise rotation in degrees.- Type: float, int, NoneType
- Default: None
property Canvas.left
The x coordinate of the left edge of the display. This is a read-only property.
function Canvas.line(sx, sy, ex, ey, **style_args)
Draws a line.
Arguments:
sx
-- The left X coordinate.- Type: int
sy
-- The top Y coordinate.- Type: int
ex
-- The right X coordinate.- Type: int
ey
-- The bottom Y coordinate.- Type: int
Keyword dict:
**style_args
: Optional style keywords that specify the style of the current drawing operation. This does not affect subsequent drawing operations.
function Canvas.lower_to_bottom(element)
Lowers an element to the bottom, so that it is drawn first; that is, it becomes the background.
Arguments:
element
-- A sketchpad element, or its name.- Type: Element, str
function Canvas.noise_patch(x, y, env=u'gaussian', size=96, stdev=12, col1=u'white', col2=u'black', bgmode=u'avg')
Draws a patch of noise, with an envelope. The exact rendering of the noise patch depends on the back-end.
Example:
my_canvas = Canvas()
# Function interface
my_canvas.noise_patch(100, 100, env='circular')
# Element interface
my_canvas['my_noise_patch'] = NoisePatch(100, 100, env='circular')
Arguments:
x
-- The center X coordinate.- Type: int
y
-- The center Y coordinate.- Type: int
Keywords:
env
-- The envelope that determines the shape of the patch. Can be "gaussian", "linear", "circular", or "rectangular".- Type: str, unicode
- Default: 'gaussian'
size
-- A size in pixels.- Type: float, int
- Default: 96
stdev
-- Standard deviation in pixels of the gaussian. Only applicable to gaussian envelopes.- Type: float, int
- Default: 12
col1
-- The first color.- Type: str, unicode
- Default: 'white'
col2
-- The second color. Note: The psycho back-end ignores this parameter and always uses the inverse ofcol1
.- Type: str, unicode
- Default: 'black'
bgmode
-- Specifies whether the background is the average of col1 col2 ('avg', corresponding to a typical Gabor patch), or equal to col2 ('col2'), useful for blending into the background. Note: this parameter is ignored by the psycho backend, which uses increasing transparency for the background.- Type: str, unicode
- Default: 'avg'
function Canvas.polygon(vertices, **style_args)
Draws a polygon that defined by a list of vertices. I.e. a shape of points connected by lines.
Example:
my_canvas = Canvas()
n1 = 0,0
n2 = 100, 100
n3 = 0, 100
# Function interface
my_canvas.polygon([n1, n2, n3])
# Element interface
my_canvas['my_polygon'] = Polygon([n1, n2, n3])
Arguments:
vertices
-- A list of tuples, where each tuple corresponds to a vertex. For example, [(100,100), (200,100), (100,200)] will draw a triangle.- Type: list
Keyword dict:
**style_args
: Optional style keywords that specify the style of the current drawing operation. This does not affect subsequent drawing operations.
function Canvas.raise_to_top(element)
Raises an element to the top, so that it is drawn last; that is, it becomes the foreground.
Arguments:
element
-- A sketchpad element, or its name.- Type: Element, str
function Canvas.rect(x, y, w, h, **style_args)
Draws a rectangle.
Example:
my_canvas = Canvas()
# Function interface
my_canvas.rect(-10, -10, 20, 20, fill=True)
# Element interface
my_canvas['my_rect'] = Rect(-10, -10, 20, 20, fill=True)
Arguments:
x
-- The left X coordinate.- Type: int
y
-- The top Y coordinate.- Type: int
w
-- The width.- Type: int
h
-- The height.- Type: int
Keyword dict:
**style_args
: Optional style keywords that specify the style of the current drawing operation. This does not affect subsequent drawing operations.
property Canvas.right
The x coordinate of the right edge of the display. This is a read-only property.
function Canvas.show()
Shows, or 'flips', the canvas on the screen.
Example:
my_canvas = Canvas()
my_canvas.fixdot()
t = my_canvas.show()
exp.set('time_fixdot', t)
Returns:
A timestamp of the time at which the canvas actually appeared on the screen, or a best guess if precise temporal information is not available. For more information about timing, see . Depending on the back-end the timestamp is an int
or a float
.
- Type: int, float
property Canvas.size
The size of the canvas as a (width, height)
tuple. This is a read-only property.
function Canvas.text(text, center=True, x=None, y=None, max_width=None, **style_args)
Draws text.
Example:
my_canvas = Canvas()
# Function interface
my_canvas.text('Some text with <b>boldface</b> and <i>italics</i>')
# Element interface
my_canvas['my_text'] = Text('Some text with <b>boldface</b> and <i>italics</i>')
Arguments:
text
-- A string of text. When using Python 2, this should be eitherunicode
or a utf-8-encodedstr
. When using Python 3, this should be eitherstr
or a utf-8-encodedbytes
.- Type: str, unicode
Keywords:
center
-- A bool indicating whether the coordinates reflect the center (True
) or top-left (False
) of the text.- Type: bool
- Default: True
x
-- The X coordinate, or None to draw horizontally centered text.- Type: int, NoneType
- Default: None
y
-- The Y coordinate, or None to draw vertically centered text.- Type: int, NoneType
- Default: None
max_width
-- The maximum width of the text in pixels, before wrapping to a new line, orNone
to wrap at screen edge.- Type: int, NoneType
- Default: None
Keyword dict:
**style_args
: Optional style keywords that specify the style of the current drawing operation. This does not affect subsequent drawing operations.
function Canvas.text_size(text, center=True, max_width=None, **style_args)
Determines the size of a text string in pixels.
Example:
my_canvas = Canvas()
w, h = my_canvas.text_size('Some text')
Arguments:
text
-- A string of text.- Type: str, unicode
Keywords:
center
-- A bool indicating whether the coordinates reflect the center (True
) or top-left (False
) of the text.- Type: bool
- Default: True
max_width
-- The maximum width of the text in pixels, before wrapping to a new line, orNone
to wrap at screen edge.- Type: int, NoneType
- Default: None
Keyword dict:
**style_args
: Optional style keywords that specify the style of the current drawing operation. This does not affect subsequent drawing operations.
Returns:
A (width, height) tuple containing the dimensions of the text string.
- Type: tuple
property Canvas.top
The y coordinate of the top edge of the display. This is a read-only property.
property Canvas.width
The width of the canvas. This is a read-only property.