A PyQT GUI application for converting InfoLease report outputs into Excel files. Handles parsing and summarizing. Learns where files are meant to be store and compiles monthly and yearly summaries.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
InfoLeaseExtract/venv/Lib/site-packages/pandas/tests/plotting/test_converter.py

384 lines
12 KiB

from datetime import (
date,
datetime,
)
import subprocess
import sys
import numpy as np
import pytest
import pandas._config.config as cf
import pandas.util._test_decorators as td
from pandas import (
Index,
Period,
Series,
Timestamp,
date_range,
)
import pandas._testing as tm
from pandas.plotting import (
deregister_matplotlib_converters,
register_matplotlib_converters,
)
from pandas.tseries.offsets import (
Day,
Micro,
Milli,
Second,
)
try:
from pandas.plotting._matplotlib import converter
except ImportError:
# try / except, rather than skip, to avoid internal refactoring
# causing an improper skip
pass
pytest.importorskip("matplotlib.pyplot")
dates = pytest.importorskip("matplotlib.dates")
pytestmark = pytest.mark.slow
def test_registry_mpl_resets():
# Check that Matplotlib converters are properly reset (see issue #27481)
code = (
"import matplotlib.units as units; "
"import matplotlib.dates as mdates; "
"n_conv = len(units.registry); "
"import pandas as pd; "
"pd.plotting.register_matplotlib_converters(); "
"pd.plotting.deregister_matplotlib_converters(); "
"assert len(units.registry) == n_conv"
)
call = [sys.executable, "-c", code]
subprocess.check_output(call)
def test_timtetonum_accepts_unicode():
assert converter.time2num("00:01") == converter.time2num("00:01")
class TestRegistration:
def test_dont_register_by_default(self):
# Run in subprocess to ensure a clean state
code = (
"import matplotlib.units; "
"import pandas as pd; "
"units = dict(matplotlib.units.registry); "
"assert pd.Timestamp not in units"
)
call = [sys.executable, "-c", code]
assert subprocess.check_call(call) == 0
@td.skip_if_no("matplotlib", min_version="3.1.3")
def test_registering_no_warning(self):
plt = pytest.importorskip("matplotlib.pyplot")
s = Series(range(12), index=date_range("2017", periods=12))
_, ax = plt.subplots()
# Set to the "warn" state, in case this isn't the first test run
register_matplotlib_converters()
ax.plot(s.index, s.values)
plt.close()
def test_pandas_plots_register(self):
plt = pytest.importorskip("matplotlib.pyplot")
s = Series(range(12), index=date_range("2017", periods=12))
# Set to the "warn" state, in case this isn't the first test run
with tm.assert_produces_warning(None) as w:
s.plot()
try:
assert len(w) == 0
finally:
plt.close()
def test_matplotlib_formatters(self):
units = pytest.importorskip("matplotlib.units")
# Can't make any assertion about the start state.
# We we check that toggling converters off removes it, and toggling it
# on restores it.
with cf.option_context("plotting.matplotlib.register_converters", True):
with cf.option_context("plotting.matplotlib.register_converters", False):
assert Timestamp not in units.registry
assert Timestamp in units.registry
@td.skip_if_no("matplotlib", min_version="3.1.3")
def test_option_no_warning(self):
pytest.importorskip("matplotlib.pyplot")
ctx = cf.option_context("plotting.matplotlib.register_converters", False)
plt = pytest.importorskip("matplotlib.pyplot")
s = Series(range(12), index=date_range("2017", periods=12))
_, ax = plt.subplots()
# Test without registering first, no warning
with ctx:
ax.plot(s.index, s.values)
# Now test with registering
register_matplotlib_converters()
with ctx:
ax.plot(s.index, s.values)
plt.close()
def test_registry_resets(self):
units = pytest.importorskip("matplotlib.units")
dates = pytest.importorskip("matplotlib.dates")
# make a copy, to reset to
original = dict(units.registry)
try:
# get to a known state
units.registry.clear()
date_converter = dates.DateConverter()
units.registry[datetime] = date_converter
units.registry[date] = date_converter
register_matplotlib_converters()
assert units.registry[date] is not date_converter
deregister_matplotlib_converters()
assert units.registry[date] is date_converter
finally:
# restore original stater
units.registry.clear()
for k, v in original.items():
units.registry[k] = v
class TestDateTimeConverter:
def setup_method(self, method):
self.dtc = converter.DatetimeConverter()
self.tc = converter.TimeFormatter(None)
def test_convert_accepts_unicode(self):
r1 = self.dtc.convert("12:22", None, None)
r2 = self.dtc.convert("12:22", None, None)
assert r1 == r2, "DatetimeConverter.convert should accept unicode"
def test_conversion(self):
rs = self.dtc.convert(["2012-1-1"], None, None)[0]
xp = dates.date2num(datetime(2012, 1, 1))
assert rs == xp
rs = self.dtc.convert("2012-1-1", None, None)
assert rs == xp
rs = self.dtc.convert(date(2012, 1, 1), None, None)
assert rs == xp
rs = self.dtc.convert("2012-1-1", None, None)
assert rs == xp
rs = self.dtc.convert(Timestamp("2012-1-1"), None, None)
assert rs == xp
# also testing datetime64 dtype (GH8614)
rs = self.dtc.convert("2012-01-01", None, None)
assert rs == xp
rs = self.dtc.convert("2012-01-01 00:00:00+0000", None, None)
assert rs == xp
rs = self.dtc.convert(
np.array(["2012-01-01 00:00:00+0000", "2012-01-02 00:00:00+0000"]),
None,
None,
)
assert rs[0] == xp
# we have a tz-aware date (constructed to that when we turn to utc it
# is the same as our sample)
ts = Timestamp("2012-01-01").tz_localize("UTC").tz_convert("US/Eastern")
rs = self.dtc.convert(ts, None, None)
assert rs == xp
rs = self.dtc.convert(ts.to_pydatetime(), None, None)
assert rs == xp
rs = self.dtc.convert(Index([ts - Day(1), ts]), None, None)
assert rs[1] == xp
rs = self.dtc.convert(Index([ts - Day(1), ts]).to_pydatetime(), None, None)
assert rs[1] == xp
def test_conversion_float(self):
rtol = 0.5 * 10**-9
rs = self.dtc.convert(Timestamp("2012-1-1 01:02:03", tz="UTC"), None, None)
xp = converter.dates.date2num(Timestamp("2012-1-1 01:02:03", tz="UTC"))
tm.assert_almost_equal(rs, xp, rtol=rtol)
rs = self.dtc.convert(
Timestamp("2012-1-1 09:02:03", tz="Asia/Hong_Kong"), None, None
)
tm.assert_almost_equal(rs, xp, rtol=rtol)
rs = self.dtc.convert(datetime(2012, 1, 1, 1, 2, 3), None, None)
tm.assert_almost_equal(rs, xp, rtol=rtol)
def test_conversion_outofbounds_datetime(self):
# 2579
values = [date(1677, 1, 1), date(1677, 1, 2)]
rs = self.dtc.convert(values, None, None)
xp = converter.dates.date2num(values)
tm.assert_numpy_array_equal(rs, xp)
rs = self.dtc.convert(values[0], None, None)
xp = converter.dates.date2num(values[0])
assert rs == xp
values = [datetime(1677, 1, 1, 12), datetime(1677, 1, 2, 12)]
rs = self.dtc.convert(values, None, None)
xp = converter.dates.date2num(values)
tm.assert_numpy_array_equal(rs, xp)
rs = self.dtc.convert(values[0], None, None)
xp = converter.dates.date2num(values[0])
assert rs == xp
@pytest.mark.parametrize(
"time,format_expected",
[
(0, "00:00"), # time2num(datetime.time.min)
(86399.999999, "23:59:59.999999"), # time2num(datetime.time.max)
(90000, "01:00"),
(3723, "01:02:03"),
(39723.2, "11:02:03.200"),
],
)
def test_time_formatter(self, time, format_expected):
# issue 18478
result = self.tc(time)
assert result == format_expected
def test_dateindex_conversion(self):
rtol = 10**-9
for freq in ("B", "L", "S"):
dateindex = tm.makeDateIndex(k=10, freq=freq)
rs = self.dtc.convert(dateindex, None, None)
xp = converter.dates.date2num(dateindex._mpl_repr())
tm.assert_almost_equal(rs, xp, rtol=rtol)
def test_resolution(self):
def _assert_less(ts1, ts2):
val1 = self.dtc.convert(ts1, None, None)
val2 = self.dtc.convert(ts2, None, None)
if not val1 < val2:
raise AssertionError(f"{val1} is not less than {val2}.")
# Matplotlib's time representation using floats cannot distinguish
# intervals smaller than ~10 microsecond in the common range of years.
ts = Timestamp("2012-1-1")
_assert_less(ts, ts + Second())
_assert_less(ts, ts + Milli())
_assert_less(ts, ts + Micro(50))
def test_convert_nested(self):
inner = [Timestamp("2017-01-01"), Timestamp("2017-01-02")]
data = [inner, inner]
result = self.dtc.convert(data, None, None)
expected = [self.dtc.convert(x, None, None) for x in data]
assert (np.array(result) == expected).all()
class TestPeriodConverter:
def setup_method(self, method):
self.pc = converter.PeriodConverter()
class Axis:
pass
self.axis = Axis()
self.axis.freq = "D"
def test_convert_accepts_unicode(self):
r1 = self.pc.convert("2012-1-1", None, self.axis)
r2 = self.pc.convert("2012-1-1", None, self.axis)
assert r1 == r2
def test_conversion(self):
rs = self.pc.convert(["2012-1-1"], None, self.axis)[0]
xp = Period("2012-1-1").ordinal
assert rs == xp
rs = self.pc.convert("2012-1-1", None, self.axis)
assert rs == xp
rs = self.pc.convert([date(2012, 1, 1)], None, self.axis)[0]
assert rs == xp
rs = self.pc.convert(date(2012, 1, 1), None, self.axis)
assert rs == xp
rs = self.pc.convert([Timestamp("2012-1-1")], None, self.axis)[0]
assert rs == xp
rs = self.pc.convert(Timestamp("2012-1-1"), None, self.axis)
assert rs == xp
rs = self.pc.convert("2012-01-01", None, self.axis)
assert rs == xp
rs = self.pc.convert("2012-01-01 00:00:00+0000", None, self.axis)
assert rs == xp
rs = self.pc.convert(
np.array(
["2012-01-01 00:00:00", "2012-01-02 00:00:00"],
dtype="datetime64[ns]",
),
None,
self.axis,
)
assert rs[0] == xp
def test_integer_passthrough(self):
# GH9012
rs = self.pc.convert([0, 1], None, self.axis)
xp = [0, 1]
assert rs == xp
def test_convert_nested(self):
data = ["2012-1-1", "2012-1-2"]
r1 = self.pc.convert([data, data], None, self.axis)
r2 = [self.pc.convert(data, None, self.axis) for _ in range(2)]
assert r1 == r2
class TestTimeDeltaConverter:
"""Test timedelta converter"""
@pytest.mark.parametrize(
"x, decimal, format_expected",
[
(0.0, 0, "00:00:00"),
(3972320000000, 1, "01:06:12.3"),
(713233432000000, 2, "8 days 06:07:13.43"),
(32423432000000, 4, "09:00:23.4320"),
],
)
def test_format_timedelta_ticks(self, x, decimal, format_expected):
tdc = converter.TimeSeries_TimedeltaFormatter
result = tdc.format_timedelta_ticks(x, pos=None, n_decimals=decimal)
assert result == format_expected
@pytest.mark.parametrize("view_interval", [(1, 2), (2, 1)])
def test_call_w_different_view_intervals(self, view_interval, monkeypatch):
# previously broke on reversed xlmits; see GH37454
class mock_axis:
def get_view_interval(self):
return view_interval
tdc = converter.TimeSeries_TimedeltaFormatter()
monkeypatch.setattr(tdc, "axis", mock_axis())
tdc(0.0, 0)