Module mplutil

Utilities for use with matplotlib. Classes AxesCallback, CanvasCallback, TimeCallback and VariableColormap and module-internal function KeyPressFilter().

Class AxesCallback

class kapteyn.mplutil.AxesCallback(proc, axes, eventtype, schedule=True, **attr)[source]

AxesCallback has been built on top of matplotlib’s event handling mechanism. Objects of this class provide a more powerful mechanism for handling events from LocationEvent and derived classes than matplotlib provides itself. This class allows the programmer to register a callback function with an event type combined with an Axes object. Whenever the event occurs within the specified Axes object, the callback function is called with the AxesCallback object as its single argument. Different from matplotlib-style event handlers, it is possible to handle overlapping Axes objects. An AxesCallback object will not be deleted as long as it is scheduled (“active”), so it is not always necessary to keep a reference to it.

Parameters:
  • proc – the function to be called upon receiving an event of the specified type and occurring in the specified Axes object. It is called with one argument: the current AxesCallback object. If it returns a value which evaluates to True, processing of the current event stops, i.e., no further callback functions will be called for this event.
  • axes – the matplotlib Axes object.
  • eventtype – the matplotlib event type such as ‘motion_notify_event’ or ‘key_press_event’.
  • schedule – indicates whether the object should start handling events immediately. Default True.
  • attr – keyword arguments each resulting in an attribute with the same name.

Attributes:

axes

The specified axes object.

canvas

The FigureCanvas object to which axes belongs.

eventtype

The specified event type.

active

True if callback is scheduled, False otherwise.

xdata, ydata

The cursor position in data coordinates within the specified Axes object. These values may be different from the attributes with the same name of the event object.

event

The Event object delivered by matplotlib.

Methods:

schedule()[source]

Activate the object so that it will start receiving matplotlib events and calling the callback function. If the object is already active, it will be put in front of the list of active objects so that its callback function will be called before others.

deschedule()[source]

Deactivate the object so that it does not receive matplotlib events anymore and will not call its callback function. If the object is already inactive, nothing will be done.

Example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/usr/bin/env python

from matplotlib.pyplot import figure, show
from kapteyn.mplutil import AxesCallback

def draw_cb(cb):
   if cb.event.button:
      if cb.pos is not None:
         cb.axes.plot((cb.pos[0], cb.xdata), (cb.pos[1], cb.ydata), cb.c)
         cb.canvas.draw()
      cb.pos = (cb.xdata, cb.ydata)
   else:
      cb.pos = None

def colour_cb(cb):
   cb.drawer.c = cb.event.key

fig = figure()

frame = fig.add_axes((0.1, 0.1, 0.8, 0.8))
frame.set_autoscale_on(False)

draw = AxesCallback(draw_cb, frame, 'motion_notify_event', pos=None, c='r')
setc = AxesCallback(colour_cb, frame, 'key_press_event', drawer=draw)

show()

The above code implements a complete, though very simple, drawing program. It first creates a drawing frame and then connects two AxesCallback objects to it. The first object, draw, connects to the callback function draw_cb(), which will draw line segments as long as the mouse is moved with a button down. The previous position is “remembered” by draw via its attribute pos. The drawing colour is determined by draw’s attribute c which can be modified by the callback function colour_cb() by typing one of the letters ‘r’, ‘g’, ‘b’, ‘y’, ‘m’, ‘c’, ‘w’ or ‘k’. This callback function is called via the second AxesCallback object setc which has the first AxesCallback object draw as an attribute.

Class CanvasCallback

class kapteyn.mplutil.CanvasCallback(proc, canvas, eventtype, schedule=True, **attr)[source]

CanvasCallback has been built on top of matplotlib’s event handling mechanism. Objects of this class provide a more powerful mechanism for handling events than matplotlib provides itself. This class allows the programmer to register a callback function with an event type combined with an FigureCanvas object. Whenever the event occurs within the specified FigureCanvas object, the callback function is called with the CanvasCallback object as its single argument. A CanvasCallback object will not be deleted as long as it is scheduled (“active”), so it is not always necessary to keep a reference to it. This class is a simplified version of AxesCallback and is intended for situations where either no Axes object is available or the event type is not a LocationEvent, i.e., there is no position involved.

Parameters:
  • proc – the function to be called upon receiving an event of the specified type and occurring in the specified FigureCanvas. It is called with one argument: the current CanvasCallback object. If it returns a value which evaluates to True, processing of the current event stops, i.e., no further callback functions will be called for this event.
  • canvas – the matplotlib FigureCanvas object.
  • eventtype – the matplotlib event type such as ‘resize_event’ or ‘motion_notify_event’.
  • schedule – indicates whether the object should start handling events immediately. Default True.
  • attr – keyword arguments each resulting in an attribute with the same name.

Attributes:

canvas

The specified FigureCanvas object.

eventtype

The specified event type.

active

True if callback is scheduled, False otherwise.

event

The Event object delivered by matplotlib.

Methods:

schedule()[source]

Activate the object so that it will start receiving matplotlib events and calling the callback function. If the object is already active, it will be put in front of the list of active objects so that its callback function will be called before others.

deschedule()[source]

Deactivate the object so that it does not receive matplotlib events anymore and will not call its callback function. If the object is already inactive, nothing will be done.

Class TimeCallback

class kapteyn.mplutil.TimeCallback(proc, interval, schedule=True, **attr)[source]

Objects of this class are responsible for handling timer events. Timer events occur periodically whenever a predefined period of time expires. A TimeCallback object will not be deleted as long as it is scheduled (“active”), so it is not always necessary to keep a reference to it. This class is backend-dependent. Currently supported backends are GTKAgg, GTK, Qt4Agg, Qt5Agg and TkAgg.

Parameters:
  • proc – the function to be called upon receiving an event of the specified type and occurring in the specified Axes object. It is called with one argument: the current TimeCallback object.
  • interval – the time interval in seconds.
  • schedule – indicates whether the object should start handling events immediately. Default True.
  • attr – keyword arguments each resulting in an attribute with the same name.

Attribute:

active

True if callback is scheduled, False otherwise.

Methods:

schedule()[source]

Activate the object so that it will start calling the callback function periodically. If the object is already active, nothing will be done.

deschedule()[source]

Deactivate the object so that it stops calling its callback function. If the object is already inactive, nothing will be done.

set_interval(interval)[source]

Changes the object’s time interval in seconds.

Example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#/usr/bin/env python

from matplotlib import pyplot
from kapteyn.mplutil import VariableColormap, TimeCallback
import numpy
from matplotlib import mlab

def colour_cb(cb):
   slope = cb.cmap.slope
   shift = cb.cmap.shift
   if shift>0.5:
      shift = -0.5
   cb.cmap.modify(slope, shift+0.01)                   # change colormap

figure = pyplot.figure(figsize=(8,8))
frame = figure.add_axes([0.05, 0.05, 0.85, 0.85])

colormap = VariableColormap('jet')
colormap.add_frame(frame)
TimeCallback(colour_cb, 0.1, cmap=colormap)             # change every 0.1 s

x = y = numpy.arange(-3.0, 3.0, 0.025)
X, Y  = numpy.meshgrid(x, y)
Z1    = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0) # Gaussian 1
Z2    = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1)     # Gaussian 2
Z     = Z2-Z1                                           # difference

img = frame.imshow(Z, origin="lower", cmap=colormap)

pyplot.show()

This code displays an image composed of 2 Gaussians and continuously modifies its colormap’s shift value between -0.5 and 0.5 in steps of 0.01. These steps take place at 0.1 second intervals.

Class VariableColormap

class kapteyn.mplutil.VariableColormap(source, name='Variable')[source]

VariableColormap is a subclass of matplotlib.colors.Colormap with special methods that allow the colormap to be modified. A VariableColormap can be constructed from any other matplotlib colormap object, from a NumPy array with one RGB triplet per row or from a textfile with one RGB triplet per line. Values should be between 0.0 and 1.0.

