Agg eps and bounding box / OO problems

With the script

···

----
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure
from matplotlib.patches import Rectangle
fig = Figure()
canvas = FigureCanvas(fig)
ax = fig.add_subplot(111)
ax.plot([.5,.7],[1.5, 2.5])
ax.add_artist(Rectangle((.5, 1.5), .2, 1, fill=False))
ax.set_aspect("equal")
canvas.print_figure('test.eps')
----

I get a file 'test.eps'. Using matplotlib 0.87.7 the PS bounding box
of the generated plot is far to wide. Is this a problem with my script
or a Problem of FigureCanvasAgg (and FigureCanvasPS)? What can I do to
get a tight bounding box?

Further, when I leave out the "ax.plot" line, the generated figure is
missing the "Rectangle" and is showing only a pair of axes counting
from 0 to 1. Is that a bug of matplotlib or something I have to fix in
my script?

Thanks
Berthold

--
berthold@...1453... / <http://höllmanns.de/>
bhoel@...273... / <http://starship.python.net/crew/bhoel/>

With the script

----
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure
from matplotlib.patches import Rectangle
fig = Figure()
canvas = FigureCanvas(fig)
ax = fig.add_subplot(111)
ax.plot([.5,.7],[1.5, 2.5])
ax.add_artist(Rectangle((.5, 1.5), .2, 1, fill=False))
ax.set_aspect("equal")
canvas.print_figure('test.eps')
----

I get a file 'test.eps'. Using matplotlib 0.87.7 the PS bounding box
of the generated plot is far to wide. Is this a problem with my script
or a Problem of FigureCanvasAgg (and FigureCanvasPS)? What can I do to
get a tight bounding box?

The bounding box is determined by the size of your figure window. Try
something like:

fig=Figure(figsize=(2,4))

Further, when I leave out the "ax.plot" line, the generated figure is
missing the "Rectangle" and is showing only a pair of axes counting
from 0 to 1. Is that a bug of matplotlib or something I have to fix in
my script?

It looks like a bug to me, but right now I don't have time to look into it
further. Maybe someone else could comment, or you could file a bug report at
sourceforge.

Darren

···

On Monday 05 February 2007 04:06:45 pm Berthold Höllmann wrote:

I get a file 'test.eps'. Using matplotlib 0.87.7 the PS bounding box
of the generated plot is far to wide. Is this a problem with my script
or a Problem of FigureCanvasAgg (and FigureCanvasPS)? What can I do to
get a tight bounding box?

This is a problem with the way PS computes the bounding box -- it uses
the bounding box of the Figure and ignores the fact that much of your
figure is whitespace. It should compute the bounding box of the
visible figure elements, so this should be considered a bug. To
workaround, you can set the figure size to be more like the size of
the content

  fig = Figure((3,7)) # set the width and height in inches
  canvas = FigureCanvas(fig)
  ax = fig.add_subplot(111)
  ax.plot([.5,.7],[1.5, 2.5])
  ax.add_artist(Rectangle((.5, 1.5), .2, 1, fill=False))
  ax.set_aspect("equal")
  canvas.print_figure('test.eps')

Further, when I leave out the "ax.plot" line, the generated figure is
missing the "Rectangle" and is showing only a pair of axes counting
from 0 to 1. Is that a bug of matplotlib or something I have to fix in
my script?

Use add_patch instead of add_artist. add_artist is the most generic
method and Axes doesn't know how to query it's argument for it's data
limits, which it then feeds to the autoscaler. If you use add_line to
add lines.Line2D and add_patch to add patches.Patch instances, then
Axes will know how to introspect them and update the autoscaler. But
you will need to explicitly call "autoscale_view" before saving.
Something like

  ax = fig.add_subplot(111)
  ax.add_patch(Rectangle((.5, 1.5), .2, 1, edgecolor='red', fill=False))
  ax.set_aspect("equal")
  ax.autoscale_view()
  canvas.print_figure('test.eps')

Note if all you are doing is creating postscript, you don't need to
import Agg at all. Just do

  from matplotlib.backends.backend_ps import FigureCanvasPS as FigureCanvas

JDH

···

On 2/5/07, Berthold Höllmann <bhoel@...1406...> wrote:

I respectfully disagree. The current behavior is consistent with other output
formats, such as png. If we want to support tight bounding boxes, maybe it
would be better to do so with a kwarg.

Darren

···

On Monday 05 February 2007 04:57:40 pm John Hunter wrote:

On 2/5/07, Berthold Höllmann <bhoel@...1406...> wrote:
> I get a file 'test.eps'. Using matplotlib 0.87.7 the PS bounding box
> of the generated plot is far to wide. Is this a problem with my script
> or a Problem of FigureCanvasAgg (and FigureCanvasPS)? What can I do to
> get a tight bounding box?

This is a problem with the way PS computes the bounding box -- it uses
the bounding box of the Figure and ignores the fact that much of your
figure is whitespace. It should compute the bounding box of the
visible figure elements, so this should be considered a bug.

I'm happy to be wrong (especially because then we don't have any work
to do) but I don't see the tight bounding box as inconsistent with
Agg's behavior. I agree that the *.ps output should be consistent
with the Agg png behavior since neither make a claim to clip the image
to the visible elements. But *.eps implies a bounding box, it might
make sense to offer a bounding box that is reduced to the visible
elements.

I certainly don't feel strongly, nor do I think it would be terribly
hard to do.....

JDH

···

On 2/5/07, Darren Dale <dd55@...163...> wrote:

I respectfully disagree. The current behavior is consistent with other output
formats, such as png. If we want to support tight bounding boxes, maybe it
would be better to do so with a kwarg.

> I respectfully disagree. The current behavior is consistent with other
> output formats, such as png. If we want to support tight bounding boxes,
> maybe it would be better to do so with a kwarg.

I'm happy to be wrong (especially because then we don't have any work
to do) but I don't see the tight bounding box as inconsistent with
Agg's behavior. I agree that the *.ps output should be consistent
with the Agg png behavior since neither make a claim to clip the image
to the visible elements. But *.eps implies a bounding box, it might
make sense to offer a bounding box that is reduced to the visible
elements.

Maybe I'm confusing two issues. I'm comparing png's image extent with eps's
bounding box.

I certainly don't feel strongly, nor do I think it would be terribly
hard to do.....

Perhaps reducing the image size to the visible elements would be a good option
for all output formats?

···

On Monday 05 February 2007 05:23:04 pm John Hunter wrote:

On 2/5/07, Darren Dale <dd55@...163...> wrote:

Darren Dale wrote:
[...]

Perhaps reducing the image size to the visible elements would be a good option for all output formats?

This sounds to me like a very desirable option to have. I have not thought at all about implementation, though.

Eric