Skip to content

BUG: Line plots aligned from start #57594 #57713

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
wants to merge 10 commits into from
2 changes: 1 addition & 1 deletion pandas/plotting/_matplotlib/timeseries.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ def maybe_convert_index(ax: Axes, data: NDFrameT) -> NDFrameT:
if isinstance(data.index, ABCDatetimeIndex):
data = data.tz_localize(None).to_period(freq=freq_str)
elif isinstance(data.index, ABCPeriodIndex):
data.index = data.index.asfreq(freq=freq_str)
data.index = data.index.asfreq(freq=freq_str, how = "S") #Lineplot alignes to the start of period
Copy link
Contributor

@natmokval natmokval Mar 10, 2024

Choose a reason for hiding this comment

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

Could you please check ruff, ruff-format and codespell errors on line 313?
If you try the following command: pre-commit run --all-file, it should help fix these errors.

return data


Expand Down
38 changes: 8 additions & 30 deletions pandas/tests/indexes/period/test_period_range.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,16 @@ class TestPeriodRange:
@pytest.mark.parametrize(
"freq_offset, freq_period",
[
("h", "h"),
("7h", "7h"),
("D", "D"),
("W", "W"),
("QE", "Q"),
("15D", "15D"),
("ME", "M"),
("3ME", "3M"),
("YE", "Y"),
("8YE", "8Y"),
("20s", "20s"),
("2QE", "2Q"),
],
)
def test_construction_from_string(self, freq_offset, freq_period):
Expand Down Expand Up @@ -113,34 +119,6 @@ def test_construction_from_string(self, freq_offset, freq_period):
result = period_range(start=end, end=start, freq=freq_period, name="foo")
tm.assert_index_equal(result, expected)

def test_construction_from_string_monthly(self):
Copy link
Contributor

@natmokval natmokval Mar 10, 2024

Choose a reason for hiding this comment

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

Thank you for noticing code duplication in pandas/tests/indexes/period/test_period_range.py. I am not sure how it’s related to this bug. Could you please move these changes to separate PR?

# non-empty
expected = date_range(
start="2017-01-01", periods=5, freq="ME", name="foo"
).to_period()
start, end = str(expected[0]), str(expected[-1])

result = period_range(start=start, end=end, freq="M", name="foo")
tm.assert_index_equal(result, expected)

result = period_range(start=start, periods=5, freq="M", name="foo")
tm.assert_index_equal(result, expected)

result = period_range(end=end, periods=5, freq="M", name="foo")
tm.assert_index_equal(result, expected)

# empty
expected = PeriodIndex([], freq="M", name="foo")

result = period_range(start=start, periods=0, freq="M", name="foo")
tm.assert_index_equal(result, expected)

result = period_range(end=end, periods=0, freq="M", name="foo")
tm.assert_index_equal(result, expected)

result = period_range(start=end, end=start, freq="M", name="foo")
tm.assert_index_equal(result, expected)

def test_construction_from_period(self):
# upsampling
start, end = Period("2017Q1", freq="Q"), Period("2018Q1", freq="Q")
Expand Down
24 changes: 24 additions & 0 deletions pandas/tests/plotting/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,30 @@ def _check_plot_works(f, default_axes=False, **kwargs):
plt.close(fig)

return ret

def _check_inputdata_equals_outputdata(idx, ax):
from pandas.core.indexes.datetimes import (
DatetimeIndex,
)

"""
Check that the input dates is equal to the plotted dates
Parameters
----------
idx : PeriodIndex , DatetimeIndex
The input data based on freq
ax : matplotlib Axes object
The plotted data
"""

#Convert to periodIndex to use same formatting as the output
if isinstance(idx, DatetimeIndex):
idx = idx.to_period()
input = [str(period) for period in idx]
output_unformatted = ax.get_lines()[0].get_xdata()
output = [str(period) for period in output_unformatted]
# Convert idx and lines to lists of strings representing dates
assert input == output


def _gen_default_plot(f, fig, **kwargs):
Expand Down
26 changes: 26 additions & 0 deletions pandas/tests/plotting/test_datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
)
from pandas.core.indexes.timedeltas import timedelta_range
from pandas.tests.plotting.common import _check_ticks_props
from pandas.tests.plotting.common import _check_inputdata_equals_outputdata

from pandas.tseries.offsets import WeekOfMonth

Expand Down Expand Up @@ -69,6 +70,31 @@ def test_fontsize_set_correctly(self):
for label in ax.get_xticklabels() + ax.get_yticklabels():
assert label.get_fontsize() == 2

@pytest.mark.parametrize("freq", ["20s","3s","60min","5min","7h","4D","8W","11M","2Q","Y", "3Y", "10Y"])
Copy link
Contributor

@natmokval natmokval Mar 10, 2024

Choose a reason for hiding this comment

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

pre-commit run --all-file fails. Could you please check it?

def test_period_range_content(self, freq):
# Setup your DataFrame as in your scenario
Copy link
Contributor

Choose a reason for hiding this comment

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

instead of the comments, e.g. # Setup your DataFrame as in your scenario, could you please just add the number of GitHub issue: # GH#57594

idx = period_range("2000-01-01", freq=freq, periods=4)
df = DataFrame(
np.array([0, 1, 0, 1]),
index=idx,
columns=["A"],
)

ax = df.plot()
_check_inputdata_equals_outputdata(idx=idx, ax=ax)

@pytest.mark.parametrize("freq", ["20s","3s","60min","5min","7h","4D","8W","11ME","2QE","YE", "3YE", "10YE"])
def test_date_range_content(self, freq):
# Setup your DataFrame as in your scenario
idx = date_range("2000/01/01", freq=freq, periods=4)
df = DataFrame(
np.array([0, 1, 0, 1]),
index=idx,
columns=["A"],
)
ax = df.plot()
_check_inputdata_equals_outputdata(idx=idx, ax=ax)

def test_frame_inferred(self):
# inferred freq
idx = date_range("1/1/1987", freq="MS", periods=100)
Expand Down