I've been working on shifting our axes and gridline plotting work to use matplotlib native constructs. The result is way, way simpler code with much, much nicer pictures. This also clears up a lot of bugs and annoyances that have been expressed for a long time. I'd like some comment on the current work, though.
The ticket is http://trac.sagemath.org/sage_trac/ticket/5448; the patch is http://trac.sagemath.org/sage_trac/attachment/ticket/5448/trac-5448-matplotlib-axes-gridlines.patch. You need the new matplotlib spkg at http://sage.math.washington.edu/home/jason/matplotlib-0.99.0.spkg. This is based against 4.1---I don't have 4.1.1 yet to rebase. Feedback I'm looking for: * Do I need to rebase this against 4.1.1? (Sorry for not trying yet---I'm running out of time to work on this in the near future...) * Are there any big things missing/wrong? (or tiny things?) Also, I noticed that the gridline spec is rather hideous. It follows what I think is a fault of Mathematica, which is that *everything* must be specified in one command. If you want to draw several different horizontal/vertical lines as "gridlines" in mathematica, you must specify them all at once, inside your plot command, and end up with an unreadable mess of double or triple-nested lists. Of course, we have nice objects and easy ways of combining plot objects, which can make the code much, *much* clearer. The current gridline spec is: --------------------------------------------------------------------- - ``gridlines`` - (default: None) can be any of the following: - None, False: do not add grid lines. - True, "automatic", "major": add grid lines at major ticks of the axes. - "minor": add grid at major and minor ticks. - [xlist,ylist]: a tuple or list containing two elements, where xlist (or ylist) can be any of the following. - None, False: don't add horizontal (or vertical) lines. - True, "automatic", "major": add horizontal (or vertical) grid lines at the major ticks of the axes. - "minor": add horizontal (or vertical) grid lines at major and minor ticks of axes. - an iterable yielding numbers n or pairs (n,opts), where n is the coordinate of the line and opt is a dictionary of MATPLOTLIB options for rendering the line. ------------------------------------------------------------------------- I propose instead a spec like the following: ------------------------------------------------------------------------- - ``gridlines`` - (default: False) can be any of the following: - False: do not add grid lines. - True, "major": add grid lines at major ticks of the axes. - "minor": add grid at major and minor ticks. - [xlist,ylist]: a tuple or list containing two elements, where xlist (or ylist) can be any of the following. - False: don't add horizontal (or vertical) lines. - True, "major": add horizontal (or vertical) grid lines at the major ticks of the axes. - "minor": add horizontal (or vertical) grid lines at major and minor ticks of axes. -------------------------------------------------------------------------- To let the user still draw arbitrary horizontal and vertical lines that span the picture, I can make a vertical_line and horizontal_line graphic object, which behave just like the line object, but span the entire picture (so, in a sense, are real infinite lines, not just segments between two points). The end result is code that looks like this: sage: x, y = var('x, y') sage: p = implicit_plot((y^2-x^2)*(x-1)*(2*x-3)-4*(x^2+y^2-2*x)^2, \ ... (x,-2,2), (y,-2,2), plot_points=1000) sage: p.show(gridlines=( ... [ ... (1,{"color":"red","linestyle":":"}), ... (0,{"color":"blue","linestyle":"--"}) ... ], ... [ ... (-1,{"color":"red","linestyle":":"}), ... (0,{"color":"blue","linestyle":"--"}), ... (1,{"color":"red","linestyle":":"}), ... ] ... ), ... gridlinesstyle=dict(marker='x',color="black")) is instead written like this: sage: x, y = var('x, y') sage: p = implicit_plot((y^2-x^2)*(x-1)*(2*x-3)-4*(x^2+y^2-2*x)^2, \ ... (x,-2,2), (y,-2,2), plot_points=1000) sage: opt=dict(marker='x') sage: p += vertical_line(1, color='red', linestyle=':', **opt) sage: p += vertical_line(0, color='blue', linestyle='--', **opt) sage: p += horizontal_line(-1, color='red', linestyle=':', **opt) sage: p += horizontal_line(0, color='blue', linestyle='--', **opt) sage: p += horizontal_line(1, color='red', linestyle=':', **opt) sage: p.show() or maybe even like this: sage: x, y = var('x, y') sage: p = implicit_plot((y^2-x^2)*(x-1)*(2*x-3)-4*(x^2+y^2-2*x)^2, \ ... (x,-2,2), (y,-2,2), plot_points=1000) sage: opt=dict(marker='x') sage: for pos,style in ... [ ... (1,{"color":"red","linestyle":":"}), ... (0,{"color":"blue","linestyle":"--"}) ... ]: ... style.update(opt) ... p += vertical_line(pos, **style) sage: for pos,style in [ ... (-1,{"color":"red","linestyle":":"}), ... (0,{"color":"blue","linestyle":"--"}), ... (1,{"color":"red","linestyle":":"}), ... ]: ... style.update(opt) ... p += horizontal_line(pos, **style) Okay, maybe this isn't as clear-cut as I thought it was. I'm still interested in feedback about which way people prefer things. I'm realizing that sometimes, Mathematica's everything-must-be-a-single-hugely-nested-function-call approach is sometimes just horrendous. Thanks, Jason --~--~---------~--~----~------------~-------~--~----~ To post to this group, send an email to sage-devel@googlegroups.com To unsubscribe from this group, send an email to sage-devel-unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~----------~----~----~----~------~----~------~--~---