Logo Search packages:      
Sourcecode: matplotlib version File versions


00001 """
An agg http://antigrain.com/ backend

Features that are implemented

 * capstyles and join styles
 * dashes
 * linewidth
 * lines, rectangles, ellipses
 * clipping to a rectangle
 * output to RGBA and PNG
 * alpha blending
 * DPI scaling properly - everything scales properly (dashes, linewidths, etc)
 * draw polygon
 * freetype2 w/ ft2font


  * allow save to file handle

  * allow load from png

  * integrate screen dpi w/ ppi and text



    Numeric 22+
    agg2 (see below)
    freetype 2

  Install AGG2 (cut and paste below into xterm should work)

    wget http://www.antigrain.com/agg2.tar.gz
    tar xvfz agg2.tar.gz
    cd agg2

    (Optional) if you want to make the examples:
    cd examples/X11

  Installing backend_agg

   Edit setup.py: change aggsrc to point to the agg2 src tree and
   replace if 0: with if 1: in the backend_agg section

   Then just do the usual thing: python setup.py build

   Please let me know if you encounter build problems, and tell me
   platform, gcc version, etc...  Currently the paths in setupext.py
   assume as linux like filesystem (eg X11 include dir, location of
   libttf, etcc) so you may need to tweak these

  Using agg backend

    python somefile.py -dAgg


    import matplotlib

from __future__ import division

import os, sys
import matplotlib
from matplotlib import verbose, rcParams
from matplotlib.numerix import array, Float, zeros, transpose
from matplotlib._image import fromarray
from matplotlib._pylab_helpers import Gcf
from matplotlib.backend_bases import RendererBase,\
     GraphicsContextBase, FigureManagerBase, FigureCanvasBase

from matplotlib.cbook import enumerate, is_string_like, exception_to_str
from matplotlib.figure import Figure
from matplotlib.font_manager import fontManager
from matplotlib.ft2font import FT2Font
from matplotlib.mathtext import math_parse_s_ft2font
from matplotlib.transforms import lbwh_to_bbox
from matplotlib.numerix.mlab import fliplr
import matplotlib.numerix

if matplotlib.numerix.which[0] == "numarray":
    from _na_backend_agg import RendererAgg as _RendererAgg
elif matplotlib.numerix.which[0] == "numeric":
    from _nc_backend_agg import RendererAgg as _RendererAgg
    from _ns_backend_agg import RendererAgg as _RendererAgg

backend_version = 'v2.2'
_fontd = {}     # a map from fname to font instances

00102 class RendererAgg(RendererBase):
    The renderer handles all the drawing primitives using a graphics
    context instance that controls the colors/styles

    texd = {}  # a cache of tex image rasters
    def __init__(self, width, height, dpi):
        if __debug__: verbose.report('RendererAgg.__init__', 'debug-annoying')
        self.dpi = dpi
        self.width = width
        self.height = height
        if __debug__: verbose.report('RendererAgg.__init__ width=%s, \
                        height=%s'%(width, height), 'debug-annoying')
        self._renderer = _RendererAgg(int(width), int(height), dpi.get(),
        if __debug__: verbose.report('RendererAgg.__init__ _RendererAgg done',
        self.draw_polygon = self._renderer.draw_polygon
        self.draw_rectangle = self._renderer.draw_rectangle
        self.draw_path = self._renderer.draw_path
        self.draw_lines = self._renderer.draw_lines
        self.draw_markers = self._renderer.draw_markers
        self.draw_image = self._renderer.draw_image
        self.draw_line_collection = self._renderer.draw_line_collection
        self.draw_quad_mesh = self._renderer.draw_quad_mesh
        self.draw_poly_collection = self._renderer.draw_poly_collection
        self.draw_regpoly_collection = self._renderer.draw_regpoly_collection

        self.copy_from_bbox = self._renderer.copy_from_bbox
        self.restore_region = self._renderer.restore_region

        self.bbox = lbwh_to_bbox(0,0, self.width, self.height)
        if __debug__: verbose.report('RendererAgg.__init__ done',

00141     def draw_arc(self, gcEdge, rgbFace, x, y, width, height, angle1, angle2, rotation):
        Draw an arc centered at x,y with width and height and angles
        from 0.0 to 360.0

        If rgbFace is not None, fill the rectangle with that color.  gcEdge
        is a GraphicsContext instance

        Currently, I'm only supporting ellipses, ie angle args are
        if __debug__: verbose.report('RendererAgg.draw_arc', 'debug-annoying')
            gcEdge, rgbFace, x, y, width/2, height/2, rotation)  # ellipse takes radius

00157     def draw_line(self, gc, x1, y1, x2, y2):
        x and y are equal length arrays, draw lines connecting each
        point in x, y
        if __debug__: verbose.report('RendererAgg.draw_line', 'debug-annoying')
        x = array([x1,x2], typecode=Float)
        y = array([y1,y2], typecode=Float)
        self._renderer.draw_lines(gc, x, y)

00168     def draw_point(self, gc, x, y):
        Draw a single point at x,y
        if __debug__: verbose.report('RendererAgg.draw_point', 'debug-annoying')
        rgbFace = gc.get_rgb()
            gc, rgbFace, x, y, 0.5, 0.5, 0.0)
00177     def draw_mathtext(self, gc, x, y, s, prop, angle):
        Draw the math text using matplotlib.mathtext
        if __debug__: verbose.report('RendererAgg.draw_mathtext',
        size = prop.get_size_in_points()
        width, height, fonts = math_parse_s_ft2font(
            s, self.dpi.get(), size, angle)

        if angle == 90:
            width, height = height, width
        for font in fonts:
            if angle == 90:
                font.horiz_image_to_vert_image() # <-- Rotate
                self._renderer.draw_text( font, int(x)-width, int(y)-height, gc)
                self._renderer.draw_text( font, int(x), int(y)-height, gc)
        if 0:
            self._renderer.draw_rectangle(gc, None,
                                          width, height)

00203     def draw_text(self, gc, x, y, s, prop, angle, ismath):
        Render the text
        if __debug__: verbose.report('RendererAgg.draw_text', 'debug-annoying')

        if ismath:
            return self.draw_mathtext(gc, x, y, s, prop, angle)

        font = self._get_agg_font(prop)
        if font is None: return None
        if len(s)==1 and ord(s)>127:

            font.set_text(s, angle)

        #print x, y, int(x), int(y)

        self._renderer.draw_text(font, int(x), int(y), gc)

00226     def get_text_width_height(self, s, prop, ismath, rgb=(0,0,0)):
        get the width and height in display coords of the string s
        with FontPropertry prop

        # passing rgb is a little hack to make cacheing in the
        # texmanager more efficient.  It is not meant to be used
        # outside the backend

        if ismath=='TeX':
            # todo: handle props
            size = prop.get_size_in_points()
            texmanager = self.get_texmanager()
            Z = texmanager.get_rgba(s, size, self.dpi.get(), rgb)
            m,n,tmp = Z.shape
            return n,m

        if ismath:
            width, height, fonts = math_parse_s_ft2font(
                s, self.dpi.get(), prop.get_size_in_points())
            return width, height
        font = self._get_agg_font(prop)
        font.set_text(s, 0.0)  # the width and height of unrotated string
        w, h = font.get_width_height()
        w /= 64.0  # convert from subpixels
        h /= 64.0
        return w, h

    def draw_tex(self, gc, x, y, s, prop, angle):
        # todo, handle props, angle, origins
        rgb = gc.get_rgb()
        size = prop.get_size_in_points()
        dpi = self.dpi.get()

        flip = angle==90
        w,h = self.get_text_width_height(s, prop, 'TeX', rgb)
        if flip:
            w,h = h,w
            x -= w

        texmanager = self.get_texmanager()
        key = s, size, dpi, rgb, angle, texmanager.get_font_config()
        im = self.texd.get(key)
        if im is None:
            Z = texmanager.get_rgba(s, size, dpi, rgb)
            if flip:
                r = Z[:,:,0]
                g = Z[:,:,1]
                b = Z[:,:,2]
                a = Z[:,:,3]
                m,n,tmp = Z.shape

                def func(x):
                    return transpose(fliplr(x))

                Z = zeros((n,m,4), typecode=Float)
                Z[:,:,0] = func(r)
                Z[:,:,1] = func(g)
                Z[:,:,2] = func(b)
                Z[:,:,3] = func(a)
            im = fromarray(Z, 1)
            self.texd[key] = im

        cliprect = gc.get_clip_rectangle()
        if cliprect is None: bbox = None
        else: bbox = lbwh_to_bbox(*cliprect)
        self.draw_image(x, self.height-y, im, bbox)

    def get_canvas_width_height(self):
        'return the canvas width and height in display coords'
        return self.width, self.height

00301     def _get_agg_font(self, prop):
        Get the font for text instance t, cacheing for efficiency
        if __debug__: verbose.report('RendererAgg._get_agg_font',

        key = hash(prop)
        font = _fontd.get(key)

        if font is None:
            fname = fontManager.findfont(prop)
            font = FT2Font(str(fname))
            _fontd[key] = font

        size = prop.get_size_in_points()
        font.set_size(size, self.dpi.get())

        return font

00323     def points_to_pixels(self, points):
        convert point measures to pixes using dpi and the pixels per
        inch of the display
        if __debug__: verbose.report('RendererAgg.points_to_pixels',
        return points*self.dpi.get()/72.0

    def tostring_rgb(self):
        if __debug__: verbose.report('RendererAgg.tostring_rgb',
        return self._renderer.tostring_rgb()

    def tostring_argb(self):
        if __debug__: verbose.report('RendererAgg.tostring_argb',
        return self._renderer.tostring_argb()

    def buffer_rgba(self,x,y):
        if __debug__: verbose.report('RendererAgg.buffer_rgba',
        return self._renderer.buffer_rgba(x,y)

    def clear(self):

00352 def new_figure_manager(num, *args, **kwargs):
    Create a new figure manager instance
    if __debug__: verbose.report('backend_agg.new_figure_manager',

    FigureClass = kwargs.pop('FigureClass', Figure)
    thisFig = FigureClass(*args, **kwargs)
    canvas = FigureCanvasAgg(thisFig)
    manager = FigureManagerBase(canvas, num)
    return manager

00367 class FigureCanvasAgg(FigureCanvasBase):
    The canvas the figure renders into.  Calls the draw and print fig
    methods, creates the renderers, etc...

    Public attribute

      figure - A Figure instance

    def copy_from_bbox(self, bbox):
        renderer = self.get_renderer()
        return renderer.copy_from_bbox(bbox)

    def restore_region(self, region):
        renderer = self.get_renderer()
        return renderer.restore_region(region)

00385     def draw(self):
        Draw the figure using the renderer
        if __debug__: verbose.report('FigureCanvasAgg.draw', 'debug-annoying')

        renderer = self.get_renderer()

    def get_renderer(self):
        l,b,w,h = self.figure.bbox.get_bounds()
        key = w, h, self.figure.dpi.get()
        try: self._lastKey, self.renderer
        except AttributeError: need_new_renderer = True
        else:  need_new_renderer = (self._lastKey != key)

        if need_new_renderer:
            self.renderer = RendererAgg(w, h, self.figure.dpi)
            self._lastKey = key
        return self.renderer

    def tostring_rgb(self):
        if __debug__: verbose.report('FigureCanvasAgg.tostring_rgb',
        return self.renderer.tostring_rgb()

    def tostring_argb(self):
        if __debug__: verbose.report('FigureCanvasAgg.tostring_argb',
        return self.renderer.tostring_argb()

    def buffer_rgba(self,x,y):
        if __debug__: verbose.report('FigureCanvasAgg.buffer_rgba',
        return self.renderer.buffer_rgba(x,y)

00421     def print_figure(self, filename, dpi=None, facecolor='w', edgecolor='w',
                     orientation='portrait', **kwargs):
        Render the figure to hardcopy.  Set the figure patch face and
        edge colors.  This is useful because some of the GUIs have a
        gray figure face color background and you'll probably want to
        override this on hardcopy

        If the extension matches PNG, write a PNG file

        If the extension matches BMP or RAW, write an RGBA bitmap file

        If filename is a fileobject, write png to file object (thus
        you can, for example, write the png to stdout
        if __debug__: verbose.report('FigureCanvasAgg.print_figure',
        if dpi is None: dpi = matplotlib.rcParams['savefig.dpi']

        # store the orig figure dpi, color and size information so we
        # can restore them later.  For image creation alone, this is
        # not important since after the print the figure is done.  But
        # backend_agg may be used as a renderer for a GUI figure, and
        # restoring figure props will be important in that case.
        # TODO: move most of this functionality into backend_bases

        origDPI = self.figure.dpi.get()
        origfacecolor = self.figure.get_facecolor()
        origedgecolor = self.figure.get_edgecolor()


        # render the printed figure

        printfunc = None
        if not is_string_like(filename):
            # assume png and write to fileobject
            # take a look at the extension and choose the print handler
            basename, ext = os.path.splitext(filename)
            if not len(ext):
                ext = '.png'
                filename += ext

            ext = ext.lower()
            if (ext.find('rgb')>=0 or
                ext.find('raw')>=0 or
                ext.find('bmp')>=0 ):
                # agg doesn't handle unicode yet
            elif ext.find('png')>=0:
                # agg doesn't handle unicode yet
            elif ext.find('svg')>=0:
                from backend_svg import FigureCanvasSVG
                svg = self.switch_backends(FigureCanvasSVG)
                printfunc = svg.print_figure
            elif ext.find('ps')>=0 or ext.find('ep')>=0:
                from backend_ps import FigureCanvasPS # lazy import
                ps = self.switch_backends(FigureCanvasPS)
                printfunc = ps.print_figure
            elif ext.find('pdf')>=0:
                from backend_pdf import FigureCanvasPdf
                pdf = self.switch_backends(FigureCanvasPdf)
                printfunc = pdf.print_figure
                raise IOError('Do not know know to handle extension *%s' % ext)

        if printfunc is not None:
                printfunc(filename, dpi, facecolor, edgecolor, orientation, **kwargs)
                # restore the original figure properties

        # restore the original figure properties

Generated by  Doxygen 1.6.0   Back to index