Author: Hans Terlouw <gipsy@astro.rug.nl>
Utilities for use with matplotlib. Classes AxesCallback, CanvasCallback, TimeCallback and VariableColormap and module-internal function KeyPressFilter().
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: |
|
---|
Attributes:
The specified axes object.
The FigureCanvas object to which axes belongs.
The specified event type.
True if callback is scheduled, False otherwise.
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.
The Event object delivered by matplotlib.
Methods:
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.
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.
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: |
|
---|
Attributes:
The specified FigureCanvas object.
The specified event type.
True if callback is scheduled, False otherwise.
The Event object delivered by matplotlib.
Methods:
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.
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.
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 and TkAgg.
Parameters: |
|
---|
Attribute:
True if callback is scheduled, False otherwise.
Methods:
Activate the object so that it will start calling the callback function periodically. If the object is already active, nothing will be done.
Deactivate the object so that it stops calling its callback function. If the object is already inactive, nothing will be done.
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.
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: |
|
---|
Attributes:
Indicates whether Axes objects registered with method add_frame() will be automatically updated when the colormap changes. Default True.
The colormap’s current scale as specified with method set_scale().
The object (string or colormap) from which the colormap is currently derived.
Methods
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.
Apply a scale to this colormap. scale can be one of: ‘LINEAR’, ‘LOG’, ‘EXP’, ‘SQRT’ and ‘SQUARE’.
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.
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.
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.
Disassociate matplotlib Axes object frame from this colormap.
Redraw all images in the Axes objects registered with method add_frame(). update() is called automatically when the colormap changes while auto is True.
Return a list with filenames of colormaps available within the package.
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.
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()
|
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.
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’.
By default, the Qt4Agg backend does not report resize events. This work-around takes care of this.