vispy.visuals.transforms package#

Subpackages#

Submodules#

Module contents#

Provides classes representing different transform types suitable for use with visuals and scenes.

class vispy.visuals.transforms.ChainTransform(*transforms)#

Bases: BaseTransform

BaseTransform subclass that performs a sequence of transformations in order. Internally, this class uses shaders.FunctionChain to generate its glsl_map and glsl_imap functions.

Parameters:
transformslist of BaseTransform instances

See transforms property.

property Isometric#
property Linear#
property NonScaling#
property Orthogonal#
append(tr)#

Add a new transform to the end of this chain.

Parameters:
trinstance of Transform

The transform to use.

glsl_imap = None#
glsl_map = None#
imap(coords)#

Inverse map coordinates

Parameters:
coordsarray-like

Coordinates to inverse map.

Returns:
coordsndarray

Coordinates.

map(coords)#

Map coordinates

Parameters:
coordsarray-like

Coordinates to map.

Returns:
coordsndarray

Coordinates.

prepend(tr)#

Add a new transform to the beginning of this chain.

Parameters:
trinstance of Transform

The transform to use.

shader_imap()#

See shader_map.

shader_map()#

Return a shader Function that accepts only a single vec4 argument and defines new attributes / uniforms supplying the Function with any static input.

property simplified#

A simplified representation of the same transformation.

property transforms#

The list of transform that make up the transform chain.

The order of transforms is given such that the last transform in the list is the first to be invoked when mapping coordinates through the chain.

For example, the following two mappings are equivalent:

# Map coordinates through individual transforms:
trans1 = STTransform(scale=(2, 3), translate=(0, 1))
trans2 = PolarTransform()
mapped = trans1.map(trans2.map(coords))

# Equivalent mapping through chain:
chain = ChainTransform([trans1, trans2])
mapped = chain.map(coords)
class vispy.visuals.transforms.LogTransform(base=None)#

Bases: BaseTransform

Transform perfoming logarithmic transformation on three axes.

Maps (x, y, z) => (log(base.x, x), log(base.y, y), log(base.z, z))

No transformation is applied for axes with base == 0.

If base < 0, then the inverse function is applied: x => base.x ** x

Parameters:
basearray-like

Base for the X, Y, Z axes.

Isometric = False#
Linear = False#
NonScaling = False#
Orthogonal = True#
property base#

base is a tuple (x, y, z) containing the log base that should be applied to each axis of the input vector. If any axis has a base <= 0, then that axis is not affected.

glsl_imap = '\n        vec4 LogTransform_map(vec4 pos) {\n            if($base.x > 1.0)\n                pos.x = log(pos.x) / log($base.x);\n            else if($base.x < -1.0)\n                pos.x = pow(-$base.x, pos.x);\n\n            if($base.y > 1.0)\n                pos.y = log(pos.y) / log($base.y);\n            else if($base.y < -1.0)\n                pos.y = pow(-$base.y, pos.y);\n\n            if($base.z > 1.0)\n                pos.z = log(pos.z) / log($base.z);\n            else if($base.z < -1.0)\n                pos.z = pow(-$base.z, pos.z);\n            return pos;\n        }\n        '#
glsl_map = '\n        vec4 LogTransform_map(vec4 pos) {\n            if($base.x > 1.0)\n                pos.x = log(pos.x) / log($base.x);\n            else if($base.x < -1.0)\n                pos.x = pow(-$base.x, pos.x);\n\n            if($base.y > 1.0)\n                pos.y = log(pos.y) / log($base.y);\n            else if($base.y < -1.0)\n                pos.y = pow(-$base.y, pos.y);\n\n            if($base.z > 1.0)\n                pos.z = log(pos.z) / log($base.z);\n            else if($base.z < -1.0)\n                pos.z = pow(-$base.z, pos.z);\n            return pos;\n        }\n        '#
imap(coords)#

Return obj mapped through the inverse transformation.

Parameters:
objtuple (x,y) or (x,y,z)

array with shape (…, 2) or (…, 3)

map(coords, base=None)#

Return obj mapped through the forward transformation.

Parameters:
objtuple (x,y) or (x,y,z)

array with shape (…, 2) or (…, 3)

shader_imap()#

See shader_map.

shader_map()#

Return a shader Function that accepts only a single vec4 argument and defines new attributes / uniforms supplying the Function with any static input.

class vispy.visuals.transforms.MatrixTransform(matrix=None)#

Bases: BaseTransform

Affine transformation class

Parameters:
matrixarray-like | None

4x4 array to use for the transform.

Isometric = False#
Linear = True#
NonScaling = False#
Orthogonal = False#
glsl_imap = '\n        vec4 affine_transform_imap(vec4 pos) {\n            return $inv_matrix * pos;\n        }\n    '#
glsl_map = '\n        vec4 affine_transform_map(vec4 pos) {\n            return $matrix * pos;\n        }\n    '#
imap(coords)#

Inverse map coordinates

Parameters:
coordsarray-like

Coordinates to inverse map.

Returns:
coordsndarray

Coordinates.

property inv_matrix#
map(coords)#

Map coordinates

Parameters:
coordsarray-like

Coordinates to map.

Returns:
coordsndarray

Coordinates.

property matrix#
reset()#
rotate(angle, axis)#

Rotate the matrix by some angle about a given axis.

The rotation is applied after the transformations already present in the matrix.

Parameters:
anglefloat

The angle of rotation, in degrees.

axisarray-like

The x, y and z coordinates of the axis vector to rotate around.

scale(scale, center=None)#

Scale the matrix about a given origin.

The scaling is applied after the transformations already present in the matrix.

Parameters:
scalearray-like

Scale factors along x, y and z axes.

centerarray-like or None

The x, y and z coordinates to scale around. If None, (0, 0, 0) will be used.

set_frustum(l, r, b, t, n, f)#

Set the frustum

Parameters:
lfloat

Left.

rfloat

Right.

bfloat

Bottom.

tfloat

Top.

nfloat

Near.

ffloat

Far.

set_mapping(points1, points2)#

Set to a 3D transformation matrix that maps points1 onto points2.

Parameters:
points1array-like, shape (4, 3)

Four starting 3D coordinates.

points2array-like, shape (4, 3)

Four ending 3D coordinates.

set_ortho(l, r, b, t, n, f)#

Set ortho transform

Parameters:
lfloat

Left.

rfloat

Right.

bfloat

Bottom.

tfloat

Top.

nfloat

Near.

ffloat

Far.

set_perspective(fov, aspect, near, far)#

Set the perspective

Parameters:
fovfloat

Field of view.

aspectfloat

Aspect ratio.

nearfloat

Near location.

farfloat

Far location.

shader_imap()#

See shader_map.

shader_map()#

Return a shader Function that accepts only a single vec4 argument and defines new attributes / uniforms supplying the Function with any static input.

translate(pos)#

Translate the matrix

The translation is applied after the transformations already present in the matrix.

Parameters:
posarrayndarray

Position to translate by.

class vispy.visuals.transforms.NullTransform#

Bases: BaseTransform

Transform having no effect on coordinates (identity transform).

Isometric = True#
Linear = True#
NonScaling = True#
Orthogonal = True#
glsl_imap = 'vec4 null_transform_imap(vec4 pos) {return pos;}'#
glsl_map = 'vec4 null_transform_map(vec4 pos) {return pos;}'#
imap(coords)#

Inverse map coordinates

Parameters:
coordsarray-like

Coordinates to inverse map.

map(coords)#

Map coordinates

Parameters:
coordsarray-like

Coordinates to map.

class vispy.visuals.transforms.PanZoomTransform(canvas=None, aspect=None, **kwargs)#

Bases: STTransform

Pan-zoom transform

Parameters:
canvasinstance of Canvas | None

The canvas to attch to.

aspectfloat | None

The aspect ratio to apply.

**kwargsdict

Keyword arguments to pass to the underlying STTransform.

attach(canvas)#

Attach this tranform to a canvas

Parameters:
canvasinstance of Canvas

The canvas.

property canvas_tr#
on_mouse_move(event)#

Mouse move handler

Parameters:
eventinstance of Event

The event.

on_mouse_wheel(event)#

Mouse wheel handler

Parameters:
eventinstance of Event

The event.

on_resize(event)#

Resize handler

Parameters:
eventinstance of Event

The event.

class vispy.visuals.transforms.PolarTransform#

Bases: BaseTransform

Polar transform

Maps (theta, r, z) to (x, y, z), where x = r*cos(theta) and y = r*sin(theta).

Isometric = False#
Linear = False#
NonScaling = False#
Orthogonal = False#
glsl_imap = '\n        vec4 polar_transform_map(vec4 pos) {\n            // TODO: need some modulo math to handle larger theta values..?\n            float theta = atan(pos.y, pos.x);\n            float r = length(pos.xy);\n            return vec4(theta, r, pos.z, 1.);\n        }\n        '#
glsl_map = '\n        vec4 polar_transform_map(vec4 pos) {\n            return vec4(pos.y * cos(pos.x), pos.y * sin(pos.x), pos.z, 1.);\n        }\n        '#
imap(coords)#

Return obj mapped through the inverse transformation.

Parameters:
objtuple (x,y) or (x,y,z)

array with shape (…, 2) or (…, 3)

map(coords)#

Return obj mapped through the forward transformation.

Parameters:
objtuple (x,y) or (x,y,z)

array with shape (…, 2) or (…, 3)

class vispy.visuals.transforms.STTransform(scale=None, translate=None)#

Bases: BaseTransform

Transform performing only scale and translate, in that order.

Parameters:
scalearray-like

Scale factors for X, Y, Z axes.

translatearray-like

Scale factors for X, Y, Z axes.

Isometric = False#
Linear = True#
NonScaling = False#
Orthogonal = True#
as_matrix()#
classmethod from_mapping(x0, x1)#

Create an STTransform from the given mapping

See set_mapping for details.

Parameters:
x0array-like

Start.

x1array-like

End.

Returns:
tinstance of STTransform

The transform.

glsl_imap = '\n        vec4 st_transform_imap(vec4 pos) {\n            return vec4((pos.xyz - $translate.xyz * pos.w) / $scale.xyz,\n                        pos.w);\n        }\n    '#
glsl_map = '\n        vec4 st_transform_map(vec4 pos) {\n            return vec4(pos.xyz * $scale.xyz + $translate.xyz * pos.w, pos.w);\n        }\n    '#
imap(coords)#

Invert map coordinates

Parameters:
coordsarray-like

Coordinates to inverse map.

Returns:
coordsndarray

Coordinates.

map(coords)#

Map coordinates

Parameters:
coordsarray-like

Coordinates to map.

Returns:
coordsndarray

Coordinates.

move(move)#

Change the translation of this transform by the amount given.

Parameters:
movearray-like

The values to be added to the current translation of the transform.

property scale#
set_mapping(x0, x1, update=True)#

Configure this transform such that it maps points x0 => x1

Parameters:
x0array-like, shape (2, 2) or (2, 3)

Start location.

x1array-like, shape (2, 2) or (2, 3)

End location.

updatebool

If False, then the update event is not emitted.

Examples

For example, if we wish to map the corners of a rectangle:

>>> p1 = [[0, 0], [200, 300]]

onto a unit cube:

>>> p2 = [[-1, -1], [1, 1]]

then we can generate the transform as follows:

>>> tr = STTransform()
>>> tr.set_mapping(p1, p2)
>>> assert tr.map(p1)[:,:2] == p2  # test
shader_imap()#

See shader_map.

shader_map()#

Return a shader Function that accepts only a single vec4 argument and defines new attributes / uniforms supplying the Function with any static input.

property translate#
zoom(zoom, center=(0, 0, 0), mapped=True)#

Update the transform such that its scale factor is changed, but the specified center point is left unchanged.

Parameters:
zoomarray-like

Values to multiply the transform’s current scale factors.

centerarray-like

The center point around which the scaling will take place.

mappedbool

Whether center is expressed in mapped coordinates (True) or unmapped coordinates (False).

class vispy.visuals.transforms.TransformSystem(canvas=None, dpi=None)#

Bases: object

TransformSystem encapsulates information about the coordinate systems needed to draw a Visual.

Visual rendering operates in six coordinate systems:

  • Visual - arbitrary local coordinate frame of the visual. Vertex buffers used by the visual are usually specified in this coordinate system.

  • Scene - This is an isometric coordinate system used mainly for lighting calculations.

  • Document - This coordinate system has units of _logical_ pixels, and should usually represent the pixel coordinates of the canvas being drawn to. Visuals use this coordinate system to make measurements for font size, line width, and in general anything that is specified in physical units (px, pt, mm, in, etc.). In most circumstances, this is exactly the same as the canvas coordinate system.

  • Canvas - This coordinate system represents the logical pixel coordinates of the canvas. It has its origin in the top-left corner of the canvas, and is typically the coordinate system that mouse and touch events are reported in. Note that, by convention, _logical_ pixels are not necessarily the same size as the _physical_ pixels in the framebuffer that is being rendered to.

  • Framebuffer - The buffer coordinate system has units of _physical_ pixels, and should usually represent the coordinates of the current framebuffer (on the canvas or an FBO) being rendered to. Visuals use this coordinate system primarily for antialiasing calculations. It is also the coorinate system used by glFragCoord. In most cases, this will have the same scale as the document and canvas coordinate systems because the active framebuffer is the back buffer of the canvas, and the canvas will have _logical_ and _physical_ pixels of the same size. However, the scale may be different in the case of high-resolution displays, or when rendering to an off-screen framebuffer with different scaling or boundaries than the canvas.

  • Render - This coordinate system is the obligatory system for vertices returned by a vertex shader. It has coordinates (-1, -1) to (1, 1) across the current glViewport. In OpenGL terminology, this is called clip coordinates.

