Friday, May 11, 2007

The Case for Dropping Matplotlib

My pet motivation for SymPy Graphing is to aid in the creation of interactive calculus visualizations. I want to be able to write an example program which visualizes the normal and tangential components of acceleration along a curve. I want to be able to graph a 3d surface subject to a constraint, perhaps to see only the portion of a surface which falls within a cylindrical boundary. Ondrej mentioned that he would like to be able to plot curvature as the vertex color across a 3d surface. All of these things should be doable. At the same time, SymPy Graphing should be simple and intuitive enough for a non-programming Calc III student to use in Python's interactive mode as a graphing calculator.



In my work on 2d graphing this week, I've utilized matplotlib's pylab interface. Using matplotlib to plot functions from SymPy is pretty straightforward, though I find it clunky and have had many frustrations with it. But as the name implies, matplotlib isn't meant to do much beyond plotting, and has only limited 3d support. I want to do a lot more with SymPy Graphing.

As mentioned above, I'd like to support plotting an arbitrary function as the vertex color across a surface; matplotlib has no mechanism for this. Jason and I have discussed allowing geometric figures and line segments from the geometry module to be drawn through the graphing interface; again, not possible. I'd also like to support interactive rotation, zooming, translation, etc., and possibly someday (outside the scope of GSoC) point-picking; to my knowledge, you cannot do these things in matplotlib.

As I said in my proposal, 3d graphing will be supported through PyOpenGL. In general, this is not a very difficult task (there is a good summary of what it entails at the plot3d website) and this approach will provide the flexibility I want.

The upshot of all this is that I am considering a shift away from matplotlib altogether and toward supporting all graphing, 2d and 3d, through a unified OpenGL interface. I only want to support a fraction of the features of matplotlib. (I'm not trying to banish matplotlib from sympy. In any event, one can easily use matplotlib directly. See the current revision of modules/graphing.py in SVN for an example.) If my project goal was simply to write a SymPy wrapper for matplotlib, I'd be done before the official coding period even begins. To do this right, I'm going to need to get my hands a bit dirtier.

Update:
The 3d support in Matplotlib is better than I'd thought (it can do interactive rotation and scaling). There is a good example here. It also looks like it might be able to do colormaps. I'm looking into it in more depth right now.

1 comment:

Ondrej Certik said...

I agree. I think there should be a function in the graphing module, that would just give you a set of (x,y) points, and the user would do what he wants with it - for example he can call pylab.plot(x,y), or whatever. That way we are not depending on matplotlib - why should we anyway? Matplotlib, as well as any other python library, is just it - it is a library, so it should be the user who decides what libraries he wants to use. SymPy will just give him the graph in the form of points (for example the list of "x" and "y" coordinates).

For 3D plots - let's do it your way - I also think that matplotlib is not well suited for that. I don't know if it is possible, but it would be fine, if the interface would be quite similar to 2D - that sympy will just calculate the graph (for example a set of x,y,z points, or any other better representation, plus a function (or normal) that you want to plot, or whatever) and the graphing module will be more or less independent of sympy.

Maybe it would be nice, if you could investigate how mathematica and maple are doing 3D graphs.