The problem is that I don't think we can do this for all artists. Some
may need to create groupings, or push and pop state even if they are
"invisible". For instance, this is used in the SVG backend to create
named groupings (possibly empty) that are referenced from Javascript to
provide interactivity. I think I'd rather keep this to the contained
solution in the PR and not try to generalize it beyond that.
If we did want to generalize, this would only apply to "leaf node"
artists, and not artists that simply exist to contain other artists --
and conceivably we could implement that using either a decorator or
explicit chaining to a base class, but in any event it would have to be
a manual process to determine which artists this would apply to. We
could insert a class in the heirarchy of "ConcreteArtist" (or somesuch)
to handle this.
Mike
On 11/26/2012 06:17 AM, Phil Elson wrote:
I've just been reviewing a really useful PR
(https://github.com/matplotlib/matplotlib/pull/1531) from Pierre
Haessig which speeds up the drawing of non-visible artists by bringing
the following line to the top of the LineArtist's draw method:
if self.get_visible() is False:
return
This *does* fix the problem (and will fix the problem for all other
artists if applied in the same way), but it relies on a developer
remembering the rule of thumb that they must always start their draw
method with these two (simple) lines. Additionally, testing this
functionality is actually quite hard without resorting to timing the
execution.
It made we wonder if there was a better approach to fixing this.
Having a decorator to do this for you is a good idea, except that a
developer would need to remember to decorate their subclass' draw
method, so the next level up is to use a metaclass to *always* wrap
the draw method with the "if visible" lines.
An example of implementing this (apologies if the code doesn't come
out well in the email):
class ArtistMeta(type):
def __new__(cls, classname, bases, class_dict):
# replace the draw method with one which short-circuits if
self.visible is False
draw_method = class_dict['draw']
def draw(self, *args, **kwargs):
if self.visible is False:
print 'draw **not** called with
visible={}'.format(self.visible)
return
else:
return draw_method(self, *args, **kwargs)
class_dict['draw'] = draw
return type.__new__(cls, classname, bases, class_dict)
class Artist(object):
__metaclass__ = ArtistMeta
def __init__(self, visible=True):
self.visible = visible
def draw(self, renderer=None):
print 'draw called with visible={}'.format(self.visible)
return 'foobar'
class SubArtist(Artist):
def draw(self, renderer=None):
print "subclass' draw method"
return Artist.draw(self, renderer=renderer)
With the following results:
>>> a = Artist().draw('wibble')
draw called with visible=True
>>> b = Artist(False).draw('wibble')
draw **not** called with visible=False
>>> c = SubArtist(True).draw('wibble')
subclass' draw method
draw called with visible=True
>>> d = SubArtist(False).draw('wibble')
draw **not** called with visible=False
In my eyes this makes testing the functionality possible without
timing (and is therefore an improvement), but I wanted to know how
others felt about the approach, and in particular, using more
metaclasses in matplotlib (a simple tutorial which I found useful:
http://www.voidspace.org.uk/python/articles/metaclasses.shtml).
Cheers,
Phil
------------------------------------------------------------------------------
Monitor your physical, virtual and cloud infrastructure from a single
web console. Get in-depth insight into apps, servers, databases, vmware,
SAP, cloud infrastructure, etc. Download 30-day Free Trial.
Pricing starts from $795 for 25 servers or applications!
http://p.sf.net/sfu/zoho_dev2dev_nov
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel
------------------------------------------------------------------------------
Monitor your physical, virtual and cloud infrastructure from a single
web console. Get in-depth insight into apps, servers, databases, vmware,
SAP, cloud infrastructure, etc. Download 30-day Free Trial.
Pricing starts from $795 for 25 servers or applications!
http://p.sf.net/sfu/zoho_dev2dev_nov
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel