legend refactoring

Dear Matplotlib developers,

Attached is a patch to improve the functionality of legend.
The two biggest changes are as follows,

* Drawing of legend is delegated to "legend handlers".
* Introduces a new "Container" class. This is primarily to support
legend of complex plots (e.g., bar, errorbar, etc).

The first change is to ease the creation of customized legends. See
"legend_demo_custom_handler.py" for example.
The second change is to support legend of complex plots. Axes
instances now have a "containers" attribute. And this is only intended
to be used for generating a legend. For example, "bar" plots create a
series of Rectangle patches. Previously, it returned a list of these
patches. With the current change, it creates a container object of
these rectangle patches and return it instead. As the container class
is derived from a tuple, it should be backward-compatible.
Furthermore, the container object is added to the Axes.containers
attributes. And legend command use this "container" attribute to
properly create a legend for the bar.

A two example figures are attached.

As this patch introduces relatively significant changes. I wanted to
get some comments from others before I commit.
The change will be divided into four commits.

Regards,

-JJ

legend_demo_custom_handler.png

legend_demo4.png

legend_refactor.patch (38.7 KB)

Nice. I will look through it this week and see if I can break it.

Ben Root

···

On Tue, Jan 18, 2011 at 12:27 AM, Jae-Joon Lee <lee.j.joon@…552…149…> wrote:

Dear Matplotlib developers,

Attached is a patch to improve the functionality of legend.

The two biggest changes are as follows,

  • Drawing of legend is delegated to “legend handlers”.

  • Introduces a new “Container” class. This is primarily to support

legend of complex plots (e.g., bar, errorbar, etc).

The first change is to ease the creation of customized legends. See

“legend_demo_custom_handler.py” for example.

The second change is to support legend of complex plots. Axes

instances now have a “containers” attribute. And this is only intended

to be used for generating a legend. For example, “bar” plots create a

series of Rectangle patches. Previously, it returned a list of these

patches. With the current change, it creates a container object of

these rectangle patches and return it instead. As the container class

is derived from a tuple, it should be backward-compatible.

Furthermore, the container object is added to the Axes.containers

attributes. And legend command use this “container” attribute to

properly create a legend for the bar.

A two example figures are attached.

As this patch introduces relatively significant changes. I wanted to

get some comments from others before I commit.

The change will be divided into four commits.

Regards,

-JJ

Jae-Joon,

I finally got around to doing some testing with your refactor of legend. I find the concepts behind the refactor interesting, however the current implementation doesn’t seem to work properly in some basic use-cases.

In particular, the following just produces an empty box:

import matplotlib.pyplot as plt

x = [1,2,3,4,5]
y1 = [1, 2, 3, 4, 5]
y2 = [5, 4, 3, 2, 1]

plt.plot(x, y1, ‘rx-’)
plt.plot(x, y2, ‘bx-’)

plt.legend((‘a’, ‘b’))

plt.show()

However, it does work if I use the label= kwarg in the plot commands.

Another use-case that doesn’t seem addressed yet (and isn’t quite right in regular mpl either) is legends for stemplots.

I haven’t tried out the new features yet, as I am mostly concerned about backwards-compatibility right now.

Ben Root

···

On Sat, Jan 22, 2011 at 10:18 AM, Benjamin Root <ben.root@…867…> wrote:

On Tue, Jan 18, 2011 at 12:27 AM, Jae-Joon Lee <lee.j.joon@…149…> wrote:

Dear Matplotlib developers,

Attached is a patch to improve the functionality of legend.

The two biggest changes are as follows,

  • Drawing of legend is delegated to “legend handlers”.

  • Introduces a new “Container” class. This is primarily to support

legend of complex plots (e.g., bar, errorbar, etc).

The first change is to ease the creation of customized legends. See

“legend_demo_custom_handler.py” for example.

The second change is to support legend of complex plots. Axes

instances now have a “containers” attribute. And this is only intended

to be used for generating a legend. For example, “bar” plots create a

series of Rectangle patches. Previously, it returned a list of these

patches. With the current change, it creates a container object of

these rectangle patches and return it instead. As the container class

is derived from a tuple, it should be backward-compatible.

Furthermore, the container object is added to the Axes.containers

attributes. And legend command use this “container” attribute to

properly create a legend for the bar.

A two example figures are attached.

As this patch introduces relatively significant changes. I wanted to

get some comments from others before I commit.

The change will be divided into four commits.

Regards,

-JJ

Nice. I will look through it this week and see if I can break it.

Ben Root

In particular, the following just produces an empty box:

This has been fixed in my side, and the fix will be included when I commit.

Another use-case that doesn't seem addressed yet (and isn't quite right in
regular mpl either) is legends for stemplots.

So far, I only implemented legend for "bars" and "errorbars". For
other plots, such as stemplot, while I'll try to implement some of
them eventually, contribution from others will be needed.

Regards,

-JJ

···

On Sun, Feb 13, 2011 at 6:08 AM, Benjamin Root <ben.root@...553...> wrote: