I guess this in turns comes from what happens in auto_adjust_subplotpars, in the output of _get_bottom and _get_top:
(Pdb) p ax_bbox.ymin
0.3716666666666667
(Pdb) p tight_bbox.ymin
-0.16733398437499999
(Pdb) p ax_bbox.ymin - tight_bbox.ymin
0.53900065104166672
(Pdb) p tight_bbox.ymax
1.1673339843749999
(Pdb) p ax_bbox.ymax
0.6283333333333333
(Pdb) p tight_bbox.ymax - ax_bbox.ymax
0.53900065104166661
I don't know what ax_bbox and tight_bbox exactly are.
I just guess the algorithm to determine the figure properties do not play well with the data I want to plot. Can this be considered a bug ?
I have seen exceptions like this before if you have strings (in this case probably ylabels) on a multi-Axes figure where the text is wider than two axes.
Without a minimal example there is not much we can do as, (as you point out) the tight layout code is rather complicated.
I'm currently trying to build a minimal example, but what I can already say is that this indeed has to do with ylabels. If I shorten my label by 4 letters, the bug doesn't show up.
If I call this with n = 15, the bug doesn't occur. With n = 16, it does:
./debug.py 15
/usr/lib/python2.7/dist-packages/matplotlib/tight_layout.py:225: UserWarning: tight_layout : falling back to Agg renderer
warnings.warn("tight_layout : falling back to Agg renderer")
./debug.py 16
/usr/lib/python2.7/dist-packages/matplotlib/tight_layout.py:225: UserWarning: tight_layout : falling back to Agg renderer
warnings.warn("tight_layout : falling back to Agg renderer")
Traceback (most recent call last):
File "./debug.py", line 72, in <module>
plt.tight_layout()
File "/usr/lib/python2.7/dist-packages/matplotlib/pyplot.py", line 1288, in tight_layout
fig.tight_layout(pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect)
File "/usr/lib/python2.7/dist-packages/matplotlib/figure.py", line 1656, in tight_layout
self.subplots_adjust(**kwargs)
File "/usr/lib/python2.7/dist-packages/matplotlib/figure.py", line 1516, in subplots_adjust
self.subplotpars.update(*args, **kwargs)
File "/usr/lib/python2.7/dist-packages/matplotlib/figure.py", line 225, in update
raise ValueError('bottom cannot be >= top')
ValueError: bottom cannot be >= top
This probably needs a better error message (its possible there already is one for 3.0, I’ve not checked, though I recall this coming up before). However, if you get this error, it means your decorators are not leaving room for your axes, and its size has shrunk to nothing. Either make your decorators smaller or your figure larger.
Either make your decorators smaller or your figure larger
It happens when tight_layout() is called. It is resizing the elements that were OK before it was called. So it's a bug there, it must figure automatically if there's no room and leave all as is.
@maahn That should be what it is doing and it is notifying you it can not satisfy the constraints by raising an exception. You can then catch this and do what ever the right thing for your application is.
I got the same error as a result of calling import matplotlib.pyplot as plt; plt.tight_layout(pad=1.0). The workaround, which allowed me to get rid of the error, was to reduce the font size on my legend. So, it seems, one can get the error if the legend does not fit on the figure.
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.set_ylabel('a'*50000)
plt.tight_layout()
Running the code above still results in the stack trace below, in matplotlib 3.0.3, the latest version available for Python 2.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/dist-packages/matplotlib/pyplot.py", line 1379, in tight_layout
fig.tight_layout(pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect)
File "/usr/lib/python2.7/dist-packages/matplotlib/figure.py", line 1756, in tight_layout
self.subplots_adjust(**kwargs)
File "/usr/lib/python2.7/dist-packages/matplotlib/figure.py", line 1612, in subplots_adjust
self.subplotpars.update(*args, **kwargs)
File "/usr/lib/python2.7/dist-packages/matplotlib/figure.py", line 230, in update
raise ValueError('bottom cannot be >= top')
ValueError: bottom cannot be >= top
Activity
jenshnielsen commented on Nov 10, 2015
Could you provide a minimal example of what you are trying to do. That makes it easier to understand if this is a bug and how to fix it.
tacaswell commented on Nov 11, 2015
I have seen exceptions like this before if you have strings (in this case probably ylabels) on a multi-Axes figure where the text is wider than two axes.
Without a minimal example there is not much we can do as, (as you point out) the tight layout code is rather complicated.
blaiseli commented on Nov 17, 2015
I'm currently trying to build a minimal example, but what I can already say is that this indeed has to do with ylabels. If I shorten my label by 4 letters, the bug doesn't show up.
blaiseli commented on Nov 17, 2015
Here's an example:
If I call this with n = 15, the bug doesn't occur. With n = 16, it does:
./debug.py 15 /usr/lib/python2.7/dist-packages/matplotlib/tight_layout.py:225: UserWarning: tight_layout : falling back to Agg renderer warnings.warn("tight_layout : falling back to Agg renderer") ./debug.py 16 /usr/lib/python2.7/dist-packages/matplotlib/tight_layout.py:225: UserWarning: tight_layout : falling back to Agg renderer warnings.warn("tight_layout : falling back to Agg renderer") Traceback (most recent call last): File "./debug.py", line 72, in <module> plt.tight_layout() File "/usr/lib/python2.7/dist-packages/matplotlib/pyplot.py", line 1288, in tight_layout fig.tight_layout(pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect) File "/usr/lib/python2.7/dist-packages/matplotlib/figure.py", line 1656, in tight_layout self.subplots_adjust(**kwargs) File "/usr/lib/python2.7/dist-packages/matplotlib/figure.py", line 1516, in subplots_adjust self.subplotpars.update(*args, **kwargs) File "/usr/lib/python2.7/dist-packages/matplotlib/figure.py", line 225, in update raise ValueError('bottom cannot be >= top') ValueError: bottom cannot be >= toptacaswell commented on Nov 18, 2015
is a minimal example.
There is a check in tight_layout that the pad can not be negative, but there also needs to be one that it can not be > .5.
Fix matplotlib#5456: Keep margins <= .5 in tight_layout
Fix matplotlib#5456: Keep margins <= .5 in tight_layout
josecv commented on Mar 15, 2016
Hey guys we've written up a quick fix for this one and put in a pull request. Let us know if it's cool with you.
Thanks!
Issue matplotlib#5456 style fixes.
10 remaining items
madanh commented on Jun 5, 2018
Affects me on version 2.2.2
jklymak commented on Jun 5, 2018
This probably needs a better error message (its possible there already is one for 3.0, I’ve not checked, though I recall this coming up before). However, if you get this error, it means your decorators are not leaving room for your axes, and its size has shrunk to nothing. Either make your decorators smaller or your figure larger.
timhoffm commented on Jun 5, 2018
The error message is still the same on master.
madanh commented on Jun 8, 2018
@jklymak
It happens when tight_layout() is called. It is resizing the elements that were OK before it was called. So it's a bug there, it must figure automatically if there's no room and leave all as is.
tacaswell commented on Jun 8, 2018
@maahn That should be what it is doing and it is notifying you it can not satisfy the constraints by raising an exception. You can then catch this and do what ever the right thing for your application is.
jklymak commented on Jun 8, 2018
Right. Or conversely, how small do you want it to make the axes before it errors?
jklymak commented on Jun 10, 2018
OK, the error here was in the logit scale as in #11386, closed by #11404
vss888 commented on Jun 25, 2018
I got the same error as a result of calling import matplotlib.pyplot as plt; plt.tight_layout(pad=1.0). The workaround, which allowed me to get rid of the error, was to reduce the font size on my legend. So, it seems, one can get the error if the legend does not fit on the figure.
matplotlib.__version__: 2.2.2
dstansby commented on May 14, 2019
Using @tacaswell's minimum example now gives
Which I think is good enough to close this as "fixed with a sensible warning". If I've missed anything, feel free to comment or re-open this issue.
EliteMasterEric commented on Aug 26, 2019
import matplotlib.pyplot as plt fig, ax = plt.subplots() ax.set_ylabel('a'*50000) plt.tight_layout()Running the code above still results in the stack trace below, in matplotlib 3.0.3, the latest version available for Python 2.
Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python2.7/dist-packages/matplotlib/pyplot.py", line 1379, in tight_layout fig.tight_layout(pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect) File "/usr/lib/python2.7/dist-packages/matplotlib/figure.py", line 1756, in tight_layout self.subplots_adjust(**kwargs) File "/usr/lib/python2.7/dist-packages/matplotlib/figure.py", line 1612, in subplots_adjust self.subplotpars.update(*args, **kwargs) File "/usr/lib/python2.7/dist-packages/matplotlib/figure.py", line 230, in update raise ValueError('bottom cannot be >= top') ValueError: bottom cannot be >= topjklymak commented on Aug 26, 2019
3.0.3 is not py2 compatible. Maybe you mean 2.2.3? Doubt this fix will be back ported
EliteMasterEric commented on Aug 26, 2019
Apologies, it appears the version of matplotlib I was using as 1.5.1, not 2.2.4.
Upgrading to that version makes the above code function as expected.
add workaround for matplotlib bug which occurs with very long labels