Skip to content

Switching to log scale when there is no positive data crashes the Qt5 backend, causes inconsistent internal state in others #6852

Closed

Description

@anntzer

mpl 1.5.1/2.0b3/master, Qt5Agg backend, Python 3.5.2, Arch Linux

plt.plot([-1, -2]); plt.show()

and press l while the mouse is over the axes.

Qt5 aborts Python due to the exception propagating out of the slot:

/usr/lib/python3.5/site-packages/matplotlib/axes/_base.py:2270: RuntimeWarning: invalid value encountered in double_scalars
  delta = (x1t - x0t) * margin
Traceback (most recent call last):
  File "/usr/lib/python3.5/site-packages/matplotlib/backends/backend_qt5.py", line 314, in keyPressEvent
    FigureCanvasBase.key_press_event(self, key, guiEvent=event)
  File "/usr/lib/python3.5/site-packages/matplotlib/backend_bases.py", line 1842, in key_press_event
    self.callbacks.process(s, event)
  File "/usr/lib/python3.5/site-packages/matplotlib/cbook.py", line 550, in process
    proxy(*args, **kwargs)
  File "/usr/lib/python3.5/site-packages/matplotlib/cbook.py", line 417, in __call__
    return mtd(*args, **kwargs)
  File "/usr/lib/python3.5/site-packages/matplotlib/backend_bases.py", line 2639, in key_press
    key_press_handler(event, self.canvas, self.canvas.toolbar)
  File "/usr/lib/python3.5/site-packages/matplotlib/backend_bases.py", line 2546, in key_press_handler
    ax.set_yscale('log')
  File "/usr/lib/python3.5/site-packages/matplotlib/axes/_base.py", line 3146, in set_yscale
    self.autoscale_view(scalex=False)
  File "/usr/lib/python3.5/site-packages/matplotlib/axes/_base.py", line 2288, in autoscale_view
    margins['bottom'], margins['top'], self.set_ybound)
  File "/usr/lib/python3.5/site-packages/matplotlib/axes/_base.py", line 2278, in handle_single_axis
    x0, x1 = locator.view_limits(x0, x1)
  File "/usr/lib/python3.5/site-packages/matplotlib/ticker.py", line 1803, 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.
Fatal Python error: Aborted

Not sure what the best approach is but I think we should certainly try to avoid a fatal crash...

While it may be tempting to just wrap key_press_handler in a try... except or disable the abort()ing behavior of PyQt5 by installing a custom excepthook (see http://pyqt.sourceforge.net/Docs/PyQt5/incompatibilities.html section for PyQt5.5), this would hide the fact that the canvas is left in an inconsistent state as the axes internally believe to have switched to log-scale. This can be seen e.g. by using the Qt4Agg backend (where the exception is printed but the program not abort()ed), by typing l and then trying to zoom in (again with the mouse): the canvas becomes completely empty in that case.

Activity

  1. LindyBalboa commented on Jul 29, 2016

    @LindyBalboa
    Contributor

    Would it perhaps make sense to change the default to symlog? I know it is only suppose to be used for exceptional sign changes to standard math (I use it all the time for transistor curves), but I think it would lead to a more intuitive behavior.

    Edit: Shouldn't this be handled by nonposy nonposx in mpl.axes.Axes.set_yscale?

  2. LindyBalboa commented on Jul 30, 2016

    @LindyBalboa
    Contributor

    I posted here last night, but maybe forgot to submit?

    I played around with it and it seems nonposy is only successfully handled via masking and clipping if there is at least one positive value. The existing structures don't seem too well suited to handle this situation. The way it is, I would guess the smallest effective change would be to add a all(i<0 for i in y) somewhere inside `set_x/yscale' or the appropriate method called from it.

    I personally would still recommend changing the default behavior of l and k to symlog. Although it isn't mathematically correct, it has more real world applications and is more intuitive from a graphical sense.

  3. anntzer commented on Aug 26, 2016

    @anntzer
    ContributorAuthor

    Actually my comment about wrapping in a try... except was incorrect: that can work, one simply has to restore the original scale in case of a failure. See #6983.

  4. tacaswell commented on Aug 27, 2016

    @tacaswell
    Member

    Closed by #6983

    please re-open if I am confused.

  5. added this to the milestone on Aug 27, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions