Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Type promotion error with datetime bins in hist #15332

Copy link
Copy link
Closed
@pganssle

Description

@pganssle
Issue body actions

Bug report

It appears that pyplot.hist (and I believe the equivalent axis method) does not allow lists of date or datetime objects to be used as the bin edges, even if the things being binned are dates, so:

from datetime import datetime

import matplotlib as mpl
from matplotlib import pyplot as plt

dates = [
    datetime(2019, 1, 5), datetime(2019, 1, 11), datetime(2019, 2, 1),
    datetime(2019, 2, 5), datetime(2019, 2, 18), datetime(2019, 3, 1),
]

date_edges = [
    datetime(2019, 1, 1), datetime(2019, 2, 1), datetime(2019, 3, 1),
]

plt.hist(dates)   # Works
plt.hist(dates, bins=mpl.dates.date2num(date_edges))  # Works
plt.hist(dates, bins=date_edges)   # Fails

The first hist call works but doesn't specify the bins, the second one works and does what we want, but it requires actively converting date_edges. The third one should do the same thing as the second one, but instead it fails with:

TypeError: '<' not supported between instances of 'float' and 'datetime.datetime'

Full error message below:

TypeError                                 Traceback (most recent call last)
<ipython-input-27-5b07a69daccb> in <module>
----> 1 plt.hist(dates, bins=date_bins)

/tmp/mpl/lib/python3.7/site-packages/matplotlib/pyplot.py in hist(x, bins, range, density, weights, cumulative, bottom, histtype, align, orientation, rwidth, log, color, label, stacked, normed, data, **kwargs)
   2640         align=align, orientation=orientation, rwidth=rwidth, log=log,
   2641         color=color, label=label, stacked=stacked, normed=normed,
-> 2642         **({"data": data} if data is not None else {}), **kwargs)
   2643
   2644

/tmp/mpl/lib/python3.7/site-packages/matplotlib/__init__.py in inner(ax, data, *args, **kwargs)
   1599     def inner(ax, *args, data=None, **kwargs):
   1600         if data is None:
-> 1601             return func(ax, *map(sanitize_sequence, args), **kwargs)
   1602
   1603         bound = new_sig.bind(ax, *args, **kwargs)

/tmp/mpl/lib/python3.7/site-packages/matplotlib/axes/_axes.py in hist(self, x, bins, range, density, weights, cumulative, bottom, histtype, align, orientation, rwidth, log, color, label, stacked, normed, **kwargs)
   6765             # this will automatically overwrite bins,
   6766             # so that each histogram uses the same bins
-> 6767             m, bins = np.histogram(x[i], bins, weights=w[i], **hist_kwargs)
   6768             m = m.astype(float)  # causes problems later if it's an int
   6769             if mlast is None:

<__array_function__ internals> in histogram(*args, **kwargs)

/tmp/mpl/lib/python3.7/site-packages/numpy/lib/histograms.py in histogram(a, bins, range, normed, weights, density)
    869             for i in _range(0, len(a), BLOCK):
    870                 sa = np.sort(a[i:i+BLOCK])
--> 871                 cum_n += _search_sorted_inclusive(sa, bin_edges)
    872         else:
    873             zero = np.zeros(1, dtype=ntype)

/tmp/mpl/lib/python3.7/site-packages/numpy/lib/histograms.py in _search_sorted_inclusive(a, v)
    452     """
    453     return np.concatenate((
--> 454         a.searchsorted(v[:-1], 'left'),
    455         a.searchsorted(v[-1:], 'right')
    456     ))

TypeError: '<' not supported between instances of 'float' and 'datetime.datetime'

I think this is another manifestation of the same underlying problem we saw in #12863 (see my comments in there for some more details on that), which is that a lot of the datetime stuff converts somewhat eagerly to floats but some of it doesn't.

I think this case is easier than #12863 in the sense that you can almost certainly translate this into an unambiguous point on the number line and eagerly convert the bin edges early on, depending on how matplotlib treats naive datetimes. It's possible that you may want to detect if x and bins are both naive or both aware and throw an error if they aren't, but I don't see that as a major sticking point.

Matplotlib version

  • Operating system: Linux
  • Matplotlib version: 3.1.1
  • Matplotlib backend (print(matplotlib.get_backend())): TkAgg
  • Python version: 3.7.4

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

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.