Skip to content

Plotting zero values with logarithmic axes triggers OverflowError, Matplotlib hangs permanently #7493

Closed

Description

@FilipDominec

I write an application with a graphical user interface to load and plot data files (https://github.com/FilipDominec/plotcommander). When I simultaneously select the y-axis to be logarithmic and load a file containing zeros, the Ticker class from Matplotlib encounters an error and the plotting window stops working permanently, even if I try to open some "safe" file thereafter. In such a case of error, the whole window of my program has to be closed and launched again, which is obviously not acceptable for a user.

As a mere downstream programmer who only uses the library, I have no clue how to fix this issue myself. I tried to always reset the plotting by self.fig.clf(), but it did not help. I believe that correct catching of the OverflowError would make Matplotlib more robust.

  • Matplotlib version 1.5.1-1ubuntu1, Python version2.7.12, Platform Ubuntu 16.04 x64
  • same experience under python 3
  • I installed Matplotlib and Python from apt repository

Error message:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/matplotlib/backends/backend_gtk3cairo.py", line 45, in on_draw_event
	self._render_figure(w, h)
  File "/usr/lib/python3/dist-packages/matplotlib/backends/backend_gtk3cairo.py", line 34, in _render_figure
	self.figure.draw (self._renderer)
  File "/usr/lib/python3/dist-packages/matplotlib/artist.py", line 61, in draw_wrapper
	draw(artist, renderer, *args, **kwargs)
  File "/usr/lib/python3/dist-packages/matplotlib/figure.py", line 1091, in draw
	self.tight_layout(renderer, **self._tight_parameters)
  File "/usr/lib/python3/dist-packages/matplotlib/figure.py", line 1754, in tight_layout
	rect=rect)
  File "/usr/lib/python3/dist-packages/matplotlib/tight_layout.py", line 349, in get_tight_layout_figure
	pad=pad, h_pad=h_pad, w_pad=w_pad)
  File "/usr/lib/python3/dist-packages/matplotlib/tight_layout.py", line 126, in auto_adjust_subplotpars
	tight_bbox_raw = union([ax.get_tightbbox(renderer) for ax in subplots])
  File "/usr/lib/python3/dist-packages/matplotlib/tight_layout.py", line 126, in <listcomp>
	tight_bbox_raw = union([ax.get_tightbbox(renderer) for ax in subplots])
  File "/usr/lib/python3/dist-packages/matplotlib/axes/_base.py", line 3683, in get_tightbbox
	bb_yaxis = self.yaxis.get_tightbbox(renderer)
  File "/usr/lib/python3/dist-packages/matplotlib/axis.py", line 1073, in get_tightbbox
	ticks_to_draw = self._update_ticks(renderer)
  File "/usr/lib/python3/dist-packages/matplotlib/axis.py", line 949, in _update_ticks
	tick_tups = [t for t in self.iter_ticks()]
  File "/usr/lib/python3/dist-packages/matplotlib/axis.py", line 949, in <listcomp>
	tick_tups = [t for t in self.iter_ticks()]
  File "/usr/lib/python3/dist-packages/matplotlib/axis.py", line 892, in iter_ticks
	majorLocs = self.major.locator()
  File "/usr/lib/python3/dist-packages/matplotlib/ticker.py", line 1538, in __call__
	return self.tick_values(vmin, vmax)
  File "/usr/lib/python3/dist-packages/matplotlib/ticker.py", line 1565, in tick_values
	numdec = math.floor(vmax) - math.ceil(vmin)
OverflowError: cannot convert float infinity to integer

