|
From: <bh...@de...> - 2007-02-05 21:20:17
|
With the script
----
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure
from matplotlib.patches import Rectangle
fig =3D Figure()
canvas =3D FigureCanvas(fig)
ax =3D fig.add_subplot(111)
ax.plot([.5,.7],[1.5, 2.5])
ax.add_artist(Rectangle((.5, 1.5), .2, 1, fill=3DFalse))
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
--=20
ber...@xn... / <http://h=C3=B6llmanns.de/>
bh...@we... / <http://starship.python.net/crew/bhoel/>
|
|
From: Darren D. <dd...@co...> - 2007-02-05 21:41:34
|
On Monday 05 February 2007 04:06:45 pm Berthold H=C3=B6llmann wrote:
> With the script
>
> ----
> from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanv=
as
> from matplotlib.figure import Figure
> from matplotlib.patches import Rectangle
> fig =3D Figure()
> canvas =3D FigureCanvas(fig)
> ax =3D fig.add_subplot(111)
> ax.plot([.5,.7],[1.5, 2.5])
> ax.add_artist(Rectangle((.5, 1.5), .2, 1, fill=3DFalse))
> 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=20
something like:
fig=3DFigure(figsize=3D(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=
=20
further. Maybe someone else could comment, or you could file a bug report a=
t=20
sourceforge.
Darren
|
|
From: John H. <jd...@gm...> - 2007-02-05 21:57:51
|
On 2/5/07, Berthold H=F6llmann <bh...@de...> 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 =3D Figure((3,7)) # set the width and height in inches
canvas =3D FigureCanvas(fig)
ax =3D fig.add_subplot(111)
ax.plot([.5,.7],[1.5, 2.5])
ax.add_artist(Rectangle((.5, 1.5), .2, 1, fill=3DFalse))
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 =3D fig.add_subplot(111)
ax.add_patch(Rectangle((.5, 1.5), .2, 1, edgecolor=3D'red', fill=3DFalse)=
)
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
|
|
From: Darren D. <dd...@co...> - 2007-02-05 22:12:38
|
On Monday 05 February 2007 04:57:40 pm John Hunter wrote: > On 2/5/07, Berthold H=F6llmann <bh...@de...> 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. =20 I respectfully disagree. The current behavior is consistent with other outp= ut=20 formats, such as png. If we want to support tight bounding boxes, maybe it= =20 would be better to do so with a kwarg. Darren |
|
From: John H. <jd...@gm...> - 2007-02-05 22:23:18
|
On 2/5/07, Darren Dale <dd...@co...> 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'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 |
|
From: Darren D. <dd...@co...> - 2007-02-05 22:30:59
|
On Monday 05 February 2007 05:23:04 pm John Hunter wrote: > On 2/5/07, Darren Dale <dd...@co...> 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'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? |
|
From: Eric F. <ef...@ha...> - 2007-02-05 23:23:21
|
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 |
|
From: <bh...@de...> - 2007-02-05 22:46:41
|
"John Hunter" <jd...@gm...> writes: > On 2/5/07, Berthold H=C3=B6llmann <bhoel-lDxpuoTbsqf2eFz/2M...@pu...= ane.org> 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 =3D Figure((3,7)) # set the width and height in inches > canvas =3D FigureCanvas(fig) > ax =3D fig.add_subplot(111) > ax.plot([.5,.7],[1.5, 2.5]) > ax.add_artist(Rectangle((.5, 1.5), .2, 1, fill=3DFalse)) > ax.set_aspect("equal") > canvas.print_figure('test.eps') So there is no way to calculate the size occupied by the visible figure elements? In my target application I also have no easy way to figure out the size of the resulting plot, I hoped matplotlib has a way tp extract it from the plotted data. something like ----- ax.set_aspect("equal") ax.autoscale_view() w, h =3D fig.get_size_inches() xmin, xmax =3D ax.get_xlim() ymin, ymax =3D ax.get_ylim() xext =3D xmax - xmin yext =3D ymax - ymin if xext < yext: w =3D h * xext/yext else: h =3D w * yext/xext ----- gives a tighter bounding box, still having somehow too much room in the unchanged direction. >> 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 I had tried "add_patch" but missed the ax.autoscale_view() call. Thanks Berthold --=20 ber...@xn... / <http://h=C3=B6llmanns.de/> bh...@we... / <http://starship.python.net/crew/bhoel/> |