Layout of subplots in output

Hi all,

When saving plots (using plt.figsave and matplotlib from SVN)
consisting of subplots, the layout is a bit messed up. As an example,
have a look at

http://mentat.za.net/refer/segmentation.pdf

I have tried adjusting the figure size, the font size, the w- and
hspace, etc. Is this a known problem, or am I doing something silly?

Thanks for your time,
Stéfan

Stéfan van der Walt wrote:

Hi all,

When saving plots (using plt.figsave and matplotlib from SVN)
consisting of subplots, the layout is a bit messed up. As an example,
have a look at

http://mentat.za.net/refer/segmentation.pdf

Wow, that's really ugly! I suspect that for anyone to provide any help on this, you will need to supply a minimal script to show what you are doing. I take it you are starting with something that looks reasonable on the screen, but comes out quite different when you save it?

Eric

···

I have tried adjusting the figure size, the font size, the w- and
hspace, etc. Is this a known problem, or am I doing something silly?

Thanks for your time,
Stéfan

Hi Eric,

2009/9/28 Eric Firing <efiring@...229...>:

When saving plots (using plt.figsave and matplotlib from SVN)
consisting of subplots, the layout is a bit messed up. As an example,
have a look at

http://mentat.za.net/refer/segmentation.pdf

Wow, that's really ugly! I suspect that for anyone to provide any help
on this, you will need to supply a minimal script to show what you are
doing. I take it you are starting with something that looks reasonable
on the screen, but comes out quite different when you save it?

I narrowed the problem down to this line:

matplotlib.rc('figure', dpi=300)

Does it do some magic behind the scenes?

Attached is the script that produces this:

http://mentat.za.net/refer/badplot.pdf

I'm running 1.0.svn on OSX Snow Leopard, Python 2.6 and NumPy dev.

Regards
Stéfan

Stéfan van der Walt wrote:

Hi Eric,

2009/9/28 Eric Firing <efiring@...229...>:

When saving plots (using plt.figsave and matplotlib from SVN)
consisting of subplots, the layout is a bit messed up. As an example,
have a look at

http://mentat.za.net/refer/segmentation.pdf

Wow, that's really ugly! I suspect that for anyone to provide any help
on this, you will need to supply a minimal script to show what you are
doing. I take it you are starting with something that looks reasonable
on the screen, but comes out quite different when you save it?

I narrowed the problem down to this line:

matplotlib.rc('figure', dpi=300)

Does it do some magic behind the scenes?

Attached is the script that produces this:

Stefan,

You forgot the attachment.

dpi is an inherently confusing parameter because it can relate to font rendering and to the resolution of an image. So there are different kinds of dpi, but the distinction between them is not kept clear in the code--at least it wasn't the last time I looked into this, quite a long time ago.

Eric

···

http://mentat.za.net/refer/badplot.pdf

I'm running 1.0.svn on OSX Snow Leopard, Python 2.6 and NumPy dev.

Regards
Stéfan

------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
matplotlib-devel List Signup and Options

2009/10/31 Eric Firing <efiring@...229...>:

You forgot the attachment.

I hate it when that happens -- here it is!

Cheers
Stéfan

badplot.py (301 Bytes)

2009/11/1 Stéfan van der Walt <stefan@...337...>:

2009/10/31 Eric Firing <efiring@...229...>:

You forgot the attachment.

I hate it when that happens -- here it is!

Hey Stéfan,

To avoid the overlap on the titles and ticks, you will want to play
with the font size of the ticks and title, but most importantly the
subplots_adjust parameters hspace and wspace.
If using a suptitle, you may also want to adjust top.

Eg,

# you can also click on the "subplots adjust" toolbar icon to play with the
# settings to get something that looks right and then hard code this
fig.subplots_adjust(hspace=0.4, wspace=0.4)

for ax in ax1, ax2, ax3, ax4:
    ax.title.set_fontsize(11)
    for label in ax.get_xticklabels() + ax.get_yticklabels)():
        label.set_fontsize(9)

You can also use rc parameters to control the defaults:
http://matplotlib.sourceforge.net/users/customizing.html

JDH

Hi John

2009/11/1 John Hunter <jdh2358@...149...>:

To avoid the overlap on the titles and ticks, you will want to play
with the font size of the ticks and title, but most importantly the
subplots_adjust parameters hspace and wspace.
If using a suptitle, you may also want to adjust top.

Thanks for the advice, I'll play around with those parameters.

I was surprised that this works fine under Linux, so I tried switching
to the PDF backend on OSX, and now everything renders perfectly.
Could it be that the MacOSX backend does something strange?

Regards
Stéfan

Stefan,

Can you try to install matplotlib again, after removing old ones.
The mac os X had a bug that does take care of the dpi. But I guess
this bug has been fixed in the svn.

http://old.nabble.com/Re%3A-Font-size-and-savefig-p23337463.html

-JJ

2009/11/1 Stéfan van der Walt <stefan@...337...>:

···

Hi John

2009/11/1 John Hunter <jdh2358@...149...>:

To avoid the overlap on the titles and ticks, you will want to play
with the font size of the ticks and title, but most importantly the
subplots_adjust parameters hspace and wspace.
If using a suptitle, you may also want to adjust top.

Thanks for the advice, I'll play around with those parameters.

I was surprised that this works fine under Linux, so I tried switching
to the PDF backend on OSX, and now everything renders perfectly.
Could it be that the MacOSX backend does something strange?

Regards
Stéfan

------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
matplotlib-devel List Signup and Options

Hi JJ

2009/11/1 Jae-Joon Lee <lee.j.joon@...149...>:

Can you try to install matplotlib again, after removing old ones.
The mac os X had a bug that does take care of the dpi. But I guess
this bug has been fixed in the svn.

Unfortunately, I still see the same behaviour using the latest version
from SVN. As noted earlier, I work around the issue now by switching
to the pdf backend.

Regards
Stéfan

I now think this is not the dpi issue.
Can you check the size of your figure in mac os X backend, after the
plot is drawn?

print f.get_size_inches()

8x6 inch is the default.

With dpi setting of 300 and bigger, the figure size (in pixel) will be
likely larger than your monitor size. And it seems that in mac os X
backend, the figure gets shrunken to fit the display, effectively
reducing the figuresize.

So, my recommendation is to use smaller dpi for screen display
(default is something like 80), and increase the dpi when saving the
figure ("savefig" has a dpi parameter).

Regards,

-JJ

2009/11/2 Stéfan van der Walt <stefan@...337...>:

···

Hi JJ

this bug has been fixed in the svn.

Unfortunately, I still see the same behaviour using the latest version
from SVN. As noted earlier, I work around the issue now by switching
to the pdf backend.

Regards
Stéfan

Hi JJ

2009/11/2 Jae-Joon Lee <lee.j.joon@...149...>:

I now think this is not the dpi issue.
Can you check the size of your figure in mac os X backend, after the
plot is drawn?

print f.get_size_inches()

8x6 inch is the default.

It says [4, 2.52], so I think you are right!

So, my recommendation is to use smaller dpi for screen display
(default is something like 80), and increase the dpi when saving the
figure ("savefig" has a dpi parameter).

This fixes the problem. Now, why does the MacOSX end do this when
none of the others do?

Thanks for helping me track this down!
Stéfan

2009/11/3 Stéfan van der Walt <stefan@...337...>:

Hi JJ

2009/11/2 Jae-Joon Lee <lee.j.joon@...149...>:

I now think this is not the dpi issue.
Can you check the size of your figure in mac os X backend, after the
plot is drawn?

print f.get_size_inches()

8x6 inch is the default.

It says [4, 2.52], so I think you are right!

So, my recommendation is to use smaller dpi for screen display
(default is something like 80), and increase the dpi when saving the
figure ("savefig" has a dpi parameter).

This fixes the problem. Now, why does the MacOSX end do this when
none of the others do?

Thanks for helping me track this down!

Perhaps you can file a bug report on the tracker so Michiel can look into it?

Thanks,
JDH

2009/11/3 John Hunter <jdh2358@...149...>:

Perhaps you can file a bug report on the tracker so Michiel can look into it?

Here we go:

https://sourceforge.net/tracker/?func=detail&aid=2891502&group_id=80706&atid=560720

Cheers
Stéfan

Hi everybody,

I was looking at this bug about a memory leak:

https://sourceforge.net/tracker/?func=detail&atid=560720&aid=2889570&group_id=80706

