Re: [matplotlib-devel] tight subplot parameters

2010-07-22 Thread Michiel de Hoon
--- On Wed, 7/21/10, Tony S Yu  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 
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
[email protected]
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  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
[email protected]
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  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
  

Re: [matplotlib-devel] tight subplot parameters

2010-07-22 Thread John Hunter
On Thu, Jul 22, 2010 at 8:57 AM, Tony S Yu > 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
[email protected]
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  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
[email protected]
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  
>>> 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
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel


Re: [matplotlib-devel] rendering problem in mplot3d

2010-07-22 Thread Benjamin Root
On Mon, Jul 19, 2010 at 10:13 AM, Ryan May  wrote:

> On Sun, Jul 18, 2010 at 6:16 PM, Benjamin Root  wrote:
> > A few corrections.  First, I wrong, it is unusual.  The second axes that
> I
> > noticed in a 2d case came from a colorbar being added.  Second, in the 3d
> > case, it was the Axes3DSubplot object being added twice, not the regular
> > object like I originally said.
> >
> > The cause of this is due to the Axes3D initializer adding itself to the
> > figure object being passed in.  This initializer is called when
> > add_subplot() is called, so add_subplot also adds the axes when it is
> > finished making it.  For normal projections, the initializer does not add
> > itself to the axes.
> >
> > Removing the add_axes in the Axes3D initializer would "solve" the issue
> > outright, however, there are plenty of legacy code where Axes3D is called
> > with a figure passed in in order to create the axes, and this would break
> > that use pattern.
>
> I think the fact that add_axes will just blindly add a duplicate axes
> is a bug. So why not have add_axes do something like the following:
>
> if ax not in axes_list:
>  axes_list.append(ax)
>  
>
> Anyone see anything wrong with this approach?
>
>
I agree, this is probably the best way to nip this in the bud without
breaking backwards compatibility.  However, I am concerned that this might
bury other bugs (current or future) by preventing a mistake from making
itself apparent.  Is there some way to have a special warning put out in the
"else" branch of that if?

Ben Root
--
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel


Re: [matplotlib-devel] plot artifacts when zoomed in

2010-07-22 Thread Benjamin Root
Heh, looks more pervasive than just the Tkinter backend, and it isn't just
caused by zooming.  Just moving the image off to the side is enough, and
saving that figure using the "Save" button produces this attached image.

And further testing shows that this occurs if I manually set my limits
before the .show() call and save using .savefig()

Attached is a simple script.

Ben

On Thu, Jul 22, 2010 at 9:14 PM, Benjamin Root  wrote:

> Attached is a screenshot of what I am seeing with the Tkinter backend (I
> haven't tested others).  The lines aren't getting plotted outside the
> zoomed-in region, but the markers are.  I don't recall this happening
> before, but I can't be 100% sure of that.
>
> I am using the latest mpl from SVN.
>
> Ben Root
>
<>import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 50, 25)
y = np.linspace(0, 35, 25)

fig = plt.figure()
ax = fig.gca()

ax.plot(x, y, marker='.')

ax.set_xlim([5, 45])
ax.set_ylim([2, 30])

plt.show()

--
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel


Re: [matplotlib-devel] plot artifacts when zoomed in

2010-07-22 Thread Eric Firing
On 07/22/2010 04:34 PM, Benjamin Root wrote:
> Heh, looks more pervasive than just the Tkinter backend, and it isn't
> just caused by zooming.  Just moving the image off to the side is
> enough, and saving that figure using the "Save" button produces this
> attached image.
>
> And further testing shows that this occurs if I manually set my limits
> before the .show() call and save using .savefig()
>
> Attached is a simple script.

Running your script, I don't see any artifacts with gtkagg or with 
tkagg, or if I save the file to png.  I'm also running with latest svn.

I wonder whether your installation has gotten scrambled?  You might try 
deleting your build directory and your installed mpl, then rebuild and 
reinstall.  It is not uncommon that a clean rebuild and reinstallation 
is the solution to mystifying problems.

Eric

>
> Ben
>
> On Thu, Jul 22, 2010 at 9:14 PM, Benjamin Root  > wrote:
>
> Attached is a screenshot of what I am seeing with the Tkinter
> backend (I haven't tested others).  The lines aren't getting plotted
> outside the zoomed-in region, but the markers are.  I don't recall
> this happening before, but I can't be 100% sure of that.
>
> I am using the latest mpl from SVN.
>
> Ben Root
>
>
>
>
> --
> 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
> [email protected]
> 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
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel


Re: [matplotlib-devel] plot artifacts when zoomed in

2010-07-22 Thread Benjamin Root
On Thu, Jul 22, 2010 at 9:46 PM, Eric Firing  wrote:

> On 07/22/2010 04:34 PM, Benjamin Root wrote:
> > Heh, looks more pervasive than just the Tkinter backend, and it isn't
> > just caused by zooming.  Just moving the image off to the side is
> > enough, and saving that figure using the "Save" button produces this
> > attached image.
> >
> > And further testing shows that this occurs if I manually set my limits
> > before the .show() call and save using .savefig()
> >
> > Attached is a simple script.
>
> Running your script, I don't see any artifacts with gtkagg or with
> tkagg, or if I save the file to png.  I'm also running with latest svn.
>
> I wonder whether your installation has gotten scrambled?  You might try
> deleting your build directory and your installed mpl, then rebuild and
> reinstall.  It is not uncommon that a clean rebuild and reinstallation
> is the solution to mystifying problems.
>
> Eric
>
>
Looks like you are right.  A complete clean-out and rebuild fixes the
problem.  I might have messed something up a while back when testing some
clipping issues.

Thanks,
Ben Root
--
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel