On Jul 25, 2007, at 12:09 PM, John Hunter wrote:
>
> Hi Ken -- sorry for the radio silence, I'm not intentionally ignoring
> you.  Real life has made some demands on my time of late, and probably
> will until next week, but I was able to download, read through and
> test your code.

I appreciate you making the time to take a look at my code in spite  
of it.

> But I don't think that closes the book on the subject -- for  
> example, I have realized I am introducing too much complexity and  
> trait forwarding, and I think I know a way to work around this, so  
> I will be hacking through my version one more time while at the  
> same time taking a closer look at yours.

I'd hardly expect it to close the book on the subject.  Although it  
functions as a proof-of-concept, my rendering model needs more work  
before it can handle special cases like the blended affine  
transformation to plot an axis.  I've been thinking about how best to  
accomplish this and will try to have something for you to look at by  
early next week.  Please drop me a line when you're satisfied with  
your changes to mpl1.py, as I'm looking forward to seeing them.

> I also would like to hear more about the "hard to optimize" part,  
> because that is not intuitively clear to me.

Moving to a rendering model when the primitives modify the CTM  
instead of replacing it with a pre-calculated value removes the  
dependency between primitives and their containers.  A Primitive  
object, like a Path, may be reused and shared between renderers.  The  
native version of a Primitive object is stored by the Primitive  
object itself, so it can be reused by any Canvas that draws the  
Primitive.  This also means that you incur very little cost in  
clearing a Renderer and then repopulating it with existing  
Primitives.  An Artist-level implementation of z-order could leverage  
this to avoid having to sort primitives by z-order every time a  
figure is rendered.

Since primitives modify graphics state instead of replacing it  
wholesale the it's easier for the Canvas to push as few changes to  
the backend as possible.  For example, if none of the child  
primitives of a ScaledView have their own transforms then the CTM  
only gets modified once when the ScaledView is rendered.  The same is  
true for all of the other graphics state parameters, like linewidth  
and strokecolor.  This saves on unnecessary backend overhead (e.g.  
creating the same agg.trans_affine repeatedly).  It could also lead  
to tighter PDF and EPS output.

Finally, the Renderer class is canvas-independent so it can be used  
to draw on multiple canvases during the course of its lifetime.  I  
hope this will substantially simplify the process of saving a figure  
that was drawn interactively.  I'm also contemplating making  
Renderers able to contain child Renderers so parts of a figure can be  
selectively updated.  For example, drawing the non-Axis children of  
an Axes by using a subrenderer could further improve animation  
performance.

> I confess to being a meta-class ignoramus, so I am intrigued to study
> how you handled the canvas primitive cache problem using meta classes.

I hate to disappoint you, but metaclasses aren't involved.  Right now  
the caching is implemented cooperatively by Canvas and  
CanvasPrimitive to reduce duplicate code.   
CanvasPrimitive.get_canvas_primitive() handles the caching logic and  
calls CanvasPrimitive.create_canvas_primitive() to create a new  
native object if necessary.  Subclasses of CanvasPrimitiveoverride  
create_canvas_primitive() to delegate the call to the appropriate  
method of Canvas, e.g. Path.create_canvas_primitive() returns the  
result of Canvas.create_canvas_path().  Subclasses of Canvas that do  
not cache Primitives should not override the create_canvas_xxx()  
methods.

> How for example, if one modifies a Rectangle object which embodies a
> path primitive, would the canvas get the notification to update it's
> internal path representation (egg the agg_path_storage)?.

Native canvas objects are always created at render-time, so rectangle  
would just update its associated Path instance when its bounds  
changed.  The next time the Path is drawn, Canvas.draw_path() would  
call CanvasPrimitive.get_canvas_primitive() and end up with a new AGG  
path.  That being said, it might be more efficient if all Rectangles  
share one Path that draws a unit square and change its size by  
updating the CTM.

> With traits, I use the trait event handling mechanism so that when  
> any of
> the box properties (left, width, top, etc...) are modified, the
> PathPrimitiveAgg would get a callback.  So when the user does
>
> rect.left = 0.1
>
> the agg path knows to update itself.  This is pretty cool.

Yes it is, and I agree that mpl1 should have an attribute-based API  
for modifying plot object parameters.

> vis-a-vis properties vs traits, I second Peter's comment that once
> you've written 8,000 setters and getters and manually constructed
> properties, you'll probably evolve toward something like traits, w/o
> all the features.  This is a library that has been bug and performance
> vetted in production applications for years, so we should seriously
> consider it as a properties alternative.

Traits does look excellent at what it does, but I'm still of the  
opinion that the cost of adding a large external dependency that is  
not available in Debian or Ubuntu outweighs the benefits of replacing  
vanilla properties with traits.

> I strongly encourage you to download Fernando's mplconfig sandbox  
> stuff and try the edit_traits demo in the presence of a wx enabled  
> traits.

I'll give it a try.

> He is somewhat blown away by the fact that he got a sophisticated,  
> nested GUI dialog w/o writing *any* code.  Since you are a  
> committed wx user, you might find this particularly appealing.

No one's committed me yet, mwahaha!  Actually, that feature does  
little to advance my primary use case for mpl, embedding plots in  
applications.  I my experience you have to put enough effort into  
making the plots look good that you don't want users to be able to  
edit them at runtime.  That being said, I wouldn't be surprised to  
learn that others' experiences differ.

> But at the end of the day, I think the *notification* aspect of  
> traits is the killer feature.

I know, and I still think that for matplotlib it's a bad Software  
Engineering move due to the implicit inter-object dependencies it  
creates.  I can't see why drawing plots should require that much  
"spooky action at a distance".  I could be wrong, but for now I'll  
keep working to find a way that doesn't.

> I think your approach of working on a display PDF renderer interface
> is also a good one, for several reasons.  It uses an established
> specification instead of a home grown one, and it makes it easier for
> us to consider things like integrating with Kiva or Chaco.

It's nice to hear you like it.  Those are two of the specific goals I  
have in mind.  I also like the idea of having a generic retained  
drawing system available in Python.

> I am glad you interpreted my mpl1 sketch in the right vein, as a  
> lab in which
> people can advocate ideas as working code.

Well, I'm glad you've taken my criticisms of mpl1.py in the spirit  
they were intended in.  I also appreciate you taking the time to  
review the code I submitted instead of just telling me how very nice  
and convenient traits are.  ;-)

> Hopefully next week we can come to some consensus and start merging  
> our two lines.

That sounds like a plan.  I'll try to make some progress on the  
blended affines for drawing axis tickmarks and the Artists layer.

Ken

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel

Reply via email to