Yesterday I brought up some user interface issues with John. He agreed that these generally ought to be discussed in a broader forum (meaning he wasn't dead set against them; at least not most of them). So here were some of the thoughts that I raised that pertain mainly to generating plots during interactive analysis sessions:
1) Seems to me that repr for the plot objects could be blanked out for interactive mode. Having python print out what it does now isn't usually useful and in some cases (like error bars) leads to a dump on the screen. Any reason not to make repr mode dependent (or at least configurable)?
John pointed out that one of the worst offenders (error bars) actually return lists of plot objects so it wouldn't do much good to override repr for the plot objects unless one used a list object where repr was overridden as well. The annoyance factor in interactive use is perhaps sufficient to do this though. What do others think?
2) Any support for being able to specify colors using more than single character codes (say, using "red" or "green", and line styles and symbols with more descriptive terms like "dashed". This is not in place of the existing scheme, but as a more verbose alternative. Along those lines, allowing something like:
plot(x1, y1, x2, y2, x3, y3, color=['red','green','blue'])
3) Tick control can be awkward if one simply wants to add an integral number of minor ticks to the chosen major tick interval. Currently using minor ticks forces one to access the plot objects, and specify the major tick interval as well. It would be nice if one could just ask for n minor ticks for each major tick interval by using the appropriate keyword (name tbd). Some illustrations of possible alternatives:
plot(x, y, xmajor=5)
plot(x, y, xmajor=5, xminor=1)
plot(x, y, xminordiv=5) # 5 minor ticks per major regardless of major tick size
Generally, I expect that people set these interactively after plotting without these options. When they see what is automatically produced, this is a simple way of tweaking the plot without doing a lot of object manipulation.
4) The current means of doing overplotting is modal and confusing to many used to IDL's approach. It is easy to forget what the current mode is. IDL uses different commands (e.g., oplot vs plot) to overplot. Some alternatives John and I mentioned:
a) generate 'o' versions of all plot functions (oplot, oimplot, etc.). Easy to do but clutters the namespace.
b) have an 'over' function to apply to all such commands: over(plot, x, y, color='g')
c) use a keyword argument to only apply to the function call:
plot(x, y, hold=True) # doesn't change the hold state after completion, but does overplot
I'm happy to have c) myself.
5) For many customizations plot objects must be manipulated directly. I'm wondering if this is a problem or not (I suspect that it is for a reasonably large class of user). In particular I'm worried that the leap to the object view is sufficiently high enough that many less
sophisticated users will find that an off-putting hurdle. How does matlab handle these sorts of customizations? The same way matplotlib does? If so then I suppose my worries are unfounded. Keeping a lot of the customization exposed within a purely functional interface means
adding more functions or keywords which is its own problem. To be more specific, how minor ticking is handled is a good example of making the keyword interface richer and avoiding object manipulations for common customizations:
plot(x, y, xminordiv=4)
vs
plot(x, y)
ax = gca()
ax.xaxis.set_major_locator(MultipleLocator(20))
ax.xaxis.set_minor_locator(MultipleLocator(5))
# update
The same could be said for specifying different kinds of tickers
6) If one does these object manipulations the display is not updated. One of John's list postings suggests resizing or calling the draw method. The first is often unacceptable, and the second isn't quite so obvious (since it requires specifying a renderer). Perhaps a simple function to do the update that doesn't start a mainloop (as show does) is needed. John responded:
This is a problem. I think the solution may be to override setattr in
the artist base class to call draw_if_interactive. The matlab
interface could add this method at module load time so as to not break
the interface separation between the OO layer and the matlab layer.
I'll have to look into it.
(could it be as simple as defining update() to get the current renderer and then call gcf().draw(currentrenderer)?)
It's possible that there are two or more different kinds of functional interfaces and philosophy such that there should be different modules to satisfy the different camps. But both John and I thought that if at all possible, these sorts of issues should be accommodated within one module. That the matlab (soon to be pylab) shouldn't necessarily be a strict matlab clone in interface but also take some of the better ideas from other packages. Any comments on the above suggestions?
Perry Greenfield