While this bug is now essentially fixed, I noticed that the Figure class contains some circular references that prevent it from being cleaned up by the garbage collector, which is effectively a memory leak. At least, for this code:

from matplotlib.figure import Figure
fig = Figure()
del fig

the garbage collector reports 76 unreachable objects. This seems to be independent of which backend is being used.

Is it worthwhile to look deeper into it? Or should we accept that it is unavoidable that a library of the size of matplotlib will have circular references?

--Michiel.

Michiel de Hoon wrote:

Hi everybody,

I was looking at this bug about a memory leak:

https://sourceforge.net/tracker/?func=detail&atid=560720&aid=2889570&group_id=80706

While this bug is now essentially fixed, I noticed that the Figure class contains some circular references that prevent it from being cleaned up by the garbage collector, which is effectively a memory leak. At least, for this code:

from matplotlib.figure import Figure
fig = Figure()
del fig

the garbage collector reports 76 unreachable objects. This seems to be independent of which backend is being used.

Is it worthwhile to look deeper into it? Or should we accept that it is unavoidable that a library of the size of matplotlib will have circular references?

The purpose of the garbage collector is to handle the case of circular references--and mpl is full of circular references. When there are no circular references, then reference counting suffices. The garbage collector fails to handle circular references when an object has a __del__ method. I don't think we have that problem.

I am not actually seeing the result you describe, though. Using python from the interactive prompt--no ipython--when I do gc.collect() and then gc.get_count() I get back to the count from before instantiating the Figure.

>>> gc.get_count()
(4, 0, 0)
>>> gc.get_count()
(5, 0, 0)
>>> gc.get_count()
(5, 0, 0)
>>> gc.get_count()
(5, 0, 0)
>>> fig = Figure()
>>> gc.get_count()
(128, 0, 0)
>>> del(fig)
>>> gc.get_count()
(128, 0, 0)
>>> gc.collect()
76
>>> gc.get_count()
(4, 0, 0)
>>> gc.get_count()
(5, 0, 0)

Eric

···

--Michiel.

I guess you're right... I misunderstood the result of gc.collect() as the number of objects that could not be freed. The good news is that after fixing the bug I was looking at, there are no more objects that cannot be freed (gc.garbage is empty).

Thanks!

--Michiel.

···

--- On Sun, 11/8/09, Eric Firing <efiring@...229...> wrote:

From: Eric Firing <efiring@...229...>
Subject: Re: [matplotlib-devel] Circular references in Figure
To: "Michiel de Hoon" <mjldehoon@...42...>
Cc: matplotlib-devel@lists.sourceforge.net
Date: Sunday, November 8, 2009, 1:43 AM
Michiel de Hoon wrote:
> Hi everybody,
>
> I was looking at this bug about a memory leak:
>
> https://sourceforge.net/tracker/?func=detail&atid=560720&aid=2889570&group_id=80706
>
> While this bug is now essentially fixed, I noticed
that the Figure class contains some circular references that
prevent it from being cleaned up by the garbage collector,
which is effectively a memory leak. At least, for this
code:
>
>>>> from matplotlib.figure import Figure
>>>> fig = Figure()
>>>> del fig
>
> the garbage collector reports 76 unreachable objects.
This seems to be independent of which backend is being
used.
>
> Is it worthwhile to look deeper into it? Or should we
accept that it is unavoidable that a library of the size of
matplotlib will have circular references?
>

The purpose of the garbage collector is to handle the case
of circular references--and mpl is full of circular
references. When there are no circular references,
then reference counting suffices. The garbage
collector fails to handle circular references when an object
has a __del__ method. I don't think we have that
problem.

I am not actually seeing the result you describe,
though. Using python from the interactive prompt--no
ipython--when I do gc.collect() and then gc.get_count() I
get back to the count from before instantiating the Figure.

>>> gc.get_count()
(4, 0, 0)
>>> gc.get_count()
(5, 0, 0)
>>> gc.get_count()
(5, 0, 0)
>>> gc.get_count()
(5, 0, 0)
>>> fig = Figure()
>>> gc.get_count()
(128, 0, 0)
>>> del(fig)
>>> gc.get_count()
(128, 0, 0)
>>> gc.collect()
76
>>> gc.get_count()
(4, 0, 0)
>>> gc.get_count()
(5, 0, 0)

Eric

>
> --Michiel.
>