Activity

  1. changed the title [-]Logarithmic axes with zero values should catch OverflowError[/-] [+]Logarithmic axes with zero values trigger OverflowError, Matplotlib hangs permanently[/+] on Nov 21, 2016
  2. added this to the milestone on Nov 21, 2016
  3. tacaswell commented on Nov 21, 2016

    @tacaswell
    Member

    Can you provide a minimal code snippet to reproduce this?

  4. FilipDominec commented on Nov 21, 2016

    @FilipDominec
    Author

    I surely would if it was easy to reproduce in some script. But it occurs in GUI and so far I am not sure that it is fully deterministic. I will try to find a minimum example and post it here, though.

  5. changed the title [-]Logarithmic axes with zero values trigger OverflowError, Matplotlib hangs permanently[/-] [+]Plotting zero values with logarithmic axes triggers OverflowError, Matplotlib hangs permanently[/+] on Nov 21, 2016
  6. FilipDominec commented on Nov 21, 2016

    @FilipDominec
    Author

    I think I have traced the source of error. I plotted a line using ax.set_yscale('log'), and then I switched to a contour plot, keeping the y-axis in the logarithmic mode. Then, the bottom border of the contour plot would be positioned at log(0), which is obviously a nonsense.

    So the error is on my side. Still I believe matplotlib should be more robust and recover from my impossible demand, so that one can switch back to logarithmic lines. Currently, it just keeps printing an error message over and over, without plotting even a line.

  7. tacaswell commented on Nov 21, 2016

    @tacaswell
    Member

    mpl should raise when you set the invalid state, not at draw time (because drawing tends to happen in GUI callback threads which are hard to debug / catch errors from).

    This is hitting an API design edge, user facing / interface code should never raise, libraries should raise early and often. These two uses cases historically been mixed in mpl, but we should be moving more towards the 'raise early and often' side of things and leave the exception handling to your application.

  8. anntzer commented on Nov 21, 2016

    @anntzer
    Contributor

    Currently you just have to catch the error yourself in the GUI thread (which as @tacaswell says is not optimal, but not so easy to fix...), see #6983 for how it's done by mpl itself.

  9. FilipDominec commented on Nov 22, 2016

    @FilipDominec
    Author

    I must admit that I am not able to catch the error myself. It happens in the library and does not write out the offending line of my code.

    Naturally, I have had the try .. except clause around the plotting commands, but the error handler is never executed and matplotlib keeps "freezing" as I described above. Then the program ceases to plot anything, no matter that I return the settings to original safe values, and has to be restarted.

    Without running a debugger and plunging deep into the matplotlib code, I have probably no means of tracing the source of error, nor even preventing it from happening.

  10. anntzer commented on Nov 22, 2016

    @anntzer
    Contributor

    Ah, now I remember I did write something about that. Can you try with #7197?

  11. FilipDominec commented on Nov 22, 2016

    @FilipDominec
    Author

    @anntzer, to test your fix, I have run

    git remote add anntzer https://github.com/anntzer/matplotlib
    git fetch anntzer 
    git cherry-pick 129bee9
    python3 setup.py build; sudo python3 setup.py install
    

    The error message is different from that I got previously, but occurs at the same situation and causes the same troublesome behaviour. (Note that I also diffed the following error message against that one from the latest commit of the matplotlib trunk - and both messages are almost the same except for the matplotlib revision numbers +2909.gd36e499 != +2910.g1bb648c.)

    Traceback (most recent call last):
      File "/usr/local/lib/python3.5/dist-packages/matplotlib-2.0.0b4+2910.g1bb648c-py3.5-linux-x86_64.egg/matplotlib/backends/backend_gtk3cairo.py", line 45, in on_draw_event
    	self._render_figure(w, h)
      File "/usr/local/lib/python3.5/dist-packages/matplotlib-2.0.0b4+2910.g1bb648c-py3.5-linux-x86_64.egg/matplotlib/backends/backend_gtk3cairo.py", line 34, in _render_figure
    	self.figure.draw (self._renderer)
      File "/usr/local/lib/python3.5/dist-packages/matplotlib-2.0.0b4+2910.g1bb648c-py3.5-linux-x86_64.egg/matplotlib/artist.py", line 68, in draw_wrapper
    	return draw(artist, renderer, *args, **kwargs)
      File "/usr/local/lib/python3.5/dist-packages/matplotlib-2.0.0b4+2910.g1bb648c-py3.5-linux-x86_64.egg/matplotlib/figure.py", line 1262, in draw
    	renderer, self, dsu, self.suppressComposite)
      File "/usr/local/lib/python3.5/dist-packages/matplotlib-2.0.0b4+2910.g1bb648c-py3.5-linux-x86_64.egg/matplotlib/image.py", line 139, in _draw_list_compositing_images
    	a.draw(renderer)
      File "/usr/local/lib/python3.5/dist-packages/matplotlib-2.0.0b4+2910.g1bb648c-py3.5-linux-x86_64.egg/matplotlib/artist.py", line 68, in draw_wrapper
    	return draw(artist, renderer, *args, **kwargs)
      File "/usr/local/lib/python3.5/dist-packages/matplotlib-2.0.0b4+2910.g1bb648c-py3.5-linux-x86_64.egg/matplotlib/axes/_base.py", line 2394, in draw
    	mimage._draw_list_compositing_images(renderer, self, dsu)
      File "/usr/local/lib/python3.5/dist-packages/matplotlib-2.0.0b4+2910.g1bb648c-py3.5-linux-x86_64.egg/matplotlib/image.py", line 139, in _draw_list_compositing_images
    	a.draw(renderer)
      File "/usr/local/lib/python3.5/dist-packages/matplotlib-2.0.0b4+2910.g1bb648c-py3.5-linux-x86_64.egg/matplotlib/artist.py", line 68, in draw_wrapper
    	return draw(artist, renderer, *args, **kwargs)
      File "/usr/local/lib/python3.5/dist-packages/matplotlib-2.0.0b4+2910.g1bb648c-py3.5-linux-x86_64.egg/matplotlib/axis.py", line 1121, in draw
    	ticks_to_draw = self._update_ticks(renderer)
      File "/usr/local/lib/python3.5/dist-packages/matplotlib-2.0.0b4+2910.g1bb648c-py3.5-linux-x86_64.egg/matplotlib/axis.py", line 954, in _update_ticks
    	tick_tups = [t for t in self.iter_ticks()]
      File "/usr/local/lib/python3.5/dist-packages/matplotlib-2.0.0b4+2910.g1bb648c-py3.5-linux-x86_64.egg/matplotlib/axis.py", line 954, in <listcomp>
    	tick_tups = [t for t in self.iter_ticks()]
      File "/usr/local/lib/python3.5/dist-packages/matplotlib-2.0.0b4+2910.g1bb648c-py3.5-linux-x86_64.egg/matplotlib/axis.py", line 897, in iter_ticks
    	majorLocs = self.major.locator()
      File "/usr/local/lib/python3.5/dist-packages/matplotlib-2.0.0b4+2910.g1bb648c-py3.5-linux-x86_64.egg/matplotlib/ticker.py", line 1815, in __call__
    	return self.tick_values(vmin, vmax)
      File "/usr/local/lib/python3.5/dist-packages/matplotlib-2.0.0b4+2910.g1bb648c-py3.5-linux-x86_64.egg/matplotlib/ticker.py", line 1823, in tick_values
    	locs = self._raw_ticks(vmin, vmax)
      File "/usr/local/lib/python3.5/dist-packages/matplotlib-2.0.0b4+2910.g1bb648c-py3.5-linux-x86_64.egg/matplotlib/ticker.py", line 1770, in _raw_ticks
    	nbins = max(min(self.axis.get_tick_space(), 9),
      File "/usr/local/lib/python3.5/dist-packages/matplotlib-2.0.0b4+2910.g1bb648c-py3.5-linux-x86_64.egg/matplotlib/axis.py", line 2031, in get_tick_space
    	return int(np.floor(length / size))
    ValueError: cannot convert float NaN to integer\
    

    Maybe I just did something wrong, I will be thankful for some tips for testing it further.

  12. anntzer commented on Nov 22, 2016

    @anntzer
    Contributor

    You probably didn't, something else is going on I guess...

  13. jfmoulin commented on Dec 8, 2016

    @jfmoulin

    I have the same problem in a script which could be reduced to

    pylab.plot(pylab.arange(-10,-1))
    pylab.gca().set_yscale('log')
    

    (This crashes IPython beyond repair by the way, with errors coming up in an apparently random fashion from that point.

  14. FilipDominec commented on Dec 8, 2016

    @FilipDominec
    Author

    @jfmoulin In my case (see configuration in the first post), I could not reproduce the crashing in Python nor IPython, version 2 nor 3. Instead, matplotlib always correctly reports the error.

    >>> pylab.gca().set_yscale('log')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/usr/lib/python3/dist-packages/matplotlib/axes/_base.py", line 2837, in set_yscale
    	self.autoscale_view(scalex=False)
      File "/usr/lib/python3/dist-packages/matplotlib/axes/_base.py", line 1966, in autoscale_view
    	y0, y1 = ylocator.view_limits(y0, y1)
      File "/usr/lib/python3/dist-packages/matplotlib/ticker.py", line 1525, in view_limits
    	"Data has no positive values, and therefore can not be "
    ValueError: Data has no positive values, and therefore can not be log-scaled.
    
  15. efiring commented on Dec 8, 2016

    @efiring
    Member

    I'm working on this and related problems. I hope to have a PR within a day or two.

  16. self-assigned this
    on Dec 8, 2016
  17. QuLogic commented on Dec 13, 2016

    @QuLogic
    Member

    Closed by #7598.

  18. modified the milestones: , on Dec 13, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions