-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Version 2.2.0rc1 triggers TypeError #10476
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@ewels Would you mind providing a minimal self-contained example? Did you try with a different backend an can report any differences? |
Yup, I'll see if I can put something together. I first found the error because of my tests started failing on Travis (Linux with multiple python versions). The only thing that I could see that had changed since the previous tests was that the matplotlib version had bumped from v2.1.2 to 2.2.0rc1. I then tried locally on my machine (OSX py2.7) and couldn't replicate it until I forced an upgrade to 2.2.0rc1, then I got the same failure. So seems to be the same failure across a range of backends. Phil |
My guess is someplace in tight_layout needs to more aggressively force a draw to make user all of the sizes we sort out at draw time are set before it tries to optimize the sizes. Strongly suspect that |
Ok, after a lot of trial and error I think I have whittled it down to a minimal example: #!/usr/bin/env python
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
print matplotlib.__version__ # 2.2.0rc1
fig = plt.figure()
axes = fig.add_subplot(111)
d1 = [29388871, 12448, 40, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
d2 = [28396236, 981940, 22171, 537, 123, 88, 41, 42, 40, 26, 26, 84, 6, 2, 0, 0, 0, 0, 0]
axes.plot(d1, label='series 1')
axes.plot(d2, label='series 2')
axes.legend(mode='expand')
#### THIS IS WHERE THE CRASH HAPPENS
plt.tight_layout(rect=[0,0.08,1,0.92])
fig.savefig('test.png', format='png', bbox_inches='tight')
plt.close(fig) With the previous version:
With the new version:
Traceback (most recent call last):
File "mpl_test.py", line 18, in <module>
plt.tight_layout(rect=[0,0.08,1,0.92])
File "/Users/ewels/miniconda2/envs/matplotlib_bug/lib/python2.7/site-packages/matplotlib/pyplot.py", line 1366, in tight_layout
fig.tight_layout(pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect)
File "/Users/ewels/miniconda2/envs/matplotlib_bug/lib/python2.7/site-packages/matplotlib/figure.py", line 2273, in tight_layout
pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect)
File "/Users/ewels/miniconda2/envs/matplotlib_bug/lib/python2.7/site-packages/matplotlib/tight_layout.py", line 328, in get_tight_layout_figure
pad=pad, h_pad=h_pad, w_pad=w_pad)
File "/Users/ewels/miniconda2/envs/matplotlib_bug/lib/python2.7/site-packages/matplotlib/tight_layout.py", line 115, in auto_adjust_subplotpars
if ax.get_visible()])
File "/Users/ewels/miniconda2/envs/matplotlib_bug/lib/python2.7/site-packages/matplotlib/axes/_base.py", line 4179, in get_tightbbox
bb.append(child._legend_box.get_window_extent(renderer))
File "/Users/ewels/miniconda2/envs/matplotlib_bug/lib/python2.7/site-packages/matplotlib/offsetbox.py", line 262, in get_window_extent
w, h, xd, yd, offsets = self.get_extent_offsets(renderer)
File "/Users/ewels/miniconda2/envs/matplotlib_bug/lib/python2.7/site-packages/matplotlib/offsetbox.py", line 384, in get_extent_offsets
for c in self.get_visible_children()]
File "/Users/ewels/miniconda2/envs/matplotlib_bug/lib/python2.7/site-packages/matplotlib/offsetbox.py", line 255, in get_extent
w, h, xd, yd, offsets = self.get_extent_offsets(renderer)
File "/Users/ewels/miniconda2/envs/matplotlib_bug/lib/python2.7/site-packages/matplotlib/offsetbox.py", line 481, in get_extent_offsets
return width + 2 * pad, height + 2 * pad, \
TypeError: unsupported operand type(s) for +: 'NoneType' and 'float' |
@ewels Thank you for the working example :). FWIW,
Pinging @jklymak who is the author of the relevant commit. |
A bit more digging reveals that I think the problem isn't actually that new, but that commit just exposed it. The following bit of code when matplotlib/lib/matplotlib/offsetbox.py Lines 72 to 86 in 962847d
|
Based on what @dstansby noticed, I may have a fix. |
Sorry, at a meeting, and won’t have time or help. Glad I helped expose a bug: of course before my fix, tight layout would have ignored the legend altogether. |
Well it is still a bit unclear to me why the following seems to be fixing the issue: elif mode == "expand":
if total is None:
total = np.nextafter(1, 2) - 1 # <-- ?!!!! Very unrealistic total length...
if len(w_list) > 1:
sep = (total - sum(w_list)) / (len(w_list) - 1.)
else:
sep = 0
offsets_ = np.cumsum([0] + [w + sep for w in w_list])
offsets = offsets_[:-1]
return total, offsets Initially I was planning to use something like ...
if total is None:
total = 1.0
... but then I realized that |
@afvincent I suspect the issue is that this is drawn in two passes so the first value does not really matter, but just needs to be not |
Perfect minimal example from @ewels suggested fix from @afvincent closes matplotlib#10476
@tacaswell Thanks for the plausible explanation :), that would indeed make sense. And thank you for the PR (I was waiting to better understand what was going on here before opening the promised PR but as I did not make any progress on it...). |
Thank you very much everyone! That was a speedy diagnosis and fix indeed.. :) How does the release cycle work for matplotlib? Will this release candidate 1 be superseded in the near future? (I’m wondering whether I need to update my tool requirements to explicitly avoid it). Phil |
RC1 will turn into the proper 2.2 release at some point, so no need to explicitly avoid RC1. |
Aha, yes - just found the milestone. Ok great, thanks! |
The RC seems to be going relatively well, I don't think there will be an RC2 before 2.2 final. |
Bug report
Bug summary
MatPlotLib release v2.2.0rc1 triggers a previously unseen
TypeError
:Code for reproduction
The line of code that triggers the error is within my Python tool MultiQC here.
Actual outcome
Expected outcome
Last tested on MatPlotLib v2.1.2 and worked fine. Code has been in use for over two years.
Matplotlib version
print(matplotlib.get_backend())
): MacOSXmatplotlib installed using pip, python installed using conda locally (OSX) and on Travis CI.
The text was updated successfully, but these errors were encountered: