Re: [matplotlib-devel] tight subplot parameters

2010-07-22 Thread Eric Firing
On 07/21/2010 05:26 PM, John Hunter wrote:
 On Wed, Jul 21, 2010 at 10:09 PM, Tony S Yutsy...@gmail.com  wrote:
 Wow, I don't see that at all. I'm on OS X, mpl svn HEAD (r8567), and Qt4Agg. 
 I don't have GTK installed, so unfortunately, I can't really do a proper 
 comparison. Here's the output I get from your modified script. I get 
 something similar with TkAgg (unfortunately, I get an AttributeError with 
 the macosx backend).

 Works on my system for tkagg and qtagg4, so the bug appears gtkagg
 specific.  Must be something in the draw vs window realized and sized
 pipeline.  It appears you are getting some bogus size info.Wonder
 if connecting to the draw_event might help here (longshot) or if any
 any of Eric's recent work on show is impacting th behavior here.

No. I modified the script to eliminate the subplots() calls so that I 
could run it on 0.99.3 (the first 2 figures only), and it still doesn't 
work on gtkagg, but does work on qt4agg.

Eric

--
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
___
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel


Re: [matplotlib-devel] tight subplot parameters

2010-07-22 Thread Eric Firing
On 07/21/2010 05:26 PM, John Hunter wrote:
 On Wed, Jul 21, 2010 at 10:09 PM, Tony S Yutsy...@gmail.com  wrote:
 Wow, I don't see that at all. I'm on OS X, mpl svn HEAD (r8567), and Qt4Agg. 
 I don't have GTK installed, so unfortunately, I can't really do a proper 
 comparison. Here's the output I get from your modified script. I get 
 something similar with TkAgg (unfortunately, I get an AttributeError with 
 the macosx backend).

 Works on my system for tkagg and qtagg4, so the bug appears gtkagg
 specific.  Must be something in the draw vs window realized and sized
 pipeline.  It appears you are getting some bogus size info.Wonder
 if connecting to the draw_event might help here (longshot) or if any
 any of Eric's recent work on show is impacting th behavior here.

It is not anything I changed, but it is related to when drawing occurs. 
  The following change makes it work with gtk, and keep working with qt4agg:


efir...@manini:~/temp$ diff -u tight_layout.py tight_layout_gtk.py
--- tight_layout.py 2010-07-21 20:28:16.0 -1000
+++ tight_layout_gtk.py 2010-07-21 20:29:05.0 -1000
@@ -131,6 +131,7 @@
  if __name__ == '__main__':
  import numpy as np
  np.random.seed(1234)
+plt.ion()
  fontsizes = [8, 16, 24, 32]
  def example_plot(ax):
  ax.plot([1, 2])
@@ -164,5 +165,6 @@
  for ax in row:
  example_plot(ax)
  tight_layout()
+plt.ioff()
  fig.savefig('tight5')
  plt.show()


I have not tracked down the reason why gtk is behaving differently; 
drawing with gtkagg is a bit convoluted. It appears that gtk is more 
efficient in delaying drawing, and in drawing only once at the end, 
while the others are less clever, and actually draw when the 
canvas.draw() method is executed.

Eric


 --
 This SF.net email is sponsored by Sprint
 What will you do first with EVO, the first 4G phone?
 Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
 ___
 Matplotlib-devel mailing list
 Matplotlib-devel@lists.sourceforge.net
 https://lists.sourceforge.net/lists/listinfo/matplotlib-devel


--
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
___
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel


Re: [matplotlib-devel] tight subplot parameters

2010-07-22 Thread Michiel de Hoon
--- On Wed, 7/21/10, Tony S Yu tsy...@gmail.com wrote:
 I get something similar with TkAgg (unfortunately, I get an
 AttributeError with the macosx backend).

This is the AttributeError:

Traceback (most recent call last):
  File Desktop/tight_layout.py, line 142, in module
tight_layout()
  File Desktop/tight_layout.py, line 28, in tight_layout
tight_subplot_spacing(fig, h_pad_inches, w_pad_inches)
  File Desktop/tight_layout.py, line 64, in tight_subplot_spacing
ax_bottom, ax_top, ax_left, ax_right = _get_grid_boundaries(fig)
  File Desktop/tight_layout.py, line 99, in _get_grid_boundaries
renderer = fig.canvas.get_renderer()
AttributeError: 'FigureCanvasMac' object has no attribute 'get_renderer'
 

Is a backend required to implement a get_renderer method? I only see it 
implemented in backend_agg.py, and it's missing in backend_bases.py, 
backend_template.py, backend_cairo.py, and in the macosx backend. If you want 
to try your code with the macosx backend, you can use fig.canvas.renderer 
instead of fig.canvas.get_renderer().

--Michiel.


  

--
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
___
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel


Re: [matplotlib-devel] tight subplot parameters

2010-07-22 Thread John Hunter
On Thu, Jul 22, 2010 at 7:40 AM, Michiel de Hoon mjldeh...@yahoo.com wrote:

 Is a backend required to implement a get_renderer method? I only see it 
 implemented in backend_agg.py, and it's missing in backend_bases.py, 
 backend_template.py, backend_cairo.py, and in the macosx backend. If you want 
 to try your code with the macosx backend, you can use fig.canvas.renderer 
 instead of fig.canvas.get_renderer().

According to backend_bases.FigureCanvas, a renderer attr is not
guaranteed either.
The Agg* backends rely on get_renderer so that they can get a properly
sized renderer on figure resizes, dpi changes, etc.  We could handle
this on the agg side with a property, or require all canvases to
supply get renderer.

The tricky bit is that renderers may not be available until draw time
for some backends, and thus may not have proper size information if
accessed too early (this is probably at the heart of the gtk bug we
are seeing).  It is probably a good idea to settle on something so
developers can get access to the renderer in a consistent state, and
this might require support a raise_event which one could connect to
and get the figure as soon as it is raised (which would be triggered
on canvas creation for non gui backends presumably and after the
window is raised for gui backends).  In the callback, accessing
canvas.renderer or canvas.get_renderer would return a renderer with
proper sizing.

JDH

--
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
___
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel


Re: [matplotlib-devel] tight subplot parameters

2010-07-22 Thread Tony S Yu

On Jul 22, 2010, at 8:59 AM, John Hunter wrote:

 On Thu, Jul 22, 2010 at 7:40 AM, Michiel de Hoon mjldeh...@yahoo.com wrote:
 
 Is a backend required to implement a get_renderer method? I only see it 
 implemented in backend_agg.py, and it's missing in backend_bases.py, 
 backend_template.py, backend_cairo.py, and in the macosx backend. If you 
 want to try your code with the macosx backend, you can use 
 fig.canvas.renderer instead of fig.canvas.get_renderer().
 
 According to backend_bases.FigureCanvas, a renderer attr is not
 guaranteed either.
 The Agg* backends rely on get_renderer so that they can get a properly
 sized renderer on figure resizes, dpi changes, etc.  We could handle
 this on the agg side with a property, or require all canvases to
 supply get renderer.
 
 The tricky bit is that renderers may not be available until draw time
 for some backends, and thus may not have proper size information if
 accessed too early (this is probably at the heart of the gtk bug we
 are seeing).  It is probably a good idea to settle on something so
 developers can get access to the renderer in a consistent state, and
 this might require support a raise_event which one could connect to
 and get the figure as soon as it is raised (which would be triggered
 on canvas creation for non gui backends presumably and after the
 window is raised for gui backends).  In the callback, accessing
 canvas.renderer or canvas.get_renderer would return a renderer with
 proper sizing.
 
 JDH

Sorry, I don't know much about how the backends are structured. But this talk 
of backends got me thinking: Since the Agg backend (non-GUI version) is 
guaranteed to be installed (correct?), you could create an Agg renderer, and 
just use that to calculate all the sizing information. This experiment worked 
for all GUI backends on my system (Qt4Agg, TkAgg, MacOSX).

Are there any downsides to using Agg to calculate sizing info and then 
rendering again on a GUI backend? Performance issues? I guess it's possible 
differences in sizing between backends will show up in the resized subplots, 
but these differences should be small, right?

-Tony

P.S. I've removed calls to subplots in example code for easier testing.

import numpy as np

import matplotlib.pyplot as plt
from matplotlib.backends.backend_agg import RendererAgg
from matplotlib.transforms import TransformedBbox, Affine2D


PAD_INCHES = 0.1


def tight_layout(pad_inches=PAD_INCHES, h_pad_inches=None, w_pad_inches=None):
Adjust subplot parameters to give specified padding.

Parameters
--
pad_inches : float
minimum padding between the figure edge and the edges of subplots.
h_pad_inches, w_pad_inches : float
minimum padding (height/width) between edges of adjacent subplots.
Defaults to `pad_inches`.

if h_pad_inches is None:
h_pad_inches = pad_inches
if w_pad_inches is None:
w_pad_inches = pad_inches

fig = plt.gcf()
renderer = RendererAgg(fig.get_figwidth(),
   fig.get_figheight(),
   fig.get_dpi())

tight_borders(fig, renderer, pad_inches=pad_inches)
# NOTE: border padding affects subplot spacing; tighten border first
tight_subplot_spacing(fig, renderer, h_pad_inches, w_pad_inches)


def tight_borders(fig, renderer, pad_inches=PAD_INCHES):
Stretch subplot boundaries to figure edges plus padding.
# call draw to update the renderer and get accurate bboxes.
fig.draw(renderer)
bbox_original = fig.bbox_inches
bbox_tight = fig.get_tightbbox(renderer).padded(pad_inches)

# figure dimensions ordered like bbox.extents: x0, y0, x1, y1
lengths = np.array([bbox_original.width, bbox_original.height,
bbox_original.width, bbox_original.height])
whitespace = (bbox_tight.extents - bbox_original.extents) / lengths

# border padding ordered like bbox.extents: x0, y0, x1, y1
current_borders = np.array([fig.subplotpars.left, fig.subplotpars.bottom,
fig.subplotpars.right, fig.subplotpars.top])

left, bottom, right, top = current_borders - whitespace
fig.subplots_adjust(bottom=bottom, top=top, left=left, right=right)


def tight_subplot_spacing(fig, renderer, h_pad_inches, w_pad_inches):
Stretch subplots so adjacent subplots are separated by given padding.
# Zero hspace and wspace to make it easier to calculate the spacing.
fig.subplots_adjust(hspace=0, wspace=0)
fig.draw(renderer)

figbox = fig.bbox_inches
ax_bottom, ax_top, ax_left, ax_right = _get_grid_boundaries(fig, renderer)
nrows, ncols = ax_bottom.shape

subplots_height = fig.subplotpars.top - fig.subplotpars.bottom
if nrows  1:
h_overlap_inches = ax_top[1:] - ax_bottom[:-1]
hspace_inches = h_overlap_inches.max() + h_pad_inches
hspace_fig_frac = hspace_inches / figbox.height
hspace = 

Re: [matplotlib-devel] tight subplot parameters

2010-07-22 Thread John Hunter
On Thu, Jul 22, 2010 at 8:57 AM, Tony S Yu tsyu80@

 According to backend_bases.FigureCanvas, a renderer attr is not
 guaranteed either.
 The Agg* backends rely on get_renderer so that they can get a properly
 sized renderer on figure resizes, dpi changes, etc.  We could handle
 this on the agg side with a property, or require all canvases to
 supply get renderer.

No, this won't work because the sizing information depends on the GUI
window size.  Agg adapts the renderer to the GUI window size.  So in
GTKAgg we are using the Agg renderer, but GTK is determining the
window size when it is raised.   We try to get GTK to produce a canvas
of a fixed size, but cannot guarantee it so we reset the renderer size
in necessary when the canvas is raised.

JDH

--
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
___
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel


Re: [matplotlib-devel] tight subplot parameters

2010-07-22 Thread Michiel de Hoon
--- On Thu, 7/22/10, John Hunter jdh2...@gmail.com wrote:
 We could handle this on the agg side with a property,
 or require all canvases to supply get renderer.
 
Do we actually need a renderer in each of the backends? At least when I was 
writing the Mac OS X backend, it was not clear to me what functionality should 
go in the renderer and what should go in the graphics context. I expect that 
the same is true for the other postscript-style backends such as the cairo, 
pdf, and ps backends.

