8000 Logit scale doesn't position x/ylabel correctly first draw · Issue #11386 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content

Logit scale doesn't position x/ylabel correctly first draw #11386

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

Closed
ImportanceOfBeingErnest opened this issue Jun 6, 2018 · 5 comments · Fixed by #11417
Closed

Logit scale doesn't position x/ylabel correctly first draw #11386

ImportanceOfBeingErnest opened this issue Jun 6, 2018 · 5 comments · Fixed by #11417
Milestone

Comments

@ImportanceOfBeingErnest
Copy link
Member
ImportanceOfBeingErnest commented Jun 6, 2018

Bug report

Bug summary

Using constrained_layout or tight_layout in conjunction with a logit scale fails or crashes.

Constrained layout:

import matplotlib.pyplot as plt
fig, ax = plt.subplots(constrained_layout=True)

ax.plot([.2,.4,.6,.8],[.2, .4, .5, .9])
ax.set_xscale('logit')

plt.show()

results in a crash of python in Windows. I.e. it shows a pop up saying python needs to be closed because it crashed.

Tight layout

import matplotlib.pyplot as plt
fig, ax = plt.subplots()

ax.plot([.2,.4,.6,.8],[.2, .4, .5, .9])
ax.set_xscale('logit')

fig.tight_layout()
plt.show()

produces a long traceback for a ValueError: cannot convert float NaN to integer.

D:\...\envs\mplgit\lib\site-packages\numpy\core\_methods.py:29: RuntimeWarning: invalid value encountered in reduce
  return umr_minimum(a, axis, None, out, keepdims)
D:\...\envs\mplgit\lib\site-packages\numpy\core\_methods.py:26: RuntimeWarning: invalid value encountered in reduce
  return umr_maximum(a, axis, None, out, keepdims)
posx and posy should be finite values
posx and posy should be finite values
posx and posy should be finite values
posx and posy should be finite values
posx and posy should be finite values
posx and posy should be finite values
posx and posy should be finite values

Traceback (most recent call last):
  File "d:\...\python\matplotlib\source\matplotlibgit\matplotlib\lib\matplotlib\backends\backend_qt5.py", line 513, in _draw_idle
    self.draw()
  File "d:\...\python\matplotlib\source\matplotlibgit\matplotlib\lib\matplotlib\backends\backend_agg.py", line 421, in draw
    self.figure.draw(self.renderer)
  File "d:\...\python\matplotlib\source\matplotlibgit\matplotlib\lib\matplotlib\artist.py", line 50, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "d:\...\python\matplotlib\source\matplotlibgit\matplotlib\lib\matplotlib\figure.py", line 1478, in draw
    renderer, self, artists, self.suppressComposite)
  File "d:\...\python\matplotlib\source\matplotlibgit\matplotlib\lib\matplotlib\image.py", line 138, in _draw_list_compositing_images
    a.draw(renderer)
  File "d:\...\python\matplotlib\source\matplotlibgit\matplotlib\lib\matplotlib\artist.py", line 50, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "d:\...\python\matplotlib\source\matplotlibgit\matplotlib\lib\matplotlib\axes\_base.py", line 2583, in draw
    mimage._draw_list_compositing_images(renderer, self, artists)
  File "d:\...\python\matplotlib\source\matplotlibgit\matplotlib\lib\matplotlib\image.py", line 138, in _draw_list_compositing_images
    a.draw(renderer)
  File "d:\...\python\matplotlib\source\matplotlibgit\matplotlib\lib\matplotlib\artist.py", line 50, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "d:\...\python\matplotlib\source\matplotlibgit\matplotlib\lib\matplotlib\axis.py", line 1177, in draw
    ticks_to_draw = self._update_ticks(renderer)
  File "d:\...\python\matplotlib\source\matplotlibgit\matplotlib\lib\matplotlib\axis.py", line 1017, in _update_ticks
    tick_tups = list(self.iter_ticks())  # iter_ticks calls the locator
  File "d:\...\python\matplotlib\source\matplotlibgit\matplotlib\lib\matplotlib\axis.py", line 961, in iter_ticks
    majorLocs = self.major.locator()
  File "d:\...\python\matplotlib\source\matplotlibgit\matplotlib\lib\matplotlib\ticker.py", line 1922, in __call__
    return self.tick_values(vmin, vmax)
  File "d:\...\python\matplotlib\source\matplotlibgit\matplotlib\lib\matplotlib\ticker.py", line 1930, in tick_values
    locs = self._raw_ticks(vmin, vmax)
  File "d:\...\python\matplotlib\source\matplotlibgit\matplotlib\lib\matplotlib\ticker.py", line 1876, in _raw_ticks
    nbins = np.clip(self.axis.get_tick_space(),
  File "d:\...\python\matplotlib\source\matplotlibgit\matplotlib\lib\matplotlib\axis.py", line 2503, in get_tick_space
    return int(np.floor(length / size))
ValueError: cannot convert float NaN to integer

Expected outcome

Using either of above without layout manager gives the correct figure.

Also, using either of above without the line ax.set_xscale('logit') produces the expected output.

This may be related to #5456.

Matplotlib version

  • Operating system: Windows 8.1
  • Matplotlib version: 2.2.2.post1271+g0a70730fa
  • Matplotlib backend (print(matplotlib.get_backend())): Qt5Agg, TkAgg
  • Python version: 3.6
@jklymak
Copy link
Member
jklymak commented Jun 7, 2018

I don’t have a computer to see what the issue could be. Off the top of my head I can’t see why either layout manager would care what the scale is so there must be something funky going on here...

@fredrik-1
Copy link
Contributor

I tried to look at it and my guess is that the problem is that the following spine consist of infs in the first call in axis._update_label_position. But I don't even know what a spine is. I just tried to find out when something started to look wrong.

spine=ax.spines['bottom']
spine.get_transform().transform_path(spine.get_path()).get_extents()

subplotpars consist of np.nans after tight_layout. This seems to be due to axes. get_tightbbox and the above calculation in axis._update_label_position.

@afvincent
Copy link
Contributor

@fredrik-1 Thanks :)! It may indeed be consistent with my quick look at the issue, which suggests that something is going wrong with the positions of some ticks (=> the attached text label(s) possibly receiving a non finite position, which could lead an “infinite” length somewhere).

FYI, spines are the “borders” of the axes. See for example this plot (bottom right)

@jklymak
Copy link
Member
jklymak commented Jun 10, 2018

Logit is putting some text at -inf; I assume there is a 1/0 error in there somewhere.

@jklymak
Copy link
Member
jklymak commented Jun 11, 2018

So, just to clarify this bug:

The error is in _update_label_position. The following returns a bbox with Bbox(x0=inf, y0=inf, x1=-inf, y1=-inf):

spinebbox = spine.get_transform().transform_path(
                    spine.get_path()).get_extents()

The reason is that for the first call to spine.get_path() it returns nonesense:

Path(array([[  0.,  13.],
       [  0.,  13.]]), None)

and a logit scale doesn't deal well with the values of 13, which are greater than 1. (a/(1-a) == inf)

Interesting other scales return the same path; Of course the ylabel position shouldn't need to know anything about the y-extent of the path, so the bad value in the path doesn't normally affect the transform. But because it goes to inf, it screws up the matrix algebra of the transform and makes a mess for the Logit scale.

Note that on master, the logit scale does not display the ylabel on the first draw.

Subsequent draws, the Path is correct, and the ylabel appears.

The fudnamental issue is Spines.linear_spine sets the Path to 0, 13 or 13, 0. That choice doesn't matter, and is obviously just a placeholder, but I think should be less than 1.

@jklymak jklymak changed the title Logit scale fails with layout managers Logit scale doesn't position x/ylabel correctly Jun 11, 2018
@jklymak jklymak changed the title Logit scale doesn't position x/ylabel correctly Logit scale doesn't position x/ylabel correctly first draw Jun 11, 2018
@dstansby dstansby added this to the v3.0 milestone Jun 12, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants
0