Module eyekit.vis

Defines the Image, Figure, and Booklet objects, which are used to create visualizations.

Functions

def set_default_font(font_face: str = None, font_size: Union[int, float] = None)

Set the default font face and/or size that will be used in figure captions and image annotations. This selection can be overridden on a per-image, per-figure, or per-annotation basis. If no font is set, Eyekit defaults to 8pt Arial.

Classes

class Image (screen_width: int, screen_height: int)

The Image class is used to create visualizations of text blocks and fixation sequences, and it provides methods for drawing various kinds of annotation. The general usage pattern is:

img = eyekit.vis.Image(1920, 1080)
img.draw_text_block(txt)
img.draw_fixation_sequence(seq)
img.save('image.pdf')

Initialized with:

  • screen_width Width of the screen in pixels.
  • screen_height Height of the screen in pixels.

Methods

def set_caption(self, caption: str, *, font_face: str = None, font_size: Union[int, float] = None)

Set the image's caption, which will be shown above the image if you place it inside a Figure. If no font is set, the default font will be used (see set_default_font()).

def set_background_color(self, color: Union[str, tuple])

Set the background color of the image. By default the background color is white. If color is set to None, the background will be transparent.

def set_background_image(self, file_path)

Set a background image. The background image must be a PNG file that matches the dimensions of the Image object. Note also that the resulting Image object must be saved as a PNG (a background image cannot be combined with vector output).

def set_crop_area(self, rect)

Crop the final image to a particular rectangular area of the screen. rect should be a tuple of the form (x, y, width, height) specifying the crop area (in screen coordinates) or a Box-like object, such as a TextBlock or InterestArea. If no crop area is set, then it defaults to the maximum extents of all TextBlocks drawn to the Image.

def draw_text_block(self, text_block, *, color: Union[str, tuple] = None, mask_text: bool = False)

Draw a TextBlock on the image. color defaults to black if unspecified. If mask_text is set to True, the text will be displayed as a series of rectangles, which is useful if you want to deemphasize the linguistic content.

def draw_fixation_sequence(self, fixation_sequence, *, show_saccades: bool = True, show_discards: bool = False, color: Union[str, tuple, ] = 'black', discard_color: Union[str, tuple] = 'gray', saccade_color: Union[str, tuple] = None, number_fixations: bool = False, fixation_radius: Union[int, float, ] = None, stroke_width: Union[int, float] = 0.5, opacity: float = 1.0)

Draw a FixationSequence on the image. Optionally, you can choose whether or not to display saccade lines and discarded fixations. color, discard_color, and saccade_color determine the colors of fixations, discarded fixations, and saccade lines respectively. If number_fixations is True, each fixation is superimposed with its index. By default, the radius of each fixation is calculated as sqrt(duration/pi), such that the area of each fixation will correspond to duration. If fixation_radius is set to a number, all fixations will be rendered at a constant size. stroke_width controls the thickness of saccade lines. opacity controls the opacity of fixations. If you want to set the color or fixation_radius of each fixation independently, pass in a function that takes a fixation and returns a color. For example, to color code fixations that have the tag special_fixation you could use a lambda function such as

color = lambda fxn: 'red' if fxn.has_tag('special_fixation') else 'black'

or to base the fixation size on pupil size, you could use:

fixation_radius = lambda fxn: (fxn.pupil_size / 3.14159) ** 0.5
def draw_heatmap(self, text_block, distribution, *, color: Union[str, tuple] = 'red')

Draw a TextBlock on the image along with an associated distribution, which is represented in heatmap form. This is can be used to visualize the output from duration_mass(). color determines the color of the heatmap.

def draw_line(self, start_xy: tuple, end_xy: tuple, *, color: Union[str, tuple] = 'black', stroke_width: Union[int, float] = 1, dashed: Union[bool, tuple] = False, opacity: float = 1.0)

Draw an arbitrary line on the image from start_xy to end_xy. stroke_width is set in points for vector output or pixels for PNG output. If dashed is True, the line will have a dashed style (or a custom dash pattern can be supplied, e.g. dashed=(1,2,4,2)).

def draw_circle(self, xy: tuple, radius: Union[int, float], *, color: Union[str, tuple] = None, stroke_width: Union[int, float] = 1, dashed: Union[bool, tuple] = False, fill_color: Union[str, tuple] = None, opacity: float = 1.0)