Parameters:
  • source – the object from which the VariableColormap is created. Either an other colormap object or its registered name, a NumPy array or the name of a text file containing RGB triplets. A number of colormap files is available within the package. A list of names can be obtained with class method luts().
  • name – the name of the color map.

Attributes:

auto

Indicates whether Axes objects registered with method add_frame() will be automatically updated when the colormap changes. Default True.

slope

The colormap slope as specified with method modify().

shift

The colormap shift as specified with method modify().

scale

The colormap’s current scale as specified with method set_scale().

source

The object (string or colormap) from which the colormap is currently derived.

Methods

modify(slope, shift)[source]

Apply a slope and a shift to the colormap. Defaults are 1.0 and 0.0. If one or more Axes objects have been registered with method add_frame(), the images in them will be updated and the corresponding canvases will be redrawn.

set_scale(scale='LINEAR')[source]

Apply a scale to this colormap. scale can be one of: ‘LINEAR’, ‘LOG’, ‘EXP’, ‘SQRT’ and ‘SQUARE’.

set_source(source)[source]

Define an alternative source for the colormap. source can be any other matplotlib colormap object or its registered name, a NumPy array with one RGB triplet per row or the name of a textfile with one RGB triplet per line. Values should be between 0.0 and 1.0.

set_length(length)[source]

Change the colormap’s number of entries. The new set of entries is derived from the current set by linear interpolation. The current length can be obtained with the function len(). For best results, the new length should be chosen such that the original colormap entries are represented unmodified in the new set. This can be achieved by setting \(n_{new} = kn_{old}-k+1\), where \(n_i\) is the colormap’s length and \(k\) is integer.

For normal work, the ‘standard’ length of 256 is usually sufficient, but in special cases increasing the colormap’s length can be helpful to eliminate false contours.

add_frame(frame)[source]

Associate matplotlib Axes object frame with this colormap. If the colormap is subsequently modified, images in this frame will be updated and frame’s canvas will be redrawn.

remove_frame(frame)[source]

Disassociate matplotlib Axes object frame from this colormap.

update()[source]

Redraw all images in the Axes objects registered with method add_frame(). update() is called automatically when the colormap changes while auto is True.

classmethod luts()[source]

Return a list with filenames of colormaps available within the package.

Key press filter

Via its internal function KeyPressFilter() the module filters key_press events for the backend in which the application displays its contents. By default all key_press events are discarded by the filter and do not reach the backend. This behaviour can be changed by assigning a list of acceptable keys to KeyPressFilter’s attribute allowed. E.g., KeyPressFilter.allowed = ['g', 'f'] will allow characters g and f to reach the backend so that the backend’s grid- and full-screen toggles will be available again. The filtering can be completely switched on and off by assigning True or False to KeyPressFilter’s attribute enabled. E.g., KeyPressFilter.enabled = False.

GIPSY keyword event connection

kapteyn.mplutil.gipsy_connect()[source]

Function only to be used by GIPSY tasks. It should be called by matplotlib programs when GIPSY’s keyword events need to be handled, i.e., when the task uses the class KeyCallback. Here is an example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/usr/bin/env python

import gipsy
from matplotlib.pyplot import figure, show
from kapteyn.mplutil import AxesCallback, gipsy_connect

def key_handler(cb):
   gipsy.anyout('Event: %s %s' % (cb.key, gipsy.usertext(cb.key)))

gipsy.init()

fig = figure()

frame = fig.add_axes((0.1, 0.1, 0.8, 0.8))

gipsy_connect()

gipsy.KeyCallback(key_handler, 'TESTKEY=')

show()

gipsy.finis()

Matplotlib backends work-arounds

This module provides work-arounds for limitations of the matplotlib Qt4 and Qt4Agg backends. They will become available when mplutil is imported. No other action is required.

Special keys

By default, the Qt4 backend does not return a number of special key codes in key_press_event objects. This work-around makes the following key codes available: ‘pageup’, ‘pagedown’, ‘left’, ‘right’, ‘up’, ‘down’, ‘home’ and ‘end’.

Resize events

By default, the Qt4Agg backend does not report resize events. This work-around takes care of this.