Parameters:
canvasCanvas

The canvas being drawn to.

dpifloat

The dot-per-inch resolution of the document coordinate system. By default this is set to the resolution of the canvas.

Notes

By default, TransformSystems are configured such that the document coordinate system matches the logical pixels of the canvas,

Examples

1. To convert local vertex coordinates to normalized device coordinates in the vertex shader, we first need a vertex shader that supports configurable transformations:

vec4 a_position;
void main() {
    gl_Position = $transform(a_position);
}

Next, we supply the complete chain of transforms when drawing the visual:

def draw(tr_sys):

tr = tr_sys.get_full_transform() self.program[‘transform’] = tr.shader_map() self.program[‘a_position’] = self.vertex_buffer self.program.draw(‘triangles’)

2. Draw a line whose width is given in mm. To start, we need normal vectors for each vertex, which tell us the direction the vertex should move in order to set the line width:

vec4 a_position;
vec4 a_normal;
float u_line_width;
float u_dpi;
void main() {
    // map vertex position and normal vector to the document cs
    vec4 doc_pos = $visual_to_doc(a_position);
    vec4 doc_normal = $visual_to_doc(a_position + a_normal) - doc_pos;

    // Use DPI to convert mm line width to logical pixels
    float px_width = (u_line_width / 25.4) * dpi;

    // expand by line width
    doc_pos += normalize(doc_normal) * px_width;

    // finally, map the remainder of the way to normalized device
    // coordinates.
    gl_Position = $doc_to_render(a_position);
}

In this case, we need to access the transforms independently, so get_full_transform() is not useful here:

def draw(tr_sys):
    # Send two parts of the full transform separately
    self.program['visual_to_doc'] = tr_sys.visual_to_doc.shader_map()
    doc_to_render = (tr_sys.framebuffer_transform *
                     tr_sys.document_transform)
    self.program['visual_to_doc'] = doc_to_render.shader_map()

    self.program['u_line_width'] = self.line_width
    self.program['u_dpi'] = tr_sys.dpi
    self.program['a_position'] = self.vertex_buffer
    self.program['a_normal'] = self.normal_buffer
    self.program.draw('triangles')
  1. Draw a triangle with antialiasing at the edge.

  2. Using inverse transforms in the fragment shader

property canvas#

The Canvas being drawn to.

property canvas_transform#

Transform mapping from canvas coordinate frame to framebuffer coordinate frame.

configure(viewport=None, fbo_size=None, fbo_rect=None, canvas=None)#

Automatically configure the TransformSystem:

  • canvas_transform maps from the Canvas logical pixel coordinate system to the framebuffer coordinate system, taking into account the logical/physical pixel scale factor, current FBO position, and y-axis inversion.

  • framebuffer_transform maps from the current GL viewport on the framebuffer coordinate system to clip coordinates (-1 to 1).

Parameters:
viewporttuple or None

The GL viewport rectangle (x, y, w, h). If None, then it is assumed to cover the entire canvas.

fbo_sizetuple or None

The size of the active FBO. If None, then it is assumed to have the same size as the canvas’s framebuffer.

fbo_recttuple or None

The position and size (x, y, w, h) of the FBO in the coordinate system of the canvas’s framebuffer. If None, then the bounds are assumed to cover the entire active framebuffer.

canvasCanvas instance

Optionally set the canvas for this TransformSystem. See the canvas property.

property document_transform#

Transform mapping from document coordinate frame to the framebuffer (physical pixel) coordinate frame.

property dpi#

Physical resolution of the document coordinate system (dots per inch).

property framebuffer_transform#

Transform mapping from pixel coordinate frame to rendering coordinate frame.

get_transform(map_from='visual', map_to='render')#

Return a transform mapping between any two coordinate systems.

Parameters:
map_fromstr

The starting coordinate system to map from. Must be one of: visual, scene, document, canvas, framebuffer, or render.

map_tostr

The ending coordinate system to map to. Must be one of: visual, scene, document, canvas, framebuffer, or render.

property pixel_scale#
property scene_transform#

Transform mapping from scene coordinate frame to document coordinate frame.

property visual_transform#

Transform mapping from visual local coordinate frame to scene coordinate frame.