Draw an arbitrary circle on the image centered at xy with some radius. stroke_width is set in points for vector output or pixels for PNG output. If dashed is True, the line will have a dashed style (or a custom dash pattern can be supplied, e.g. dashed=(1,2,4,2)). If no color or fill_color is provided, color will default to black. opacity controls the opacity of the circle's fill color and should be set between 0 (fully transparent) and 1 (fully opaque).

def draw_rectangle(self, rect, *, color: Union[str, tuple] = None, stroke_width: Union[int, float] = 1, dashed: Union[bool, tuple] = False, fill_color: Union[str, tuple] = None, opacity: float = 1.0)

Draw a rectangle on the image. You can pass in some Box-like object, such as an InterestArea, or you can pass a tuple of the form (x, y, width, height). stroke_width is set in points for vector output or pixels for PNG output. If dashed is True, the line will have a dashed style (or a custom dash pattern can be supplied, e.g. dashed=(1,2,4,2)). If no color or fill_color is provided, color will default to black. opacity controls the opacity of the rectangle's fill color and should be set between 0 (fully transparent) and 1 (fully opaque).

def draw_annotation(self, xy: tuple, text: str, *, font_face: str = None, font_size: Union[int, float] = None, color: Union[str, tuple] = 'black', anchor: str = 'left')

Draw arbitrary text on the image located at xy. If no font is set, the default font will be used (see set_default_font()). font_size is set in points for vector output or pixels for PNG output. anchor controls how the text is aligned relative to xy and may be set to left, center, or right.

def save(self, output_path, *, width: int = 150, crop_margin: int = None)

Save the image to some output_path. Images can be saved as .pdf, .eps, .svg, or .png. width only applies to the vector formats and determines the millimeter width of the output file; PNG images are saved at actual pixel size. If you set a crop margin, the image will be cropped to the size of the TextBlock plus the specified margin. Margins are specified in millimeters (PDF, EPS, SVG) or pixels (PNG). EPS does not support opacity effects.

def render_frame(self)

Render the image to PNG and return the bytestream. This can be used to build videos and animations.

class Figure (n_rows: int = 1, n_cols: int = 1)

The Figure class is used to combine one or more images into a publication-ready figure. The general usage pattern is:

fig = eyekit.vis.Figure(1, 2)
fig.add_image(img1)
fig.add_image(img2)
fig.save('figure.pdf')

Initialized with:

  • n_rows Number of rows in the figure.
  • n_cols Number of columns in the figure.

Methods

def set_crop_margin(self, crop_margin: int)

Set the crop margin of the embedded images. Each image in the figure will be cropped to the size and positioning of the most extreme text block extents, plus the specified margin. This has the effect of zooming in to all images in a consistent way – maintaining the aspect ratio and relative positioning of the text blocks across images. Margins are specified in figure millimeters.

def set_border_style(self, *, stroke_width: Union[int, float] = None, color: Union[str, tuple] = None)

Set the thickness and color of the image borders. By default, image border are 1pt black.

def set_enumeration(self, style: str = None, *, font_face: str = None, font_size: Union[int, float] = None)

By default, each image caption is prefixed with a letter in parentheses: (A), (B), (C), etc. If you want to turn this off, call Figure.set_enumeration(False) prior to saving. You can also specify a custom style using the <A>, <a>, or <1> tags; for example Figure.set_enumeration('[<1>]') will result in [1], [2], [3] etc. If no font is set, the default font will be used (see set_default_font()).

def set_padding(self, *, vertical: int = None, horizontal: int = None, edge: int = None)

Set the vertical or horizontal padding between images or the padding around the edge of the figure. Padding is expressed in millimeters. By default, the vertical and horizontal padding between images is 4mm and the edge padding is 1mm.

def add_image(self, image: Image, *, row: int = None, col: int = None)

Add an Image to the figure. If a row and column index is specified, the image is placed in that position. Otherwise, image is placed in the next available position.

def save(self, output_path, *, width: int = 150)

Save the figure to some output_path. Figures can be saved as .pdf, .eps, or .svg. width determines the millimeter width of the output file. EPS does not support opacity effects.

class Booklet

The Booklet class is used to combine one or more figures into a multipage PDF booklet. The general usage pattern is:

booklet = eyekit.vis.Booklet()
booklet.add_figure(fig1)
booklet.add_figure(fig2)
booklet.save('booklet.pdf')

Methods

def add_figure(self, figure: Figure)

Add a Figure to a new page in the booklet.

def save(self, output_path, *, width: int = 210, height: int = 297)

Save the booklet to some output_path. Booklets can only be saved as .pdf. width and height determine the millimeter sizing of the booklet pages, which defaults to A4 (210x297mm).