Cool, that makes sense. Another question: what plot types
> generate 10000 Line2D objects? I can see quiver doing
> something like that if one plots an 100x100 grid, but it
> seems to me the resulting arrows would be totally
some contours may generate this many line objects. scatters and
pcolors can generate tens of thousands of polygons or more... Never
underestimate the power of the user to throw more stuff into a plot
than previously thought impossible.
> Cool, so I take this to mean it would be helpful to add
> some code to the __init__() funcs of the collection
> objects so they can accept objects as well as vertex data?
> Cause I think I could do that.
My weak preference is to have higher level functions that create the
collection objects (think Axes.scatter, Axes.pcolor or many of the
functions in the finance module) rather than overloading the
constructor, which might get confusing. A Collection is at the level
of Line2D -- most users don't create them directly, and helper
functions should make them easy to use.
> So, are the basic drawing primitives in matplotlib Line2D,
> LineCollection, Patch, and PolyCollection, with QuadMesh a
> special case so that pcolor renders fast?
The base types are Text, Line2D, Patch, Image and Collection. Some of
these are specialized, eg TextWithDash inherits from Text, Polygon and
Rectangle inherit from Patch, LineCollection inherits from Collection
and so on. There are several types of Images. There is an artist
hierarchy diagram in the PDF user's guide which is fairly
comprehensive but not entirely up-to-date, eg QuadMesh is not there.
Regarding the design question. I think there is near uniform
consensus that the transforms are kludgy and hard to work with, but as
Andrew has pointed out, it would be a lot of work to replace them with
something more intuitive since they pervade the code; "open heart
surgery on matplotlib", I think he called it. It would have been a good
summer-of-code project. I think it is a reasonably hard problem --
how to support affines plus general non-linear transformations and
have your transformations efficiently updated in the presence of
window resizes and the like. Certainly not a very hard problem --
lots of people have solved it -- but nontrivial. Typically one ends
up special casing the common transformations, so polar plots are
supported with custom axes. One could make a generic axes object that
drew good tick lines and labels in the presence of arbitrary nonlinear
transformations on non-separable axes, but it would take some smarts.
One of the things that makes transformations hard to do well is that
beyond the pure math of affines and functions on those affines, which
is pretty easy, you have to make the results play nicely in the
presence of axes graphs that have tick labels on them in nice places
and user's who want to pan and zoom. What should zoom-to-rect do on a
I regard the collections as a bit kludgy too -- I had a few specific
use cases I was targeting, basically a few plots types where lots of
objects were being creates: scatters, pcolors, financial candlestick
plots, and tried to find some common denominators. Collections were
the first attempt at solving this problem, and I think I traded too
much flexibility for a somewhat non-intuitive interface and subpar
performance. There is yet room to either refactor the existing
collections or design new ones to solve specific problems better
(think QuadMesh). Whatever their current short-comings, I still think
back fondly to the bad-old-days, when the pcolor_demo advised you to
"go get a cup of coffee" while you waited for it to render. And it
really took that long.
The Axis code needs some improvement, because the notion of each Axes
having a single x-axis and y-axis is fairly limiting, and the ticking
is too slow. Separate objects for each tick line and label slow things
down a lot.
The Axes code does too much -- handling almost all of the object
creation and the objects these methods return are too primitive (eg
plot, scatter and pcolor are axes methods that return graphics
primitives like Line2D). There is some consensus that we should have
high level plot objects (FunctionItem, ScatterItem, XYPlotItem) which
are created separately from an Axes and contain their primitive
graphics objects. This is closer to the gnuplot model.
Many of the other objects seem to be holding up fairly well and handle
common and unusual cases fairly elegantly -- the FigureCanvas, Figure,
Line2D, Patch, Text and matplotlib Events seem to work pretty well.
Hope this helps,