One thing that could help here is if all the drawing
> commands were "vectorized". This would mean that rather
> than asking the back-end to draw one primitive at a time, a
> whole set could be passed in. This would allow the back end
> to possibly optimize the drawing of the set. An example is
> wxPython's DC.DrawXXXList() methods. These methods take a
> python sequence of drawing primitives, and loop through
> that sequence in C++ code. It makes a huge difference when
> drawing simple objects, like points or line segments.
> I haven't looked closely at the matplotlib code to see if
> this can be done, but it could make a difference.
This is basically what collections already do --
Typically when we find an area of code where a bunch of primitives are
being drawn independently, we refactor them as a collection. There is
a default draw implementation in python that the backends can override
in extension code (as agg does). Even if you just use the default
python drawing implementation, eg
backend_bases.RendererBase.draw_line_collection, the result is much
faster that instantiating a large number of independent objects.
Every property in a collection is a sequence (might be just length
one) and the drawing code iterates over the collection and gets the
value of a property for the i-th element of the collection as
thisprop = prop[i % len(props)]
So if you have a len(1) list, every element in the collection shares
the prop, if you have a len(props) list, every element has a unique
property and < len(props) the props cycle.
Actually, a dictionary mapping element index to property value, which
has a default value, would be more flexible, and the performance hit
might not be bad. Might be worth refactoring.
Actually, the code to plot line markers could be sped up by using
collections to draw line markers. Currently we're using plain old
python loops for this.