I realized after sending that off that I need to provide more context....sorry about that. What I'm trying to do can be boiled down to the following: I'm trying to place a legend precisely, using the top left corner of legend as the "sticky" point. In other words, if I want to place the legend here: +---------------------------------+-----------+ | | | | | legend | | The plot... |-----------+ | | | | | | | | | | | | +---------------------------------+ I would have thought that I would set bbox_to_anchor = (0,0,1,1), and loc = (1,1). I found out quickly, though, that this places the legend like this: +-----------+ | | | legend | +---------------------------------+-----------+ | | | | | The plot... | | | | | | | | | | | | | +---------------------------------+ Which makes perfect sense from matplotlib's perspective. So all I need to do is figure out how tall the legend is, and subtract that off the y coordinate before passing 'loc' off to matplotlib's legend. I just can't seem to figure out how to get that number. I tried self.ax.get_legend().get_frame().get_height(), but that just returns 1 all the time. Ascii art is fun! :) -- Daniel Hyams dh...@gm...
Daniel Hyams, on 2010年10月29日 17:07, wrote: > I realized after sending that off that I need to provide more > context....sorry about that. > > What I'm trying to do can be boiled down to the following: I'm trying to > place a legend precisely, using the top left corner of legend as the > "sticky" point. In other words, if I want to place the legend here: > > +---------------------------------+-----------+ > | | | > | | legend | > | The plot... |-----------+ > | | > | | > | | > | | > | | > | | > +---------------------------------+ > > I would have thought that I would set bbox_to_anchor = (0,0,1,1), and loc = > (1,1). I found out quickly, though, that this places the legend like this: > +-----------+ > | | > | legend | > +---------------------------------+-----------+ > | | > | | > | The plot... | > | | > | | > | | > | | > | | > | | > +---------------------------------+ > > Which makes perfect sense from matplotlib's perspective. So all I need to > do is figure out how tall the legend is, and subtract that off the y > coordinate before passing 'loc' off to matplotlib's legend. I just can't > seem to figure out how to get that number. I tried > self.ax.get_legend().get_frame().get_height(), but that just returns 1 all > the time. I think you can just get what you want using: plt.plot([3,1,4,1,5,9,2,6,5], label='awesome') plt.legend(bbox_to_anchor=(1,1),loc=2) where loc=2 could have also been written as loc='upper left' > > Ascii art is fun! :) Indeed! P.S. Your posts made it to this and the devel list - they (frustratingly) don't send you your own copy back when you post something. I usually verify that the post went through my checking gmane or sourceforge archives. best, -- Paul Ivanov 314 address only used for lists, off-list direct email at: http://pirsquared.org | GPG/PGP key id: 0x0F3E28F7
Daniel Hyams, on 2010年10月29日 23:48, wrote: > Thanks Paul! Your suggestion got me part of the way, but I've run > into another problem...I'm using draggable legends, I'm also wanting > to fetch the current position of the legend after a drag. The > draggable legend always updates 'loc', and not 'bbox_to_anchor', so > I'm afraid that I'm stuck manipulating 'loc' for my purposes and not > the bbox_to_anchor property. > > Is there really no way to get the dimensions of a legend? It has to be > there somewhere, otherwise the legend wouldn't know where to draw > itself ;) Hi Daniel, I'm replying to the list, so that someone correct me if I'm wrong, or point out a better way of doing this. there totally is a way to get the dimensions of a legend. You can get it in pixel coordinates using l = plt.legend() bbox = l.get_window_extent() bbox.width,bbox.height or in axes coordinates using something like bbox2 = bbox.transformed(l.axes.transAxes.inverted()) bbox2.width,bbox2.height The bboxes have other handy attributes like p0,p1,x0,x1,y0,y1 etc, as well as methods like bbox.padded(), etc. best, -- Paul Ivanov 314 address only used for lists, off-list direct email at: http://pirsquared.org | GPG/PGP key id: 0x0F3E28F7
With Paul's suggestions (greatly appreciated!) I almost have this thing working....there is still something strange going on in that when I call get_window_extent() on the legend, I always get ones and zeros no matter where it is...but that's for another post on another day. This one, I hope, is an easy one. The last thing I need to do is position the legend precisely. For example, the code below doesn't quite position the top left corner of the legend at the top left corner in the plot: import pylab,matplotlib pylab.plot([1,2,3,4,5],[1,2,3,4,5],"bo",label="data") ax = pylab.gca() pylab.legend(bbox_to_anchor=(0,1),loc=2) # draw an X to make sure of coordinates. ax.lines.append(matplotlib.lines.Line2D((0,1),(0,1),transform=ax.transAxes,color='blue')) ax.lines.append(matplotlib.lines.Line2D((0,1),(1,0),transform=ax.transAxes,color='red')) pylab.show() It's close, but not there.....so the question becomes, how do I place a legend exactly at the coordinates that I want? On Sat, Oct 30, 2010 at 1:16 AM, Paul Ivanov <piv...@gm...> wrote: > Daniel Hyams, on 2010年10月29日 23:48, wrote: >> Thanks Paul! Your suggestion got me part of the way, but I've run >> into another problem...I'm using draggable legends, I'm also wanting >> to fetch the current position of the legend after a drag. The >> draggable legend always updates 'loc', and not 'bbox_to_anchor', so >> I'm afraid that I'm stuck manipulating 'loc' for my purposes and not >> the bbox_to_anchor property. >> >> Is there really no way to get the dimensions of a legend? It has to be >> there somewhere, otherwise the legend wouldn't know where to draw >> itself ;) > > Hi Daniel, > > I'm replying to the list, so that someone correct me if I'm > wrong, or point out a better way of doing this. > > there totally is a way to get the dimensions of a legend. > > You can get it in pixel coordinates using > > l = plt.legend() > bbox = l.get_window_extent() > bbox.width,bbox.height > > or in axes coordinates using something like > > bbox2 = bbox.transformed(l.axes.transAxes.inverted()) > bbox2.width,bbox2.height > > The bboxes have other handy attributes like p0,p1,x0,x1,y0,y1 > etc, as well as methods like bbox.padded(), etc. > > best, > -- > Paul Ivanov > 314 address only used for lists, off-list direct email at: > http://pirsquared.org | GPG/PGP key id: 0x0F3E28F7 > > ------------------------------------------------------------------------------ > Nokia and AT&T present the 2010 Calling All Innovators-North America contest > Create new apps & games for the Nokia N8 for consumers in U.S. and Canada > 10ドル million total in prizes - 4ドルM cash, 500 devices, nearly 6ドルM in marketing > Develop with Nokia Qt SDK, Web Runtime, or Java and Publish to Ovi Store > http://p.sf.net/sfu/nokia-dev2dev > _______________________________________________ > Matplotlib-users mailing list > Mat...@li... > https://lists.sourceforge.net/lists/listinfo/matplotlib-users > -- Daniel Hyams dh...@gm...
On Sat, Oct 30, 2010 at 2:16 PM, Paul Ivanov <piv...@gm...> wrote: >> Thanks Paul! Your suggestion got me part of the way, but I've run >> into another problem...I'm using draggable legends, I'm also wanting >> to fetch the current position of the legend after a drag. The >> draggable legend always updates 'loc', and not 'bbox_to_anchor', so >> I'm afraid that I'm stuck manipulating 'loc' for my purposes and not >> the bbox_to_anchor property. > >From svn r8784, you can optionally make legend to update bbox_to_anchor parameter (and leave *loc* untouched) when dragged. d = my_legend.draggable(update="bbox") The default is to update *loc*. Regards, -JJ