Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
29 changes: 18 additions & 11 deletions lib/matplotlib/axes/_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -7416,7 +7416,16 @@

# Massage 'x' for processing.
x = cbook._reshape_2D(x, 'x')
nx = len(x) # number of datasets
nx = len(x)
Comment thread
timhoffm marked this conversation as resolved.
Outdated

Check warning on line 7420 in lib/matplotlib/axes/_axes.py

View workflow job for this annotation

GitHub Actions / ruff

[rdjson] reported by reviewdog 🐶 Blank line contains whitespace Raw Output: message:"Blank line contains whitespace" location:{path:"/home/runner/work/matplotlib/matplotlib/lib/matplotlib/axes/_axes.py" range:{start:{line:7420 column:1} end:{line:7420 column:9}}} severity:WARNING source:{name:"ruff" url:"https://docs.astral.sh/ruff"} code:{value:"W293" url:"https://docs.astral.sh/ruff/rules/blank-line-with-whitespace"} suggestions:{range:{start:{line:7420 column:1} end:{line:7420 column:9}}}
new_x = []
for xi in x:
arr = np.asarray(xi)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is unnecessary. cbook._reshape_2D() already returns a list of arrays.

So at least

x = [arr / np.timedelta64(1, 'D') if np.issubdtype(arr.dtype, np.timedelta64) else arr
     for arr in x]

is possible.


Another question to be investigated: Is arr / np.timedelta64(1, 'D') equivalent to arr.astype(float) for timedelta arrays? If so, would a general x = [arr.astype(float) for arr in x] be reasonable?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is arr / np.timedelta64(1, 'D') equivalent to arr.astype(float) for timedelta arrays?

No, which is the whole problem here. If it was possible to cast timedelta64 to float, the comparison would work.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

astype(float) is valid, and I think is the better solution. Dividing by one day is going to give you tiny numbers if you started with seconds, and is going to error if you started with months or years.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

astype(float) is unsafe so if you choose to cast in this function you should be explicit in the documentation

if np.issubdtype(arr.dtype, np.timedelta64):
arr = arr / np.timedelta64(1, 'D')
new_x.append(arr)

x = new_x

# Process unit information. _process_unit_info sets the unit and
# converts the first dataset; then we convert each following dataset
Expand Down Expand Up @@ -7470,16 +7479,14 @@
# does not do this for us when guessing the range (but will
# happily ignore nans when computing the histogram).
if bin_range is None:
xmin = np.inf
xmax = -np.inf
for xi in x:
if len(xi):
# python's min/max ignore nan,
# np.minnan returns nan for all nan input
xmin = min(xmin, np.nanmin(xi))
xmax = max(xmax, np.nanmax(xi))
if xmin <= xmax: # Only happens if we have seen a finite value.
bin_range = (xmin, xmax)
flat = [np.ravel(xi) for xi in x if len(xi)]
if flat:
all_data = np.concatenate(flat)
xmin = np.nanmin(all_data)
xmax = np.nanmax(all_data)
bin_range = (xmin, xmax)
else:
bin_range = None
Comment thread
scottshambaugh marked this conversation as resolved.
Outdated
Comment thread
scottshambaugh marked this conversation as resolved.
Outdated

# If bins are not specified either explicitly or via range,
# we need to figure out the range required for all datasets,
Expand Down
9 changes: 9 additions & 0 deletions lib/matplotlib/tests/test_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2461,6 +2461,15 @@ def test_hist_log_barstacked():
assert axs[0].get_ylim() == axs[1].get_ylim()


def test_hist_timedelta_no_crash():
import numpy as np
import matplotlib.pyplot as plt

arr = np.array([1,2,5,7], dtype="timedelta64[D]")
fig, ax = plt.subplots()
ax.hist(arr)

Comment thread
timhoffm marked this conversation as resolved.

@image_comparison(['hist_bar_empty.png'], remove_text=True)
def test_hist_bar_empty():
# From #3886: creating hist from empty dataset raises ValueError
Expand Down
Loading