Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 32 additions & 6 deletions pandas/plotting/_matplotlib/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2041,15 +2041,41 @@ def _make_plot(self, fig: Figure) -> None:
self._append_legend_handles_labels(rect, label)

def _post_plot_logic(self, ax: Axes, data) -> None:
if self.use_index:
str_index = [pprint_thing(key) for key in data.index]
else:
str_index = [pprint_thing(key) for key in range(data.shape[0])]

s_edge = self.ax_pos[0] - 0.25 + self.lim_offset
e_edge = self.ax_pos[-1] + 0.25 + self.bar_width + self.lim_offset

self._decorate_ticks(ax, self._get_index_name(), str_index, s_edge, e_edge)
# GH#1918: Apply date formatter for time series indices
if self._is_ts_plot():
freq = data.index.freq
# Set freq on axis for formatter to use, but don't call decorate_axes
# to avoid adding _plot_data attribute (which bar plots shouldn't have)
ax.freq = freq # type: ignore[attr-defined]
xaxis = ax.get_xaxis()
xaxis.freq = freq # type: ignore[attr-defined]

index = data.index
if isinstance(index, ABCDatetimeIndex):
index = index.to_period(freq=freq)

if isinstance(index, ABCPeriodIndex):
format_dateaxis(ax, freq, index)

ax.set_xlim((s_edge, e_edge))
if self.xticks is not None:
ax.set_xticks(np.array(self.xticks))
else:
ax.set_xticks(self.tick_pos)

index_name = self._get_index_name()
if index_name is not None and self.use_index:
ax.set_xlabel(index_name)
else:
if self.use_index:
str_index = [pprint_thing(key) for key in data.index]
else:
str_index = [pprint_thing(key) for key in range(data.shape[0])]

self._decorate_ticks(ax, self._get_index_name(), str_index, s_edge, e_edge)

def _decorate_ticks(
self,
Expand Down
4 changes: 2 additions & 2 deletions pandas/tests/plotting/frame/test_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -2162,13 +2162,13 @@ def test_memory_leak(self, kind):
df = DataFrame(
np.random.default_rng(2).standard_normal((10, 4)),
columns=Index(list("ABCD"), dtype=object),
index=date_range("2000-01-01", periods=10, freq="B"),
index=date_range("2000-01-01", periods=10, freq="D"),
).abs()
else:
df = DataFrame(
np.random.default_rng(2).standard_normal((10, 4)),
columns=Index(list("ABCD"), dtype=object),
index=date_range("2000-01-01", periods=10, freq="B"),
index=date_range("2000-01-01", periods=10, freq="D"),
)

ax = df.plot(kind=kind, **args)
Expand Down
23 changes: 17 additions & 6 deletions pandas/tests/plotting/test_datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -1264,7 +1264,7 @@ def test_secondary_legend(self):
df = DataFrame(
np.random.default_rng(2).standard_normal((10, 4)),
columns=Index(list("ABCD"), dtype=object),
index=date_range("2000-01-01", periods=10, freq="B"),
index=date_range("2000-01-01", periods=10, freq="D"),
)
df.plot(secondary_y=["A", "B"], ax=ax)
leg = ax.get_legend()
Expand All @@ -1285,7 +1285,7 @@ def test_secondary_legend_right(self):
df = DataFrame(
np.random.default_rng(2).standard_normal((10, 4)),
columns=Index(list("ABCD"), dtype=object),
index=date_range("2000-01-01", periods=10, freq="B"),
index=date_range("2000-01-01", periods=10, freq="D"),
)
fig = mpl.pyplot.figure()
ax = fig.add_subplot(211)
Expand All @@ -1301,7 +1301,7 @@ def test_secondary_legend_bar(self):
df = DataFrame(
np.random.default_rng(2).standard_normal((10, 4)),
columns=Index(list("ABCD"), dtype=object),
index=date_range("2000-01-01", periods=10, freq="B"),
index=date_range("2000-01-01", periods=10, freq="D"),
)
fig, ax = mpl.pyplot.subplots()
df.plot(kind="bar", secondary_y=["A"], ax=ax)
Expand All @@ -1313,7 +1313,7 @@ def test_secondary_legend_bar_right(self):
df = DataFrame(
np.random.default_rng(2).standard_normal((10, 4)),
columns=Index(list("ABCD"), dtype=object),
index=date_range("2000-01-01", periods=10, freq="B"),
index=date_range("2000-01-01", periods=10, freq="D"),
)
fig, ax = mpl.pyplot.subplots()
df.plot(kind="bar", secondary_y=["A"], mark_right=False, ax=ax)
Expand All @@ -1325,14 +1325,14 @@ def test_secondary_legend_multi_col(self):
df = DataFrame(
np.random.default_rng(2).standard_normal((10, 4)),
columns=Index(list("ABCD"), dtype=object),
index=date_range("2000-01-01", periods=10, freq="B"),
index=date_range("2000-01-01", periods=10, freq="D"),
)
fig = mpl.pyplot.figure()
ax = fig.add_subplot(211)
df = DataFrame(
np.random.default_rng(2).standard_normal((10, 4)),
columns=Index(list("ABCD"), dtype=object),
index=date_range("2000-01-01", periods=10, freq="B"),
index=date_range("2000-01-01", periods=10, freq="D"),
)
ax = df.plot(secondary_y=["C", "D"], ax=ax)
leg = ax.get_legend()
Expand Down Expand Up @@ -1691,6 +1691,17 @@ def test_pickle_fig(self, temp_file, frame_or_series, idx):
with temp_file.open(mode="wb") as path:
pickle.dump(fig, path)

def test_bar_plot_with_datetime_index_uses_date_formatter(self):
# GH#1918 - bar plots should use DateFormatter for datetime indices
df = DataFrame(
np.random.default_rng(2).standard_normal((10, 2)),
index=date_range("2020-01-01", periods=10),
columns=["A", "B"],
)
ax_bar = df.plot(kind="bar")
bar_formatter = ax_bar.get_xaxis().get_major_formatter()
assert isinstance(bar_formatter, conv.TimeSeries_DateFormatter)


def _check_plot_works(f, freq=None, series=None, *args, **kwargs):
fig = plt.gcf()
Expand Down
Loading