In the end, I decided to mainly use the graphics context because it nicely maps 
to the Quartz graphics context at the C level, whereas the renderer doesn't 
have a corresponding data structure at the C level. In the Mac OS X backend, 
basically what the renderer does is to forward to the graphics context. In the 
ps backend most of the work is being done in the renderer instead of the 
graphics context, but again this is just a choice. I think that we should first 
remove such inconsistencies between backends.

--Michiel


  

--
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
___
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel


Re: [matplotlib-devel] tight subplot parameters

2010-07-22 Thread Tony S Yu

On Jul 22, 2010, at 10:07 AM, John Hunter wrote:

 On Thu, Jul 22, 2010 at 8:57 AM, Tony S Yu tsyu80@
 
 According to backend_bases.FigureCanvas, a renderer attr is not
 guaranteed either.
 The Agg* backends rely on get_renderer so that they can get a properly
 sized renderer on figure resizes, dpi changes, etc.  We could handle
 this on the agg side with a property, or require all canvases to
 supply get renderer.
 
 No, this won't work because the sizing information depends on the GUI
 window size.  Agg adapts the renderer to the GUI window size.  So in
 GTKAgg we are using the Agg renderer, but GTK is determining the
 window size when it is raised.   We try to get GTK to produce a canvas
 of a fixed size, but cannot guarantee it so we reset the renderer size
 in necessary when the canvas is raised.
 
 JDH

I'm not sure if I understand. Are you talking about responding to window 
resizing events, or are you saying that Figure.get_height/get_width don't match 
the window size for some GUI backends? 

I create the Agg renderer based on Figure.get_height/get_width. If the window 
is resized, then the layout would definitely change, but you could call 
`tight_layout` again to adjust subplot spacing (which would create a new Agg 
renderer based on the new window size). Am I missing something here? Were you 
thinking I wanted to interactively adapt the spacings? (If that's the case, I 
wasn't that ambitious.)

-Tony
--
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
___
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel


Re: [matplotlib-devel] tight subplot parameters

2010-07-21 Thread John Hunter
On Wed, Jul 21, 2010 at 10:09 PM, Tony S Yu tsy...@gmail.com wrote:
 Wow, I don't see that at all. I'm on OS X, mpl svn HEAD (r8567), and Qt4Agg. 
 I don't have GTK installed, so unfortunately, I can't really do a proper 
 comparison. Here's the output I get from your modified script. I get 
 something similar with TkAgg (unfortunately, I get an AttributeError with the 
 macosx backend).

Works on my system for tkagg and qtagg4, so the bug appears gtkagg
specific.  Must be something in the draw vs window realized and sized
pipeline.  It appears you are getting some bogus size info.Wonder
if connecting to the draw_event might help here (longshot) or if any
any of Eric's recent work on show is impacting th behavior here.

--
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
___
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel


Re: [matplotlib-devel] tight subplot parameters

2010-07-21 Thread Tony S Yu

On Jul 21, 2010, at 11:26 PM, John Hunter wrote:

 On Wed, Jul 21, 2010 at 10:09 PM, Tony S Yu tsy...@gmail.com wrote:
 Wow, I don't see that at all. I'm on OS X, mpl svn HEAD (r8567), and Qt4Agg. 
 I don't have GTK installed, so unfortunately, I can't really do a proper 
 comparison. Here's the output I get from your modified script. I get 
 something similar with TkAgg (unfortunately, I get an AttributeError with 
 the macosx backend).
 
 Works on my system for tkagg and qtagg4, so the bug appears gtkagg
 specific.  Must be something in the draw vs window realized and sized
 pipeline.  It appears you are getting some bogus size info.Wonder
 if connecting to the draw_event might help here (longshot) or if any
 any of Eric's recent work on show is impacting th behavior here.

Well, since I don't have access to GTK, it's not really something I can debug 
(kind of a cop out, I know).  

Your original GTK image is really strange: it seems as though the script moves 
the ticks, axis labels, and titles relative to their associated axes-frame. But 
the only function I use to affect the plot spacing is Figure.subplots_adjust 
(everything else in the script serves to calculate appropriate spacing-values). 
I don't think Figure.subplots_adjust is designed to move the 
ticks/axis-labels/titles relative to its own axes, right?

-Tony
--
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
___
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel