Logo Search packages:      
Sourcecode: mascyma version File versions  Download package

backend_template.py

00001 """
This is a fully functional do nothing backend to provide a template to
backend writers.  It is fully functional in that you can select it as
a backend with

  import matplotlib
  matplotlib.use('Template')

and your matplotlib scripts will (should!) run without error, though
no output is produced.  This provides a nice starting points for
backend writers because you can selectively start implementing methods
(draw_rectangle, draw_lines, etc...) and slowly see your figure come
to life w/o having to have a full blown implementation before getting
any results.

Copy this to backend_xxx.py and replace all instances of 'template'
with 'xxx'.  Then implement the class methods and functions below, and
add 'xxx' to the switchyard in matplotlib/backends/__init__.py and
'xxx' to the _knownBackends dict in matplotlib/__init__.py and you're
off.  You can use your backend with

  import matplotlib
  matplotlib.use('xxx')
  from matplotlib.matlab import *
  plot([1,2,3])
  show()

The files that are most relevant to backend_writers are

  matplotlib/backends/backend_your_backend.py
  matplotlib/backend_bases.py
  matplotlib/backends/__init__.py
  matplotlib/__init__.py
  matplotlib/_matlab_helpers.py
  
Naming Conventions

  * classes MixedUpperCase

  * varables lowerUpper

  * functions underscore_separated

REQUIREMENTS

  matplotlib requires python2.2 and Numeric, and I don't yet want to
  make python2.3 a requirement.  I provide the Python Cookbook version
  of enumerate in cbook.py and define the constants True and False if
  version <=2.3.  Of course as a backend writer, you are free to make
  additional requirements, but the less required the better.

"""

import sys
from matplotlib._matlab_helpers import Gcf
from matplotlib.backend_bases import RendererBase, GraphicsContextBase,\
     FigureBase, FigureManagerBase, AxisTextBase, _process_text_args, error_msg

from matplotlib.cbook import True, False
from matplotlib.transforms import Bound1D, Bound2D, Transform
from matplotlib.artist import DPI

00063 def error_msg_template(msg, *args):
    """
    Signal an error condition -- in a GUI, popup a error dialog
    """
    print >>sys.stderr, 'Error:', msg
    sys.exit()
    
00070 class RendererTemplate(RendererBase):
    """
    The renderer handles all the drawing primitives using a graphics
    context instance that controls the colors/styles
    """
    
00076     def draw_arc(self, gcEdge, faceColor, x, y, width, height, angle1, angle2):
        """
        Draw an arc centered at x,y with width and height and angles
        from 0.0 to 360.0.

        If faceColor is not None, fill the rectangle with it.  gcEdge
        is a GraphicsContext instance
        """
        pass
    
00086     def draw_line(self, gc, x1, y1, x2, y2):
        """
        Draw a single line from x1,y1 to x2,y2
        """
        pass
    
00092     def draw_lines(self, gc, x, y):
        """
        x and y are equal length arrays, draw lines connecting each
        point in x, y
        """
        pass
    
00099     def draw_polygon(self, gcEdge, faceColor, points):
        """
        Draw a polygon.  points is a len vertices tuple, each element
        giving the x,y coords a vertex.

        If faceColor is not None, fill the rectangle with it.  gcEdge
        is a GraphicsContext instance
        """  
        pass

00109     def draw_rectangle(self, gcEdge, faceColor, x, y, width, height):
        """
        Draw a rectangle at lower left x,y with width and height.

        If faceColor is not None, fill the rectangle with it.  gcEdge
        is a GraphicsContext instance
        """
        pass

00118     def draw_point(self, gc, x, y):
        """
        Draw a single point at x,y
        """
        pass


00125     def new_gc(self):
        """
        Return an instance of a GraphicsContextTemplate
        """
        return GraphicsContextTemplate()


00132 class GraphicsContextTemplate(GraphicsContextBase):
    """
    The graphics context provides the color, line styles, etc...  See
    the gtk and postscript backends for examples of mapping the
    graphics context attributes (cap styles, join styles, line widths,
    colors) to a particular backend.  In GTK this is done by wrapping
    a gtk.gdk.GC object and forwarding the appropriate calls to it
    using a dictionary mapping styles to gdk constants.  In
    Postscript, all the work is done by the renderer, mapping line
    styles to postscript calls.

    The base GraphicsContext stores colors as a RGB tuple on the unit
    interval, eg, (0.5, 0.0, 1.0).  You will probably need to map this
    to colors appropriate for your backend.  Eg, see the ColorManager
    class for the GTK backend.  If it's more appropriate to do the
    mapping at the renderer level (as in the postscript backend), you
    don't need to override any of the GC methods.  If it's more
    approritate to wrap an instance (as in the GTK backend) and do the
    mapping here, you'll need to override several of the setter
    methods.
    """
    pass
              
00155 class FigureTemplate(FigureBase):
    """
    The figure is the main object -- it contains the Axes and Text,
    which in turn contain lines, patches, and more text

    GUI implementers will probably want to look at FigureGTK in
    backend_gtk.py for examples of handling events with respect to
    matplotlib.
    """
    def __init__(self, figsize, dpi):
        FigureBase.__init__(self, figsize, dpi)
        self._isRealized = False
        
00168     def draw(self, drawable=None, *args, **kwargs):
        """
        Render the figure using RendererTemplate instance drawable
        """
        # at the least, you'll want to do some version of the following

        # the drawable instance is saved so that redraws can be qued
        # and the print_figure instance has access to the last
        # drawable

        if drawable is not None: self.drawable = drawable
        else: drawable=self.drawable
        if drawable is None: return

        # draw the figure bounding box, perhaps none for white figure
        self._figurePatch.draw(drawable)

        # render the axes
        for a in self.axes:
            a.wash_brushes()
            a.draw(drawable)

        # render the figure text
        for t in self._text:
            t.draw(drawable)
    
00194     def print_figure(self, filename, dpi=300):
        """
        Render the figure to hardcopy using self.drawable as the
        renderer if neccessary
        """
        pass

00201     def realize(self, *args):
        """
        This method will be called when the system is ready to draw,
        eg when a GUI window is realized
        """
        self._isRealized = True  
        drawable = RendererTemplate()
        self.draw(drawable)

00210     def text(self, x, y, s, *args, **kwargs):
        """
        Add text to figure at location x,y (relative 0-1 coords) See
        the help for Axis text for the meaning of the other arguments
        """

        override = _process_text_args({}, *args, **kwargs)
        t = AxisTextTemplate(
            self.dpi, self.bbox,
            x=x, y=y, text=s,
            transx = Transform(Bound1D(0,1), self.bbox.x),
            transy = Transform(Bound1D(0,1), self.bbox.y),
            **override)
        self._text.append(t)
        return t

00226 class AxisTextTemplate(AxisTextBase):    
    """
    Handle storing and drawing of text
    """

    def __init__(self, *args, **kwargs):
        AxisTextBase.__init__(self, *args, **kwargs)
    
00234     def _compute_offsets(self):
        """
        Return the (x,y) offsets to adjust for the alignment
        specifications
        """
        return (0,0)  # your actual offsets here
    
00241     def _draw(self, drawable, *args, **kwargs):
        """
        Render the text using the RendererTemplate instance
        """
        pass
         
00247     def get_window_extent(self):
        """
        Return the ink extent of the text as Bound2D instance
        """
        return Bound2D(0,0,1,1)  # your actual extent here
    
00253     def _set_font(self):
        """
        Update any font information; this function will be called if
        font state (eg, fontsize, fontweight) has been changed
        """
        # update font info then turn off reset
        self._reset = False
        
########################################################################
#    
# The following functions and classes are for matlab compatibility
# mode (matplotlib.matlab) and implement window/figure managers,
# etc...
#
########################################################################

00269 def draw_if_interactive():
    """
    This should be overriden in a windowing environment if drawing
    should be done in interactive python mode
    """
    pass

00276 def show():
    """
    This is usually the last line of a matlab script and tells the
    backend that it is time to draw.  In interactive mode, this may be
    a do nothing func.  See the GTK backend for an example of how to
    handle interactive versus batch mode
    """
    for manager in Gcf.get_all_fig_managers():
        manager.figure.realize()


00287 def new_figure_manager(num, figsize, dpi):
    """
    Create a new figure manager instance
    """
    thisFig = FigureTemplate(figsize, dpi)
    manager = FigureManagerTemplate(thisFig, num)
    return manager


class FigureManagerTemplate(FigureManagerBase):
    'GUIs need to override'
    pass


########################################################################
#    
# Now just provide the standard names that backend.__init__ is expecting
# 
########################################################################


FigureManager = FigureManagerTemplate
AxisText = AxisTextTemplate
Figure = FigureTemplate
error_msg = error_msg_template
         

Generated by  Doxygen 1.6.0   Back to index