Skip to content

FIX: show bars when the first location is nan #23751

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

Merged
merged 2 commits into from
Sep 19, 2022

Conversation

tacaswell
Copy link
Member

PR Summary

Due to the way we handle units on the bar width having an invalid value in the
first position of the x bar (of y of barh) would effectively poison all of the
widths making all of the bars invisible.

This also renames the cbook function _safe_first_non_none function ->
_safe_first_finite and adjusts the behavior to also drop nans

closes #23687

PR Checklist

Tests and Styling

  • Has pytest style unit tests (and pytest passes).
  • Is Flake 8 compliant (install flake8-docstrings and run flake8 --docstring-convention=all).

Due to the way we handle units on the bar width having an invalid value in the
first position of the x bar (of y of barh) would effectively poison all of the
widths making all of the bars invisible.

This also renames the cbook function _safe_first_non_none function ->
_safe_first_finite and adjusts the behavior to also drop nans

closes matplotlib#23687
@tacaswell tacaswell added this to the v3.7.0 milestone Aug 26, 2022


def _safe_first_non_none(obj, skip_none=True):
def _safe_first_finite(obj, *, skip_nonfinite=True):
"""
Return the first non-None element in *obj*.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docstring needs to be adapted.

return next(val for val in obj if val is not None)
return next(
val for val in obj
if val is not None and safe_isfinite(val)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logically, should we absorb the None check in safe_isfinite? -I think None is not finite.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to check this here:

In [62]: np.isfinite(None)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In [63], line 1
----> 1 np.isfinite(None)

TypeError: ufunc 'isfinite' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we need the check. I was suggesting that it could logically belong inside safe_isfinite (by the argument that None is not a finite number, similar to NaN).

i.e.

def safe_isfinite(val):
    if val is None:
        return False
    ...

and here next(val for val in obj if safe_isfinite(val))

I just realized that this is an inner function, so it's not too important, but I'd still have a slight preference. I'll approve and you can decide whether you want to change it or leave it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that is nicer.

@anntzer
Copy link
Contributor

anntzer commented Sep 13, 2022

Will this break the (somewhat edge) case where the user passes in an array with only NaTs (not-a-time) and expect the plot to be configured to use datetimes?

Copy link
Member

@timhoffm timhoffm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One optional logical improvement.

return next(val for val in obj if val is not None)
return next(
val for val in obj
if val is not None and safe_isfinite(val)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we need the check. I was suggesting that it could logically belong inside safe_isfinite (by the argument that None is not a finite number, similar to NaN).

i.e.

def safe_isfinite(val):
    if val is None:
        return False
    ...

and here next(val for val in obj if safe_isfinite(val))

I just realized that this is an inner function, so it's not too important, but I'd still have a slight preference. I'll approve and you can decide whether you want to change it or leave it.

@timhoffm timhoffm modified the milestones: v3.7.0, v3.6.1 Sep 19, 2022
@timhoffm timhoffm merged commit 91dd120 into matplotlib:main Sep 19, 2022
meeseeksmachine pushed a commit to meeseeksmachine/matplotlib that referenced this pull request Sep 19, 2022
timhoffm added a commit that referenced this pull request Sep 19, 2022
…751-on-v3.6.x

Backport PR #23751 on branch v3.6.x (FIX: show bars when the first location is nan)
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 this pull request may close these issues.

[Bug]: barplot does not show anything when x or bottom start and end with NaN
4 participants