Jae-Joon,

Thanks for your comments. You have successfully found areas in my
patch that were overcomplicated!

I have attached a new patch which doesn't alter the api of draw_image
and uses the im object as Jae-Joon suggests.

I've tested this on Linux Python 2.5 as before, but not on Windows as
I don't have the correct development environment set up at the moment.

Regards

Andrew

On Fri, Nov 7, 2008 at 10:36 AM, Jae-Joon Lee <[EMAIL PROTECTED]> wrote:
> Andrew,
>
> I just had a quick look at your patch.
> I'm a bit distracted with your changes regarding the "url" support of the 
> image.
> Do we need to change the api of the draw_image()? Can we just utilize
> "im" object as we did with the "gc"? Check the patch below. This
> simple method seem to work fine for me.
>
> I also noted that,  in the __init__() methods of the Patch and the
> AxesImage class, you explicitly declare "url" as a keyword argument
> and also initialize self.url. I don't think these are necessary as
> "url" is already a property of the Artist class.
>
> IHTH,
>
> -JJ
>
>
> Index: lib/matplotlib/image.py
> ===================================================================
> --- lib/matplotlib/image.py     (revision 6361)
> +++ lib/matplotlib/image.py     (working copy)
> @@ -234,6 +234,7 @@
>             self.axes.get_yscale() != 'linear'):
>             warnings.warn("Images are not supported on non-linear axes.")
>         im = self.make_image(renderer.get_image_magnification())
> +        im._url = self.get_url()
>         l, b, widthDisplay, heightDisplay = self.axes.bbox.bounds
>         renderer.draw_image(round(l), round(b), im, self.axes.bbox.frozen(),
>                             *self.get_transformed_clip_path_and_affine())
> Index: lib/matplotlib/backends/backend_svg.py
> ===================================================================
> --- lib/matplotlib/backends/backend_svg.py      (revision 6361)
> +++ lib/matplotlib/backends/backend_svg.py      (working copy)
> @@ -274,6 +283,9 @@
>
>         h,w = im.get_size_out()
>
> +        url = im._url
> +        if url is not None:
> +            self._svgwriter.write('<a xlink:href="%s">' % url)
>         self._svgwriter.write (
>             '<image x="%f" y="%f" width="%f" height="%f" '
>             '%s xlink:href="'%(x/trans[0],
> (self.height-y)/trans[3]-h, w, h, transstr)
> @@ -298,6 +310,8 @@
>             self._svgwriter.write(filename)
>
>         self._svgwriter.write('"/>\n')
> +        if url is not None:
> +            self._svgwriter.write('</a>')
>
>     def draw_text(self, gc, x, y, s, prop, angle, ismath):
>         if ismath:
>
>
>
>
> On Thu, Nov 6, 2008 at 11:40 AM, Andrew Stock
> <[EMAIL PROTECTED]> wrote:
>> Thanks  Michael,
>>
>> I've attached a new diff file which I believe also has all the
>> necessary changes to the collections and images. I've also attached
>> two simple scripts which test the collections and image functionality.
>>
>> I've had to make some modification to extension code in this patch
>> which is definitely not my area of expertise so it would be worth
>> someone more experienced casting an eye over this.
>>
>> I've tested this on Linux and successfully run the backend_driver.py
>> file (or at least, it failed with the same errors as before I applied
>> the patch!).
>>
>> Any other comments welcome
>>
>> Thanks
>>
>> On Wed, Nov 5, 2008 at 2:31 PM, Michael Droettboom <[EMAIL PROTECTED]> wrote:
>>> This looks great to me.  I can confirm that this works on Linux as well.
>>>
>>> I think from here it's just a matter of applying the same pattern of changes
>>> to collections and images.  Once that's done, I'm happy to apply the patch.
>>>  And if you plan to make a lot of changes in the future, it generally pretty
>>> easy to get commit access.  Just ask.
>>>
>>> Mike
>>>
>>> Andrew Stock wrote:
>>>>
>>>> Hi,
>>>>
>>>> I've attached a diff file which implements the basic functionality. It
>>>> currently doesn't handle collections or draw_image, but I wanted to
>>>> get something simple working first, before expanding the scope.  A
>>>> simple test program is as follows:
>>>>
>>>> from pylab import *
>>>>
>>>> f = figure()
>>>> a,b = bar([1,2], [2,5], url='http://www.bbc.co.uk/')
>>>>
>>>> a.set_url('http://www.google.com')
>>>>
>>>> f.canvas.print_figure(r'c:\test.svg')
>>>>
>>>> I'd be interested in comments / feedback on the attached before I
>>>> start to branch out into more significant changes!
>>>>
>>>> Thanks
>>>>
>>>> Andrew
>>>>
>>>> On Thu, Oct 30, 2008 at 8:02 PM, Michael Droettboom <[EMAIL PROTECTED]>
>>>> wrote:
>>>>
>>>>>
>>>>> I realised in my earlier message, I didn't really address your initial
>>>>> request for feedback on your approach.
>>>>>
>>>>> I think the goal here should be to make the url support as pervasive as
>>>>> possible wrt both plot types and backends.
>>>>>
>>>>> Many of the high-level plotting functions (such as bar()) take a standard
>>>>> set of "Artist" keywords.  In the docs, you'll often see a table like the
>>>>> one at the bottom for bar():
>>>>>
>>>>>
>>>>>  
>>>>> http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.bar
>>>>>
>>>>> This support all happens automatically simply by adding a setter and
>>>>> getter
>>>>> to the "Artist" class.  So, in Artist, simply add set_url/get_url methods
>>>>> and a private attribute to store the url.  You shouldn't have to touch
>>>>> any
>>>>> of the high-level plotting functions to have this supported everywhere
>>>>> where
>>>>> it makes sense.
>>>>>
>>>>> Then, to use the url value, you'll want to store it in a GraphicsContext
>>>>> object to pass to the backend.  So you'll want to add an attribute and
>>>>> getter/setter in GraphicsContextBase as well.
>>>>>
>>>>> All of the places where the front-end creates a gc and passes it to the
>>>>> backend will need to be updated (such as Artist.draw, Text.draw, perhaps
>>>>> others, do a grep for the public methods in RendererBase).  Where it sets
>>>>> things like facecolor on the GraphicsContext, it should also set a url.
>>>>>
>>>>> Then, in backends where appropriate you would use the url value if
>>>>> present.
>>>>> You could start with SVG, and maybe someone can come along and add PDF
>>>>> support later.
>>>>>
>>>>> An additional complication for completeness is handling Collections.
>>>>>  Collections store a list of graphics context information (facecolor,
>>>>> edgecolor etc.) rather than a single one.  Therefore, you'll want to add
>>>>> set_urls/get_urls to Collection as well, and then deal with passing those
>>>>> values to the backend.  Collections don't use a GraphicsContext class, so
>>>>> you'll need to add a new arg to draw_path_collection in all backends.
>>>>>  (Refactoring this so we pass an object to the backends rather than a
>>>>> long
>>>>> list of arguments would be welcome to avoid needing to update multiple
>>>>> backends for these sorts of new features in the future).  You will also
>>>>> need
>>>>> to update RendererBase._iter_collection to support iterating over URLs in
>>>>> the same way as everything else there.
>>>>>
>>>>> draw_image also doesn't use a gc, so you'll need to add an argument
>>>>> there.
>>>>>
>>>>> Hope that gives you a road map...  Please let me know if I can help
>>>>> further.
>>>>>
>>>>> Mike
>>>>>
>>>>> Andrew Stock wrote:
>>>>>
>>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> I have a requirement to make clickable bar charts using the SVG output
>>>>>> (rather than html maps).
>>>>>>
>>>>>> An initial look has suggested that the following changes would be
>>>>>> required:
>>>>>>
>>>>>> backend_bases.py: Add a url property to GraphicsContextBase
>>>>>> (defaulting to None, so it's all backwards compatible)
>>>>>> axes.py: Add a url option to the bar function and pass this on to the
>>>>>> constructor of the Rectangle object
>>>>>> patches.py: Pass the url option in the constructor for the Patch
>>>>>> object to the GraphicsContextBase object created in the draw function
>>>>>> backends/backend_svg.py: Add check to _draw_svg_element for url set in
>>>>>> gc. If it is, write out SVG code for xlink.
>>>>>>
>>>>>> I can make these changes and (if people think it would be useful)
>>>>>> contribute the changes back.  However, before I do this, I wanted to
>>>>>> check whether this is the right approach to take - I'm not experienced
>>>>>> with the internals of matplotlib and so if there's a better way of
>>>>>> doing it, I'd be grateful for the advice.
>>>>>>
>>>>>> Once I got the bar charts working, I would be interested in possibly
>>>>>> extending this to other chart types.
>>>>>>
>>>>>> Regards
>>>>>>
>>>>>> Andrew
>>>>>>
>>>>>>
>>>>>> -------------------------------------------------------------------------
>>>>>> This SF.Net email is sponsored by the Moblin Your Move Developer's
>>>>>> challenge
>>>>>> Build the coolest Linux based applications with Moblin SDK & win great
>>>>>> prizes
>>>>>> Grand prize is a trip for two to an Open Source event anywhere in the
>>>>>> world
>>>>>> http://moblin-contest.org/redirect.php?banner_id=100&url=/
>>>>>> _______________________________________________
>>>>>> Matplotlib-devel mailing list
>>>>>> Matplotlib-devel@lists.sourceforge.net
>>>>>> https://lists.sourceforge.net/lists/listinfo/matplotlib-devel
>>>>>>
>>>>>>
>>>>>
>>>>> --
>>>>> Michael Droettboom
>>>>> Science Software Branch
>>>>> Operations and Engineering Division
>>>>> Space Telescope Science Institute
>>>>> Operated by AURA for NASA
>>>>>
>>>>>
>>>>>
>>>
>>> --
>>> Michael Droettboom
>>> Science Software Branch
>>> Operations and Engineering Division
>>> Space Telescope Science Institute
>>> Operated by AURA for NASA
>>>
>>>
>>
>> -------------------------------------------------------------------------
>> This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
>> Build the coolest Linux based applications with Moblin SDK & win great prizes
>> Grand prize is a trip for two to an Open Source event anywhere in the world
>> http://moblin-contest.org/redirect.php?banner_id=100&url=/
>> _______________________________________________
>> Matplotlib-devel mailing list
>> Matplotlib-devel@lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/matplotlib-devel
>>
>>
>
Index: src/_backend_agg.cpp
===================================================================
--- src/_backend_agg.cpp	(revision 6367)
+++ src/_backend_agg.cpp	(working copy)
@@ -959,7 +959,8 @@
    const Py::Object&              edgecolors_obj,
    const Py::SeqBase<Py::Float>&  linewidths,
    const Py::SeqBase<Py::Object>& linestyles_obj,
-   const Py::SeqBase<Py::Int>&    antialiaseds) {
+   const Py::SeqBase<Py::Int>&    antialiaseds,
+   const Py::SeqBase<Py::Object>&  urls) {
   typedef agg::conv_transform<typename PathGenerator::path_iterator> transformed_path_t;
   typedef SimplifyPath<transformed_path_t>			     simplify_t;
   typedef agg::conv_curve<simplify_t>				     simplified_curve_t;
@@ -1154,7 +1155,7 @@
 Py::Object
 RendererAgg::draw_path_collection(const Py::Tuple& args) {
   _VERBOSE("RendererAgg::draw_path_collection");
-  args.verify_length(13);
+  args.verify_length(14);
 
   //segments, trans, clipbox, colors, linewidths, antialiaseds
   agg::trans_affine	  master_transform = py_to_agg_transformation_matrix(args[0]);
@@ -1170,7 +1171,7 @@
   Py::SeqBase<Py::Float>  linewidths	   = args[10];
   Py::SeqBase<Py::Object> linestyles_obj   = args[11];
   Py::SeqBase<Py::Int>    antialiaseds	   = args[12];
-
+  Py::SeqBase<Py::Object> urls             = args[13];
   PathListGenerator path_generator(paths);
 
   try {
@@ -1187,7 +1188,8 @@
        edgecolors_obj,
        linewidths,
        linestyles_obj,
-       antialiaseds);
+       antialiaseds,
+       urls);
   } catch (const char *e) {
     throw Py::RuntimeError(e);
   }
@@ -1295,6 +1297,7 @@
   Py::SeqBase<Py::Object> linestyles_obj;
   Py::Tuple antialiaseds(1);
   antialiaseds[0] = Py::Int(antialiased ? 1 : 0);
+  Py::SeqBase<Py::Object> urls;
 
   if (showedges) {
     npy_intp dims[] = { 1, 4, 0 };
@@ -1326,7 +1329,8 @@
          edgecolors_obj,
          linewidths,
          linestyles_obj,
-         antialiaseds);
+         antialiaseds,
+         urls);
     } catch (const char* e) {
       throw Py::RuntimeError(e);
     }
Index: src/_backend_agg.h
===================================================================
--- src/_backend_agg.h	(revision 6367)
+++ src/_backend_agg.h	(working copy)
@@ -228,7 +228,8 @@
      const Py::Object&              edgecolors_obj,
      const Py::SeqBase<Py::Float>&  linewidths,
      const Py::SeqBase<Py::Object>& linestyles_obj,
-     const Py::SeqBase<Py::Int>&    antialiaseds);
+     const Py::SeqBase<Py::Int>&    antialiaseds,
+     const Py::SeqBase<Py::Object>&  urls);
 
 private:
   void create_alpha_buffers();
Index: lib/matplotlib/backend_bases.py
===================================================================
--- lib/matplotlib/backend_bases.py	(revision 6367)
+++ lib/matplotlib/backend_bases.py	(working copy)
@@ -107,7 +107,7 @@
     def draw_path_collection(self, master_transform, cliprect, clippath,
                              clippath_trans, paths, all_transforms, offsets,
                              offsetTrans, facecolors, edgecolors, linewidths,
-                             linestyles, antialiaseds):
+                             linestyles, antialiaseds, urls):
         """
         Draws a collection of paths, selecting drawing properties from
         the lists *facecolors*, *edgecolors*, *linewidths*,
@@ -136,7 +136,7 @@
         for xo, yo, path_id, gc, rgbFace in self._iter_collection(
             path_ids, cliprect, clippath, clippath_trans,
             offsets, offsetTrans, facecolors, edgecolors,
-            linewidths, linestyles, antialiaseds):
+            linewidths, linestyles, antialiaseds, urls):
             path, transform = path_id
             transform = transforms.Affine2D(transform.get_matrix()).translate(xo, yo)
             self.draw_path(gc, path, transform, rgbFace)
@@ -164,7 +164,7 @@
         return self.draw_path_collection(
             master_transform, cliprect, clippath, clippath_trans,
             paths, [], offsets, offsetTrans, facecolors, edgecolors,
-            linewidths, [], [antialiased])
+            linewidths, [], [antialiased], [None])
 
     def _iter_collection_raw_paths(self, master_transform, paths, all_transforms):
         """
@@ -198,7 +198,7 @@
 
     def _iter_collection(self, path_ids, cliprect, clippath, clippath_trans,
                          offsets, offsetTrans, facecolors, edgecolors,
-                         linewidths, linestyles, antialiaseds):
+                         linewidths, linestyles, antialiaseds, urls):
         """
         This is a helper method (along with
         :meth:`_iter_collection_raw_paths`) to make it easier to write
@@ -232,6 +232,7 @@
         Nlinewidths = len(linewidths)
         Nlinestyles = len(linestyles)
         Naa         = len(antialiaseds)
+        Nurls       = len(urls)
 
         if (Nfacecolors == 0 and Nedgecolors == 0) or Npaths == 0:
             return
@@ -268,6 +269,9 @@
                 gc.set_alpha(rgbFace[-1])
                 rgbFace = rgbFace[:3]
             gc.set_antialiased(antialiaseds[i % Naa])
+            
+            if Nurls:
+                gc.set_url(urls[i % Nurls])
 
             yield xo, yo, path_id, gc, rgbFace
 
@@ -433,6 +437,7 @@
         self._linewidth = 1
         self._rgb = (0.0, 0.0, 0.0)
         self._hatch = None
+        self._url = None
 
     def copy_properties(self, gc):
         'Copy properties from gc to self'
@@ -447,6 +452,7 @@
         self._linewidth = gc._linewidth
         self._rgb = gc._rgb
         self._hatch = gc._hatch
+        self._url = gc._url
 
     def get_alpha(self):
         """
@@ -521,6 +527,12 @@
         matlab format string, a html hex color string, or a rgb tuple
         """
         return self._rgb
+    
+    def get_url(self):
+        """
+        returns a url if one is set, None otherwise
+        """
+        return self._url
 
     def set_alpha(self, alpha):
         """
@@ -621,6 +633,12 @@
             raise ValueError('Unrecognized linestyle: %s' % style)
         self._linestyle = style
         self.set_dashes(offset, dashes)
+        
+    def set_url(self, url):
+        """
+        Sets the url for links in compatible backends
+        """
+        self._url = url
 
     def set_hatch(self, hatch):
         """
Index: lib/matplotlib/artist.py
===================================================================
--- lib/matplotlib/artist.py	(revision 6367)
+++ lib/matplotlib/artist.py	(working copy)
@@ -50,6 +50,7 @@
         self._propobservers = {} # a dict from oids to funcs
         self.axes = None
         self._remove_method = None
+        self._url = None
 
     def remove(self):
         """
@@ -313,6 +314,18 @@
         """
         return self.figure is not None
 
+    def get_url(self):
+        """
+        Returns the url
+        """
+        return self._url
+    
+    def set_url(self, url):
+        """
+        Sets the url for the artist
+        """
+        self._url = url
+
     def get_figure(self):
         """
         Return the :class:`~matplotlib.figure.Figure` instance the
Index: lib/matplotlib/patches.py
===================================================================
--- lib/matplotlib/patches.py	(revision 6367)
+++ lib/matplotlib/patches.py	(working copy)
@@ -278,6 +278,7 @@
         gc.set_antialiased(self._antialiased)
         self._set_gc_clip(gc)
         gc.set_capstyle('projecting')
+        gc.set_url(self._url)
 
         if (not self.fill or self._facecolor is None or
             (cbook.is_string_like(self._facecolor) and self._facecolor.lower()=='none')):
Index: lib/matplotlib/axes.py
===================================================================
--- lib/matplotlib/axes.py	(revision 6367)
+++ lib/matplotlib/axes.py	(working copy)
@@ -5480,7 +5480,7 @@
     def imshow(self, X, cmap=None, norm=None, aspect=None,
                interpolation=None, alpha=1.0, vmin=None, vmax=None,
                origin=None, extent=None, shape=None, filternorm=1,
-               filterrad=4.0, imlim=None, resample=None, **kwargs):
+               filterrad=4.0, imlim=None, resample=None, url=None, **kwargs):
         """
         call signature::
 
@@ -5601,6 +5601,7 @@
             im.set_clim(vmin, vmax)
         else:
             im.autoscale_None()
+        im.set_url(url)
 
         xmin, xmax, ymin, ymax = im.get_extent()
 
Index: lib/matplotlib/collections.py
===================================================================
--- lib/matplotlib/collections.py	(revision 6367)
+++ lib/matplotlib/collections.py	(working copy)
@@ -71,6 +71,7 @@
                  norm = None,  # optional for ScalarMappable
                  cmap = None,  # ditto
                  pickradius = 5.0,
+                 urls = None,
                  **kwargs
                  ):
         """
@@ -86,6 +87,7 @@
         self.set_linewidth(linewidths)
         self.set_linestyle(linestyles)
         self.set_antialiased(antialiaseds)
+        self.set_urls(urls)
 
         self._uniform_offsets = None
         self._offsets = np.array([], np.float_)
@@ -203,7 +205,7 @@
             paths, self.get_transforms(),
             offsets, transOffset,
             self.get_facecolor(), self.get_edgecolor(), self._linewidths,
-            self._linestyles, self._antialiaseds)
+            self._linestyles, self._antialiaseds, self._urls)
         renderer.close_group(self.__class__.__name__)
 
     def contains(self, mouseevent):
@@ -227,6 +229,14 @@
     def set_pickradius(self,pickradius): self.pickradius = 5
     def get_pickradius(self): return self.pickradius
 
+    def set_urls(self, urls):
+	if urls is None:
+            self._urls = [None,]
+        else:
+            self._urls = urls
+        
+    def get_urls(self): return self._urls
+
     def set_offsets(self, offsets):
         """
         Set the offsets for the collection.  *offsets* can be a scalar
Index: lib/matplotlib/image.py
===================================================================
--- lib/matplotlib/image.py	(revision 6367)
+++ lib/matplotlib/image.py	(working copy)
@@ -88,13 +88,10 @@
         self.set_filterrad(filterrad)
         self._filterrad = filterrad
 
-
-
         self.set_interpolation(interpolation)
         self.set_resample(resample)
         self.axes = ax
 
-
         self._imcache = None
 
         self.update(kwargs)
@@ -234,9 +231,11 @@
             self.axes.get_yscale() != 'linear'):
             warnings.warn("Images are not supported on non-linear axes.")
         im = self.make_image(renderer.get_image_magnification())
+        im._url = self.get_url()
         l, b, widthDisplay, heightDisplay = self.axes.bbox.bounds
+        clippath, affine = self.get_transformed_clip_path_and_affine()
         renderer.draw_image(round(l), round(b), im, self.axes.bbox.frozen(),
-                            *self.get_transformed_clip_path_and_affine())
+                            clippath, affine)
 
     def contains(self, mouseevent):
         """Test whether the mouse event occured within the image.
Index: lib/matplotlib/backends/backend_ps.py
===================================================================
--- lib/matplotlib/backends/backend_ps.py	(revision 6367)
+++ lib/matplotlib/backends/backend_ps.py	(working copy)
@@ -531,7 +531,7 @@
     def draw_path_collection(self, master_transform, cliprect, clippath,
                              clippath_trans, paths, all_transforms, offsets,
                              offsetTrans, facecolors, edgecolors, linewidths,
-                             linestyles, antialiaseds):
+                             linestyles, antialiaseds, urls):
         write = self._pswriter.write
 
         path_codes = []
@@ -548,7 +548,7 @@
         for xo, yo, path_id, gc, rgbFace in self._iter_collection(
             path_codes, cliprect, clippath, clippath_trans,
             offsets, offsetTrans, facecolors, edgecolors,
-            linewidths, linestyles, antialiaseds):
+            linewidths, linestyles, antialiaseds, urls):
 
             ps = "%g %g %s" % (xo, yo, path_id)
             self._draw_ps(ps, gc, rgbFace)
Index: lib/matplotlib/backends/backend_svg.py
===================================================================
--- lib/matplotlib/backends/backend_svg.py	(revision 6367)
+++ lib/matplotlib/backends/backend_svg.py	(working copy)
@@ -67,9 +67,13 @@
         else:
             clippath = 'clip-path="url(#%s)"' % clipid
 
+        if gc.get_url() is not None:
+            self._svgwriter.write('<a xlink:href="%s">' % gc.get_url())
         style = self._get_style(gc, rgbFace)
         self._svgwriter.write ('<%s style="%s" %s %s/>\n' % (
                 element, style, clippath, details))
+        if gc.get_url() is not None:
+            self._svgwriter.write('</a>')
 
     def _get_font(self, prop):
         key = hash(prop)
@@ -224,7 +228,7 @@
     def draw_path_collection(self, master_transform, cliprect, clippath,
                              clippath_trans, paths, all_transforms, offsets,
                              offsetTrans, facecolors, edgecolors, linewidths,
-                             linestyles, antialiaseds):
+                             linestyles, antialiaseds, urls):
         write = self._svgwriter.write
 
         path_codes = []
@@ -242,8 +246,11 @@
         for xo, yo, path_id, gc, rgbFace in self._iter_collection(
             path_codes, cliprect, clippath, clippath_trans,
             offsets, offsetTrans, facecolors, edgecolors,
-            linewidths, linestyles, antialiaseds):
+            linewidths, linestyles, antialiaseds, urls):
             clipid = self._get_gc_clip_svg(gc)
+            url = gc.get_url()
+            if url is not None:
+                self._svgwriter.write('<a xlink:href="%s">' % url)
             if clipid is not None:
                 write('<g clip-path="url(#%s)">' % clipid)
             details = 'xlink:href="#%s" x="%f" y="%f"' % (path_id, xo, self.height - yo)
@@ -251,6 +258,8 @@
             self._svgwriter.write ('<use style="%s" %s/>\n' % (style, details))
             if clipid is not None:
                 write('</g>')
+            if url is not None:
+                self._svgwriter.write('</a>')
 
         self._path_collection_id += 1
 
@@ -274,6 +283,9 @@
 
         h,w = im.get_size_out()
 
+        url = getattr(im, '_url', None)
+        if url is not None:
+            self._svgwriter.write('<a xlink:href="%s">' % url)
         self._svgwriter.write (
             '<image x="%f" y="%f" width="%f" height="%f" '
             '%s xlink:href="'%(x/trans[0], (self.height-y)/trans[3]-h, w, h, transstr)
@@ -298,6 +310,8 @@
             self._svgwriter.write(filename)
 
         self._svgwriter.write('"/>\n')
+        if url is not None:
+            self._svgwriter.write('</a>')
 
     def draw_text(self, gc, x, y, s, prop, angle, ismath):
         if ismath:
Index: lib/matplotlib/text.py
===================================================================
--- lib/matplotlib/text.py	(revision 6367)
+++ lib/matplotlib/text.py	(working copy)
@@ -464,6 +464,7 @@
         gc = renderer.new_gc()
         gc.set_foreground(self._color)
         gc.set_alpha(self._alpha)
+        gc.set_url(self._url)
         if self.get_clip_on():
             gc.set_clip_rectangle(self.clipbox)
 
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel

Reply via email to