Lines and columns in legends

Jae-Joon hi,

I am a newbie with matplolib. I need a horizontal legend because my figures are pretty wide and I need to automate the process of generating it.

Since matplotlib does not support horizontal legends I am hacking around it.

I modified your example below. So the following works:

from matplotlib.pylab import *
from matplotlib.legend import Legend
from matplotlib.patches import Rectangle

#fig = figure()
ax = gca()
pl_list = []
for i in range(10):
pl, = ax.plot(random(10))
pl_list.append(pl)

xleg,yleg= 0.5,0.5

l1 = Legend(ax, pl_list[0:1], “0”, loc=1)
hg1, wd1 = l1.get_frame().get_height(), l1.get_frame().get_width()
l2 = Legend(ax, pl_list[1:2], “1”, loc=1)
hg2, wd2 = l2.get_frame().get_height(), l2.get_frame().get_width()
l3 = Legend(ax, pl_list[2:3], “2”, loc=1)
hg3, wd3 = l3.get_frame().get_height(), l3.get_frame().get_width()
l4 = Legend(ax, pl_list[3:4], “3”, loc=1)
hg4, wd4 = l4.get_frame().get_height(), l4.get_frame().get_width()

total_height = hg1
total_width = wd1+wd2+wd3+wd4

print total_height, total_width

l1 = Legend(ax, pl_list[0:1], “0”, loc=(xleg, yleg))
l2 = Legend(ax, pl_list[1:2], “1”, loc=(xleg+wd1/5, yleg))
l3 = Legend(ax, pl_list[2:3], “2”, loc=(xleg+(wd1+wd2)/5, yleg))
l4 = Legend(ax, pl_list[3:4], “3”, loc=(xleg+(wd1+wd2+wd3)/5, yleg))
l1.get_frame().set_visible(False) # make background frame of legends invisible
l2.get_frame().set_visible(False)
l3.get_frame().set_visible(False)
l4.get_frame().set_visible(False)

make a large background frame

rect = Rectangle((xleg, yleg), 0.45, 0.05, # adjust these values (in normalized axes coordinate)
fc=“w”, ec=“k”,
transform=ax.transAxes, zorder=4)
ax.add_artist(rect)
ax.add_artist(l1)
ax.add_artist(l2)
ax.add_artist(l3)
ax.add_artist(l4)

The basic idea is to create a legend with the line and label I need and then use its dimensions to create the background frame.

The problem is that the height and width I get are in different units that the normalized axes coordinates and I do not know how

to properly transfrom them which leads to the hacky /5 , otherwise the legends are off the figure.

Any suggestions on how I can automate this part?

Thanks in advance.

Jae-Joon Lee
Thu, 09 Oct 2008 12:21:56 -0700

Although I think it is possible to calculate the bounding box of the
all legends automatically,
Here is a manual way.

from matplotlib.patches import Rectangle

l1.get_frame().set_visible(False) # make background frame of legends invisible

l2.get_frame().set_visible(False)

# make a large background frame
rect = Rectangle((0.05, 0.75), 0.3, 0.2, # adjust these values (in
normalized axes coordinate)
                 fc="w", ec="k",

                 transform=ax.transAxes, zorder=4)
ax.add_artist(rect)

I hope this help,

-JJ

<details class='elided'>
<summary title='Show trimmed content'>&#183;&#183;&#183;</summary>

On Thu, Oct 9, 2008 at 2:43 PM, José Alexandre Nalon <[EMAIL PROTECTED]> wrote:
> Hello,

>
> Em Thursday 09 October 2008 13:46:52 Jae-Joon Lee escreveu:
>> Meanwhile, you may try to make multiple legends as a posible workarounds.
>
> Thanks for your answer. That did the trick, and the figure

> looks more or less as I wanted. It would look exactly as I
> wanted if I could remove the border from the legends and
> draw a box around the legends. How could I do that?
>
> (I apologize if this seems trivial. I use matplotlib a lot,

> but standard functions always seem to do what I need, so I
> don't go deep in its behaviour).
>
> --
> José Alexandre Nalon
> [EMAIL PROTECTED]
>
> -------------------------------------------------------------------------

> This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
> Build the coolest Linux based applications with Moblin SDK & win great prizes
> Grand prize is a trip for two to an Open Source event anywhere in the world

> [http://moblin-contest.org/redirect.php?banner_id=100&url=/](http://moblin-contest.org/redirect.php?banner_id=100&url=/)
> _______________________________________________
> Matplotlib-users mailing list

> Matplotlib-users@lists.sourceforge.net
> [https://lists.sourceforge.net/lists/listinfo/matplotlib-users](https://lists.sourceforge.net/lists/listinfo/matplotlib-users)

>
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes

Grand prize is a trip for two to an Open Source event anywhere in the world
[http://moblin-contest.org/redirect.php?banner_id=100&url=/](http://moblin-contest.org/redirect.php?banner_id=100&url=/)

_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
[https://lists.sourceforge.net/lists/listinfo/matplotlib-users](https://lists.sourceforge.net/lists/listinfo/matplotlib-users)

The recent version of the mpl now supports multi-column legend.

http://matplotlib.sourceforge.net/examples/pylab_examples/legend_demo3.html

Thus, it would be great if you to try the new version, and if your
problem is still not solved, please report it again.

Regards,

-JJ

···

On Sun, Apr 12, 2009 at 11:12 PM, Vasileios Kontorinis <bkontorinis@...287...> wrote:

Jae-Joon hi,

I am a newbie with matplolib. I need a horizontal legend because my
figures are pretty wide and I need to automate the process of generating it.

Since matplotlib does not support horizontal legends I am hacking around it.

I modified your example below. So the following works:

from matplotlib.pylab import *
from matplotlib.legend import Legend
from matplotlib.patches import Rectangle

#fig = figure()
ax = gca()
pl_list =
for i in range(10):
pl, = ax.plot(random(10))
pl_list.append(pl)

xleg,yleg= 0.5,0.5

l1 = Legend(ax, pl_list[0:1], "0", loc=1)
hg1, wd1 = l1.get_frame().get_height(), l1.get_frame().get_width()
l2 = Legend(ax, pl_list[1:2], "1", loc=1)
hg2, wd2 = l2.get_frame().get_height(), l2.get_frame().get_width()
l3 = Legend(ax, pl_list[2:3], "2", loc=1)
hg3, wd3 = l3.get_frame().get_height(), l3.get_frame().get_width()
l4 = Legend(ax, pl_list[3:4], "3", loc=1)
hg4, wd4 = l4.get_frame().get_height(), l4.get_frame().get_width()

total_height = hg1
total_width = wd1+wd2+wd3+wd4

print total_height, total_width

l1 = Legend(ax, pl_list[0:1], "0", loc=(xleg, yleg))
l2 = Legend(ax, pl_list[1:2], "1", loc=(xleg+wd1/5, yleg))
l3 = Legend(ax, pl_list[2:3], "2", loc=(xleg+(wd1+wd2)/5, yleg))
l4 = Legend(ax, pl_list[3:4], "3", loc=(xleg+(wd1+wd2+wd3)/5, yleg))
l1.get_frame().set_visible(False) # make background frame of legends
invisible
l2.get_frame().set_visible(False)
l3.get_frame().set_visible(False)
l4.get_frame().set_visible(False)

# make a large background frame
rect = Rectangle((xleg, yleg), 0.45, 0.05, # adjust these values (in
normalized axes coordinate)
fc="w", ec="k",
transform=ax.transAxes, zorder=4)
ax.add_artist(rect)
ax.add_artist(l1)
ax.add_artist(l2)
ax.add_artist(l3)
ax.add_artist(l4)

The basic idea is to create a legend with the line and label I need and then
use its dimensions to create the background frame.

The problem is that the height and width I get are in different units that
the normalized axes coordinates and I do not know how

to properly transfrom them which leads to the hacky /5 , otherwise the
legends are off the figure.

Any suggestions on how I can automate this part?

Thanks in advance.

Jae-Joon Lee
Thu, 09 Oct 2008 12:21:56 -0700

Although I think it is possible to calculate the bounding box of the
all legends automatically,
Here is a manual way.

from matplotlib.patches import Rectangle

l1.get_frame().set_visible(False) # make background frame of legends
invisible

l2.get_frame().set_visible(False)

# make a large background frame
rect = Rectangle((0.05, 0.75), 0.3, 0.2, # adjust these values (in
normalized axes coordinate)
                 fc="w", ec="k",

                 transform=ax.transAxes, zorder=4)
ax.add_artist(rect)

I hope this help,

-JJ

On Thu, Oct 9, 2008 at 2:43 PM, José Alexandre Nalon <[EMAIL PROTECTED]> > wrote:

Hello,

Em Thursday 09 October 2008 13:46:52 Jae-Joon Lee escreveu:

Meanwhile, you may try to make multiple legends as a posible workarounds.

Thanks for your answer. That did the trick, and the figure

looks more or less as I wanted. It would look exactly as I
wanted if I could remove the border from the legends and
draw a box around the legends. How could I do that?

(I apologize if this seems trivial. I use matplotlib a lot,

but standard functions always seem to do what I need, so I
don't go deep in its behaviour).

--
José Alexandre Nalon
[EMAIL PROTECTED]

-------------------------------------------------------------------------

This SF.Net email is sponsored by the Moblin Your Move Developer's
challenge
Build the coolest Linux based applications with Moblin SDK & win great
prizes
Grand prize is a trip for two to an Open Source event anywhere in the
world

http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Matplotlib-users mailing list

Matplotlib-users@lists.sourceforge.net
matplotlib-users List Signup and Options

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great
prizes

Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/

_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
matplotlib-users List Signup and Options

------------------------------------------------------------------------------
This SF.net email is sponsored by:
High Quality Requirements in a Collaborative Environment.
Download a free trial of Rational Requirements Composer Now!
http://p.sf.net/sfu/www-ibm-com
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
matplotlib-users List Signup and Options