Skip to content

Commit 56df926

Browse files
authored
TST: Always close figures in plotting tests (#53929)
* centeralize mpl_cleanup, make hist_df smaller * remove def close * trigger ci * Bump to 50
1 parent 76541f5 commit 56df926

12 files changed

+27
-132
lines changed

pandas/_testing/__init__.py

-2
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@
5050
bdate_range,
5151
)
5252
from pandas._testing._io import (
53-
close,
5453
round_trip_localpath,
5554
round_trip_pathlib,
5655
round_trip_pickle,
@@ -1094,7 +1093,6 @@ def shares_memory(left, right) -> bool:
10941093
"box_expected",
10951094
"BYTES_DTYPES",
10961095
"can_set_locale",
1097-
"close",
10981096
"COMPLEX_DTYPES",
10991097
"convert_rows_list_to_csv_str",
11001098
"DATETIME64_DTYPES",

pandas/_testing/_io.py

-17
Original file line numberDiff line numberDiff line change
@@ -166,20 +166,3 @@ def write_to_compressed(compression, path, data, dest: str = "test"):
166166

167167
with compress_method(path, mode=mode) as f:
168168
getattr(f, method)(*args)
169-
170-
171-
# ------------------------------------------------------------------
172-
# Plotting
173-
174-
175-
def close(fignum=None) -> None:
176-
from matplotlib.pyplot import (
177-
close as _close,
178-
get_fignums,
179-
)
180-
181-
if fignum is None:
182-
for fignum in get_fignums():
183-
_close(fignum)
184-
else:
185-
_close(fignum)

pandas/tests/plotting/common.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ def _check_data(xp, rs):
7777
xp : matplotlib Axes object
7878
rs : matplotlib Axes object
7979
"""
80+
import matplotlib.pyplot as plt
81+
8082
xp_lines = xp.get_lines()
8183
rs_lines = rs.get_lines()
8284

@@ -86,7 +88,7 @@ def _check_data(xp, rs):
8688
rsdata = rsl.get_xydata()
8789
tm.assert_almost_equal(xpdata, rsdata)
8890

89-
tm.close()
91+
plt.close("all")
9092

9193

9294
def _check_visible(collections, visible=True):
@@ -538,7 +540,7 @@ def _check_plot_works(f, default_axes=False, **kwargs):
538540
plt.savefig(path)
539541

540542
finally:
541-
tm.close(fig)
543+
plt.close(fig)
542544

543545
return ret
544546

pandas/tests/plotting/conftest.py

+16-18
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import gc
2+
13
import numpy as np
24
import pytest
35

@@ -8,32 +10,28 @@
810

911

1012
@pytest.fixture(autouse=True)
11-
def non_interactive():
12-
mpl = pytest.importorskip("matplotlib")
13-
mpl.use("template")
14-
yield
15-
16-
17-
@pytest.fixture(autouse=True)
18-
def reset_rcParams():
13+
def mpl_cleanup():
14+
# matplotlib/testing/decorators.py#L24
15+
# 1) Resets units registry
16+
# 2) Resets rc_context
17+
# 3) Closes all figures
1918
mpl = pytest.importorskip("matplotlib")
19+
mpl_units = pytest.importorskip("matplotlib.units")
20+
plt = pytest.importorskip("matplotlib.pyplot")
21+
orig_units_registry = mpl_units.registry.copy()
2022
with mpl.rc_context():
23+
mpl.use("template")
2124
yield
22-
23-
24-
@pytest.fixture(autouse=True)
25-
def close_all_figures():
26-
# https://stackoverflow.com/q/31156578
27-
yield
28-
plt = pytest.importorskip("matplotlib.pyplot")
29-
plt.cla()
30-
plt.clf()
25+
mpl_units.registry.clear()
26+
mpl_units.registry.update(orig_units_registry)
3127
plt.close("all")
28+
# https://matplotlib.org/stable/users/prev_whats_new/whats_new_3.6.0.html#garbage-collection-is-no-longer-run-on-figure-close # noqa: E501
29+
gc.collect(1)
3230

3331

3432
@pytest.fixture
3533
def hist_df():
36-
n = 100
34+
n = 50
3735
np_random = np.random.RandomState(42)
3836
gender = np_random.choice(["Male", "Female"], size=n)
3937
classroom = np_random.choice(["A", "B", "C"], size=n)

pandas/tests/plotting/frame/test_frame.py

+4-23
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
from pandas.io.formats.printing import pprint_thing
4848

4949
mpl = pytest.importorskip("matplotlib")
50+
plt = pytest.importorskip("matplotlib.pyplot")
5051

5152

5253
class TestDataFramePlots:
@@ -323,8 +324,6 @@ def test_xcompat(self):
323324
assert not isinstance(lines[0].get_xdata(), PeriodIndex)
324325
_check_ticks_props(ax, xrot=30)
325326

326-
tm.close()
327-
328327
def test_xcompat_plot_params(self):
329328
df = tm.makeTimeDataFrame()
330329
plotting.plot_params["xaxis.compat"] = True
@@ -333,8 +332,6 @@ def test_xcompat_plot_params(self):
333332
assert not isinstance(lines[0].get_xdata(), PeriodIndex)
334333
_check_ticks_props(ax, xrot=30)
335334

336-
tm.close()
337-
338335
def test_xcompat_plot_params_x_compat(self):
339336
df = tm.makeTimeDataFrame()
340337
plotting.plot_params["x_compat"] = False
@@ -344,8 +341,6 @@ def test_xcompat_plot_params_x_compat(self):
344341
assert not isinstance(lines[0].get_xdata(), PeriodIndex)
345342
assert isinstance(PeriodIndex(lines[0].get_xdata()), PeriodIndex)
346343

347-
tm.close()
348-
349344
def test_xcompat_plot_params_context_manager(self):
350345
df = tm.makeTimeDataFrame()
351346
# useful if you're plotting a bunch together
@@ -355,8 +350,6 @@ def test_xcompat_plot_params_context_manager(self):
355350
assert not isinstance(lines[0].get_xdata(), PeriodIndex)
356351
_check_ticks_props(ax, xrot=30)
357352

358-
tm.close()
359-
360353
def test_xcompat_plot_period(self):
361354
df = tm.makeTimeDataFrame()
362355
ax = df.plot()
@@ -376,7 +369,6 @@ def test_period_compat(self):
376369

377370
df.plot()
378371
mpl.pyplot.axhline(y=0)
379-
tm.close()
380372

381373
@pytest.mark.parametrize("index_dtype", [np.int64, np.float64])
382374
def test_unsorted_index(self, index_dtype):
@@ -390,7 +382,6 @@ def test_unsorted_index(self, index_dtype):
390382
rs = lines.get_xydata()
391383
rs = Series(rs[:, 1], rs[:, 0], dtype=np.int64, name="y")
392384
tm.assert_series_equal(rs, df.y, check_index_type=False)
393-
tm.close()
394385

395386
@pytest.mark.parametrize(
396387
"df",
@@ -956,14 +947,12 @@ def test_boxplot(self, hist_df):
956947
ax.xaxis.get_ticklocs(), np.arange(1, len(numeric_cols) + 1)
957948
)
958949
assert len(ax.lines) == 7 * len(numeric_cols)
959-
tm.close()
960950

961951
def test_boxplot_series(self, hist_df):
962952
df = hist_df
963953
series = df["height"]
964954
axes = series.plot.box(rot=40)
965955
_check_ticks_props(axes, xrot=40, yrot=0)
966-
tm.close()
967956

968957
_check_plot_works(series.plot.box)
969958

@@ -1093,7 +1082,6 @@ def test_hist_df_series(self):
10931082
series = Series(np.random.rand(10))
10941083
axes = series.plot.hist(rot=40)
10951084
_check_ticks_props(axes, xrot=40, yrot=0)
1096-
tm.close()
10971085

10981086
def test_hist_df_series_cumulative_density(self):
10991087
from matplotlib.patches import Rectangle
@@ -1103,7 +1091,6 @@ def test_hist_df_series_cumulative_density(self):
11031091
# height of last bin (index 5) must be 1.0
11041092
rects = [x for x in ax.get_children() if isinstance(x, Rectangle)]
11051093
tm.assert_almost_equal(rects[-1].get_height(), 1.0)
1106-
tm.close()
11071094

11081095
def test_hist_df_series_cumulative(self):
11091096
from matplotlib.patches import Rectangle
@@ -1113,7 +1100,6 @@ def test_hist_df_series_cumulative(self):
11131100
rects = [x for x in ax.get_children() if isinstance(x, Rectangle)]
11141101

11151102
tm.assert_almost_equal(rects[-2].get_height(), 10.0)
1116-
tm.close()
11171103

11181104
def test_hist_df_orientation(self):
11191105
df = DataFrame(np.random.randn(10, 4))
@@ -1801,8 +1787,6 @@ def test_errorbar_asymmetrical(self):
18011787
with pytest.raises(ValueError, match=msg):
18021788
df.plot(yerr=err.T)
18031789

1804-
tm.close()
1805-
18061790
def test_table(self):
18071791
df = DataFrame(np.random.rand(10, 3), index=list(string.ascii_letters[:10]))
18081792
_check_plot_works(df.plot, table=True)
@@ -1897,13 +1881,12 @@ def _check(axes):
18971881
df.plot(x="a", y="b", title="title", ax=ax, sharex=True)
18981882
gs.tight_layout(plt.gcf())
18991883
_check(axes)
1900-
tm.close()
1884+
plt.close("all")
19011885

19021886
gs, axes = _generate_4_axes_via_gridspec()
19031887
with tm.assert_produces_warning(UserWarning):
19041888
axes = df.plot(subplots=True, ax=axes, sharex=True)
19051889
_check(axes)
1906-
tm.close()
19071890

19081891
def test_sharex_false_and_ax(self):
19091892
# https://github.com/pandas-dev/pandas/issues/9737 using gridspec,
@@ -1930,7 +1913,6 @@ def test_sharex_false_and_ax(self):
19301913
_check_visible(ax.get_yticklabels(), visible=True)
19311914
_check_visible(ax.get_xticklabels(), visible=True)
19321915
_check_visible(ax.get_xticklabels(minor=True), visible=True)
1933-
tm.close()
19341916

19351917
def test_sharey_and_ax(self):
19361918
# https://github.com/pandas-dev/pandas/issues/9737 using gridspec,
@@ -1963,15 +1945,14 @@ def _check(axes):
19631945
df.plot(x="a", y="b", title="title", ax=ax, sharey=True)
19641946
gs.tight_layout(plt.gcf())
19651947
_check(axes)
1966-
tm.close()
1948+
plt.close("all")
19671949

19681950
gs, axes = _generate_4_axes_via_gridspec()
19691951
with tm.assert_produces_warning(UserWarning):
19701952
axes = df.plot(subplots=True, ax=axes, sharey=True)
19711953

19721954
gs.tight_layout(plt.gcf())
19731955
_check(axes)
1974-
tm.close()
19751956

19761957
def test_sharey_and_ax_tight(self):
19771958
# https://github.com/pandas-dev/pandas/issues/9737 using gridspec,
@@ -2021,7 +2002,7 @@ def test_memory_leak(self, kind):
20212002
ref = weakref.ref(df.plot(kind=kind, **args))
20222003

20232004
# have matplotlib delete all the figures
2024-
tm.close()
2005+
plt.close("all")
20252006
# force a garbage collection
20262007
gc.collect()
20272008
assert ref() is None

0 commit comments

Comments
 (0)