Ticket #4342 (assigned enhancement)

Opened 3 months ago

Last modified 1 week ago

[with patch; positive review] Add legends to plot.py

Reported by: anakha Assigned to: anakha (accepted)
Priority: major Milestone: sage-3.4
Component: graphics Keywords:
Cc:

Description

Add support for placing legends on plots using the matplotlib facility for doing so.

Attachments

trac_4342.patch (20.8 kB) - added by anakha on 10/22/2008 03:48:48 PM.
trac_4342-2.patch (7.4 kB) - added by anakha on 10/23/2008 02:35:20 PM.
trac_4342-3.patch (1.6 kB) - added by TimothyClemans on 11/09/2008 03:26:08 PM.
mvngu's doc fixes
trac_4342.2.patch (24.2 kB) - added by mhansen on 11/27/2008 11:07:46 PM.
trac_4342_v3.patch (34.8 kB) - added by abergeron on 12/30/2008 08:23:38 PM.
trac_4342_v3.2.patch (34.6 kB) - added by abergeron on 12/30/2008 08:26:42 PM.

Change History

10/22/2008 03:48:48 PM changed by anakha

  • attachment trac_4342.patch added.

10/22/2008 03:51:32 PM changed by anakha

  • status changed from new to assigned.
  • summary changed from Add legends to plot.py to [with patch; needs review] Add legends to plot.py.

Add the option to put legends on plots.

Also fixes three long test markers that where reading #long rather than #long time and two or three minor documentation mistakes elsewhere in the code. These where bundled because they don't warrant a separate ticket for me but are still nice to fix.

10/23/2008 02:35:08 PM changed by anakha

  • type changed from defect to enhancement.

New patch to pass options around in a better way. Also now use @suboptions marker from #4203 so you need to apply that patch first.

10/23/2008 02:35:20 PM changed by anakha

  • attachment trac_4342-2.patch added.

(follow-up: ↓ 4 ) 10/27/2008 05:46:44 AM changed by mvngu

For the patch trac_4342.patch, here are possible fixes to your documentation:

1.

-denoting a color or an rgb tuple. The string can be a color name
+denoting a color or an RGB tuple. The string can be a color name

2.

-If called with no input return the current legend setting.
+If called with no input, return the current legend setting.

3.

-Sets the legend label font
+Sets the legend label font.

4.

-form is just a floating point rgb tuple with all values ranging
+form is just a floating point RGB tuple with all values ranging

11/09/2008 03:26:08 PM changed by TimothyClemans

  • attachment trac_4342-3.patch added.

mvngu's doc fixes

(in reply to: ↑ 3 ) 11/09/2008 03:28:45 PM changed by TimothyClemans

Replying to mvngu:

For the patch trac_4342.patch, here are possible fixes to your documentation:

1. {{{ -denoting a color or an rgb tuple. The string can be a color name +denoting a color or an RGB tuple. The string can be a color name }}} 2. {{{ -If called with no input return the current legend setting. +If called with no input, return the current legend setting. }}} 3. {{{ -Sets the legend label font +Sets the legend label font. }}} 4. {{{ -form is just a floating point rgb tuple with all values ranging +form is just a floating point RGB tuple with all values ranging }}}

I uploaded a patch with these fixes.

Mvngu, in the future please upload patches with your doc fixes. Thanks :)

11/27/2008 11:07:46 PM changed by mhansen

  • attachment trac_4342.2.patch added.

11/27/2008 11:10:53 PM changed by mhansen

I've folded all the patches together and rebased them against plot.py refactoring. These are in trac_4342.2.patch .

I'll try to give this a proper review sometime this weekend.

12/12/2008 01:25:02 PM changed by jason

what's the status on this? Mike, did you have time to look at it?

12/29/2008 07:22:59 PM changed by wdj

  • summary changed from [with patch; needs review] Add legends to plot.py to [with patch; negative review] Add legends to plot.py.

The good news is that Mike Hansen's patch does apply cleanly to 3.2.2.

The bad news is that this patch breaks some basic functionality:

sage: p = plot(tan(x), x, -1/2, 1/2)
sage: show(p)

raises a TypeError? exception.

That is serious but more serious (to me - maybe this exception is an easy-to-fix bug) is the design of this legend functionality.

It seems to me (and people who know about the Graphics class can hopefully correct me if I am wrong) the following is both possible and a fairly natural way of writing a legend as another graphics object:

1. given 2d plot objects P, Q (ie, instances of a Graphics class), one could wrote a function which returns (a) the functions being plotted in P,Q (resp), (b) the line style used in P,Q (resp). From this data, one can write a function taking P,Q (and a cnter point) as arguments (more generally any list of such plot objects) and returning a legend as an analog of a text plot. This can be placed anywhere by choosing the center point appropriately.

I'm happy to change my opinion (since IMHO this added functionality would be great), especially if someone with more knowledge of the plotting can comment positively on this. I really greatly appreciate the hard programming work that went into this. Maybe I'm being naive but the design to me seems a bit awkward, and in any case it breaks show (which is bad, hence making it a "show stopper", if you excuse the horribly bad pun).

12/29/2008 07:28:36 PM changed by mabshoff

  • summary changed from [with patch; negative review] Add legends to plot.py to [with patch; needs work] Add legends to plot.py.

There is no such thing as "negative review", but there is "needs work".

Cheers,

Michael

12/30/2008 08:23:38 PM changed by abergeron

  • attachment trac_4342_v3.patch added.

12/30/2008 08:26:42 PM changed by abergeron

  • attachment trac_4342_v3.2.patch added.

12/30/2008 08:46:15 PM changed by abergeron

  • summary changed from [with patch; needs work] Add legends to plot.py to [with patch; needs review] Add legends to plot.py.

The last patch (trac_4342_v3.2.patch) fixes the TypeError? problem and add tests and documentation where appropriate (can't believe I missed these).

As far as I know, there is no way to get the function that's being plotted from the GraphicsPrimitve? object (except maybe for some specialized primitives like Circle) because all you have is a matrix of sample points. So I don't think it is a good way.

About the center point, it is already possible to specify a tuple of floats between 0 and 1 that gives the relative coordinates of the legend box.

And last, about the design, I kind of copied it from matplotlib where each object is labeled beforehand. I could always provide an option to specify legend labels in show() and save() but due to the design of Graphics I think this would be shaky at best because the user has now reliable way of knowing the content of a Graphics object.

Anyway if some clever way of overcoming the obstacle(s) above is found then something like what you want could be implemented in a later patch.

12/31/2008 04:57:45 AM changed by wdj

Can you please explain exactly which patches to apply and in which order from a new clone of Sage? I can't get them to apply cleanly.

12/31/2008 11:30:08 AM changed by abergeron

You only need trac_4342_v3.2.patch. Ignore all others.

12/31/2008 12:51:44 PM changed by wdj

  • summary changed from [with patch; needs review] Add legends to plot.py to [with patch; positive review] Add legends to plot.py.

Again, I am having trouble running tests, so I can't say if they all pass. The examples seem fine (if somewhat too few). Still, which this very clever bit of programmming, this block of commands

sage: P1 = plot(exp(x), 0, 2, legend_label='$y=e^x$')
sage: P2 = plot(sin(x), 0, 2, rgbcolor=(1,0,0),legend_label='$y=\sin(x)$')
sage: show(P1+P2)

produces a beautiful plot of two curves, one red and the other blue, and the legend labels are collected into a distinctive light grey box with the correct labels.

Wonderful!!