diff --git a/pandas/tests/plotting/common.py b/pandas/tests/plotting/common.py index 921f2b3ef3368..8b357754085c8 100644 --- a/pandas/tests/plotting/common.py +++ b/pandas/tests/plotting/common.py @@ -11,9 +11,6 @@ import numpy as np -from pandas.util._decorators import cache_readonly -import pandas.util._test_decorators as td - from pandas.core.dtypes.api import is_list_like import pandas as pd @@ -24,492 +21,475 @@ from matplotlib.axes import Axes -@td.skip_if_no_mpl -class TestPlotBase: +def _check_legend_labels(axes, labels=None, visible=True): + """ + Check each axes has expected legend labels + + Parameters + ---------- + axes : matplotlib Axes object, or its list-like + labels : list-like + expected legend labels + visible : bool + expected legend visibility. labels are checked only when visible is + True + """ + if visible and (labels is None): + raise ValueError("labels must be specified when visible is True") + axes = _flatten_visible(axes) + for ax in axes: + if visible: + assert ax.get_legend() is not None + _check_text_labels(ax.get_legend().get_texts(), labels) + else: + assert ax.get_legend() is None + + +def _check_legend_marker(ax, expected_markers=None, visible=True): + """ + Check ax has expected legend markers + + Parameters + ---------- + ax : matplotlib Axes object + expected_markers : list-like + expected legend markers + visible : bool + expected legend visibility. labels are checked only when visible is + True + """ + if visible and (expected_markers is None): + raise ValueError("Markers must be specified when visible is True") + if visible: + handles, _ = ax.get_legend_handles_labels() + markers = [handle.get_marker() for handle in handles] + assert markers == expected_markers + else: + assert ax.get_legend() is None + + +def _check_data(xp, rs): + """ + Check each axes has identical lines + + Parameters + ---------- + xp : matplotlib Axes object + rs : matplotlib Axes object + """ + xp_lines = xp.get_lines() + rs_lines = rs.get_lines() + + assert len(xp_lines) == len(rs_lines) + for xpl, rsl in zip(xp_lines, rs_lines): + xpdata = xpl.get_xydata() + rsdata = rsl.get_xydata() + tm.assert_almost_equal(xpdata, rsdata) + + tm.close() + + +def _check_visible(collections, visible=True): + """ + Check each artist is visible or not + + Parameters + ---------- + collections : matplotlib Artist or its list-like + target Artist or its list or collection + visible : bool + expected visibility + """ + from matplotlib.collections import Collection + + if not isinstance(collections, Collection) and not is_list_like(collections): + collections = [collections] + + for patch in collections: + assert patch.get_visible() == visible + + +def _check_patches_all_filled(axes: Axes | Sequence[Axes], filled: bool = True) -> None: """ - This is a common base class used for various plotting tests + Check for each artist whether it is filled or not + + Parameters + ---------- + axes : matplotlib Axes object, or its list-like + filled : bool + expected filling """ - def setup_method(self): - import matplotlib as mpl + axes = _flatten_visible(axes) + for ax in axes: + for patch in ax.patches: + assert patch.fill == filled - mpl.rcdefaults() - def teardown_method(self): - tm.close() +def _get_colors_mapped(series, colors): + unique = series.unique() + # unique and colors length can be differed + # depending on slice value + mapped = dict(zip(unique, colors)) + return [mapped[v] for v in series.values] - @cache_readonly - def plt(self): - import matplotlib.pyplot as plt - return plt +def _check_colors(collections, linecolors=None, facecolors=None, mapping=None): + """ + Check each artist has expected line colors and face colors - @cache_readonly - def colorconverter(self): - from matplotlib import colors + Parameters + ---------- + collections : list-like + list or collection of target artist + linecolors : list-like which has the same length as collections + list of expected line colors + facecolors : list-like which has the same length as collections + list of expected face colors + mapping : Series + Series used for color grouping key + used for andrew_curves, parallel_coordinates, radviz test + """ + from matplotlib import colors + from matplotlib.collections import ( + Collection, + LineCollection, + PolyCollection, + ) + from matplotlib.lines import Line2D + + conv = colors.ColorConverter + if linecolors is not None: + if mapping is not None: + linecolors = _get_colors_mapped(mapping, linecolors) + linecolors = linecolors[: len(collections)] + + assert len(collections) == len(linecolors) + for patch, color in zip(collections, linecolors): + if isinstance(patch, Line2D): + result = patch.get_color() + # Line2D may contains string color expression + result = conv.to_rgba(result) + elif isinstance(patch, (PolyCollection, LineCollection)): + result = tuple(patch.get_edgecolor()[0]) + else: + result = patch.get_edgecolor() - return colors.colorConverter + expected = conv.to_rgba(color) + assert result == expected - def _check_legend_labels(self, axes, labels=None, visible=True): - """ - Check each axes has expected legend labels + if facecolors is not None: + if mapping is not None: + facecolors = _get_colors_mapped(mapping, facecolors) + facecolors = facecolors[: len(collections)] - Parameters - ---------- - axes : matplotlib Axes object, or its list-like - labels : list-like - expected legend labels - visible : bool - expected legend visibility. labels are checked only when visible is - True - """ - if visible and (labels is None): - raise ValueError("labels must be specified when visible is True") - axes = self._flatten_visible(axes) - for ax in axes: - if visible: - assert ax.get_legend() is not None - self._check_text_labels(ax.get_legend().get_texts(), labels) + assert len(collections) == len(facecolors) + for patch, color in zip(collections, facecolors): + if isinstance(patch, Collection): + # returned as list of np.array + result = patch.get_facecolor()[0] else: - assert ax.get_legend() is None - - def _check_legend_marker(self, ax, expected_markers=None, visible=True): - """ - Check ax has expected legend markers - - Parameters - ---------- - ax : matplotlib Axes object - expected_markers : list-like - expected legend markers - visible : bool - expected legend visibility. labels are checked only when visible is - True - """ - if visible and (expected_markers is None): - raise ValueError("Markers must be specified when visible is True") - if visible: - handles, _ = ax.get_legend_handles_labels() - markers = [handle.get_marker() for handle in handles] - assert markers == expected_markers - else: - assert ax.get_legend() is None + result = patch.get_facecolor() - def _check_data(self, xp, rs): - """ - Check each axes has identical lines - - Parameters - ---------- - xp : matplotlib Axes object - rs : matplotlib Axes object - """ - xp_lines = xp.get_lines() - rs_lines = rs.get_lines() - - assert len(xp_lines) == len(rs_lines) - for xpl, rsl in zip(xp_lines, rs_lines): - xpdata = xpl.get_xydata() - rsdata = rsl.get_xydata() - tm.assert_almost_equal(xpdata, rsdata) - - tm.close() - - def _check_visible(self, collections, visible=True): - """ - Check each artist is visible or not - - Parameters - ---------- - collections : matplotlib Artist or its list-like - target Artist or its list or collection - visible : bool - expected visibility - """ - from matplotlib.collections import Collection - - if not isinstance(collections, Collection) and not is_list_like(collections): - collections = [collections] - - for patch in collections: - assert patch.get_visible() == visible - - def _check_patches_all_filled( - self, axes: Axes | Sequence[Axes], filled: bool = True - ) -> None: - """ - Check for each artist whether it is filled or not - - Parameters - ---------- - axes : matplotlib Axes object, or its list-like - filled : bool - expected filling - """ - - axes = self._flatten_visible(axes) - for ax in axes: - for patch in ax.patches: - assert patch.fill == filled - - def _get_colors_mapped(self, series, colors): - unique = series.unique() - # unique and colors length can be differed - # depending on slice value - mapped = dict(zip(unique, colors)) - return [mapped[v] for v in series.values] - - def _check_colors( - self, collections, linecolors=None, facecolors=None, mapping=None - ): - """ - Check each artist has expected line colors and face colors - - Parameters - ---------- - collections : list-like - list or collection of target artist - linecolors : list-like which has the same length as collections - list of expected line colors - facecolors : list-like which has the same length as collections - list of expected face colors - mapping : Series - Series used for color grouping key - used for andrew_curves, parallel_coordinates, radviz test - """ - from matplotlib.collections import ( - Collection, - LineCollection, - PolyCollection, - ) - from matplotlib.lines import Line2D - - conv = self.colorconverter - if linecolors is not None: - if mapping is not None: - linecolors = self._get_colors_mapped(mapping, linecolors) - linecolors = linecolors[: len(collections)] - - assert len(collections) == len(linecolors) - for patch, color in zip(collections, linecolors): - if isinstance(patch, Line2D): - result = patch.get_color() - # Line2D may contains string color expression - result = conv.to_rgba(result) - elif isinstance(patch, (PolyCollection, LineCollection)): - result = tuple(patch.get_edgecolor()[0]) - else: - result = patch.get_edgecolor() - - expected = conv.to_rgba(color) - assert result == expected - - if facecolors is not None: - if mapping is not None: - facecolors = self._get_colors_mapped(mapping, facecolors) - facecolors = facecolors[: len(collections)] - - assert len(collections) == len(facecolors) - for patch, color in zip(collections, facecolors): - if isinstance(patch, Collection): - # returned as list of np.array - result = patch.get_facecolor()[0] - else: - result = patch.get_facecolor() - - if isinstance(result, np.ndarray): - result = tuple(result) - - expected = conv.to_rgba(color) - assert result == expected - - def _check_text_labels(self, texts, expected): - """ - Check each text has expected labels - - Parameters - ---------- - texts : matplotlib Text object, or its list-like - target text, or its list - expected : str or list-like which has the same length as texts - expected text label, or its list - """ - if not is_list_like(texts): - assert texts.get_text() == expected - else: - labels = [t.get_text() for t in texts] - assert len(labels) == len(expected) - for label, e in zip(labels, expected): - assert label == e - - def _check_ticks_props( - self, axes, xlabelsize=None, xrot=None, ylabelsize=None, yrot=None - ): - """ - Check each axes has expected tick properties - - Parameters - ---------- - axes : matplotlib Axes object, or its list-like - xlabelsize : number - expected xticks font size - xrot : number - expected xticks rotation - ylabelsize : number - expected yticks font size - yrot : number - expected yticks rotation - """ - from matplotlib.ticker import NullFormatter - - axes = self._flatten_visible(axes) - for ax in axes: - if xlabelsize is not None or xrot is not None: - if isinstance(ax.xaxis.get_minor_formatter(), NullFormatter): - # If minor ticks has NullFormatter, rot / fontsize are not - # retained - labels = ax.get_xticklabels() - else: - labels = ax.get_xticklabels() + ax.get_xticklabels(minor=True) - - for label in labels: - if xlabelsize is not None: - tm.assert_almost_equal(label.get_fontsize(), xlabelsize) - if xrot is not None: - tm.assert_almost_equal(label.get_rotation(), xrot) - - if ylabelsize is not None or yrot is not None: - if isinstance(ax.yaxis.get_minor_formatter(), NullFormatter): - labels = ax.get_yticklabels() - else: - labels = ax.get_yticklabels() + ax.get_yticklabels(minor=True) - - for label in labels: - if ylabelsize is not None: - tm.assert_almost_equal(label.get_fontsize(), ylabelsize) - if yrot is not None: - tm.assert_almost_equal(label.get_rotation(), yrot) - - def _check_ax_scales(self, axes, xaxis="linear", yaxis="linear"): - """ - Check each axes has expected scales - - Parameters - ---------- - axes : matplotlib Axes object, or its list-like - xaxis : {'linear', 'log'} - expected xaxis scale - yaxis : {'linear', 'log'} - expected yaxis scale - """ - axes = self._flatten_visible(axes) - for ax in axes: - assert ax.xaxis.get_scale() == xaxis - assert ax.yaxis.get_scale() == yaxis - - def _check_axes_shape(self, axes, axes_num=None, layout=None, figsize=None): - """ - Check expected number of axes is drawn in expected layout - - Parameters - ---------- - axes : matplotlib Axes object, or its list-like - axes_num : number - expected number of axes. Unnecessary axes should be set to - invisible. - layout : tuple - expected layout, (expected number of rows , columns) - figsize : tuple - expected figsize. default is matplotlib default - """ - from pandas.plotting._matplotlib.tools import flatten_axes - - if figsize is None: - figsize = (6.4, 4.8) - visible_axes = self._flatten_visible(axes) - - if axes_num is not None: - assert len(visible_axes) == axes_num - for ax in visible_axes: - # check something drawn on visible axes - assert len(ax.get_children()) > 0 - - if layout is not None: - result = self._get_axes_layout(flatten_axes(axes)) - assert result == layout - - tm.assert_numpy_array_equal( - visible_axes[0].figure.get_size_inches(), - np.array(figsize, dtype=np.float64), - ) - - def _get_axes_layout(self, axes): + if isinstance(result, np.ndarray): + result = tuple(result) + + expected = conv.to_rgba(color) + assert result == expected + + +def _check_text_labels(texts, expected): + """ + Check each text has expected labels + + Parameters + ---------- + texts : matplotlib Text object, or its list-like + target text, or its list + expected : str or list-like which has the same length as texts + expected text label, or its list + """ + if not is_list_like(texts): + assert texts.get_text() == expected + else: + labels = [t.get_text() for t in texts] + assert len(labels) == len(expected) + for label, e in zip(labels, expected): + assert label == e + + +def _check_ticks_props(axes, xlabelsize=None, xrot=None, ylabelsize=None, yrot=None): + """ + Check each axes has expected tick properties + + Parameters + ---------- + axes : matplotlib Axes object, or its list-like + xlabelsize : number + expected xticks font size + xrot : number + expected xticks rotation + ylabelsize : number + expected yticks font size + yrot : number + expected yticks rotation + """ + from matplotlib.ticker import NullFormatter + + axes = _flatten_visible(axes) + for ax in axes: + if xlabelsize is not None or xrot is not None: + if isinstance(ax.xaxis.get_minor_formatter(), NullFormatter): + # If minor ticks has NullFormatter, rot / fontsize are not + # retained + labels = ax.get_xticklabels() + else: + labels = ax.get_xticklabels() + ax.get_xticklabels(minor=True) + + for label in labels: + if xlabelsize is not None: + tm.assert_almost_equal(label.get_fontsize(), xlabelsize) + if xrot is not None: + tm.assert_almost_equal(label.get_rotation(), xrot) + + if ylabelsize is not None or yrot is not None: + if isinstance(ax.yaxis.get_minor_formatter(), NullFormatter): + labels = ax.get_yticklabels() + else: + labels = ax.get_yticklabels() + ax.get_yticklabels(minor=True) + + for label in labels: + if ylabelsize is not None: + tm.assert_almost_equal(label.get_fontsize(), ylabelsize) + if yrot is not None: + tm.assert_almost_equal(label.get_rotation(), yrot) + + +def _check_ax_scales(axes, xaxis="linear", yaxis="linear"): + """ + Check each axes has expected scales + + Parameters + ---------- + axes : matplotlib Axes object, or its list-like + xaxis : {'linear', 'log'} + expected xaxis scale + yaxis : {'linear', 'log'} + expected yaxis scale + """ + axes = _flatten_visible(axes) + for ax in axes: + assert ax.xaxis.get_scale() == xaxis + assert ax.yaxis.get_scale() == yaxis + + +def _check_axes_shape(axes, axes_num=None, layout=None, figsize=None): + """ + Check expected number of axes is drawn in expected layout + + Parameters + ---------- + axes : matplotlib Axes object, or its list-like + axes_num : number + expected number of axes. Unnecessary axes should be set to + invisible. + layout : tuple + expected layout, (expected number of rows , columns) + figsize : tuple + expected figsize. default is matplotlib default + """ + from pandas.plotting._matplotlib.tools import flatten_axes + + if figsize is None: + figsize = (6.4, 4.8) + visible_axes = _flatten_visible(axes) + + if axes_num is not None: + assert len(visible_axes) == axes_num + for ax in visible_axes: + # check something drawn on visible axes + assert len(ax.get_children()) > 0 + + if layout is not None: x_set = set() y_set = set() - for ax in axes: + for ax in flatten_axes(axes): # check axes coordinates to estimate layout points = ax.get_position().get_points() x_set.add(points[0][0]) y_set.add(points[0][1]) - return (len(y_set), len(x_set)) - - def _flatten_visible(self, axes): - """ - Flatten axes, and filter only visible - - Parameters - ---------- - axes : matplotlib Axes object, or its list-like - - """ - from pandas.plotting._matplotlib.tools import flatten_axes - - axes = flatten_axes(axes) - axes = [ax for ax in axes if ax.get_visible()] - return axes - - def _check_has_errorbars(self, axes, xerr=0, yerr=0): - """ - Check axes has expected number of errorbars - - Parameters - ---------- - axes : matplotlib Axes object, or its list-like - xerr : number - expected number of x errorbar - yerr : number - expected number of y errorbar - """ - axes = self._flatten_visible(axes) - for ax in axes: - containers = ax.containers - xerr_count = 0 - yerr_count = 0 - for c in containers: - has_xerr = getattr(c, "has_xerr", False) - has_yerr = getattr(c, "has_yerr", False) - if has_xerr: - xerr_count += 1 - if has_yerr: - yerr_count += 1 - assert xerr == xerr_count - assert yerr == yerr_count - - def _check_box_return_type( - self, returned, return_type, expected_keys=None, check_ax_title=True - ): - """ - Check box returned type is correct - - Parameters - ---------- - returned : object to be tested, returned from boxplot - return_type : str - return_type passed to boxplot - expected_keys : list-like, optional - group labels in subplot case. If not passed, - the function checks assuming boxplot uses single ax - check_ax_title : bool - Whether to check the ax.title is the same as expected_key - Intended to be checked by calling from ``boxplot``. - Normal ``plot`` doesn't attach ``ax.title``, it must be disabled. - """ - from matplotlib.axes import Axes - - types = {"dict": dict, "axes": Axes, "both": tuple} - if expected_keys is None: - # should be fixed when the returning default is changed - if return_type is None: - return_type = "dict" - - assert isinstance(returned, types[return_type]) - if return_type == "both": - assert isinstance(returned.ax, Axes) - assert isinstance(returned.lines, dict) - else: - # should be fixed when the returning default is changed - if return_type is None: - for r in self._flatten_visible(returned): - assert isinstance(r, Axes) - return - - assert isinstance(returned, Series) - - assert sorted(returned.keys()) == sorted(expected_keys) - for key, value in returned.items(): - assert isinstance(value, types[return_type]) - # check returned dict has correct mapping - if return_type == "axes": - if check_ax_title: - assert value.get_title() == key - elif return_type == "both": - if check_ax_title: - assert value.ax.get_title() == key - assert isinstance(value.ax, Axes) - assert isinstance(value.lines, dict) - elif return_type == "dict": - line = value["medians"][0] - axes = line.axes - if check_ax_title: - assert axes.get_title() == key - else: - raise AssertionError - - def _check_grid_settings(self, obj, kinds, kws={}): - # Make sure plot defaults to rcParams['axes.grid'] setting, GH 9792 - - import matplotlib as mpl - - def is_grid_on(): - xticks = self.plt.gca().xaxis.get_major_ticks() - yticks = self.plt.gca().yaxis.get_major_ticks() - xoff = all(not g.gridline.get_visible() for g in xticks) - yoff = all(not g.gridline.get_visible() for g in yticks) - - return not (xoff and yoff) - - spndx = 1 - for kind in kinds: - self.plt.subplot(1, 4 * len(kinds), spndx) + result = (len(y_set), len(x_set)) + assert result == layout + + tm.assert_numpy_array_equal( + visible_axes[0].figure.get_size_inches(), + np.array(figsize, dtype=np.float64), + ) + + +def _flatten_visible(axes): + """ + Flatten axes, and filter only visible + + Parameters + ---------- + axes : matplotlib Axes object, or its list-like + + """ + from pandas.plotting._matplotlib.tools import flatten_axes + + axes = flatten_axes(axes) + axes = [ax for ax in axes if ax.get_visible()] + return axes + + +def _check_has_errorbars(axes, xerr=0, yerr=0): + """ + Check axes has expected number of errorbars + + Parameters + ---------- + axes : matplotlib Axes object, or its list-like + xerr : number + expected number of x errorbar + yerr : number + expected number of y errorbar + """ + axes = _flatten_visible(axes) + for ax in axes: + containers = ax.containers + xerr_count = 0 + yerr_count = 0 + for c in containers: + has_xerr = getattr(c, "has_xerr", False) + has_yerr = getattr(c, "has_yerr", False) + if has_xerr: + xerr_count += 1 + if has_yerr: + yerr_count += 1 + assert xerr == xerr_count + assert yerr == yerr_count + + +def _check_box_return_type( + returned, return_type, expected_keys=None, check_ax_title=True +): + """ + Check box returned type is correct + + Parameters + ---------- + returned : object to be tested, returned from boxplot + return_type : str + return_type passed to boxplot + expected_keys : list-like, optional + group labels in subplot case. If not passed, + the function checks assuming boxplot uses single ax + check_ax_title : bool + Whether to check the ax.title is the same as expected_key + Intended to be checked by calling from ``boxplot``. + Normal ``plot`` doesn't attach ``ax.title``, it must be disabled. + """ + from matplotlib.axes import Axes + + types = {"dict": dict, "axes": Axes, "both": tuple} + if expected_keys is None: + # should be fixed when the returning default is changed + if return_type is None: + return_type = "dict" + + assert isinstance(returned, types[return_type]) + if return_type == "both": + assert isinstance(returned.ax, Axes) + assert isinstance(returned.lines, dict) + else: + # should be fixed when the returning default is changed + if return_type is None: + for r in _flatten_visible(returned): + assert isinstance(r, Axes) + return + + assert isinstance(returned, Series) + + assert sorted(returned.keys()) == sorted(expected_keys) + for key, value in returned.items(): + assert isinstance(value, types[return_type]) + # check returned dict has correct mapping + if return_type == "axes": + if check_ax_title: + assert value.get_title() == key + elif return_type == "both": + if check_ax_title: + assert value.ax.get_title() == key + assert isinstance(value.ax, Axes) + assert isinstance(value.lines, dict) + elif return_type == "dict": + line = value["medians"][0] + axes = line.axes + if check_ax_title: + assert axes.get_title() == key + else: + raise AssertionError + + +def _check_grid_settings(obj, kinds, kws={}): + # Make sure plot defaults to rcParams['axes.grid'] setting, GH 9792 + + import matplotlib as mpl + + def is_grid_on(): + xticks = mpl.pyplot.gca().xaxis.get_major_ticks() + yticks = mpl.pyplot.gca().yaxis.get_major_ticks() + xoff = all(not g.gridline.get_visible() for g in xticks) + yoff = all(not g.gridline.get_visible() for g in yticks) + + return not (xoff and yoff) + + spndx = 1 + for kind in kinds: + mpl.pyplot.subplot(1, 4 * len(kinds), spndx) + spndx += 1 + mpl.rc("axes", grid=False) + obj.plot(kind=kind, **kws) + assert not is_grid_on() + mpl.pyplot.clf() + + mpl.pyplot.subplot(1, 4 * len(kinds), spndx) + spndx += 1 + mpl.rc("axes", grid=True) + obj.plot(kind=kind, grid=False, **kws) + assert not is_grid_on() + mpl.pyplot.clf() + + if kind not in ["pie", "hexbin", "scatter"]: + mpl.pyplot.subplot(1, 4 * len(kinds), spndx) spndx += 1 - mpl.rc("axes", grid=False) + mpl.rc("axes", grid=True) obj.plot(kind=kind, **kws) - assert not is_grid_on() - self.plt.clf() + assert is_grid_on() + mpl.pyplot.clf() - self.plt.subplot(1, 4 * len(kinds), spndx) + mpl.pyplot.subplot(1, 4 * len(kinds), spndx) spndx += 1 - mpl.rc("axes", grid=True) - obj.plot(kind=kind, grid=False, **kws) - assert not is_grid_on() - self.plt.clf() - - if kind not in ["pie", "hexbin", "scatter"]: - self.plt.subplot(1, 4 * len(kinds), spndx) - spndx += 1 - mpl.rc("axes", grid=True) - obj.plot(kind=kind, **kws) - assert is_grid_on() - self.plt.clf() - - self.plt.subplot(1, 4 * len(kinds), spndx) - spndx += 1 - mpl.rc("axes", grid=False) - obj.plot(kind=kind, grid=True, **kws) - assert is_grid_on() - self.plt.clf() - - def _unpack_cycler(self, rcParams, field="color"): - """ - Auxiliary function for correctly unpacking cycler after MPL >= 1.5 - """ - return [v[field] for v in rcParams["axes.prop_cycle"]] - - def get_x_axis(self, ax): - return ax._shared_axes["x"] - - def get_y_axis(self, ax): - return ax._shared_axes["y"] + mpl.rc("axes", grid=False) + obj.plot(kind=kind, grid=True, **kws) + assert is_grid_on() + mpl.pyplot.clf() + + +def _unpack_cycler(rcParams, field="color"): + """ + Auxiliary function for correctly unpacking cycler after MPL >= 1.5 + """ + return [v[field] for v in rcParams["axes.prop_cycle"]] + + +def get_x_axis(ax): + return ax._shared_axes["x"] + + +def get_y_axis(ax): + return ax._shared_axes["y"] def _check_plot_works(f, default_axes=False, **kwargs): diff --git a/pandas/tests/plotting/conftest.py b/pandas/tests/plotting/conftest.py index 14c413f96c4ba..aa9952db17b74 100644 --- a/pandas/tests/plotting/conftest.py +++ b/pandas/tests/plotting/conftest.py @@ -7,6 +7,20 @@ ) +@pytest.fixture(autouse=True) +def reset_rcParams(): + mpl = pytest.importorskip("matplotlib") + with mpl.rc_context(): + yield + + +@pytest.fixture(autouse=True) +def close_all_figures(): + yield + plt = pytest.importorskip("matplotlib.pyplot") + plt.close("all") + + @pytest.fixture def hist_df(): n = 100 diff --git a/pandas/tests/plotting/frame/test_frame.py b/pandas/tests/plotting/frame/test_frame.py index ded3c1142f27b..77c11a5b11360 100644 --- a/pandas/tests/plotting/frame/test_frame.py +++ b/pandas/tests/plotting/frame/test_frame.py @@ -29,15 +29,27 @@ ) import pandas._testing as tm from pandas.tests.plotting.common import ( - TestPlotBase, + _check_ax_scales, + _check_axes_shape, + _check_box_return_type, + _check_colors, + _check_data, + _check_grid_settings, + _check_has_errorbars, + _check_legend_labels, _check_plot_works, + _check_text_labels, + _check_ticks_props, + _check_visible, + get_y_axis, ) from pandas.io.formats.printing import pprint_thing +mpl = pytest.importorskip("matplotlib") -@td.skip_if_no_mpl -class TestDataFramePlots(TestPlotBase): + +class TestDataFramePlots: @pytest.mark.xfail(reason="Api changed in 3.6.0") @pytest.mark.slow def test_plot(self): @@ -46,7 +58,7 @@ def test_plot(self): # _check_plot_works adds an ax so use default_axes=True to avoid warning axes = _check_plot_works(df.plot, default_axes=True, subplots=True) - self._check_axes_shape(axes, axes_num=4, layout=(4, 1)) + _check_axes_shape(axes, axes_num=4, layout=(4, 1)) axes = _check_plot_works( df.plot, @@ -54,7 +66,7 @@ def test_plot(self): subplots=True, layout=(-1, 2), ) - self._check_axes_shape(axes, axes_num=4, layout=(2, 2)) + _check_axes_shape(axes, axes_num=4, layout=(2, 2)) axes = _check_plot_works( df.plot, @@ -62,8 +74,8 @@ def test_plot(self): subplots=True, use_index=False, ) - self._check_ticks_props(axes, xrot=0) - self._check_axes_shape(axes, axes_num=4, layout=(4, 1)) + _check_ticks_props(axes, xrot=0) + _check_axes_shape(axes, axes_num=4, layout=(4, 1)) df = DataFrame({"x": [1, 2], "y": [3, 4]}) msg = "'Line2D' object has no property 'blarg'" @@ -73,7 +85,7 @@ def test_plot(self): df = DataFrame(np.random.rand(10, 3), index=list(string.ascii_letters[:10])) ax = _check_plot_works(df.plot, use_index=True) - self._check_ticks_props(ax, xrot=0) + _check_ticks_props(ax, xrot=0) _check_plot_works(df.plot, yticks=[1, 5, 10]) _check_plot_works(df.plot, xticks=[1, 5, 10]) _check_plot_works(df.plot, ylim=(-100, 100), xlim=(-100, 100)) @@ -86,25 +98,25 @@ def test_plot(self): # present). see: https://github.com/pandas-dev/pandas/issues/9737 axes = df.plot(subplots=True, title="blah") - self._check_axes_shape(axes, axes_num=3, layout=(3, 1)) + _check_axes_shape(axes, axes_num=3, layout=(3, 1)) # axes[0].figure.savefig("test.png") for ax in axes[:2]: - self._check_visible(ax.xaxis) # xaxis must be visible for grid - self._check_visible(ax.get_xticklabels(), visible=False) - self._check_visible(ax.get_xticklabels(minor=True), visible=False) - self._check_visible([ax.xaxis.get_label()], visible=False) + _check_visible(ax.xaxis) # xaxis must be visible for grid + _check_visible(ax.get_xticklabels(), visible=False) + _check_visible(ax.get_xticklabels(minor=True), visible=False) + _check_visible([ax.xaxis.get_label()], visible=False) for ax in [axes[2]]: - self._check_visible(ax.xaxis) - self._check_visible(ax.get_xticklabels()) - self._check_visible([ax.xaxis.get_label()]) - self._check_ticks_props(ax, xrot=0) + _check_visible(ax.xaxis) + _check_visible(ax.get_xticklabels()) + _check_visible([ax.xaxis.get_label()]) + _check_ticks_props(ax, xrot=0) _check_plot_works(df.plot, title="blah") tuples = zip(string.ascii_letters[:10], range(10)) df = DataFrame(np.random.rand(10, 3), index=MultiIndex.from_tuples(tuples)) ax = _check_plot_works(df.plot, use_index=True) - self._check_ticks_props(ax, xrot=0) + _check_ticks_props(ax, xrot=0) # unicode index = MultiIndex.from_tuples( @@ -130,13 +142,13 @@ def test_plot(self): # Test with single column df = DataFrame({"x": np.random.rand(10)}) axes = _check_plot_works(df.plot.bar, subplots=True) - self._check_axes_shape(axes, axes_num=1, layout=(1, 1)) + _check_axes_shape(axes, axes_num=1, layout=(1, 1)) axes = _check_plot_works(df.plot.bar, subplots=True, layout=(-1, 1)) - self._check_axes_shape(axes, axes_num=1, layout=(1, 1)) + _check_axes_shape(axes, axes_num=1, layout=(1, 1)) # When ax is supplied and required number of axes is 1, # passed ax should be used: - fig, ax = self.plt.subplots() + fig, ax = mpl.pyplot.subplots() axes = df.plot.bar(subplots=True, ax=ax) assert len(axes) == 1 result = ax.axes @@ -190,7 +202,7 @@ def test_nonnumeric_exclude(self): def test_implicit_label(self): df = DataFrame(np.random.randn(10, 3), columns=["a", "b", "c"]) ax = df.plot(x="a", y="b") - self._check_text_labels(ax.xaxis.get_label(), "a") + _check_text_labels(ax.xaxis.get_label(), "a") def test_donot_overwrite_index_name(self): # GH 8494 @@ -202,23 +214,23 @@ def test_donot_overwrite_index_name(self): def test_plot_xy(self): # columns.inferred_type == 'string' df = tm.makeTimeDataFrame() - self._check_data(df.plot(x=0, y=1), df.set_index("A")["B"].plot()) - self._check_data(df.plot(x=0), df.set_index("A").plot()) - self._check_data(df.plot(y=0), df.B.plot()) - self._check_data(df.plot(x="A", y="B"), df.set_index("A").B.plot()) - self._check_data(df.plot(x="A"), df.set_index("A").plot()) - self._check_data(df.plot(y="B"), df.B.plot()) + _check_data(df.plot(x=0, y=1), df.set_index("A")["B"].plot()) + _check_data(df.plot(x=0), df.set_index("A").plot()) + _check_data(df.plot(y=0), df.B.plot()) + _check_data(df.plot(x="A", y="B"), df.set_index("A").B.plot()) + _check_data(df.plot(x="A"), df.set_index("A").plot()) + _check_data(df.plot(y="B"), df.B.plot()) # columns.inferred_type == 'integer' df.columns = np.arange(1, len(df.columns) + 1) - self._check_data(df.plot(x=1, y=2), df.set_index(1)[2].plot()) - self._check_data(df.plot(x=1), df.set_index(1).plot()) - self._check_data(df.plot(y=1), df[1].plot()) + _check_data(df.plot(x=1, y=2), df.set_index(1)[2].plot()) + _check_data(df.plot(x=1), df.set_index(1).plot()) + _check_data(df.plot(y=1), df[1].plot()) # figsize and title ax = df.plot(x=1, y=2, title="Test", figsize=(16, 8)) - self._check_text_labels(ax.title, "Test") - self._check_axes_shape(ax, axes_num=1, layout=(1, 1), figsize=(16.0, 8.0)) + _check_text_labels(ax.title, "Test") + _check_axes_shape(ax, axes_num=1, layout=(1, 1), figsize=(16.0, 8.0)) # columns.inferred_type == 'mixed' # TODO add MultiIndex test @@ -230,15 +242,15 @@ def test_logscales(self, input_log, expected_log): df = DataFrame({"a": np.arange(100)}, index=np.arange(100)) ax = df.plot(logy=input_log) - self._check_ax_scales(ax, yaxis=expected_log) + _check_ax_scales(ax, yaxis=expected_log) assert ax.get_yscale() == expected_log ax = df.plot(logx=input_log) - self._check_ax_scales(ax, xaxis=expected_log) + _check_ax_scales(ax, xaxis=expected_log) assert ax.get_xscale() == expected_log ax = df.plot(loglog=input_log) - self._check_ax_scales(ax, xaxis=expected_log, yaxis=expected_log) + _check_ax_scales(ax, xaxis=expected_log, yaxis=expected_log) assert ax.get_xscale() == expected_log assert ax.get_yscale() == expected_log @@ -256,14 +268,14 @@ def test_xcompat(self): ax = df.plot(x_compat=True) lines = ax.get_lines() assert not isinstance(lines[0].get_xdata(), PeriodIndex) - self._check_ticks_props(ax, xrot=30) + _check_ticks_props(ax, xrot=30) tm.close() plotting.plot_params["xaxis.compat"] = True ax = df.plot() lines = ax.get_lines() assert not isinstance(lines[0].get_xdata(), PeriodIndex) - self._check_ticks_props(ax, xrot=30) + _check_ticks_props(ax, xrot=30) tm.close() plotting.plot_params["x_compat"] = False @@ -279,14 +291,14 @@ def test_xcompat(self): ax = df.plot() lines = ax.get_lines() assert not isinstance(lines[0].get_xdata(), PeriodIndex) - self._check_ticks_props(ax, xrot=30) + _check_ticks_props(ax, xrot=30) tm.close() ax = df.plot() lines = ax.get_lines() assert not isinstance(lines[0].get_xdata(), PeriodIndex) assert isinstance(PeriodIndex(lines[0].get_xdata()), PeriodIndex) - self._check_ticks_props(ax, xrot=0) + _check_ticks_props(ax, xrot=0) def test_period_compat(self): # GH 9012 @@ -298,7 +310,7 @@ def test_period_compat(self): ) df.plot() - self.plt.axhline(y=0) + mpl.pyplot.axhline(y=0) tm.close() def test_unsorted_index(self): @@ -465,7 +477,7 @@ def test_line_lim(self): assert xmax >= lines[0].get_data()[0][-1] axes = df.plot(secondary_y=True, subplots=True) - self._check_axes_shape(axes, axes_num=3, layout=(3, 1)) + _check_axes_shape(axes, axes_num=3, layout=(3, 1)) for ax in axes: assert hasattr(ax, "left_ax") assert not hasattr(ax, "right_ax") @@ -500,13 +512,13 @@ def test_area_lim(self, stacked): def test_area_sharey_dont_overwrite(self): # GH37942 df = DataFrame(np.random.rand(4, 2), columns=["x", "y"]) - fig, (ax1, ax2) = self.plt.subplots(1, 2, sharey=True) + fig, (ax1, ax2) = mpl.pyplot.subplots(1, 2, sharey=True) df.plot(ax=ax1, kind="area") df.plot(ax=ax2, kind="area") - assert self.get_y_axis(ax1).joined(ax1, ax2) - assert self.get_y_axis(ax2).joined(ax1, ax2) + assert get_y_axis(ax1).joined(ax1, ax2) + assert get_y_axis(ax2).joined(ax1, ax2) def test_bar_linewidth(self): df = DataFrame(np.random.randn(5, 5)) @@ -523,7 +535,7 @@ def test_bar_linewidth(self): # subplots axes = df.plot.bar(linewidth=2, subplots=True) - self._check_axes_shape(axes, axes_num=5, layout=(5, 1)) + _check_axes_shape(axes, axes_num=5, layout=(5, 1)) for ax in axes: for r in ax.patches: assert r.get_linewidth() == 2 @@ -656,7 +668,7 @@ def test_plot_scatter(self): # GH 6951 axes = df.plot(x="x", y="y", kind="scatter", subplots=True) - self._check_axes_shape(axes, axes_num=1, layout=(1, 1)) + _check_axes_shape(axes, axes_num=1, layout=(1, 1)) def test_raise_error_on_datetime_time_data(self): # GH 8113, datetime.time type is not supported by matplotlib in scatter @@ -751,7 +763,7 @@ def test_plot_scatter_with_c(self): # verify that we can still plot a solid color ax = df.plot.scatter(x=0, y=1, c="red") assert ax.collections[0].colorbar is None - self._check_colors(ax.collections, facecolors=["r"]) + _check_colors(ax.collections, facecolors=["r"]) # Ensure that we can pass an np.array straight through to matplotlib, # this functionality was accidentally removed previously. @@ -825,16 +837,16 @@ def test_plot_bar(self): df = DataFrame({"a": [0, 1], "b": [1, 0]}) ax = _check_plot_works(df.plot.bar) - self._check_ticks_props(ax, xrot=90) + _check_ticks_props(ax, xrot=90) ax = df.plot.bar(rot=35, fontsize=10) - self._check_ticks_props(ax, xrot=35, xlabelsize=10, ylabelsize=10) + _check_ticks_props(ax, xrot=35, xlabelsize=10, ylabelsize=10) ax = _check_plot_works(df.plot.barh) - self._check_ticks_props(ax, yrot=0) + _check_ticks_props(ax, yrot=0) ax = df.plot.barh(rot=55, fontsize=11) - self._check_ticks_props(ax, yrot=55, ylabelsize=11, xlabelsize=11) + _check_ticks_props(ax, yrot=55, ylabelsize=11, xlabelsize=11) def test_boxplot(self, hist_df): df = hist_df @@ -843,7 +855,7 @@ def test_boxplot(self, hist_df): labels = [pprint_thing(c) for c in numeric_cols] ax = _check_plot_works(df.plot.box) - self._check_text_labels(ax.get_xticklabels(), labels) + _check_text_labels(ax.get_xticklabels(), labels) tm.assert_numpy_array_equal( ax.xaxis.get_ticklocs(), np.arange(1, len(numeric_cols) + 1) ) @@ -851,7 +863,7 @@ def test_boxplot(self, hist_df): tm.close() axes = series.plot.box(rot=40) - self._check_ticks_props(axes, xrot=40, yrot=0) + _check_ticks_props(axes, xrot=40, yrot=0) tm.close() ax = _check_plot_works(series.plot.box) @@ -860,7 +872,7 @@ def test_boxplot(self, hist_df): ax = df.plot.box(positions=positions) numeric_cols = df._get_numeric_data().columns labels = [pprint_thing(c) for c in numeric_cols] - self._check_text_labels(ax.get_xticklabels(), labels) + _check_text_labels(ax.get_xticklabels(), labels) tm.assert_numpy_array_equal(ax.xaxis.get_ticklocs(), positions) assert len(ax.lines) == 7 * len(numeric_cols) @@ -871,8 +883,8 @@ def test_boxplot_vertical(self, hist_df): # if horizontal, yticklabels are rotated ax = df.plot.box(rot=50, fontsize=8, vert=False) - self._check_ticks_props(ax, xrot=0, yrot=50, ylabelsize=8) - self._check_text_labels(ax.get_yticklabels(), labels) + _check_ticks_props(ax, xrot=0, yrot=50, ylabelsize=8) + _check_text_labels(ax.get_yticklabels(), labels) assert len(ax.lines) == 7 * len(numeric_cols) axes = _check_plot_works( @@ -882,15 +894,15 @@ def test_boxplot_vertical(self, hist_df): vert=False, logx=True, ) - self._check_axes_shape(axes, axes_num=3, layout=(1, 3)) - self._check_ax_scales(axes, xaxis="log") + _check_axes_shape(axes, axes_num=3, layout=(1, 3)) + _check_ax_scales(axes, xaxis="log") for ax, label in zip(axes, labels): - self._check_text_labels(ax.get_yticklabels(), [label]) + _check_text_labels(ax.get_yticklabels(), [label]) assert len(ax.lines) == 7 positions = np.array([3, 2, 8]) ax = df.plot.box(positions=positions, vert=False) - self._check_text_labels(ax.get_yticklabels(), labels) + _check_text_labels(ax.get_yticklabels(), labels) tm.assert_numpy_array_equal(ax.yaxis.get_ticklocs(), positions) assert len(ax.lines) == 7 * len(numeric_cols) @@ -905,27 +917,27 @@ def test_boxplot_return_type(self): df.plot.box(return_type="not_a_type") result = df.plot.box(return_type="dict") - self._check_box_return_type(result, "dict") + _check_box_return_type(result, "dict") result = df.plot.box(return_type="axes") - self._check_box_return_type(result, "axes") + _check_box_return_type(result, "axes") result = df.plot.box() # default axes - self._check_box_return_type(result, "axes") + _check_box_return_type(result, "axes") result = df.plot.box(return_type="both") - self._check_box_return_type(result, "both") + _check_box_return_type(result, "both") @td.skip_if_no_scipy def test_kde_df(self): df = DataFrame(np.random.randn(100, 4)) ax = _check_plot_works(df.plot, kind="kde") expected = [pprint_thing(c) for c in df.columns] - self._check_legend_labels(ax, labels=expected) - self._check_ticks_props(ax, xrot=0) + _check_legend_labels(ax, labels=expected) + _check_ticks_props(ax, xrot=0) ax = df.plot(kind="kde", rot=20, fontsize=5) - self._check_ticks_props(ax, xrot=20, xlabelsize=5, ylabelsize=5) + _check_ticks_props(ax, xrot=20, xlabelsize=5, ylabelsize=5) axes = _check_plot_works( df.plot, @@ -933,10 +945,10 @@ def test_kde_df(self): kind="kde", subplots=True, ) - self._check_axes_shape(axes, axes_num=4, layout=(4, 1)) + _check_axes_shape(axes, axes_num=4, layout=(4, 1)) axes = df.plot(kind="kde", logy=True, subplots=True) - self._check_ax_scales(axes, yaxis="log") + _check_ax_scales(axes, yaxis="log") @td.skip_if_no_scipy def test_kde_missing_vals(self): @@ -952,7 +964,7 @@ def test_hist_df(self): ax = _check_plot_works(df.plot.hist) expected = [pprint_thing(c) for c in df.columns] - self._check_legend_labels(ax, labels=expected) + _check_legend_labels(ax, labels=expected) axes = _check_plot_works( df.plot.hist, @@ -960,11 +972,11 @@ def test_hist_df(self): subplots=True, logy=True, ) - self._check_axes_shape(axes, axes_num=4, layout=(4, 1)) - self._check_ax_scales(axes, yaxis="log") + _check_axes_shape(axes, axes_num=4, layout=(4, 1)) + _check_ax_scales(axes, yaxis="log") axes = series.plot.hist(rot=40) - self._check_ticks_props(axes, xrot=40, yrot=0) + _check_ticks_props(axes, xrot=40, yrot=0) tm.close() ax = series.plot.hist(cumulative=True, bins=4, density=True) @@ -981,7 +993,7 @@ def test_hist_df(self): # if horizontal, yticklabels are rotated axes = df.plot.hist(rot=50, fontsize=8, orientation="horizontal") - self._check_ticks_props(axes, xrot=0, yrot=50, ylabelsize=8) + _check_ticks_props(axes, xrot=0, yrot=50, ylabelsize=8) @pytest.mark.parametrize( "weights", [0.1 * np.ones(shape=(100,)), 0.1 * np.ones(shape=(100, 2))] @@ -1293,7 +1305,7 @@ def test_y_listlike(self, x, y, lbl, colors): ax = df.plot(x=x, y=y, label=lbl, color=colors) assert len(ax.lines) == len(y) - self._check_colors(ax.get_lines(), linecolors=colors) + _check_colors(ax.get_lines(), linecolors=colors) @pytest.mark.parametrize("x,y,colnames", [(0, 1, ["A", "B"]), (1, 0, [0, 1])]) def test_xy_args_integer(self, x, y, colnames): @@ -1321,7 +1333,7 @@ def test_hexbin_basic(self): # is colorbar assert len(axes[0].figure.axes) == 2 # return value is single axes - self._check_axes_shape(axes, axes_num=1, layout=(1, 1)) + _check_axes_shape(axes, axes_num=1, layout=(1, 1)) def test_hexbin_with_c(self): df = DataFrame( @@ -1368,10 +1380,10 @@ def test_pie_df(self): df.plot.pie() ax = _check_plot_works(df.plot.pie, y="Y") - self._check_text_labels(ax.texts, df.index) + _check_text_labels(ax.texts, df.index) ax = _check_plot_works(df.plot.pie, y=2) - self._check_text_labels(ax.texts, df.index) + _check_text_labels(ax.texts, df.index) axes = _check_plot_works( df.plot.pie, @@ -1380,7 +1392,7 @@ def test_pie_df(self): ) assert len(axes) == len(df.columns) for ax in axes: - self._check_text_labels(ax.texts, df.index) + _check_text_labels(ax.texts, df.index) for ax, ylabel in zip(axes, df.columns): assert ax.get_ylabel() == ylabel @@ -1396,14 +1408,14 @@ def test_pie_df(self): assert len(axes) == len(df.columns) for ax in axes: - self._check_text_labels(ax.texts, labels) - self._check_colors(ax.patches, facecolors=color_args) + _check_text_labels(ax.texts, labels) + _check_colors(ax.patches, facecolors=color_args) def test_pie_df_nan(self): df = DataFrame(np.random.rand(4, 4)) for i in range(4): df.iloc[i, i] = np.nan - fig, axes = self.plt.subplots(ncols=4) + fig, axes = mpl.pyplot.subplots(ncols=4) # GH 37668 kwargs = {"normalize": True} @@ -1434,25 +1446,25 @@ def test_errorbar_plot(self): # check line plots ax = _check_plot_works(df.plot, yerr=df_err, logy=True) - self._check_has_errorbars(ax, xerr=0, yerr=2) + _check_has_errorbars(ax, xerr=0, yerr=2) ax = _check_plot_works(df.plot, yerr=df_err, logx=True, logy=True) - self._check_has_errorbars(ax, xerr=0, yerr=2) + _check_has_errorbars(ax, xerr=0, yerr=2) ax = _check_plot_works(df.plot, yerr=df_err, loglog=True) - self._check_has_errorbars(ax, xerr=0, yerr=2) + _check_has_errorbars(ax, xerr=0, yerr=2) ax = _check_plot_works( (df + 1).plot, yerr=df_err, xerr=df_err, kind="bar", log=True ) - self._check_has_errorbars(ax, xerr=2, yerr=2) + _check_has_errorbars(ax, xerr=2, yerr=2) # yerr is raw error values ax = _check_plot_works(df["y"].plot, yerr=np.ones(12) * 0.4) - self._check_has_errorbars(ax, xerr=0, yerr=1) + _check_has_errorbars(ax, xerr=0, yerr=1) ax = _check_plot_works(df.plot, yerr=np.ones((2, 12)) * 0.4) - self._check_has_errorbars(ax, xerr=0, yerr=2) + _check_has_errorbars(ax, xerr=0, yerr=2) # yerr is column name for yerr in ["yerr", "誤差"]: @@ -1460,10 +1472,10 @@ def test_errorbar_plot(self): s_df[yerr] = np.ones(12) * 0.2 ax = _check_plot_works(s_df.plot, yerr=yerr) - self._check_has_errorbars(ax, xerr=0, yerr=2) + _check_has_errorbars(ax, xerr=0, yerr=2) ax = _check_plot_works(s_df.plot, y="y", x="x", yerr=yerr) - self._check_has_errorbars(ax, xerr=0, yerr=1) + _check_has_errorbars(ax, xerr=0, yerr=1) with tm.external_error_raised(ValueError): df.plot(yerr=np.random.randn(11)) @@ -1481,19 +1493,19 @@ def test_errorbar_plot_different_kinds(self, kind): df_err = DataFrame(d_err) ax = _check_plot_works(df.plot, yerr=df_err["x"], kind=kind) - self._check_has_errorbars(ax, xerr=0, yerr=2) + _check_has_errorbars(ax, xerr=0, yerr=2) ax = _check_plot_works(df.plot, yerr=d_err, kind=kind) - self._check_has_errorbars(ax, xerr=0, yerr=2) + _check_has_errorbars(ax, xerr=0, yerr=2) ax = _check_plot_works(df.plot, yerr=df_err, xerr=df_err, kind=kind) - self._check_has_errorbars(ax, xerr=2, yerr=2) + _check_has_errorbars(ax, xerr=2, yerr=2) ax = _check_plot_works(df.plot, yerr=df_err["x"], xerr=df_err["x"], kind=kind) - self._check_has_errorbars(ax, xerr=2, yerr=2) + _check_has_errorbars(ax, xerr=2, yerr=2) ax = _check_plot_works(df.plot, xerr=0.2, yerr=0.2, kind=kind) - self._check_has_errorbars(ax, xerr=2, yerr=2) + _check_has_errorbars(ax, xerr=2, yerr=2) axes = _check_plot_works( df.plot, @@ -1503,7 +1515,7 @@ def test_errorbar_plot_different_kinds(self, kind): subplots=True, kind=kind, ) - self._check_has_errorbars(axes, xerr=1, yerr=1) + _check_has_errorbars(axes, xerr=1, yerr=1) @pytest.mark.xfail(reason="Iterator is consumed", raises=ValueError) def test_errorbar_plot_iterator(self): @@ -1513,16 +1525,16 @@ def test_errorbar_plot_iterator(self): # yerr is iterator ax = _check_plot_works(df.plot, yerr=itertools.repeat(0.1, len(df))) - self._check_has_errorbars(ax, xerr=0, yerr=2) + _check_has_errorbars(ax, xerr=0, yerr=2) def test_errorbar_with_integer_column_names(self): # test with integer column names df = DataFrame(np.abs(np.random.randn(10, 2))) df_err = DataFrame(np.abs(np.random.randn(10, 2))) ax = _check_plot_works(df.plot, yerr=df_err) - self._check_has_errorbars(ax, xerr=0, yerr=2) + _check_has_errorbars(ax, xerr=0, yerr=2) ax = _check_plot_works(df.plot, y=0, yerr=1) - self._check_has_errorbars(ax, xerr=0, yerr=1) + _check_has_errorbars(ax, xerr=0, yerr=1) @pytest.mark.slow def test_errorbar_with_partial_columns(self): @@ -1531,13 +1543,13 @@ def test_errorbar_with_partial_columns(self): kinds = ["line", "bar"] for kind in kinds: ax = _check_plot_works(df.plot, yerr=df_err, kind=kind) - self._check_has_errorbars(ax, xerr=0, yerr=2) + _check_has_errorbars(ax, xerr=0, yerr=2) ix = date_range("1/1/2000", periods=10, freq="M") df.set_index(ix, inplace=True) df_err.set_index(ix, inplace=True) ax = _check_plot_works(df.plot, yerr=df_err, kind="line") - self._check_has_errorbars(ax, xerr=0, yerr=2) + _check_has_errorbars(ax, xerr=0, yerr=2) d = {"x": np.arange(12), "y": np.arange(12, 0, -1)} df = DataFrame(d) @@ -1545,7 +1557,7 @@ def test_errorbar_with_partial_columns(self): df_err = DataFrame(d_err) for err in [d_err, df_err]: ax = _check_plot_works(df.plot, yerr=err) - self._check_has_errorbars(ax, xerr=0, yerr=1) + _check_has_errorbars(ax, xerr=0, yerr=1) @pytest.mark.parametrize("kind", ["line", "bar", "barh"]) def test_errorbar_timeseries(self, kind): @@ -1558,19 +1570,19 @@ def test_errorbar_timeseries(self, kind): tdf_err = DataFrame(d_err, index=ix) ax = _check_plot_works(tdf.plot, yerr=tdf_err, kind=kind) - self._check_has_errorbars(ax, xerr=0, yerr=2) + _check_has_errorbars(ax, xerr=0, yerr=2) ax = _check_plot_works(tdf.plot, yerr=d_err, kind=kind) - self._check_has_errorbars(ax, xerr=0, yerr=2) + _check_has_errorbars(ax, xerr=0, yerr=2) ax = _check_plot_works(tdf.plot, y="y", yerr=tdf_err["x"], kind=kind) - self._check_has_errorbars(ax, xerr=0, yerr=1) + _check_has_errorbars(ax, xerr=0, yerr=1) ax = _check_plot_works(tdf.plot, y="y", yerr="x", kind=kind) - self._check_has_errorbars(ax, xerr=0, yerr=1) + _check_has_errorbars(ax, xerr=0, yerr=1) ax = _check_plot_works(tdf.plot, yerr=tdf_err, kind=kind) - self._check_has_errorbars(ax, xerr=0, yerr=2) + _check_has_errorbars(ax, xerr=0, yerr=2) axes = _check_plot_works( tdf.plot, @@ -1579,7 +1591,7 @@ def test_errorbar_timeseries(self, kind): yerr=tdf_err, subplots=True, ) - self._check_has_errorbars(axes, xerr=0, yerr=1) + _check_has_errorbars(axes, xerr=0, yerr=1) def test_errorbar_asymmetrical(self): np.random.seed(0) @@ -1623,14 +1635,14 @@ def test_errorbar_scatter(self): ) ax = _check_plot_works(df.plot.scatter, x="x", y="y") - self._check_has_errorbars(ax, xerr=0, yerr=0) + _check_has_errorbars(ax, xerr=0, yerr=0) ax = _check_plot_works(df.plot.scatter, x="x", y="y", xerr=df_err) - self._check_has_errorbars(ax, xerr=1, yerr=0) + _check_has_errorbars(ax, xerr=1, yerr=0) ax = _check_plot_works(df.plot.scatter, x="x", y="y", yerr=df_err) - self._check_has_errorbars(ax, xerr=0, yerr=1) + _check_has_errorbars(ax, xerr=0, yerr=1) ax = _check_plot_works(df.plot.scatter, x="x", y="y", xerr=df_err, yerr=df_err) - self._check_has_errorbars(ax, xerr=1, yerr=1) + _check_has_errorbars(ax, xerr=1, yerr=1) def _check_errorbar_color(containers, expected, has_err="has_xerr"): lines = [] @@ -1641,21 +1653,19 @@ def _check_errorbar_color(containers, expected, has_err="has_xerr"): else: lines.append(el) err_lines = [x for x in lines if x in ax.collections] - self._check_colors( - err_lines, linecolors=np.array([expected] * len(err_lines)) - ) + _check_colors(err_lines, linecolors=np.array([expected] * len(err_lines))) # GH 8081 df = DataFrame( np.abs(np.random.randn(10, 5)), columns=["a", "b", "c", "d", "e"] ) ax = df.plot.scatter(x="a", y="b", xerr="d", yerr="e", c="red") - self._check_has_errorbars(ax, xerr=1, yerr=1) + _check_has_errorbars(ax, xerr=1, yerr=1) _check_errorbar_color(ax.containers, "red", has_err="has_xerr") _check_errorbar_color(ax.containers, "red", has_err="has_yerr") ax = df.plot.scatter(x="a", y="b", yerr="e", color="green") - self._check_has_errorbars(ax, xerr=0, yerr=1) + _check_has_errorbars(ax, xerr=0, yerr=1) _check_errorbar_color(ax.containers, "green", has_err="has_yerr") def test_scatter_unknown_colormap(self): @@ -1685,13 +1695,13 @@ def test_sharex_and_ax(self): def _check(axes): for ax in axes: assert len(ax.lines) == 1 - self._check_visible(ax.get_yticklabels(), visible=True) + _check_visible(ax.get_yticklabels(), visible=True) for ax in [axes[0], axes[2]]: - self._check_visible(ax.get_xticklabels(), visible=False) - self._check_visible(ax.get_xticklabels(minor=True), visible=False) + _check_visible(ax.get_xticklabels(), visible=False) + _check_visible(ax.get_xticklabels(minor=True), visible=False) for ax in [axes[1], axes[3]]: - self._check_visible(ax.get_xticklabels(), visible=True) - self._check_visible(ax.get_xticklabels(minor=True), visible=True) + _check_visible(ax.get_xticklabels(), visible=True) + _check_visible(ax.get_xticklabels(minor=True), visible=True) for ax in axes: df.plot(x="a", y="b", title="title", ax=ax, sharex=True) @@ -1713,9 +1723,9 @@ def _check(axes): gs.tight_layout(plt.gcf()) for ax in axes: assert len(ax.lines) == 1 - self._check_visible(ax.get_yticklabels(), visible=True) - self._check_visible(ax.get_xticklabels(), visible=True) - self._check_visible(ax.get_xticklabels(minor=True), visible=True) + _check_visible(ax.get_yticklabels(), visible=True) + _check_visible(ax.get_xticklabels(), visible=True) + _check_visible(ax.get_xticklabels(minor=True), visible=True) tm.close() def test_sharey_and_ax(self): @@ -1738,12 +1748,12 @@ def test_sharey_and_ax(self): def _check(axes): for ax in axes: assert len(ax.lines) == 1 - self._check_visible(ax.get_xticklabels(), visible=True) - self._check_visible(ax.get_xticklabels(minor=True), visible=True) + _check_visible(ax.get_xticklabels(), visible=True) + _check_visible(ax.get_xticklabels(minor=True), visible=True) for ax in [axes[0], axes[1]]: - self._check_visible(ax.get_yticklabels(), visible=True) + _check_visible(ax.get_yticklabels(), visible=True) for ax in [axes[2], axes[3]]: - self._check_visible(ax.get_yticklabels(), visible=False) + _check_visible(ax.get_yticklabels(), visible=False) for ax in axes: df.plot(x="a", y="b", title="title", ax=ax, sharey=True) @@ -1767,9 +1777,9 @@ def _check(axes): gs.tight_layout(plt.gcf()) for ax in axes: assert len(ax.lines) == 1 - self._check_visible(ax.get_yticklabels(), visible=True) - self._check_visible(ax.get_xticklabels(), visible=True) - self._check_visible(ax.get_xticklabels(minor=True), visible=True) + _check_visible(ax.get_yticklabels(), visible=True) + _check_visible(ax.get_xticklabels(), visible=True) + _check_visible(ax.get_xticklabels(minor=True), visible=True) @td.skip_if_no_scipy def test_memory_leak(self): @@ -1835,9 +1845,9 @@ def _get_horizontal_grid(): ax2 = df.plot(ax=ax2) assert len(ax2.lines) == 2 for ax in [ax1, ax2]: - self._check_visible(ax.get_yticklabels(), visible=True) - self._check_visible(ax.get_xticklabels(), visible=True) - self._check_visible(ax.get_xticklabels(minor=True), visible=True) + _check_visible(ax.get_yticklabels(), visible=True) + _check_visible(ax.get_xticklabels(), visible=True) + _check_visible(ax.get_xticklabels(minor=True), visible=True) tm.close() # subplots=True @@ -1846,9 +1856,9 @@ def _get_horizontal_grid(): assert len(ax1.lines) == 1 assert len(ax2.lines) == 1 for ax in axes: - self._check_visible(ax.get_yticklabels(), visible=True) - self._check_visible(ax.get_xticklabels(), visible=True) - self._check_visible(ax.get_xticklabels(minor=True), visible=True) + _check_visible(ax.get_yticklabels(), visible=True) + _check_visible(ax.get_xticklabels(), visible=True) + _check_visible(ax.get_xticklabels(minor=True), visible=True) tm.close() # vertical / subplots / sharex=True / sharey=True @@ -1859,12 +1869,12 @@ def _get_horizontal_grid(): assert len(axes[1].lines) == 1 for ax in [ax1, ax2]: # yaxis are visible because there is only one column - self._check_visible(ax.get_yticklabels(), visible=True) + _check_visible(ax.get_yticklabels(), visible=True) # xaxis of axes0 (top) are hidden - self._check_visible(axes[0].get_xticklabels(), visible=False) - self._check_visible(axes[0].get_xticklabels(minor=True), visible=False) - self._check_visible(axes[1].get_xticklabels(), visible=True) - self._check_visible(axes[1].get_xticklabels(minor=True), visible=True) + _check_visible(axes[0].get_xticklabels(), visible=False) + _check_visible(axes[0].get_xticklabels(minor=True), visible=False) + _check_visible(axes[1].get_xticklabels(), visible=True) + _check_visible(axes[1].get_xticklabels(minor=True), visible=True) tm.close() # horizontal / subplots / sharex=True / sharey=True @@ -1873,13 +1883,13 @@ def _get_horizontal_grid(): axes = df.plot(subplots=True, ax=[ax1, ax2], sharex=True, sharey=True) assert len(axes[0].lines) == 1 assert len(axes[1].lines) == 1 - self._check_visible(axes[0].get_yticklabels(), visible=True) + _check_visible(axes[0].get_yticklabels(), visible=True) # yaxis of axes1 (right) are hidden - self._check_visible(axes[1].get_yticklabels(), visible=False) + _check_visible(axes[1].get_yticklabels(), visible=False) for ax in [ax1, ax2]: # xaxis are visible because there is only one column - self._check_visible(ax.get_xticklabels(), visible=True) - self._check_visible(ax.get_xticklabels(minor=True), visible=True) + _check_visible(ax.get_xticklabels(), visible=True) + _check_visible(ax.get_xticklabels(minor=True), visible=True) tm.close() # boxed @@ -1898,9 +1908,9 @@ def _get_boxed_grid(): for ax in axes: assert len(ax.lines) == 1 # axis are visible because these are not shared - self._check_visible(ax.get_yticklabels(), visible=True) - self._check_visible(ax.get_xticklabels(), visible=True) - self._check_visible(ax.get_xticklabels(minor=True), visible=True) + _check_visible(ax.get_yticklabels(), visible=True) + _check_visible(ax.get_xticklabels(), visible=True) + _check_visible(ax.get_xticklabels(minor=True), visible=True) tm.close() # subplots / sharex=True / sharey=True @@ -1910,20 +1920,20 @@ def _get_boxed_grid(): for ax in axes: assert len(ax.lines) == 1 for ax in [axes[0], axes[2]]: # left column - self._check_visible(ax.get_yticklabels(), visible=True) + _check_visible(ax.get_yticklabels(), visible=True) for ax in [axes[1], axes[3]]: # right column - self._check_visible(ax.get_yticklabels(), visible=False) + _check_visible(ax.get_yticklabels(), visible=False) for ax in [axes[0], axes[1]]: # top row - self._check_visible(ax.get_xticklabels(), visible=False) - self._check_visible(ax.get_xticklabels(minor=True), visible=False) + _check_visible(ax.get_xticklabels(), visible=False) + _check_visible(ax.get_xticklabels(minor=True), visible=False) for ax in [axes[2], axes[3]]: # bottom row - self._check_visible(ax.get_xticklabels(), visible=True) - self._check_visible(ax.get_xticklabels(minor=True), visible=True) + _check_visible(ax.get_xticklabels(), visible=True) + _check_visible(ax.get_xticklabels(minor=True), visible=True) tm.close() def test_df_grid_settings(self): # Make sure plot defaults to rcParams['axes.grid'] setting, GH 9792 - self._check_grid_settings( + _check_grid_settings( DataFrame({"a": [1, 2, 3], "b": [2, 3, 4]}), plotting.PlotAccessor._dataframe_kinds, kws={"x": "a", "y": "b"}, @@ -1932,19 +1942,19 @@ def test_df_grid_settings(self): def test_plain_axes(self): # supplied ax itself is a SubplotAxes, but figure contains also # a plain Axes object (GH11556) - fig, ax = self.plt.subplots() + fig, ax = mpl.pyplot.subplots() fig.add_axes([0.2, 0.2, 0.2, 0.2]) Series(np.random.rand(10)).plot(ax=ax) # supplied ax itself is a plain Axes, but because the cmap keyword # a new ax is created for the colorbar -> also multiples axes (GH11520) df = DataFrame({"a": np.random.randn(8), "b": np.random.randn(8)}) - fig = self.plt.figure() + fig = mpl.pyplot.figure() ax = fig.add_axes((0, 0, 1, 1)) df.plot(kind="scatter", ax=ax, x="a", y="b", c="a", cmap="hsv") # other examples - fig, ax = self.plt.subplots() + fig, ax = mpl.pyplot.subplots() from mpl_toolkits.axes_grid1 import make_axes_locatable divider = make_axes_locatable(ax) @@ -1952,7 +1962,7 @@ def test_plain_axes(self): Series(np.random.rand(10)).plot(ax=ax) Series(np.random.rand(10)).plot(ax=cax) - fig, ax = self.plt.subplots() + fig, ax = mpl.pyplot.subplots() from mpl_toolkits.axes_grid1.inset_locator import inset_axes iax = inset_axes(ax, width="30%", height=1.0, loc=3) @@ -1973,7 +1983,7 @@ def test_secondary_axis_font_size(self, method): kwargs = {"secondary_y": sy, "fontsize": fontsize, "mark_right": True} ax = getattr(df.plot, method)(**kwargs) - self._check_ticks_props(axes=ax.right_ax, ylabelsize=fontsize) + _check_ticks_props(axes=ax.right_ax, ylabelsize=fontsize) def test_x_string_values_ticks(self): # Test if string plot index have a fixed xtick position @@ -2022,7 +2032,7 @@ def test_xlim_plot_line(self, kind): def test_xlim_plot_line_correctly_in_mixed_plot_type(self): # test if xlim is set correctly when ax contains multiple different kinds # of plots, GH 27686 - fig, ax = self.plt.subplots() + fig, ax = mpl.pyplot.subplots() indexes = ["k1", "k2", "k3", "k4"] df = DataFrame( @@ -2080,7 +2090,7 @@ def test_group_subplot(self, kind): expected_labels = (["b", "e"], ["c", "d"], ["a"]) for ax, labels in zip(axes, expected_labels): if kind != "pie": - self._check_legend_labels(ax, labels=labels) + _check_legend_labels(ax, labels=labels) if kind == "line": assert len(ax.lines) == len(labels) diff --git a/pandas/tests/plotting/frame/test_frame_color.py b/pandas/tests/plotting/frame/test_frame_color.py index b9e24ff52070e..e7370375ba27b 100644 --- a/pandas/tests/plotting/frame/test_frame_color.py +++ b/pandas/tests/plotting/frame/test_frame_color.py @@ -10,14 +10,16 @@ from pandas import DataFrame import pandas._testing as tm from pandas.tests.plotting.common import ( - TestPlotBase, + _check_colors, _check_plot_works, + _unpack_cycler, ) from pandas.util.version import Version +mpl = pytest.importorskip("matplotlib") -@td.skip_if_no_mpl -class TestDataFrameColor(TestPlotBase): + +class TestDataFrameColor: @pytest.mark.parametrize( "color", ["C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9"] ) @@ -84,16 +86,16 @@ def test_color_and_marker(self, color, expected): def test_bar_colors(self): import matplotlib.pyplot as plt - default_colors = self._unpack_cycler(plt.rcParams) + default_colors = _unpack_cycler(plt.rcParams) df = DataFrame(np.random.randn(5, 5)) ax = df.plot.bar() - self._check_colors(ax.patches[::5], facecolors=default_colors[:5]) + _check_colors(ax.patches[::5], facecolors=default_colors[:5]) tm.close() custom_colors = "rgcby" ax = df.plot.bar(color=custom_colors) - self._check_colors(ax.patches[::5], facecolors=custom_colors) + _check_colors(ax.patches[::5], facecolors=custom_colors) tm.close() from matplotlib import cm @@ -101,21 +103,21 @@ def test_bar_colors(self): # Test str -> colormap functionality ax = df.plot.bar(colormap="jet") rgba_colors = [cm.jet(n) for n in np.linspace(0, 1, 5)] - self._check_colors(ax.patches[::5], facecolors=rgba_colors) + _check_colors(ax.patches[::5], facecolors=rgba_colors) tm.close() # Test colormap functionality ax = df.plot.bar(colormap=cm.jet) rgba_colors = [cm.jet(n) for n in np.linspace(0, 1, 5)] - self._check_colors(ax.patches[::5], facecolors=rgba_colors) + _check_colors(ax.patches[::5], facecolors=rgba_colors) tm.close() ax = df.loc[:, [0]].plot.bar(color="DodgerBlue") - self._check_colors([ax.patches[0]], facecolors=["DodgerBlue"]) + _check_colors([ax.patches[0]], facecolors=["DodgerBlue"]) tm.close() ax = df.plot(kind="bar", color="green") - self._check_colors(ax.patches[::5], facecolors=["green"] * 5) + _check_colors(ax.patches[::5], facecolors=["green"] * 5) tm.close() def test_bar_user_colors(self): @@ -206,12 +208,12 @@ def test_scatter_colors(self): with pytest.raises(TypeError, match="Specify exactly one of `c` and `color`"): df.plot.scatter(x="a", y="b", c="c", color="green") - default_colors = self._unpack_cycler(self.plt.rcParams) + default_colors = _unpack_cycler(mpl.pyplot.rcParams) ax = df.plot.scatter(x="a", y="b", c="c") tm.assert_numpy_array_equal( ax.collections[0].get_facecolor()[0], - np.array(self.colorconverter.to_rgba(default_colors[0])), + np.array(mpl.colors.ColorConverter.to_rgba(default_colors[0])), ) ax = df.plot.scatter(x="a", y="b", color="white") @@ -241,7 +243,7 @@ def test_line_colors(self): df = DataFrame(np.random.randn(5, 5)) ax = df.plot(color=custom_colors) - self._check_colors(ax.get_lines(), linecolors=custom_colors) + _check_colors(ax.get_lines(), linecolors=custom_colors) tm.close() @@ -255,27 +257,27 @@ def test_line_colors(self): ax = df.plot(colormap="jet") rgba_colors = [cm.jet(n) for n in np.linspace(0, 1, len(df))] - self._check_colors(ax.get_lines(), linecolors=rgba_colors) + _check_colors(ax.get_lines(), linecolors=rgba_colors) tm.close() ax = df.plot(colormap=cm.jet) rgba_colors = [cm.jet(n) for n in np.linspace(0, 1, len(df))] - self._check_colors(ax.get_lines(), linecolors=rgba_colors) + _check_colors(ax.get_lines(), linecolors=rgba_colors) tm.close() # make color a list if plotting one column frame # handles cases like df.plot(color='DodgerBlue') ax = df.loc[:, [0]].plot(color="DodgerBlue") - self._check_colors(ax.lines, linecolors=["DodgerBlue"]) + _check_colors(ax.lines, linecolors=["DodgerBlue"]) ax = df.plot(color="red") - self._check_colors(ax.get_lines(), linecolors=["red"] * 5) + _check_colors(ax.get_lines(), linecolors=["red"] * 5) tm.close() # GH 10299 custom_colors = ["#FF0000", "#0000FF", "#FFFF00", "#000000", "#FFFFFF"] ax = df.plot(color=custom_colors) - self._check_colors(ax.get_lines(), linecolors=custom_colors) + _check_colors(ax.get_lines(), linecolors=custom_colors) tm.close() def test_dont_modify_colors(self): @@ -287,68 +289,68 @@ def test_line_colors_and_styles_subplots(self): # GH 9894 from matplotlib import cm - default_colors = self._unpack_cycler(self.plt.rcParams) + default_colors = _unpack_cycler(mpl.pyplot.rcParams) df = DataFrame(np.random.randn(5, 5)) axes = df.plot(subplots=True) for ax, c in zip(axes, list(default_colors)): - self._check_colors(ax.get_lines(), linecolors=[c]) + _check_colors(ax.get_lines(), linecolors=[c]) tm.close() # single color char axes = df.plot(subplots=True, color="k") for ax in axes: - self._check_colors(ax.get_lines(), linecolors=["k"]) + _check_colors(ax.get_lines(), linecolors=["k"]) tm.close() # single color str axes = df.plot(subplots=True, color="green") for ax in axes: - self._check_colors(ax.get_lines(), linecolors=["green"]) + _check_colors(ax.get_lines(), linecolors=["green"]) tm.close() custom_colors = "rgcby" axes = df.plot(color=custom_colors, subplots=True) for ax, c in zip(axes, list(custom_colors)): - self._check_colors(ax.get_lines(), linecolors=[c]) + _check_colors(ax.get_lines(), linecolors=[c]) tm.close() axes = df.plot(color=list(custom_colors), subplots=True) for ax, c in zip(axes, list(custom_colors)): - self._check_colors(ax.get_lines(), linecolors=[c]) + _check_colors(ax.get_lines(), linecolors=[c]) tm.close() # GH 10299 custom_colors = ["#FF0000", "#0000FF", "#FFFF00", "#000000", "#FFFFFF"] axes = df.plot(color=custom_colors, subplots=True) for ax, c in zip(axes, list(custom_colors)): - self._check_colors(ax.get_lines(), linecolors=[c]) + _check_colors(ax.get_lines(), linecolors=[c]) tm.close() rgba_colors = [cm.jet(n) for n in np.linspace(0, 1, len(df))] for cmap in ["jet", cm.jet]: axes = df.plot(colormap=cmap, subplots=True) for ax, c in zip(axes, rgba_colors): - self._check_colors(ax.get_lines(), linecolors=[c]) + _check_colors(ax.get_lines(), linecolors=[c]) tm.close() # make color a list if plotting one column frame # handles cases like df.plot(color='DodgerBlue') axes = df.loc[:, [0]].plot(color="DodgerBlue", subplots=True) - self._check_colors(axes[0].lines, linecolors=["DodgerBlue"]) + _check_colors(axes[0].lines, linecolors=["DodgerBlue"]) # single character style axes = df.plot(style="r", subplots=True) for ax in axes: - self._check_colors(ax.get_lines(), linecolors=["r"]) + _check_colors(ax.get_lines(), linecolors=["r"]) tm.close() # list of styles styles = list("rgcby") axes = df.plot(style=styles, subplots=True) for ax, c in zip(axes, styles): - self._check_colors(ax.get_lines(), linecolors=[c]) + _check_colors(ax.get_lines(), linecolors=[c]) tm.close() def test_area_colors(self): @@ -359,12 +361,12 @@ def test_area_colors(self): df = DataFrame(np.random.rand(5, 5)) ax = df.plot.area(color=custom_colors) - self._check_colors(ax.get_lines(), linecolors=custom_colors) + _check_colors(ax.get_lines(), linecolors=custom_colors) poly = [o for o in ax.get_children() if isinstance(o, PolyCollection)] - self._check_colors(poly, facecolors=custom_colors) + _check_colors(poly, facecolors=custom_colors) handles, labels = ax.get_legend_handles_labels() - self._check_colors(handles, facecolors=custom_colors) + _check_colors(handles, facecolors=custom_colors) for h in handles: assert h.get_alpha() is None @@ -372,40 +374,40 @@ def test_area_colors(self): ax = df.plot.area(colormap="jet") jet_colors = [cm.jet(n) for n in np.linspace(0, 1, len(df))] - self._check_colors(ax.get_lines(), linecolors=jet_colors) + _check_colors(ax.get_lines(), linecolors=jet_colors) poly = [o for o in ax.get_children() if isinstance(o, PolyCollection)] - self._check_colors(poly, facecolors=jet_colors) + _check_colors(poly, facecolors=jet_colors) handles, labels = ax.get_legend_handles_labels() - self._check_colors(handles, facecolors=jet_colors) + _check_colors(handles, facecolors=jet_colors) for h in handles: assert h.get_alpha() is None tm.close() # When stacked=False, alpha is set to 0.5 ax = df.plot.area(colormap=cm.jet, stacked=False) - self._check_colors(ax.get_lines(), linecolors=jet_colors) + _check_colors(ax.get_lines(), linecolors=jet_colors) poly = [o for o in ax.get_children() if isinstance(o, PolyCollection)] jet_with_alpha = [(c[0], c[1], c[2], 0.5) for c in jet_colors] - self._check_colors(poly, facecolors=jet_with_alpha) + _check_colors(poly, facecolors=jet_with_alpha) handles, labels = ax.get_legend_handles_labels() linecolors = jet_with_alpha - self._check_colors(handles[: len(jet_colors)], linecolors=linecolors) + _check_colors(handles[: len(jet_colors)], linecolors=linecolors) for h in handles: assert h.get_alpha() == 0.5 def test_hist_colors(self): - default_colors = self._unpack_cycler(self.plt.rcParams) + default_colors = _unpack_cycler(mpl.pyplot.rcParams) df = DataFrame(np.random.randn(5, 5)) ax = df.plot.hist() - self._check_colors(ax.patches[::10], facecolors=default_colors[:5]) + _check_colors(ax.patches[::10], facecolors=default_colors[:5]) tm.close() custom_colors = "rgcby" ax = df.plot.hist(color=custom_colors) - self._check_colors(ax.patches[::10], facecolors=custom_colors) + _check_colors(ax.patches[::10], facecolors=custom_colors) tm.close() from matplotlib import cm @@ -413,20 +415,20 @@ def test_hist_colors(self): # Test str -> colormap functionality ax = df.plot.hist(colormap="jet") rgba_colors = [cm.jet(n) for n in np.linspace(0, 1, 5)] - self._check_colors(ax.patches[::10], facecolors=rgba_colors) + _check_colors(ax.patches[::10], facecolors=rgba_colors) tm.close() # Test colormap functionality ax = df.plot.hist(colormap=cm.jet) rgba_colors = [cm.jet(n) for n in np.linspace(0, 1, 5)] - self._check_colors(ax.patches[::10], facecolors=rgba_colors) + _check_colors(ax.patches[::10], facecolors=rgba_colors) tm.close() ax = df.loc[:, [0]].plot.hist(color="DodgerBlue") - self._check_colors([ax.patches[0]], facecolors=["DodgerBlue"]) + _check_colors([ax.patches[0]], facecolors=["DodgerBlue"]) ax = df.plot(kind="hist", color="green") - self._check_colors(ax.patches[::10], facecolors=["green"] * 5) + _check_colors(ax.patches[::10], facecolors=["green"] * 5) tm.close() @td.skip_if_no_scipy @@ -437,94 +439,92 @@ def test_kde_colors(self): df = DataFrame(np.random.rand(5, 5)) ax = df.plot.kde(color=custom_colors) - self._check_colors(ax.get_lines(), linecolors=custom_colors) + _check_colors(ax.get_lines(), linecolors=custom_colors) tm.close() ax = df.plot.kde(colormap="jet") rgba_colors = [cm.jet(n) for n in np.linspace(0, 1, len(df))] - self._check_colors(ax.get_lines(), linecolors=rgba_colors) + _check_colors(ax.get_lines(), linecolors=rgba_colors) tm.close() ax = df.plot.kde(colormap=cm.jet) rgba_colors = [cm.jet(n) for n in np.linspace(0, 1, len(df))] - self._check_colors(ax.get_lines(), linecolors=rgba_colors) + _check_colors(ax.get_lines(), linecolors=rgba_colors) @td.skip_if_no_scipy def test_kde_colors_and_styles_subplots(self): from matplotlib import cm - default_colors = self._unpack_cycler(self.plt.rcParams) + default_colors = _unpack_cycler(mpl.pyplot.rcParams) df = DataFrame(np.random.randn(5, 5)) axes = df.plot(kind="kde", subplots=True) for ax, c in zip(axes, list(default_colors)): - self._check_colors(ax.get_lines(), linecolors=[c]) + _check_colors(ax.get_lines(), linecolors=[c]) tm.close() # single color char axes = df.plot(kind="kde", color="k", subplots=True) for ax in axes: - self._check_colors(ax.get_lines(), linecolors=["k"]) + _check_colors(ax.get_lines(), linecolors=["k"]) tm.close() # single color str axes = df.plot(kind="kde", color="red", subplots=True) for ax in axes: - self._check_colors(ax.get_lines(), linecolors=["red"]) + _check_colors(ax.get_lines(), linecolors=["red"]) tm.close() custom_colors = "rgcby" axes = df.plot(kind="kde", color=custom_colors, subplots=True) for ax, c in zip(axes, list(custom_colors)): - self._check_colors(ax.get_lines(), linecolors=[c]) + _check_colors(ax.get_lines(), linecolors=[c]) tm.close() rgba_colors = [cm.jet(n) for n in np.linspace(0, 1, len(df))] for cmap in ["jet", cm.jet]: axes = df.plot(kind="kde", colormap=cmap, subplots=True) for ax, c in zip(axes, rgba_colors): - self._check_colors(ax.get_lines(), linecolors=[c]) + _check_colors(ax.get_lines(), linecolors=[c]) tm.close() # make color a list if plotting one column frame # handles cases like df.plot(color='DodgerBlue') axes = df.loc[:, [0]].plot(kind="kde", color="DodgerBlue", subplots=True) - self._check_colors(axes[0].lines, linecolors=["DodgerBlue"]) + _check_colors(axes[0].lines, linecolors=["DodgerBlue"]) # single character style axes = df.plot(kind="kde", style="r", subplots=True) for ax in axes: - self._check_colors(ax.get_lines(), linecolors=["r"]) + _check_colors(ax.get_lines(), linecolors=["r"]) tm.close() # list of styles styles = list("rgcby") axes = df.plot(kind="kde", style=styles, subplots=True) for ax, c in zip(axes, styles): - self._check_colors(ax.get_lines(), linecolors=[c]) + _check_colors(ax.get_lines(), linecolors=[c]) tm.close() def test_boxplot_colors(self): - def _check_colors(bp, box_c, whiskers_c, medians_c, caps_c="k", fliers_c=None): + def _check_colors_box( + bp, box_c, whiskers_c, medians_c, caps_c="k", fliers_c=None + ): # TODO: outside this func? if fliers_c is None: fliers_c = "k" - self._check_colors(bp["boxes"], linecolors=[box_c] * len(bp["boxes"])) - self._check_colors( - bp["whiskers"], linecolors=[whiskers_c] * len(bp["whiskers"]) - ) - self._check_colors( - bp["medians"], linecolors=[medians_c] * len(bp["medians"]) - ) - self._check_colors(bp["fliers"], linecolors=[fliers_c] * len(bp["fliers"])) - self._check_colors(bp["caps"], linecolors=[caps_c] * len(bp["caps"])) - - default_colors = self._unpack_cycler(self.plt.rcParams) + _check_colors(bp["boxes"], linecolors=[box_c] * len(bp["boxes"])) + _check_colors(bp["whiskers"], linecolors=[whiskers_c] * len(bp["whiskers"])) + _check_colors(bp["medians"], linecolors=[medians_c] * len(bp["medians"])) + _check_colors(bp["fliers"], linecolors=[fliers_c] * len(bp["fliers"])) + _check_colors(bp["caps"], linecolors=[caps_c] * len(bp["caps"])) + + default_colors = _unpack_cycler(mpl.pyplot.rcParams) df = DataFrame(np.random.randn(5, 5)) bp = df.plot.box(return_type="dict") - _check_colors( + _check_colors_box( bp, default_colors[0], default_colors[0], @@ -540,7 +540,7 @@ def _check_colors(bp, box_c, whiskers_c, medians_c, caps_c="k", fliers_c=None): "caps": "#123456", } bp = df.plot.box(color=dict_colors, sym="r+", return_type="dict") - _check_colors( + _check_colors_box( bp, dict_colors["boxes"], dict_colors["whiskers"], @@ -553,7 +553,7 @@ def _check_colors(bp, box_c, whiskers_c, medians_c, caps_c="k", fliers_c=None): # partial colors dict_colors = {"whiskers": "c", "medians": "m"} bp = df.plot.box(color=dict_colors, return_type="dict") - _check_colors(bp, default_colors[0], "c", "m", default_colors[0]) + _check_colors_box(bp, default_colors[0], "c", "m", default_colors[0]) tm.close() from matplotlib import cm @@ -561,21 +561,25 @@ def _check_colors(bp, box_c, whiskers_c, medians_c, caps_c="k", fliers_c=None): # Test str -> colormap functionality bp = df.plot.box(colormap="jet", return_type="dict") jet_colors = [cm.jet(n) for n in np.linspace(0, 1, 3)] - _check_colors(bp, jet_colors[0], jet_colors[0], jet_colors[2], jet_colors[0]) + _check_colors_box( + bp, jet_colors[0], jet_colors[0], jet_colors[2], jet_colors[0] + ) tm.close() # Test colormap functionality bp = df.plot.box(colormap=cm.jet, return_type="dict") - _check_colors(bp, jet_colors[0], jet_colors[0], jet_colors[2], jet_colors[0]) + _check_colors_box( + bp, jet_colors[0], jet_colors[0], jet_colors[2], jet_colors[0] + ) tm.close() # string color is applied to all artists except fliers bp = df.plot.box(color="DodgerBlue", return_type="dict") - _check_colors(bp, "DodgerBlue", "DodgerBlue", "DodgerBlue", "DodgerBlue") + _check_colors_box(bp, "DodgerBlue", "DodgerBlue", "DodgerBlue", "DodgerBlue") # tuple is also applied to all artists except fliers bp = df.plot.box(color=(0, 1, 0), sym="#123456", return_type="dict") - _check_colors(bp, (0, 1, 0), (0, 1, 0), (0, 1, 0), (0, 1, 0), "#123456") + _check_colors_box(bp, (0, 1, 0), (0, 1, 0), (0, 1, 0), (0, 1, 0), "#123456") msg = re.escape( "color dict contains invalid key 'xxxx'. The key must be either " @@ -595,8 +599,8 @@ def test_default_color_cycle(self): df = DataFrame(np.random.randn(5, 3)) ax = df.plot() - expected = self._unpack_cycler(plt.rcParams)[:3] - self._check_colors(ax.get_lines(), linecolors=expected) + expected = _unpack_cycler(plt.rcParams)[:3] + _check_colors(ax.get_lines(), linecolors=expected) def test_no_color_bar(self): df = DataFrame( @@ -664,5 +668,5 @@ def test_dataframe_none_color(self): # GH51953 df = DataFrame([[1, 2, 3]]) ax = df.plot(color=None) - expected = self._unpack_cycler(self.plt.rcParams)[:3] - self._check_colors(ax.get_lines(), linecolors=expected) + expected = _unpack_cycler(mpl.pyplot.rcParams)[:3] + _check_colors(ax.get_lines(), linecolors=expected) diff --git a/pandas/tests/plotting/frame/test_frame_groupby.py b/pandas/tests/plotting/frame/test_frame_groupby.py index 9c148645966ad..f1924185a3df1 100644 --- a/pandas/tests/plotting/frame/test_frame_groupby.py +++ b/pandas/tests/plotting/frame/test_frame_groupby.py @@ -2,21 +2,20 @@ import pytest -import pandas.util._test_decorators as td - from pandas import DataFrame -from pandas.tests.plotting.common import TestPlotBase +from pandas.tests.plotting.common import _check_visible + +pytest.importorskip("matplotlib") -@td.skip_if_no_mpl -class TestDataFramePlotsGroupby(TestPlotBase): +class TestDataFramePlotsGroupby: def _assert_ytickslabels_visibility(self, axes, expected): for ax, exp in zip(axes, expected): - self._check_visible(ax.get_yticklabels(), visible=exp) + _check_visible(ax.get_yticklabels(), visible=exp) def _assert_xtickslabels_visibility(self, axes, expected): for ax, exp in zip(axes, expected): - self._check_visible(ax.get_xticklabels(), visible=exp) + _check_visible(ax.get_xticklabels(), visible=exp) @pytest.mark.parametrize( "kwargs, expected", diff --git a/pandas/tests/plotting/frame/test_frame_legend.py b/pandas/tests/plotting/frame/test_frame_legend.py index bad42ebc85cc8..5914300b00434 100644 --- a/pandas/tests/plotting/frame/test_frame_legend.py +++ b/pandas/tests/plotting/frame/test_frame_legend.py @@ -7,11 +7,17 @@ DataFrame, date_range, ) -from pandas.tests.plotting.common import TestPlotBase +from pandas.tests.plotting.common import ( + _check_legend_labels, + _check_legend_marker, + _check_text_labels, +) from pandas.util.version import Version +mpl = pytest.importorskip("matplotlib") + -class TestFrameLegend(TestPlotBase): +class TestFrameLegend: @pytest.mark.xfail( reason=( "Open bug in matplotlib " @@ -66,27 +72,25 @@ def test_df_legend_labels(self): for kind in kinds: ax = df.plot(kind=kind, legend=True) - self._check_legend_labels(ax, labels=df.columns) + _check_legend_labels(ax, labels=df.columns) ax = df2.plot(kind=kind, legend=False, ax=ax) - self._check_legend_labels(ax, labels=df.columns) + _check_legend_labels(ax, labels=df.columns) ax = df3.plot(kind=kind, legend=True, ax=ax) - self._check_legend_labels(ax, labels=df.columns.union(df3.columns)) + _check_legend_labels(ax, labels=df.columns.union(df3.columns)) ax = df4.plot(kind=kind, legend="reverse", ax=ax) expected = list(df.columns.union(df3.columns)) + list(reversed(df4.columns)) - self._check_legend_labels(ax, labels=expected) + _check_legend_labels(ax, labels=expected) # Secondary Y ax = df.plot(legend=True, secondary_y="b") - self._check_legend_labels(ax, labels=["a", "b (right)", "c"]) + _check_legend_labels(ax, labels=["a", "b (right)", "c"]) ax = df2.plot(legend=False, ax=ax) - self._check_legend_labels(ax, labels=["a", "b (right)", "c"]) + _check_legend_labels(ax, labels=["a", "b (right)", "c"]) ax = df3.plot(kind="bar", legend=True, secondary_y="h", ax=ax) - self._check_legend_labels( - ax, labels=["a", "b (right)", "c", "g", "h (right)", "i"] - ) + _check_legend_labels(ax, labels=["a", "b (right)", "c", "g", "h (right)", "i"]) # Time Series ind = date_range("1/1/2014", periods=3) @@ -94,55 +98,55 @@ def test_df_legend_labels(self): df2 = DataFrame(np.random.randn(3, 3), columns=["d", "e", "f"], index=ind) df3 = DataFrame(np.random.randn(3, 3), columns=["g", "h", "i"], index=ind) ax = df.plot(legend=True, secondary_y="b") - self._check_legend_labels(ax, labels=["a", "b (right)", "c"]) + _check_legend_labels(ax, labels=["a", "b (right)", "c"]) ax = df2.plot(legend=False, ax=ax) - self._check_legend_labels(ax, labels=["a", "b (right)", "c"]) + _check_legend_labels(ax, labels=["a", "b (right)", "c"]) ax = df3.plot(legend=True, ax=ax) - self._check_legend_labels(ax, labels=["a", "b (right)", "c", "g", "h", "i"]) + _check_legend_labels(ax, labels=["a", "b (right)", "c", "g", "h", "i"]) # scatter ax = df.plot.scatter(x="a", y="b", label="data1") - self._check_legend_labels(ax, labels=["data1"]) + _check_legend_labels(ax, labels=["data1"]) ax = df2.plot.scatter(x="d", y="e", legend=False, label="data2", ax=ax) - self._check_legend_labels(ax, labels=["data1"]) + _check_legend_labels(ax, labels=["data1"]) ax = df3.plot.scatter(x="g", y="h", label="data3", ax=ax) - self._check_legend_labels(ax, labels=["data1", "data3"]) + _check_legend_labels(ax, labels=["data1", "data3"]) # ensure label args pass through and # index name does not mutate # column names don't mutate df5 = df.set_index("a") ax = df5.plot(y="b") - self._check_legend_labels(ax, labels=["b"]) + _check_legend_labels(ax, labels=["b"]) ax = df5.plot(y="b", label="LABEL_b") - self._check_legend_labels(ax, labels=["LABEL_b"]) - self._check_text_labels(ax.xaxis.get_label(), "a") + _check_legend_labels(ax, labels=["LABEL_b"]) + _check_text_labels(ax.xaxis.get_label(), "a") ax = df5.plot(y="c", label="LABEL_c", ax=ax) - self._check_legend_labels(ax, labels=["LABEL_b", "LABEL_c"]) + _check_legend_labels(ax, labels=["LABEL_b", "LABEL_c"]) assert df5.columns.tolist() == ["b", "c"] def test_missing_marker_multi_plots_on_same_ax(self): # GH 18222 df = DataFrame(data=[[1, 1, 1, 1], [2, 2, 4, 8]], columns=["x", "r", "g", "b"]) - fig, ax = self.plt.subplots(nrows=1, ncols=3) + fig, ax = mpl.pyplot.subplots(nrows=1, ncols=3) # Left plot df.plot(x="x", y="r", linewidth=0, marker="o", color="r", ax=ax[0]) df.plot(x="x", y="g", linewidth=1, marker="x", color="g", ax=ax[0]) df.plot(x="x", y="b", linewidth=1, marker="o", color="b", ax=ax[0]) - self._check_legend_labels(ax[0], labels=["r", "g", "b"]) - self._check_legend_marker(ax[0], expected_markers=["o", "x", "o"]) + _check_legend_labels(ax[0], labels=["r", "g", "b"]) + _check_legend_marker(ax[0], expected_markers=["o", "x", "o"]) # Center plot df.plot(x="x", y="b", linewidth=1, marker="o", color="b", ax=ax[1]) df.plot(x="x", y="r", linewidth=0, marker="o", color="r", ax=ax[1]) df.plot(x="x", y="g", linewidth=1, marker="x", color="g", ax=ax[1]) - self._check_legend_labels(ax[1], labels=["b", "r", "g"]) - self._check_legend_marker(ax[1], expected_markers=["o", "o", "x"]) + _check_legend_labels(ax[1], labels=["b", "r", "g"]) + _check_legend_marker(ax[1], expected_markers=["o", "o", "x"]) # Right plot df.plot(x="x", y="g", linewidth=1, marker="x", color="g", ax=ax[2]) df.plot(x="x", y="b", linewidth=1, marker="o", color="b", ax=ax[2]) df.plot(x="x", y="r", linewidth=0, marker="o", color="r", ax=ax[2]) - self._check_legend_labels(ax[2], labels=["g", "b", "r"]) - self._check_legend_marker(ax[2], expected_markers=["x", "o", "o"]) + _check_legend_labels(ax[2], labels=["g", "b", "r"]) + _check_legend_marker(ax[2], expected_markers=["x", "o", "o"]) def test_legend_name(self): multi = DataFrame( @@ -153,21 +157,21 @@ def test_legend_name(self): ax = multi.plot() leg_title = ax.legend_.get_title() - self._check_text_labels(leg_title, "group,individual") + _check_text_labels(leg_title, "group,individual") df = DataFrame(np.random.randn(5, 5)) ax = df.plot(legend=True, ax=ax) leg_title = ax.legend_.get_title() - self._check_text_labels(leg_title, "group,individual") + _check_text_labels(leg_title, "group,individual") df.columns.name = "new" ax = df.plot(legend=False, ax=ax) leg_title = ax.legend_.get_title() - self._check_text_labels(leg_title, "group,individual") + _check_text_labels(leg_title, "group,individual") ax = df.plot(legend=True, ax=ax) leg_title = ax.legend_.get_title() - self._check_text_labels(leg_title, "new") + _check_text_labels(leg_title, "new") @pytest.mark.parametrize( "kind", @@ -183,7 +187,7 @@ def test_legend_name(self): def test_no_legend(self, kind): df = DataFrame(np.random.rand(3, 3), columns=["a", "b", "c"]) ax = df.plot(kind=kind, legend=False) - self._check_legend_labels(ax, visible=False) + _check_legend_labels(ax, visible=False) def test_missing_markers_legend(self): # 14958 @@ -192,8 +196,8 @@ def test_missing_markers_legend(self): df.plot(y=["B"], marker="o", linestyle="dotted", ax=ax) df.plot(y=["C"], marker="<", linestyle="dotted", ax=ax) - self._check_legend_labels(ax, labels=["A", "B", "C"]) - self._check_legend_marker(ax, expected_markers=["x", "o", "<"]) + _check_legend_labels(ax, labels=["A", "B", "C"]) + _check_legend_marker(ax, expected_markers=["x", "o", "<"]) def test_missing_markers_legend_using_style(self): # 14563 @@ -206,9 +210,9 @@ def test_missing_markers_legend_using_style(self): } ) - fig, ax = self.plt.subplots() + fig, ax = mpl.pyplot.subplots() for kind in "ABC": df.plot("X", kind, label=kind, ax=ax, style=".") - self._check_legend_labels(ax, labels=["A", "B", "C"]) - self._check_legend_marker(ax, expected_markers=[".", ".", "."]) + _check_legend_labels(ax, labels=["A", "B", "C"]) + _check_legend_marker(ax, expected_markers=[".", ".", "."]) diff --git a/pandas/tests/plotting/frame/test_frame_subplots.py b/pandas/tests/plotting/frame/test_frame_subplots.py index 4f55f9504f0db..336fed6293070 100644 --- a/pandas/tests/plotting/frame/test_frame_subplots.py +++ b/pandas/tests/plotting/frame/test_frame_subplots.py @@ -8,7 +8,6 @@ from pandas.compat import is_platform_linux from pandas.compat.numpy import np_version_gte1p24 -import pandas.util._test_decorators as td import pandas as pd from pandas import ( @@ -17,47 +16,55 @@ date_range, ) import pandas._testing as tm -from pandas.tests.plotting.common import TestPlotBase +from pandas.tests.plotting.common import ( + _check_axes_shape, + _check_box_return_type, + _check_legend_labels, + _check_ticks_props, + _check_visible, + _flatten_visible, +) from pandas.io.formats.printing import pprint_thing +mpl = pytest.importorskip("matplotlib") + -@td.skip_if_no_mpl -class TestDataFramePlotsSubplots(TestPlotBase): +class TestDataFramePlotsSubplots: @pytest.mark.slow def test_subplots(self): df = DataFrame(np.random.rand(10, 3), index=list(string.ascii_letters[:10])) for kind in ["bar", "barh", "line", "area"]: axes = df.plot(kind=kind, subplots=True, sharex=True, legend=True) - self._check_axes_shape(axes, axes_num=3, layout=(3, 1)) + _check_axes_shape(axes, axes_num=3, layout=(3, 1)) assert axes.shape == (3,) for ax, column in zip(axes, df.columns): - self._check_legend_labels(ax, labels=[pprint_thing(column)]) + _check_legend_labels(ax, labels=[pprint_thing(column)]) for ax in axes[:-2]: - self._check_visible(ax.xaxis) # xaxis must be visible for grid - self._check_visible(ax.get_xticklabels(), visible=False) + _check_visible(ax.xaxis) # xaxis must be visible for grid + _check_visible(ax.get_xticklabels(), visible=False) if kind != "bar": # change https://github.com/pandas-dev/pandas/issues/26714 - self._check_visible(ax.get_xticklabels(minor=True), visible=False) - self._check_visible(ax.xaxis.get_label(), visible=False) - self._check_visible(ax.get_yticklabels()) + _check_visible(ax.get_xticklabels(minor=True), visible=False) + _check_visible(ax.xaxis.get_label(), visible=False) + _check_visible(ax.get_yticklabels()) - self._check_visible(axes[-1].xaxis) - self._check_visible(axes[-1].get_xticklabels()) - self._check_visible(axes[-1].get_xticklabels(minor=True)) - self._check_visible(axes[-1].xaxis.get_label()) - self._check_visible(axes[-1].get_yticklabels()) + _check_visible(axes[-1].xaxis) + _check_visible(axes[-1].get_xticklabels()) + _check_visible(axes[-1].get_xticklabels(minor=True)) + _check_visible(axes[-1].xaxis.get_label()) + _check_visible(axes[-1].get_yticklabels()) axes = df.plot(kind=kind, subplots=True, sharex=False) for ax in axes: - self._check_visible(ax.xaxis) - self._check_visible(ax.get_xticklabels()) - self._check_visible(ax.get_xticklabels(minor=True)) - self._check_visible(ax.xaxis.get_label()) - self._check_visible(ax.get_yticklabels()) + _check_visible(ax.xaxis) + _check_visible(ax.get_xticklabels()) + _check_visible(ax.get_xticklabels(minor=True)) + _check_visible(ax.xaxis.get_label()) + _check_visible(ax.get_yticklabels()) axes = df.plot(kind=kind, subplots=True, legend=False) for ax in axes: @@ -69,31 +76,31 @@ def test_subplots_timeseries(self): for kind in ["line", "area"]: axes = df.plot(kind=kind, subplots=True, sharex=True) - self._check_axes_shape(axes, axes_num=3, layout=(3, 1)) + _check_axes_shape(axes, axes_num=3, layout=(3, 1)) for ax in axes[:-2]: # GH 7801 - self._check_visible(ax.xaxis) # xaxis must be visible for grid - self._check_visible(ax.get_xticklabels(), visible=False) - self._check_visible(ax.get_xticklabels(minor=True), visible=False) - self._check_visible(ax.xaxis.get_label(), visible=False) - self._check_visible(ax.get_yticklabels()) - - self._check_visible(axes[-1].xaxis) - self._check_visible(axes[-1].get_xticklabels()) - self._check_visible(axes[-1].get_xticklabels(minor=True)) - self._check_visible(axes[-1].xaxis.get_label()) - self._check_visible(axes[-1].get_yticklabels()) - self._check_ticks_props(axes, xrot=0) + _check_visible(ax.xaxis) # xaxis must be visible for grid + _check_visible(ax.get_xticklabels(), visible=False) + _check_visible(ax.get_xticklabels(minor=True), visible=False) + _check_visible(ax.xaxis.get_label(), visible=False) + _check_visible(ax.get_yticklabels()) + + _check_visible(axes[-1].xaxis) + _check_visible(axes[-1].get_xticklabels()) + _check_visible(axes[-1].get_xticklabels(minor=True)) + _check_visible(axes[-1].xaxis.get_label()) + _check_visible(axes[-1].get_yticklabels()) + _check_ticks_props(axes, xrot=0) axes = df.plot(kind=kind, subplots=True, sharex=False, rot=45, fontsize=7) for ax in axes: - self._check_visible(ax.xaxis) - self._check_visible(ax.get_xticklabels()) - self._check_visible(ax.get_xticklabels(minor=True)) - self._check_visible(ax.xaxis.get_label()) - self._check_visible(ax.get_yticklabels()) - self._check_ticks_props(ax, xlabelsize=7, xrot=45, ylabelsize=7) + _check_visible(ax.xaxis) + _check_visible(ax.get_xticklabels()) + _check_visible(ax.get_xticklabels(minor=True)) + _check_visible(ax.xaxis.get_label()) + _check_visible(ax.get_yticklabels()) + _check_ticks_props(ax, xlabelsize=7, xrot=45, ylabelsize=7) def test_subplots_timeseries_y_axis(self): # GH16953 @@ -185,27 +192,27 @@ def test_subplots_layout_multi_column(self): df = DataFrame(np.random.rand(10, 3), index=list(string.ascii_letters[:10])) axes = df.plot(subplots=True, layout=(2, 2)) - self._check_axes_shape(axes, axes_num=3, layout=(2, 2)) + _check_axes_shape(axes, axes_num=3, layout=(2, 2)) assert axes.shape == (2, 2) axes = df.plot(subplots=True, layout=(-1, 2)) - self._check_axes_shape(axes, axes_num=3, layout=(2, 2)) + _check_axes_shape(axes, axes_num=3, layout=(2, 2)) assert axes.shape == (2, 2) axes = df.plot(subplots=True, layout=(2, -1)) - self._check_axes_shape(axes, axes_num=3, layout=(2, 2)) + _check_axes_shape(axes, axes_num=3, layout=(2, 2)) assert axes.shape == (2, 2) axes = df.plot(subplots=True, layout=(1, 4)) - self._check_axes_shape(axes, axes_num=3, layout=(1, 4)) + _check_axes_shape(axes, axes_num=3, layout=(1, 4)) assert axes.shape == (1, 4) axes = df.plot(subplots=True, layout=(-1, 4)) - self._check_axes_shape(axes, axes_num=3, layout=(1, 4)) + _check_axes_shape(axes, axes_num=3, layout=(1, 4)) assert axes.shape == (1, 4) axes = df.plot(subplots=True, layout=(4, -1)) - self._check_axes_shape(axes, axes_num=3, layout=(4, 1)) + _check_axes_shape(axes, axes_num=3, layout=(4, 1)) assert axes.shape == (4, 1) msg = "Layout of 1x1 must be larger than required size 3" @@ -230,7 +237,7 @@ def test_subplots_layout_single_column( # GH 6667 df = DataFrame(np.random.rand(10, 1), index=list(string.ascii_letters[:10])) axes = df.plot(subplots=True, **kwargs) - self._check_axes_shape( + _check_axes_shape( axes, axes_num=expected_axes_num, layout=expected_layout, @@ -251,25 +258,25 @@ def test_subplots_warnings(self): def test_subplots_multiple_axes(self): # GH 5353, 6970, GH 7069 - fig, axes = self.plt.subplots(2, 3) + fig, axes = mpl.pyplot.subplots(2, 3) df = DataFrame(np.random.rand(10, 3), index=list(string.ascii_letters[:10])) returned = df.plot(subplots=True, ax=axes[0], sharex=False, sharey=False) - self._check_axes_shape(returned, axes_num=3, layout=(1, 3)) + _check_axes_shape(returned, axes_num=3, layout=(1, 3)) assert returned.shape == (3,) assert returned[0].figure is fig # draw on second row returned = df.plot(subplots=True, ax=axes[1], sharex=False, sharey=False) - self._check_axes_shape(returned, axes_num=3, layout=(1, 3)) + _check_axes_shape(returned, axes_num=3, layout=(1, 3)) assert returned.shape == (3,) assert returned[0].figure is fig - self._check_axes_shape(axes, axes_num=6, layout=(2, 3)) + _check_axes_shape(axes, axes_num=6, layout=(2, 3)) tm.close() msg = "The number of passed axes must be 3, the same as the output plot" with pytest.raises(ValueError, match=msg): - fig, axes = self.plt.subplots(2, 3) + fig, axes = mpl.pyplot.subplots(2, 3) # pass different number of axes from required df.plot(subplots=True, ax=axes) @@ -277,7 +284,7 @@ def test_subplots_multiple_axes(self): # invalid lauout should not affect to input and return value # (show warning is tested in # TestDataFrameGroupByPlots.test_grouped_box_multiple_axes - fig, axes = self.plt.subplots(2, 2) + fig, axes = mpl.pyplot.subplots(2, 2) with warnings.catch_warnings(): warnings.simplefilter("ignore", UserWarning) df = DataFrame(np.random.rand(10, 4), index=list(string.ascii_letters[:10])) @@ -285,33 +292,33 @@ def test_subplots_multiple_axes(self): returned = df.plot( subplots=True, ax=axes, layout=(2, 1), sharex=False, sharey=False ) - self._check_axes_shape(returned, axes_num=4, layout=(2, 2)) + _check_axes_shape(returned, axes_num=4, layout=(2, 2)) assert returned.shape == (4,) returned = df.plot( subplots=True, ax=axes, layout=(2, -1), sharex=False, sharey=False ) - self._check_axes_shape(returned, axes_num=4, layout=(2, 2)) + _check_axes_shape(returned, axes_num=4, layout=(2, 2)) assert returned.shape == (4,) returned = df.plot( subplots=True, ax=axes, layout=(-1, 2), sharex=False, sharey=False ) - self._check_axes_shape(returned, axes_num=4, layout=(2, 2)) + _check_axes_shape(returned, axes_num=4, layout=(2, 2)) assert returned.shape == (4,) # single column - fig, axes = self.plt.subplots(1, 1) + fig, axes = mpl.pyplot.subplots(1, 1) df = DataFrame(np.random.rand(10, 1), index=list(string.ascii_letters[:10])) axes = df.plot(subplots=True, ax=[axes], sharex=False, sharey=False) - self._check_axes_shape(axes, axes_num=1, layout=(1, 1)) + _check_axes_shape(axes, axes_num=1, layout=(1, 1)) assert axes.shape == (1,) def test_subplots_ts_share_axes(self): # GH 3964 - fig, axes = self.plt.subplots(3, 3, sharex=True, sharey=True) - self.plt.subplots_adjust(left=0.05, right=0.95, hspace=0.3, wspace=0.3) + fig, axes = mpl.pyplot.subplots(3, 3, sharex=True, sharey=True) + mpl.pyplot.subplots_adjust(left=0.05, right=0.95, hspace=0.3, wspace=0.3) df = DataFrame( np.random.randn(10, 9), index=date_range(start="2014-07-01", freq="M", periods=10), @@ -321,21 +328,21 @@ def test_subplots_ts_share_axes(self): # Rows other than bottom should not be visible for ax in axes[0:-1].ravel(): - self._check_visible(ax.get_xticklabels(), visible=False) + _check_visible(ax.get_xticklabels(), visible=False) # Bottom row should be visible for ax in axes[-1].ravel(): - self._check_visible(ax.get_xticklabels(), visible=True) + _check_visible(ax.get_xticklabels(), visible=True) # First column should be visible for ax in axes[[0, 1, 2], [0]].ravel(): - self._check_visible(ax.get_yticklabels(), visible=True) + _check_visible(ax.get_yticklabels(), visible=True) # Other columns should not be visible for ax in axes[[0, 1, 2], [1]].ravel(): - self._check_visible(ax.get_yticklabels(), visible=False) + _check_visible(ax.get_yticklabels(), visible=False) for ax in axes[[0, 1, 2], [2]].ravel(): - self._check_visible(ax.get_yticklabels(), visible=False) + _check_visible(ax.get_yticklabels(), visible=False) def test_subplots_sharex_axes_existing_axes(self): # GH 9158 @@ -345,29 +352,29 @@ def test_subplots_sharex_axes_existing_axes(self): axes = df[["A", "B"]].plot(subplots=True) df["C"].plot(ax=axes[0], secondary_y=True) - self._check_visible(axes[0].get_xticklabels(), visible=False) - self._check_visible(axes[1].get_xticklabels(), visible=True) + _check_visible(axes[0].get_xticklabels(), visible=False) + _check_visible(axes[1].get_xticklabels(), visible=True) for ax in axes.ravel(): - self._check_visible(ax.get_yticklabels(), visible=True) + _check_visible(ax.get_yticklabels(), visible=True) def test_subplots_dup_columns(self): # GH 10962 df = DataFrame(np.random.rand(5, 5), columns=list("aaaaa")) axes = df.plot(subplots=True) for ax in axes: - self._check_legend_labels(ax, labels=["a"]) + _check_legend_labels(ax, labels=["a"]) assert len(ax.lines) == 1 tm.close() axes = df.plot(subplots=True, secondary_y="a") for ax in axes: # (right) is only attached when subplots=False - self._check_legend_labels(ax, labels=["a"]) + _check_legend_labels(ax, labels=["a"]) assert len(ax.lines) == 1 tm.close() ax = df.plot(secondary_y="a") - self._check_legend_labels(ax, labels=["a (right)"] * 5) + _check_legend_labels(ax, labels=["a (right)"] * 5) assert len(ax.lines) == 0 assert len(ax.right_ax.lines) == 5 @@ -407,13 +414,13 @@ def test_boxplot_subplots_return_type(self, hist_df): # normal style: return_type=None result = df.plot.box(subplots=True) assert isinstance(result, Series) - self._check_box_return_type( + _check_box_return_type( result, None, expected_keys=["height", "weight", "category"] ) for t in ["dict", "axes", "both"]: returned = df.plot.box(return_type=t, subplots=True) - self._check_box_return_type( + _check_box_return_type( returned, t, expected_keys=["height", "weight", "category"], @@ -435,12 +442,12 @@ def test_df_subplots_patterns_minorticks(self): axes = df.plot(subplots=True, ax=axes) for ax in axes: assert len(ax.lines) == 1 - self._check_visible(ax.get_yticklabels(), visible=True) + _check_visible(ax.get_yticklabels(), visible=True) # xaxis of 1st ax must be hidden - self._check_visible(axes[0].get_xticklabels(), visible=False) - self._check_visible(axes[0].get_xticklabels(minor=True), visible=False) - self._check_visible(axes[1].get_xticklabels(), visible=True) - self._check_visible(axes[1].get_xticklabels(minor=True), visible=True) + _check_visible(axes[0].get_xticklabels(), visible=False) + _check_visible(axes[0].get_xticklabels(minor=True), visible=False) + _check_visible(axes[1].get_xticklabels(), visible=True) + _check_visible(axes[1].get_xticklabels(minor=True), visible=True) tm.close() fig, axes = plt.subplots(2, 1) @@ -448,12 +455,12 @@ def test_df_subplots_patterns_minorticks(self): axes = df.plot(subplots=True, ax=axes, sharex=True) for ax in axes: assert len(ax.lines) == 1 - self._check_visible(ax.get_yticklabels(), visible=True) + _check_visible(ax.get_yticklabels(), visible=True) # xaxis of 1st ax must be hidden - self._check_visible(axes[0].get_xticklabels(), visible=False) - self._check_visible(axes[0].get_xticklabels(minor=True), visible=False) - self._check_visible(axes[1].get_xticklabels(), visible=True) - self._check_visible(axes[1].get_xticklabels(minor=True), visible=True) + _check_visible(axes[0].get_xticklabels(), visible=False) + _check_visible(axes[0].get_xticklabels(minor=True), visible=False) + _check_visible(axes[1].get_xticklabels(), visible=True) + _check_visible(axes[1].get_xticklabels(minor=True), visible=True) tm.close() # not shared @@ -461,9 +468,9 @@ def test_df_subplots_patterns_minorticks(self): axes = df.plot(subplots=True, ax=axes) for ax in axes: assert len(ax.lines) == 1 - self._check_visible(ax.get_yticklabels(), visible=True) - self._check_visible(ax.get_xticklabels(), visible=True) - self._check_visible(ax.get_xticklabels(minor=True), visible=True) + _check_visible(ax.get_yticklabels(), visible=True) + _check_visible(ax.get_xticklabels(), visible=True) + _check_visible(ax.get_xticklabels(minor=True), visible=True) tm.close() def test_subplots_sharex_false(self): @@ -473,7 +480,7 @@ def test_subplots_sharex_false(self): df.iloc[5:, 1] = np.nan df.iloc[:5, 0] = np.nan - figs, axs = self.plt.subplots(2, 1) + figs, axs = mpl.pyplot.subplots(2, 1) df.plot.line(ax=axs, subplots=True, sharex=False) expected_ax1 = np.arange(4.5, 10, 0.5) @@ -487,13 +494,13 @@ def test_subplots_constrained_layout(self): idx = date_range(start="now", periods=10) df = DataFrame(np.random.rand(10, 3), index=idx) kwargs = {} - if hasattr(self.plt.Figure, "get_constrained_layout"): + if hasattr(mpl.pyplot.Figure, "get_constrained_layout"): kwargs["constrained_layout"] = True - fig, axes = self.plt.subplots(2, **kwargs) + fig, axes = mpl.pyplot.subplots(2, **kwargs) with tm.assert_produces_warning(None): df.plot(ax=axes[0]) with tm.ensure_clean(return_filelike=True) as path: - self.plt.savefig(path) + mpl.pyplot.savefig(path) @pytest.mark.parametrize( "index_name, old_label, new_label", @@ -632,7 +639,7 @@ def _check_bar_alignment( grid=True, ) - axes = self._flatten_visible(axes) + axes = _flatten_visible(axes) for ax in axes: if kind == "bar": diff --git a/pandas/tests/plotting/frame/test_hist_box_by.py b/pandas/tests/plotting/frame/test_hist_box_by.py index 999118144b58d..c8b71c04001e5 100644 --- a/pandas/tests/plotting/frame/test_hist_box_by.py +++ b/pandas/tests/plotting/frame/test_hist_box_by.py @@ -3,15 +3,17 @@ import numpy as np import pytest -import pandas.util._test_decorators as td - from pandas import DataFrame import pandas._testing as tm from pandas.tests.plotting.common import ( - TestPlotBase, + _check_axes_shape, _check_plot_works, + get_x_axis, + get_y_axis, ) +pytest.importorskip("matplotlib") + @pytest.fixture def hist_df(): @@ -22,8 +24,7 @@ def hist_df(): return df -@td.skip_if_no_mpl -class TestHistWithBy(TestPlotBase): +class TestHistWithBy: @pytest.mark.slow @pytest.mark.parametrize( "by, column, titles, legends", @@ -172,7 +173,7 @@ def test_hist_plot_layout_with_by(self, by, column, layout, axes_num, hist_df): axes = _check_plot_works( hist_df.plot.hist, column=column, by=by, layout=layout ) - self._check_axes_shape(axes, axes_num=axes_num, layout=layout) + _check_axes_shape(axes, axes_num=axes_num, layout=layout) @pytest.mark.parametrize( "msg, by, layout", @@ -194,16 +195,16 @@ def test_axis_share_x_with_by(self, hist_df): ax1, ax2, ax3 = hist_df.plot.hist(column="A", by="C", sharex=True) # share x - assert self.get_x_axis(ax1).joined(ax1, ax2) - assert self.get_x_axis(ax2).joined(ax1, ax2) - assert self.get_x_axis(ax3).joined(ax1, ax3) - assert self.get_x_axis(ax3).joined(ax2, ax3) + assert get_x_axis(ax1).joined(ax1, ax2) + assert get_x_axis(ax2).joined(ax1, ax2) + assert get_x_axis(ax3).joined(ax1, ax3) + assert get_x_axis(ax3).joined(ax2, ax3) # don't share y - assert not self.get_y_axis(ax1).joined(ax1, ax2) - assert not self.get_y_axis(ax2).joined(ax1, ax2) - assert not self.get_y_axis(ax3).joined(ax1, ax3) - assert not self.get_y_axis(ax3).joined(ax2, ax3) + assert not get_y_axis(ax1).joined(ax1, ax2) + assert not get_y_axis(ax2).joined(ax1, ax2) + assert not get_y_axis(ax3).joined(ax1, ax3) + assert not get_y_axis(ax3).joined(ax2, ax3) @pytest.mark.slow def test_axis_share_y_with_by(self, hist_df): @@ -211,26 +212,25 @@ def test_axis_share_y_with_by(self, hist_df): ax1, ax2, ax3 = hist_df.plot.hist(column="A", by="C", sharey=True) # share y - assert self.get_y_axis(ax1).joined(ax1, ax2) - assert self.get_y_axis(ax2).joined(ax1, ax2) - assert self.get_y_axis(ax3).joined(ax1, ax3) - assert self.get_y_axis(ax3).joined(ax2, ax3) + assert get_y_axis(ax1).joined(ax1, ax2) + assert get_y_axis(ax2).joined(ax1, ax2) + assert get_y_axis(ax3).joined(ax1, ax3) + assert get_y_axis(ax3).joined(ax2, ax3) # don't share x - assert not self.get_x_axis(ax1).joined(ax1, ax2) - assert not self.get_x_axis(ax2).joined(ax1, ax2) - assert not self.get_x_axis(ax3).joined(ax1, ax3) - assert not self.get_x_axis(ax3).joined(ax2, ax3) + assert not get_x_axis(ax1).joined(ax1, ax2) + assert not get_x_axis(ax2).joined(ax1, ax2) + assert not get_x_axis(ax3).joined(ax1, ax3) + assert not get_x_axis(ax3).joined(ax2, ax3) @pytest.mark.parametrize("figsize", [(12, 8), (20, 10)]) def test_figure_shape_hist_with_by(self, figsize, hist_df): # GH 15079 axes = hist_df.plot.hist(column="A", by="C", figsize=figsize) - self._check_axes_shape(axes, axes_num=3, figsize=figsize) + _check_axes_shape(axes, axes_num=3, figsize=figsize) -@td.skip_if_no_mpl -class TestBoxWithBy(TestPlotBase): +class TestBoxWithBy: @pytest.mark.parametrize( "by, column, titles, xticklabels", [ @@ -360,7 +360,7 @@ def test_box_plot_layout_with_by(self, by, column, layout, axes_num, hist_df): axes = _check_plot_works( hist_df.plot.box, default_axes=True, column=column, by=by, layout=layout ) - self._check_axes_shape(axes, axes_num=axes_num, layout=layout) + _check_axes_shape(axes, axes_num=axes_num, layout=layout) @pytest.mark.parametrize( "msg, by, layout", @@ -380,4 +380,4 @@ def test_box_plot_invalid_layout_with_by_raises(self, msg, by, layout, hist_df): def test_figure_shape_hist_with_by(self, figsize, hist_df): # GH 15079 axes = hist_df.plot.box(column="A", by="C", figsize=figsize) - self._check_axes_shape(axes, axes_num=1, figsize=figsize) + _check_axes_shape(axes, axes_num=1, figsize=figsize) diff --git a/pandas/tests/plotting/test_backend.py b/pandas/tests/plotting/test_backend.py index c087d3be293e7..c0ad8e0c9608d 100644 --- a/pandas/tests/plotting/test_backend.py +++ b/pandas/tests/plotting/test_backend.py @@ -7,8 +7,12 @@ import pandas -dummy_backend = types.ModuleType("pandas_dummy_backend") -setattr(dummy_backend, "plot", lambda *args, **kwargs: "used_dummy") + +@pytest.fixture +def dummy_backend(): + db = types.ModuleType("pandas_dummy_backend") + setattr(db, "plot", lambda *args, **kwargs: "used_dummy") + return db @pytest.fixture @@ -26,7 +30,7 @@ def test_backend_is_not_module(): assert pandas.options.plotting.backend == "matplotlib" -def test_backend_is_correct(monkeypatch, restore_backend): +def test_backend_is_correct(monkeypatch, restore_backend, dummy_backend): monkeypatch.setitem(sys.modules, "pandas_dummy_backend", dummy_backend) pandas.set_option("plotting.backend", "pandas_dummy_backend") @@ -36,7 +40,7 @@ def test_backend_is_correct(monkeypatch, restore_backend): ) -def test_backend_can_be_set_in_plot_call(monkeypatch, restore_backend): +def test_backend_can_be_set_in_plot_call(monkeypatch, restore_backend, dummy_backend): monkeypatch.setitem(sys.modules, "pandas_dummy_backend", dummy_backend) df = pandas.DataFrame([1, 2, 3]) @@ -44,7 +48,7 @@ def test_backend_can_be_set_in_plot_call(monkeypatch, restore_backend): assert df.plot(backend="pandas_dummy_backend") == "used_dummy" -def test_register_entrypoint(restore_backend, tmp_path, monkeypatch): +def test_register_entrypoint(restore_backend, tmp_path, monkeypatch, dummy_backend): monkeypatch.syspath_prepend(tmp_path) monkeypatch.setitem(sys.modules, "pandas_dummy_backend", dummy_backend) @@ -86,7 +90,7 @@ def test_no_matplotlib_ok(): pandas.plotting._core._get_plot_backend("matplotlib") -def test_extra_kinds_ok(monkeypatch, restore_backend): +def test_extra_kinds_ok(monkeypatch, restore_backend, dummy_backend): # https://github.com/pandas-dev/pandas/pull/28647 monkeypatch.setitem(sys.modules, "pandas_dummy_backend", dummy_backend) pandas.set_option("plotting.backend", "pandas_dummy_backend") diff --git a/pandas/tests/plotting/test_boxplot_method.py b/pandas/tests/plotting/test_boxplot_method.py index 9bbc8f42b6704..c9531969f9961 100644 --- a/pandas/tests/plotting/test_boxplot_method.py +++ b/pandas/tests/plotting/test_boxplot_method.py @@ -6,8 +6,6 @@ import numpy as np import pytest -import pandas.util._test_decorators as td - from pandas import ( DataFrame, MultiIndex, @@ -18,15 +16,19 @@ ) import pandas._testing as tm from pandas.tests.plotting.common import ( - TestPlotBase, + _check_axes_shape, + _check_box_return_type, _check_plot_works, + _check_ticks_props, + _check_visible, ) from pandas.io.formats.printing import pprint_thing +mpl = pytest.importorskip("matplotlib") + -@td.skip_if_no_mpl -class TestDataFramePlots(TestPlotBase): +class TestDataFramePlots: def test_stacked_boxplot_set_axis(self): # GH2980 import matplotlib.pyplot as plt @@ -82,18 +84,18 @@ def test_boxplot_legacy2(self): # When ax is supplied and required number of axes is 1, # passed ax should be used: - fig, ax = self.plt.subplots() + fig, ax = mpl.pyplot.subplots() axes = df.boxplot("Col1", by="X", ax=ax) ax_axes = ax.axes assert ax_axes is axes - fig, ax = self.plt.subplots() + fig, ax = mpl.pyplot.subplots() axes = df.groupby("Y").boxplot(ax=ax, return_type="axes") ax_axes = ax.axes assert ax_axes is axes["A"] # Multiple columns with an ax argument should use same figure - fig, ax = self.plt.subplots() + fig, ax = mpl.pyplot.subplots() with tm.assert_produces_warning(UserWarning): axes = df.boxplot( column=["Col1", "Col2"], by="X", ax=ax, return_type="axes" @@ -102,7 +104,7 @@ def test_boxplot_legacy2(self): # When by is None, check that all relevant lines are present in the # dict - fig, ax = self.plt.subplots() + fig, ax = mpl.pyplot.subplots() d = df.boxplot(ax=ax, return_type="dict") lines = list(itertools.chain.from_iterable(d.values())) assert len(ax.get_lines()) == len(lines) @@ -110,7 +112,7 @@ def test_boxplot_legacy2(self): def test_boxplot_return_type_none(self, hist_df): # GH 12216; return_type=None & by=None -> axes result = hist_df.boxplot() - assert isinstance(result, self.plt.Axes) + assert isinstance(result, mpl.pyplot.Axes) def test_boxplot_return_type_legacy(self): # API change in https://github.com/pandas-dev/pandas/pull/7096 @@ -125,19 +127,19 @@ def test_boxplot_return_type_legacy(self): df.boxplot(return_type="NOT_A_TYPE") result = df.boxplot() - self._check_box_return_type(result, "axes") + _check_box_return_type(result, "axes") with tm.assert_produces_warning(False): result = df.boxplot(return_type="dict") - self._check_box_return_type(result, "dict") + _check_box_return_type(result, "dict") with tm.assert_produces_warning(False): result = df.boxplot(return_type="axes") - self._check_box_return_type(result, "axes") + _check_box_return_type(result, "axes") with tm.assert_produces_warning(False): result = df.boxplot(return_type="both") - self._check_box_return_type(result, "both") + _check_box_return_type(result, "both") def test_boxplot_axis_limits(self, hist_df): def _check_ax_limits(col, ax): @@ -178,9 +180,7 @@ def test_figsize(self): def test_fontsize(self): df = DataFrame({"a": [1, 2, 3, 4, 5, 6]}) - self._check_ticks_props( - df.boxplot("a", fontsize=16), xlabelsize=16, ylabelsize=16 - ) + _check_ticks_props(df.boxplot("a", fontsize=16), xlabelsize=16, ylabelsize=16) def test_boxplot_numeric_data(self): # GH 22799 @@ -317,24 +317,23 @@ def test_boxplot_group_xlabel_ylabel(self, vert): for subplot in ax: assert subplot.get_xlabel() == xlabel assert subplot.get_ylabel() == ylabel - self.plt.close() + mpl.pyplot.close() ax = df.boxplot(by="group", vert=vert) for subplot in ax: target_label = subplot.get_xlabel() if vert else subplot.get_ylabel() assert target_label == pprint_thing(["group"]) - self.plt.close() + mpl.pyplot.close() -@td.skip_if_no_mpl -class TestDataFrameGroupByPlots(TestPlotBase): +class TestDataFrameGroupByPlots: def test_boxplot_legacy1(self, hist_df): grouped = hist_df.groupby(by="gender") with tm.assert_produces_warning(UserWarning, check_stacklevel=False): axes = _check_plot_works(grouped.boxplot, return_type="axes") - self._check_axes_shape(list(axes.values), axes_num=2, layout=(1, 2)) + _check_axes_shape(list(axes.values), axes_num=2, layout=(1, 2)) axes = _check_plot_works(grouped.boxplot, subplots=False, return_type="axes") - self._check_axes_shape(axes, axes_num=1, layout=(1, 1)) + _check_axes_shape(axes, axes_num=1, layout=(1, 1)) @pytest.mark.slow def test_boxplot_legacy2(self): @@ -343,10 +342,10 @@ def test_boxplot_legacy2(self): grouped = df.groupby(level=1) with tm.assert_produces_warning(UserWarning, check_stacklevel=False): axes = _check_plot_works(grouped.boxplot, return_type="axes") - self._check_axes_shape(list(axes.values), axes_num=10, layout=(4, 3)) + _check_axes_shape(list(axes.values), axes_num=10, layout=(4, 3)) axes = _check_plot_works(grouped.boxplot, subplots=False, return_type="axes") - self._check_axes_shape(axes, axes_num=1, layout=(1, 1)) + _check_axes_shape(axes, axes_num=1, layout=(1, 1)) def test_boxplot_legacy3(self): tuples = zip(string.ascii_letters[:10], range(10)) @@ -356,9 +355,9 @@ def test_boxplot_legacy3(self): grouped = df.unstack(level=1).groupby(level=0, axis=1) with tm.assert_produces_warning(UserWarning, check_stacklevel=False): axes = _check_plot_works(grouped.boxplot, return_type="axes") - self._check_axes_shape(list(axes.values), axes_num=3, layout=(2, 2)) + _check_axes_shape(list(axes.values), axes_num=3, layout=(2, 2)) axes = _check_plot_works(grouped.boxplot, subplots=False, return_type="axes") - self._check_axes_shape(axes, axes_num=1, layout=(1, 1)) + _check_axes_shape(axes, axes_num=1, layout=(1, 1)) def test_grouped_plot_fignums(self): n = 10 @@ -369,12 +368,12 @@ def test_grouped_plot_fignums(self): gb = df.groupby("gender") res = gb.plot() - assert len(self.plt.get_fignums()) == 2 + assert len(mpl.pyplot.get_fignums()) == 2 assert len(res) == 2 tm.close() res = gb.boxplot(return_type="axes") - assert len(self.plt.get_fignums()) == 1 + assert len(mpl.pyplot.get_fignums()) == 1 assert len(res) == 2 tm.close() @@ -389,13 +388,13 @@ def test_grouped_box_return_type(self, hist_df): # old style: return_type=None result = df.boxplot(by="gender") assert isinstance(result, np.ndarray) - self._check_box_return_type( + _check_box_return_type( result, None, expected_keys=["height", "weight", "category"] ) # now for groupby result = df.groupby("gender").boxplot(return_type="dict") - self._check_box_return_type(result, "dict", expected_keys=["Male", "Female"]) + _check_box_return_type(result, "dict", expected_keys=["Male", "Female"]) columns2 = "X B C D A G Y N Q O".split() df2 = DataFrame(np.random.randn(50, 10), columns=columns2) @@ -404,18 +403,18 @@ def test_grouped_box_return_type(self, hist_df): for t in ["dict", "axes", "both"]: returned = df.groupby("classroom").boxplot(return_type=t) - self._check_box_return_type(returned, t, expected_keys=["A", "B", "C"]) + _check_box_return_type(returned, t, expected_keys=["A", "B", "C"]) returned = df.boxplot(by="classroom", return_type=t) - self._check_box_return_type( + _check_box_return_type( returned, t, expected_keys=["height", "weight", "category"] ) returned = df2.groupby("category").boxplot(return_type=t) - self._check_box_return_type(returned, t, expected_keys=categories2) + _check_box_return_type(returned, t, expected_keys=categories2) returned = df2.boxplot(by="category", return_type=t) - self._check_box_return_type(returned, t, expected_keys=columns2) + _check_box_return_type(returned, t, expected_keys=columns2) @pytest.mark.slow def test_grouped_box_layout(self, hist_df): @@ -442,37 +441,37 @@ def test_grouped_box_layout(self, hist_df): _check_plot_works( df.groupby("gender").boxplot, column="height", return_type="dict" ) - self._check_axes_shape(self.plt.gcf().axes, axes_num=2, layout=(1, 2)) + _check_axes_shape(mpl.pyplot.gcf().axes, axes_num=2, layout=(1, 2)) with tm.assert_produces_warning(UserWarning, check_stacklevel=False): _check_plot_works( df.groupby("category").boxplot, column="height", return_type="dict" ) - self._check_axes_shape(self.plt.gcf().axes, axes_num=4, layout=(2, 2)) + _check_axes_shape(mpl.pyplot.gcf().axes, axes_num=4, layout=(2, 2)) # GH 6769 with tm.assert_produces_warning(UserWarning, check_stacklevel=False): _check_plot_works( df.groupby("classroom").boxplot, column="height", return_type="dict" ) - self._check_axes_shape(self.plt.gcf().axes, axes_num=3, layout=(2, 2)) + _check_axes_shape(mpl.pyplot.gcf().axes, axes_num=3, layout=(2, 2)) # GH 5897 axes = df.boxplot( column=["height", "weight", "category"], by="gender", return_type="axes" ) - self._check_axes_shape(self.plt.gcf().axes, axes_num=3, layout=(2, 2)) + _check_axes_shape(mpl.pyplot.gcf().axes, axes_num=3, layout=(2, 2)) for ax in [axes["height"]]: - self._check_visible(ax.get_xticklabels(), visible=False) - self._check_visible([ax.xaxis.get_label()], visible=False) + _check_visible(ax.get_xticklabels(), visible=False) + _check_visible([ax.xaxis.get_label()], visible=False) for ax in [axes["weight"], axes["category"]]: - self._check_visible(ax.get_xticklabels()) - self._check_visible([ax.xaxis.get_label()]) + _check_visible(ax.get_xticklabels()) + _check_visible([ax.xaxis.get_label()]) df.groupby("classroom").boxplot( column=["height", "weight", "category"], return_type="dict" ) - self._check_axes_shape(self.plt.gcf().axes, axes_num=3, layout=(2, 2)) + _check_axes_shape(mpl.pyplot.gcf().axes, axes_num=3, layout=(2, 2)) with tm.assert_produces_warning(UserWarning, check_stacklevel=False): _check_plot_works( @@ -481,7 +480,7 @@ def test_grouped_box_layout(self, hist_df): layout=(3, 2), return_type="dict", ) - self._check_axes_shape(self.plt.gcf().axes, axes_num=4, layout=(3, 2)) + _check_axes_shape(mpl.pyplot.gcf().axes, axes_num=4, layout=(3, 2)) with tm.assert_produces_warning(UserWarning, check_stacklevel=False): _check_plot_works( df.groupby("category").boxplot, @@ -489,23 +488,23 @@ def test_grouped_box_layout(self, hist_df): layout=(3, -1), return_type="dict", ) - self._check_axes_shape(self.plt.gcf().axes, axes_num=4, layout=(3, 2)) + _check_axes_shape(mpl.pyplot.gcf().axes, axes_num=4, layout=(3, 2)) df.boxplot(column=["height", "weight", "category"], by="gender", layout=(4, 1)) - self._check_axes_shape(self.plt.gcf().axes, axes_num=3, layout=(4, 1)) + _check_axes_shape(mpl.pyplot.gcf().axes, axes_num=3, layout=(4, 1)) df.boxplot(column=["height", "weight", "category"], by="gender", layout=(-1, 1)) - self._check_axes_shape(self.plt.gcf().axes, axes_num=3, layout=(3, 1)) + _check_axes_shape(mpl.pyplot.gcf().axes, axes_num=3, layout=(3, 1)) df.groupby("classroom").boxplot( column=["height", "weight", "category"], layout=(1, 4), return_type="dict" ) - self._check_axes_shape(self.plt.gcf().axes, axes_num=3, layout=(1, 4)) + _check_axes_shape(mpl.pyplot.gcf().axes, axes_num=3, layout=(1, 4)) df.groupby("classroom").boxplot( column=["height", "weight", "category"], layout=(1, -1), return_type="dict" ) - self._check_axes_shape(self.plt.gcf().axes, axes_num=3, layout=(1, 3)) + _check_axes_shape(mpl.pyplot.gcf().axes, axes_num=3, layout=(1, 3)) @pytest.mark.slow def test_grouped_box_multiple_axes(self, hist_df): @@ -518,11 +517,11 @@ def test_grouped_box_multiple_axes(self, hist_df): # location should be changed if other test is added # which has earlier alphabetical order with tm.assert_produces_warning(UserWarning): - fig, axes = self.plt.subplots(2, 2) + fig, axes = mpl.pyplot.subplots(2, 2) df.groupby("category").boxplot(column="height", return_type="axes", ax=axes) - self._check_axes_shape(self.plt.gcf().axes, axes_num=4, layout=(2, 2)) + _check_axes_shape(mpl.pyplot.gcf().axes, axes_num=4, layout=(2, 2)) - fig, axes = self.plt.subplots(2, 3) + fig, axes = mpl.pyplot.subplots(2, 3) with tm.assert_produces_warning(UserWarning): returned = df.boxplot( column=["height", "weight", "category"], @@ -531,7 +530,7 @@ def test_grouped_box_multiple_axes(self, hist_df): ax=axes[0], ) returned = np.array(list(returned.values)) - self._check_axes_shape(returned, axes_num=3, layout=(1, 3)) + _check_axes_shape(returned, axes_num=3, layout=(1, 3)) tm.assert_numpy_array_equal(returned, axes[0]) assert returned[0].figure is fig @@ -541,20 +540,20 @@ def test_grouped_box_multiple_axes(self, hist_df): column=["height", "weight", "category"], return_type="axes", ax=axes[1] ) returned = np.array(list(returned.values)) - self._check_axes_shape(returned, axes_num=3, layout=(1, 3)) + _check_axes_shape(returned, axes_num=3, layout=(1, 3)) tm.assert_numpy_array_equal(returned, axes[1]) assert returned[0].figure is fig msg = "The number of passed axes must be 3, the same as the output plot" with pytest.raises(ValueError, match=msg): - fig, axes = self.plt.subplots(2, 3) + fig, axes = mpl.pyplot.subplots(2, 3) # pass different number of axes from required with tm.assert_produces_warning(UserWarning): axes = df.groupby("classroom").boxplot(ax=axes) def test_fontsize(self): df = DataFrame({"a": [1, 2, 3, 4, 5, 6], "b": [0, 0, 0, 1, 1, 1]}) - self._check_ticks_props( + _check_ticks_props( df.boxplot("a", by="b", fontsize=16), xlabelsize=16, ylabelsize=16 ) diff --git a/pandas/tests/plotting/test_common.py b/pandas/tests/plotting/test_common.py index faf8278675566..20daf59356248 100644 --- a/pandas/tests/plotting/test_common.py +++ b/pandas/tests/plotting/test_common.py @@ -1,17 +1,16 @@ import pytest -import pandas.util._test_decorators as td - from pandas import DataFrame from pandas.tests.plotting.common import ( - TestPlotBase, _check_plot_works, + _check_ticks_props, _gen_two_subplots, ) +plt = pytest.importorskip("matplotlib.pyplot") + -@td.skip_if_no_mpl -class TestCommon(TestPlotBase): +class TestCommon: def test__check_ticks_props(self): # GH 34768 df = DataFrame({"b": [0, 1, 0], "a": [1, 2, 3]}) @@ -19,16 +18,16 @@ def test__check_ticks_props(self): ax.yaxis.set_tick_params(rotation=30) msg = "expected 0.00000 but got " with pytest.raises(AssertionError, match=msg): - self._check_ticks_props(ax, xrot=0) + _check_ticks_props(ax, xrot=0) with pytest.raises(AssertionError, match=msg): - self._check_ticks_props(ax, xlabelsize=0) + _check_ticks_props(ax, xlabelsize=0) with pytest.raises(AssertionError, match=msg): - self._check_ticks_props(ax, yrot=0) + _check_ticks_props(ax, yrot=0) with pytest.raises(AssertionError, match=msg): - self._check_ticks_props(ax, ylabelsize=0) + _check_ticks_props(ax, ylabelsize=0) def test__gen_two_subplots_with_ax(self): - fig = self.plt.gcf() + fig = plt.gcf() gen = _gen_two_subplots(f=lambda **kwargs: None, fig=fig, ax="test") # On the first yield, no subplot should be added since ax was passed next(gen) @@ -42,7 +41,7 @@ def test__gen_two_subplots_with_ax(self): assert subplot_geometry == [2, 1, 2] def test_colorbar_layout(self): - fig = self.plt.figure() + fig = plt.figure() axes = fig.subplot_mosaic( """ diff --git a/pandas/tests/plotting/test_datetimelike.py b/pandas/tests/plotting/test_datetimelike.py index dacc0cbea7c9e..dda71328d4e6c 100644 --- a/pandas/tests/plotting/test_datetimelike.py +++ b/pandas/tests/plotting/test_datetimelike.py @@ -37,13 +37,14 @@ period_range, ) from pandas.core.indexes.timedeltas import timedelta_range -from pandas.tests.plotting.common import TestPlotBase +from pandas.tests.plotting.common import _check_ticks_props from pandas.tseries.offsets import WeekOfMonth +mpl = pytest.importorskip("matplotlib") -@td.skip_if_no_mpl -class TestTSPlot(TestPlotBase): + +class TestTSPlot: @pytest.mark.filterwarnings("ignore::UserWarning") def test_ts_plot_with_tz(self, tz_aware_fixture): # GH2877, GH17173, GH31205, GH31580 @@ -60,7 +61,7 @@ def test_ts_plot_with_tz(self, tz_aware_fixture): def test_fontsize_set_correctly(self): # For issue #8765 df = DataFrame(np.random.randn(10, 9), index=range(10)) - fig, ax = self.plt.subplots() + fig, ax = mpl.pyplot.subplots() df.plot(fontsize=2, ax=ax) for label in ax.get_xticklabels() + ax.get_yticklabels(): assert label.get_fontsize() == 2 @@ -95,10 +96,10 @@ def test_nonnumeric_exclude(self): idx = date_range("1/1/1987", freq="A", periods=3) df = DataFrame({"A": ["x", "y", "z"], "B": [1, 2, 3]}, idx) - fig, ax = self.plt.subplots() + fig, ax = mpl.pyplot.subplots() df.plot(ax=ax) # it works assert len(ax.get_lines()) == 1 # B was plotted - self.plt.close(fig) + mpl.pyplot.close(fig) msg = "no numeric data to plot" with pytest.raises(TypeError, match=msg): @@ -108,7 +109,7 @@ def test_nonnumeric_exclude(self): def test_tsplot_period(self, freq): idx = period_range("12/31/1999", freq=freq, periods=100) ser = Series(np.random.randn(len(idx)), idx) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() _check_plot_works(ser.plot, ax=ax) @pytest.mark.parametrize( @@ -117,12 +118,12 @@ def test_tsplot_period(self, freq): def test_tsplot_datetime(self, freq): idx = date_range("12/31/1999", freq=freq, periods=100) ser = Series(np.random.randn(len(idx)), idx) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() _check_plot_works(ser.plot, ax=ax) def test_tsplot(self): ts = tm.makeTimeSeries() - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ts.plot(style="k", ax=ax) color = (0.0, 0.0, 0.0, 1) assert color == ax.get_lines()[0].get_color() @@ -143,7 +144,7 @@ def test_both_style_and_color(self): @pytest.mark.parametrize("freq", ["ms", "us"]) def test_high_freq(self, freq): - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() rng = date_range("1/1/2012", periods=100, freq=freq) ser = Series(np.random.randn(len(rng)), rng) _check_plot_works(ser.plot, ax=ax) @@ -164,7 +165,7 @@ def check_format_of_first_point(ax, expected_string): assert expected_string == ax.format_coord(first_x, first_y) annual = Series(1, index=date_range("2014-01-01", periods=3, freq="A-DEC")) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() annual.plot(ax=ax) check_format_of_first_point(ax, "t = 2014 y = 1.000000") @@ -239,7 +240,7 @@ def test_line_plot_inferred_freq(self, freq): _check_plot_works(ser.plot) def test_fake_inferred_business(self): - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() rng = date_range("2001-1-1", "2001-1-10") ts = Series(range(len(rng)), index=rng) ts = concat([ts[:3], ts[5:]]) @@ -266,7 +267,7 @@ def test_uhf(self): idx = date_range("2012-6-22 21:59:51.960928", freq="L", periods=500) df = DataFrame(np.random.randn(len(idx), 2), index=idx) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() df.plot(ax=ax) axis = ax.get_xaxis() @@ -283,14 +284,14 @@ def test_irreg_hf(self): df = DataFrame(np.random.randn(len(idx), 2), index=idx) irreg = df.iloc[[0, 1, 3, 4]] - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() irreg.plot(ax=ax) diffs = Series(ax.get_lines()[0].get_xydata()[:, 0]).diff() sec = 1.0 / 24 / 60 / 60 assert (np.fabs(diffs[1:] - [sec, sec * 2, sec]) < 1e-8).all() - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() df2 = df.copy() df2.index = df.index.astype(object) df2.plot(ax=ax) @@ -301,7 +302,7 @@ def test_irregular_datetime64_repr_bug(self): ser = tm.makeTimeSeries() ser = ser.iloc[[0, 1, 2, 7]] - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ret = ser.plot(ax=ax) assert ret is not None @@ -311,7 +312,7 @@ def test_irregular_datetime64_repr_bug(self): def test_business_freq(self): bts = tm.makePeriodSeries() - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() bts.plot(ax=ax) assert ax.get_lines()[0].get_xydata()[0, 0] == bts.index[0].ordinal idx = ax.get_lines()[0].get_xdata() @@ -320,7 +321,7 @@ def test_business_freq(self): def test_business_freq_convert(self): bts = tm.makeTimeSeries(300).asfreq("BM") ts = bts.to_period("M") - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() bts.plot(ax=ax) assert ax.get_lines()[0].get_xydata()[0, 0] == ts.index[0].ordinal idx = ax.get_lines()[0].get_xdata() @@ -330,7 +331,7 @@ def test_freq_with_no_period_alias(self): # GH34487 freq = WeekOfMonth() bts = tm.makeTimeSeries(5).asfreq(freq) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() bts.plot(ax=ax) idx = ax.get_lines()[0].get_xdata() @@ -342,14 +343,14 @@ def test_nonzero_base(self): # GH2571 idx = date_range("2012-12-20", periods=24, freq="H") + timedelta(minutes=30) df = DataFrame(np.arange(24), index=idx) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() df.plot(ax=ax) rs = ax.get_lines()[0].get_xdata() assert not Index(rs).is_normalized def test_dataframe(self): bts = DataFrame({"a": tm.makeTimeSeries()}) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() bts.plot(ax=ax) idx = ax.get_lines()[0].get_xdata() tm.assert_index_equal(bts.index.to_period(), PeriodIndex(idx)) @@ -376,14 +377,14 @@ def _test(ax): assert int(result[0]) == expected[0].ordinal assert int(result[1]) == expected[1].ordinal fig = ax.get_figure() - self.plt.close(fig) + mpl.pyplot.close(fig) ser = tm.makeTimeSeries() - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ser.plot(ax=ax) _test(ax) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() df = DataFrame({"a": ser, "b": ser + 1}) df.plot(ax=ax) _test(ax) @@ -413,7 +414,7 @@ def test_finder_daily(self): for n in day_lst: rng = bdate_range("1999-1-1", periods=n) ser = Series(np.random.randn(len(rng)), rng) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ser.plot(ax=ax) xaxis = ax.get_xaxis() rs1.append(xaxis.get_majorticklocs()[0]) @@ -421,7 +422,7 @@ def test_finder_daily(self): vmin, vmax = ax.get_xlim() ax.set_xlim(vmin + 0.9, vmax) rs2.append(xaxis.get_majorticklocs()[0]) - self.plt.close(ax.get_figure()) + mpl.pyplot.close(ax.get_figure()) assert rs1 == xpl1 assert rs2 == xpl2 @@ -435,7 +436,7 @@ def test_finder_quarterly(self): for n in yrs: rng = period_range("1987Q2", periods=int(n * 4), freq="Q") ser = Series(np.random.randn(len(rng)), rng) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ser.plot(ax=ax) xaxis = ax.get_xaxis() rs1.append(xaxis.get_majorticklocs()[0]) @@ -443,7 +444,7 @@ def test_finder_quarterly(self): (vmin, vmax) = ax.get_xlim() ax.set_xlim(vmin + 0.9, vmax) rs2.append(xaxis.get_majorticklocs()[0]) - self.plt.close(ax.get_figure()) + mpl.pyplot.close(ax.get_figure()) assert rs1 == xpl1 assert rs2 == xpl2 @@ -457,7 +458,7 @@ def test_finder_monthly(self): for n in yrs: rng = period_range("1987Q2", periods=int(n * 12), freq="M") ser = Series(np.random.randn(len(rng)), rng) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ser.plot(ax=ax) xaxis = ax.get_xaxis() rs1.append(xaxis.get_majorticklocs()[0]) @@ -465,7 +466,7 @@ def test_finder_monthly(self): vmin, vmax = ax.get_xlim() ax.set_xlim(vmin + 0.9, vmax) rs2.append(xaxis.get_majorticklocs()[0]) - self.plt.close(ax.get_figure()) + mpl.pyplot.close(ax.get_figure()) assert rs1 == xpl1 assert rs2 == xpl2 @@ -473,7 +474,7 @@ def test_finder_monthly(self): def test_finder_monthly_long(self): rng = period_range("1988Q1", periods=24 * 12, freq="M") ser = Series(np.random.randn(len(rng)), rng) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ser.plot(ax=ax) xaxis = ax.get_xaxis() rs = xaxis.get_majorticklocs()[0] @@ -487,11 +488,11 @@ def test_finder_annual(self): for nyears in [5, 10, 19, 49, 99, 199, 599, 1001]: rng = period_range("1987", periods=nyears, freq="A") ser = Series(np.random.randn(len(rng)), rng) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ser.plot(ax=ax) xaxis = ax.get_xaxis() rs.append(xaxis.get_majorticklocs()[0]) - self.plt.close(ax.get_figure()) + mpl.pyplot.close(ax.get_figure()) assert rs == xp @@ -500,7 +501,7 @@ def test_finder_minutely(self): nminutes = 50 * 24 * 60 rng = date_range("1/1/1999", freq="Min", periods=nminutes) ser = Series(np.random.randn(len(rng)), rng) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ser.plot(ax=ax) xaxis = ax.get_xaxis() rs = xaxis.get_majorticklocs()[0] @@ -512,7 +513,7 @@ def test_finder_hourly(self): nhours = 23 rng = date_range("1/1/1999", freq="H", periods=nhours) ser = Series(np.random.randn(len(rng)), rng) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ser.plot(ax=ax) xaxis = ax.get_xaxis() rs = xaxis.get_majorticklocs()[0] @@ -523,7 +524,7 @@ def test_finder_hourly(self): def test_gaps(self): ts = tm.makeTimeSeries() ts.iloc[5:25] = np.nan - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ts.plot(ax=ax) lines = ax.get_lines() assert len(lines) == 1 @@ -535,13 +536,13 @@ def test_gaps(self): assert isinstance(data, np.ma.core.MaskedArray) mask = data.mask assert mask[5:25, 1].all() - self.plt.close(ax.get_figure()) + mpl.pyplot.close(ax.get_figure()) # irregular ts = tm.makeTimeSeries() ts = ts.iloc[[0, 1, 2, 5, 7, 9, 12, 15, 20]] ts.iloc[2:5] = np.nan - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = ts.plot(ax=ax) lines = ax.get_lines() assert len(lines) == 1 @@ -553,13 +554,13 @@ def test_gaps(self): assert isinstance(data, np.ma.core.MaskedArray) mask = data.mask assert mask[2:5, 1].all() - self.plt.close(ax.get_figure()) + mpl.pyplot.close(ax.get_figure()) # non-ts idx = [0, 1, 2, 5, 7, 9, 12, 15, 20] ser = Series(np.random.randn(len(idx)), idx) ser.iloc[2:5] = np.nan - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ser.plot(ax=ax) lines = ax.get_lines() assert len(lines) == 1 @@ -574,7 +575,7 @@ def test_gaps(self): def test_gap_upsample(self): low = tm.makeTimeSeries() low.iloc[5:25] = np.nan - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() low.plot(ax=ax) idxh = date_range(low.index[0], low.index[-1], freq="12h") @@ -595,7 +596,7 @@ def test_gap_upsample(self): def test_secondary_y(self): ser = Series(np.random.randn(10)) ser2 = Series(np.random.randn(10)) - fig, _ = self.plt.subplots() + fig, _ = mpl.pyplot.subplots() ax = ser.plot(secondary_y=True) assert hasattr(ax, "left_ax") assert not hasattr(ax, "right_ax") @@ -605,12 +606,12 @@ def test_secondary_y(self): tm.assert_series_equal(ser, xp) assert ax.get_yaxis().get_ticks_position() == "right" assert not axes[0].get_yaxis().get_visible() - self.plt.close(fig) + mpl.pyplot.close(fig) - _, ax2 = self.plt.subplots() + _, ax2 = mpl.pyplot.subplots() ser2.plot(ax=ax2) assert ax2.get_yaxis().get_ticks_position() == "left" - self.plt.close(ax2.get_figure()) + mpl.pyplot.close(ax2.get_figure()) ax = ser2.plot() ax2 = ser.plot(secondary_y=True) @@ -624,7 +625,7 @@ def test_secondary_y_ts(self): idx = date_range("1/1/2000", periods=10) ser = Series(np.random.randn(10), idx) ser2 = Series(np.random.randn(10), idx) - fig, _ = self.plt.subplots() + fig, _ = mpl.pyplot.subplots() ax = ser.plot(secondary_y=True) assert hasattr(ax, "left_ax") assert not hasattr(ax, "right_ax") @@ -634,12 +635,12 @@ def test_secondary_y_ts(self): tm.assert_series_equal(ser, xp) assert ax.get_yaxis().get_ticks_position() == "right" assert not axes[0].get_yaxis().get_visible() - self.plt.close(fig) + mpl.pyplot.close(fig) - _, ax2 = self.plt.subplots() + _, ax2 = mpl.pyplot.subplots() ser2.plot(ax=ax2) assert ax2.get_yaxis().get_ticks_position() == "left" - self.plt.close(ax2.get_figure()) + mpl.pyplot.close(ax2.get_figure()) ax = ser2.plot() ax2 = ser.plot(secondary_y=True) @@ -648,7 +649,7 @@ def test_secondary_y_ts(self): @td.skip_if_no_scipy def test_secondary_kde(self): ser = Series(np.random.randn(10)) - fig, ax = self.plt.subplots() + fig, ax = mpl.pyplot.subplots() ax = ser.plot(secondary_y=True, kind="density", ax=ax) assert hasattr(ax, "left_ax") assert not hasattr(ax, "right_ax") @@ -657,7 +658,7 @@ def test_secondary_kde(self): def test_secondary_bar(self): ser = Series(np.random.randn(10)) - fig, ax = self.plt.subplots() + fig, ax = mpl.pyplot.subplots() ser.plot(secondary_y=True, kind="bar", ax=ax) axes = fig.get_axes() assert axes[1].get_yaxis().get_ticks_position() == "right" @@ -682,7 +683,7 @@ def test_mixed_freq_regular_first(self): s2 = s1.iloc[[0, 5, 10, 11, 12, 13, 14, 15]] # it works! - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() s1.plot(ax=ax) ax2 = s2.plot(style="g", ax=ax) @@ -701,7 +702,7 @@ def test_mixed_freq_regular_first(self): def test_mixed_freq_irregular_first(self): s1 = tm.makeTimeSeries() s2 = s1.iloc[[0, 5, 10, 11, 12, 13, 14, 15]] - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() s2.plot(style="g", ax=ax) s1.plot(ax=ax) assert not hasattr(ax, "freq") @@ -715,7 +716,7 @@ def test_mixed_freq_regular_first_df(self): # GH 9852 s1 = tm.makeTimeSeries().to_frame() s2 = s1.iloc[[0, 5, 10, 11, 12, 13, 14, 15], :] - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() s1.plot(ax=ax) ax2 = s2.plot(style="g", ax=ax) lines = ax2.get_lines() @@ -732,7 +733,7 @@ def test_mixed_freq_irregular_first_df(self): # GH 9852 s1 = tm.makeTimeSeries().to_frame() s2 = s1.iloc[[0, 5, 10, 11, 12, 13, 14, 15], :] - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() s2.plot(style="g", ax=ax) s1.plot(ax=ax) assert not hasattr(ax, "freq") @@ -747,7 +748,7 @@ def test_mixed_freq_hf_first(self): idxl = date_range("1/1/1999", periods=12, freq="M") high = Series(np.random.randn(len(idxh)), idxh) low = Series(np.random.randn(len(idxl)), idxl) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() high.plot(ax=ax) low.plot(ax=ax) for line in ax.get_lines(): @@ -760,7 +761,7 @@ def test_mixed_freq_alignment(self): ts = Series(ts_data, index=ts_ind) ts2 = ts.asfreq("T").interpolate() - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = ts.plot(ax=ax) ts2.plot(style="r", ax=ax) @@ -771,20 +772,20 @@ def test_mixed_freq_lf_first(self): idxl = date_range("1/1/1999", periods=12, freq="M") high = Series(np.random.randn(len(idxh)), idxh) low = Series(np.random.randn(len(idxl)), idxl) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() low.plot(legend=True, ax=ax) high.plot(legend=True, ax=ax) for line in ax.get_lines(): assert PeriodIndex(data=line.get_xdata()).freq == "D" leg = ax.get_legend() assert len(leg.texts) == 2 - self.plt.close(ax.get_figure()) + mpl.pyplot.close(ax.get_figure()) idxh = date_range("1/1/1999", periods=240, freq="T") idxl = date_range("1/1/1999", periods=4, freq="H") high = Series(np.random.randn(len(idxh)), idxh) low = Series(np.random.randn(len(idxl)), idxl) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() low.plot(ax=ax) high.plot(ax=ax) for line in ax.get_lines(): @@ -795,7 +796,7 @@ def test_mixed_freq_irreg_period(self): irreg = ts.iloc[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 16, 17, 18, 29]] rng = period_range("1/3/2000", periods=30, freq="B") ps = Series(np.random.randn(len(rng)), rng) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() irreg.plot(ax=ax) ps.plot(ax=ax) @@ -806,7 +807,7 @@ def test_mixed_freq_shared_ax(self): s1 = Series(range(len(idx1)), idx1) s2 = Series(range(len(idx2)), idx2) - fig, (ax1, ax2) = self.plt.subplots(nrows=2, sharex=True) + fig, (ax1, ax2) = mpl.pyplot.subplots(nrows=2, sharex=True) s1.plot(ax=ax1) s2.plot(ax=ax2) @@ -815,7 +816,7 @@ def test_mixed_freq_shared_ax(self): assert ax1.lines[0].get_xydata()[0, 0] == ax2.lines[0].get_xydata()[0, 0] # using twinx - fig, ax1 = self.plt.subplots() + fig, ax1 = mpl.pyplot.subplots() ax2 = ax1.twinx() s1.plot(ax=ax1) s2.plot(ax=ax2) @@ -832,7 +833,7 @@ def test_mixed_freq_shared_ax(self): # ax2.lines[0].get_xydata()[0, 0]) def test_nat_handling(self): - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() dti = DatetimeIndex(["2015-01-01", NaT, "2015-01-03"]) s = Series(range(len(dti)), dti) @@ -847,7 +848,7 @@ def test_to_weekly_resampling(self): idxl = date_range("1/1/1999", periods=12, freq="M") high = Series(np.random.randn(len(idxh)), idxh) low = Series(np.random.randn(len(idxl)), idxl) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() high.plot(ax=ax) low.plot(ax=ax) for line in ax.get_lines(): @@ -858,7 +859,7 @@ def test_from_weekly_resampling(self): idxl = date_range("1/1/1999", periods=12, freq="M") high = Series(np.random.randn(len(idxh)), idxh) low = Series(np.random.randn(len(idxl)), idxl) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() low.plot(ax=ax) high.plot(ax=ax) @@ -884,7 +885,7 @@ def test_from_resampling_area_line_mixed(self): # low to high for kind1, kind2 in [("line", "area"), ("area", "line")]: - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() low.plot(kind=kind1, stacked=True, ax=ax) high.plot(kind=kind2, stacked=True, ax=ax) @@ -927,7 +928,7 @@ def test_from_resampling_area_line_mixed(self): # high to low for kind1, kind2 in [("line", "area"), ("area", "line")]: - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() high.plot(kind=kind1, stacked=True, ax=ax) low.plot(kind=kind2, stacked=True, ax=ax) @@ -974,7 +975,7 @@ def test_mixed_freq_second_millisecond(self): high = Series(np.random.randn(len(idxh)), idxh) low = Series(np.random.randn(len(idxl)), idxl) # high to low - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() high.plot(ax=ax) low.plot(ax=ax) assert len(ax.get_lines()) == 2 @@ -983,7 +984,7 @@ def test_mixed_freq_second_millisecond(self): tm.close() # low to high - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() low.plot(ax=ax) high.plot(ax=ax) assert len(ax.get_lines()) == 2 @@ -1000,7 +1001,7 @@ def test_irreg_dtypes(self): idx = date_range("1/1/2000", periods=10) idx = idx[[0, 2, 5, 9]].astype(object) df = DataFrame(np.random.randn(len(idx), 3), idx) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() _check_plot_works(df.plot, ax=ax) def test_time(self): @@ -1010,7 +1011,7 @@ def test_time(self): df = DataFrame( {"a": np.random.randn(len(ts)), "b": np.random.randn(len(ts))}, index=ts ) - fig, ax = self.plt.subplots() + fig, ax = mpl.pyplot.subplots() df.plot(ax=ax) # verify tick labels @@ -1034,7 +1035,7 @@ def test_time_change_xlim(self): df = DataFrame( {"a": np.random.randn(len(ts)), "b": np.random.randn(len(ts))}, index=ts ) - fig, ax = self.plt.subplots() + fig, ax = mpl.pyplot.subplots() df.plot(ax=ax) # verify tick labels @@ -1075,7 +1076,7 @@ def test_time_musec(self): df = DataFrame( {"a": np.random.randn(len(ts)), "b": np.random.randn(len(ts))}, index=ts ) - fig, ax = self.plt.subplots() + fig, ax = mpl.pyplot.subplots() ax = df.plot(ax=ax) # verify tick labels @@ -1104,7 +1105,7 @@ def test_secondary_upsample(self): idxl = date_range("1/1/1999", periods=12, freq="M") high = Series(np.random.randn(len(idxh)), idxh) low = Series(np.random.randn(len(idxl)), idxl) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() low.plot(ax=ax) ax = high.plot(secondary_y=True, ax=ax) for line in ax.get_lines(): @@ -1115,7 +1116,7 @@ def test_secondary_upsample(self): assert PeriodIndex(line.get_xdata()).freq == "D" def test_secondary_legend(self): - fig = self.plt.figure() + fig = mpl.pyplot.figure() ax = fig.add_subplot(211) # ts @@ -1134,9 +1135,9 @@ def test_secondary_legend(self): # TODO: color cycle problems assert len(colors) == 4 - self.plt.close(fig) + mpl.pyplot.close(fig) - fig = self.plt.figure() + fig = mpl.pyplot.figure() ax = fig.add_subplot(211) df.plot(secondary_y=["A", "C"], mark_right=False, ax=ax) leg = ax.get_legend() @@ -1145,23 +1146,23 @@ def test_secondary_legend(self): assert leg.get_texts()[1].get_text() == "B" assert leg.get_texts()[2].get_text() == "C" assert leg.get_texts()[3].get_text() == "D" - self.plt.close(fig) + mpl.pyplot.close(fig) - fig, ax = self.plt.subplots() + fig, ax = mpl.pyplot.subplots() df.plot(kind="bar", secondary_y=["A"], ax=ax) leg = ax.get_legend() assert leg.get_texts()[0].get_text() == "A (right)" assert leg.get_texts()[1].get_text() == "B" - self.plt.close(fig) + mpl.pyplot.close(fig) - fig, ax = self.plt.subplots() + fig, ax = mpl.pyplot.subplots() df.plot(kind="bar", secondary_y=["A"], mark_right=False, ax=ax) leg = ax.get_legend() assert leg.get_texts()[0].get_text() == "A" assert leg.get_texts()[1].get_text() == "B" - self.plt.close(fig) + mpl.pyplot.close(fig) - fig = self.plt.figure() + fig = mpl.pyplot.figure() ax = fig.add_subplot(211) df = tm.makeTimeDataFrame() ax = df.plot(secondary_y=["C", "D"], ax=ax) @@ -1174,11 +1175,11 @@ def test_secondary_legend(self): # TODO: color cycle problems assert len(colors) == 4 - self.plt.close(fig) + mpl.pyplot.close(fig) # non-ts df = tm.makeDataFrame() - fig = self.plt.figure() + fig = mpl.pyplot.figure() ax = fig.add_subplot(211) ax = df.plot(secondary_y=["A", "B"], ax=ax) leg = ax.get_legend() @@ -1190,9 +1191,9 @@ def test_secondary_legend(self): # TODO: color cycle problems assert len(colors) == 4 - self.plt.close() + mpl.pyplot.close() - fig = self.plt.figure() + fig = mpl.pyplot.figure() ax = fig.add_subplot(211) ax = df.plot(secondary_y=["C", "D"], ax=ax) leg = ax.get_legend() @@ -1209,7 +1210,7 @@ def test_secondary_legend(self): def test_format_date_axis(self): rng = date_range("1/1/2012", periods=12, freq="M") df = DataFrame(np.random.randn(len(rng), 3), rng) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = df.plot(ax=ax) xaxis = ax.get_xaxis() for line in xaxis.get_ticklabels(): @@ -1219,7 +1220,7 @@ def test_format_date_axis(self): def test_ax_plot(self): x = date_range(start="2012-01-02", periods=10, freq="D") y = list(range(len(x))) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() lines = ax.plot(x, y, label="Y") tm.assert_index_equal(DatetimeIndex(lines[0].get_xdata()), x) @@ -1230,7 +1231,7 @@ def test_mpl_nopandas(self): kw = {"fmt": "-", "lw": 4} - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax.plot_date([x.toordinal() for x in dates], values1, **kw) ax.plot_date([x.toordinal() for x in dates], values2, **kw) @@ -1249,7 +1250,7 @@ def test_irregular_ts_shared_ax_xlim(self): ts_irregular = ts.iloc[[1, 4, 5, 6, 8, 9, 10, 12, 13, 14, 15, 17, 18]] # plot the left section of the irregular series, then the right section - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ts_irregular[:5].plot(ax=ax) ts_irregular[5:].plot(ax=ax) @@ -1265,7 +1266,7 @@ def test_secondary_y_non_ts_xlim(self): s1 = Series(1, index=index_1) s2 = Series(2, index=index_2) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() s1.plot(ax=ax) left_before, right_before = ax.get_xlim() s2.plot(secondary_y=True, ax=ax) @@ -1281,7 +1282,7 @@ def test_secondary_y_regular_ts_xlim(self): s1 = Series(1, index=index_1) s2 = Series(2, index=index_2) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() s1.plot(ax=ax) left_before, right_before = ax.get_xlim() s2.plot(secondary_y=True, ax=ax) @@ -1295,7 +1296,7 @@ def test_secondary_y_mixed_freq_ts_xlim(self): rng = date_range("2000-01-01", periods=10000, freq="min") ts = Series(1, index=rng) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ts.plot(ax=ax) left_before, right_before = ax.get_xlim() ts.resample("D").mean().plot(secondary_y=True, ax=ax) @@ -1312,7 +1313,7 @@ def test_secondary_y_irregular_ts_xlim(self): ts = tm.makeTimeSeries()[:20] ts_irregular = ts.iloc[[1, 4, 5, 6, 8, 9, 10, 12, 13, 14, 15, 17, 18]] - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ts_irregular[:5].plot(ax=ax) # plot higher-x values on secondary axis ts_irregular[5:].plot(secondary_y=True, ax=ax) @@ -1326,7 +1327,7 @@ def test_secondary_y_irregular_ts_xlim(self): def test_plot_outofbounds_datetime(self): # 2579 - checking this does not raise values = [date(1677, 1, 1), date(1677, 1, 2)] - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax.plot(values) values = [datetime(1677, 1, 1, 12), datetime(1677, 1, 2, 12)] @@ -1337,9 +1338,9 @@ def test_format_timedelta_ticks_narrow(self): rng = timedelta_range("0", periods=10, freq="ns") df = DataFrame(np.random.randn(len(rng), 3), rng) - fig, ax = self.plt.subplots() + fig, ax = mpl.pyplot.subplots() df.plot(fontsize=2, ax=ax) - self.plt.draw() + mpl.pyplot.draw() labels = ax.get_xticklabels() result_labels = [x.get_text() for x in labels] @@ -1361,9 +1362,9 @@ def test_format_timedelta_ticks_wide(self): rng = timedelta_range("0", periods=10, freq="1 d") df = DataFrame(np.random.randn(len(rng), 3), rng) - fig, ax = self.plt.subplots() + fig, ax = mpl.pyplot.subplots() ax = df.plot(fontsize=2, ax=ax) - self.plt.draw() + mpl.pyplot.draw() labels = ax.get_xticklabels() result_labels = [x.get_text() for x in labels] @@ -1373,19 +1374,19 @@ def test_format_timedelta_ticks_wide(self): def test_timedelta_plot(self): # test issue #8711 s = Series(range(5), timedelta_range("1day", periods=5)) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() _check_plot_works(s.plot, ax=ax) # test long period index = timedelta_range("1 day 2 hr 30 min 10 s", periods=10, freq="1 d") s = Series(np.random.randn(len(index)), index) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() _check_plot_works(s.plot, ax=ax) # test short period index = timedelta_range("1 day 2 hr 30 min 10 s", periods=10, freq="1 ns") s = Series(np.random.randn(len(index)), index) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() _check_plot_works(s.plot, ax=ax) def test_hist(self): @@ -1394,7 +1395,7 @@ def test_hist(self): x = rng w1 = np.arange(0, 1, 0.1) w2 = np.arange(0, 1, 0.1)[::-1] - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax.hist([x, x], weights=[w1, w2]) def test_overlapping_datetime(self): @@ -1418,7 +1419,7 @@ def test_overlapping_datetime(self): # plot first series, then add the second series to those axes, # then try adding the first series again - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() s1.plot(ax=ax) s2.plot(ax=ax) s1.plot(ax=ax) @@ -1440,9 +1441,9 @@ def test_matplotlib_scatter_datetime64(self): # https://github.com/matplotlib/matplotlib/issues/11391 df = DataFrame(np.random.RandomState(0).rand(10, 2), columns=["x", "y"]) df["time"] = date_range("2018-01-01", periods=10, freq="D") - fig, ax = self.plt.subplots() + fig, ax = mpl.pyplot.subplots() ax.scatter(x="time", y="y", data=df) - self.plt.draw() + mpl.pyplot.draw() label = ax.get_xticklabels()[0] expected = "2018-01-01" assert label.get_text() == expected @@ -1453,25 +1454,25 @@ def test_check_xticks_rot(self): x = to_datetime(["2020-05-01", "2020-05-02", "2020-05-03"]) df = DataFrame({"x": x, "y": [1, 2, 3]}) axes = df.plot(x="x", y="y") - self._check_ticks_props(axes, xrot=0) + _check_ticks_props(axes, xrot=0) # irregular time series x = to_datetime(["2020-05-01", "2020-05-02", "2020-05-04"]) df = DataFrame({"x": x, "y": [1, 2, 3]}) axes = df.plot(x="x", y="y") - self._check_ticks_props(axes, xrot=30) + _check_ticks_props(axes, xrot=30) # use timeseries index or not axes = df.set_index("x").plot(y="y", use_index=True) - self._check_ticks_props(axes, xrot=30) + _check_ticks_props(axes, xrot=30) axes = df.set_index("x").plot(y="y", use_index=False) - self._check_ticks_props(axes, xrot=0) + _check_ticks_props(axes, xrot=0) # separate subplots axes = df.plot(x="x", y="y", subplots=True, sharex=True) - self._check_ticks_props(axes, xrot=30) + _check_ticks_props(axes, xrot=30) axes = df.plot(x="x", y="y", subplots=True, sharex=False) - self._check_ticks_props(axes, xrot=0) + _check_ticks_props(axes, xrot=0) def _check_plot_works(f, freq=None, series=None, *args, **kwargs): diff --git a/pandas/tests/plotting/test_groupby.py b/pandas/tests/plotting/test_groupby.py index 8cde3062d09f9..43e35e94164c3 100644 --- a/pandas/tests/plotting/test_groupby.py +++ b/pandas/tests/plotting/test_groupby.py @@ -4,19 +4,21 @@ import numpy as np import pytest -import pandas.util._test_decorators as td - from pandas import ( DataFrame, Index, Series, ) import pandas._testing as tm -from pandas.tests.plotting.common import TestPlotBase +from pandas.tests.plotting.common import ( + _check_axes_shape, + _check_legend_labels, +) + +pytest.importorskip("matplotlib") -@td.skip_if_no_mpl -class TestDataFrameGroupByPlots(TestPlotBase): +class TestDataFrameGroupByPlots: def test_series_groupby_plotting_nominally_works(self): n = 10 weight = Series(np.random.normal(166, 20, size=n)) @@ -80,11 +82,9 @@ def test_groupby_hist_frame_with_legend(self, column, expected_axes_num): g = df.groupby("c") for axes in g.hist(legend=True, column=column): - self._check_axes_shape( - axes, axes_num=expected_axes_num, layout=expected_layout - ) + _check_axes_shape(axes, axes_num=expected_axes_num, layout=expected_layout) for ax, expected_label in zip(axes[0], expected_labels): - self._check_legend_labels(ax, expected_label) + _check_legend_labels(ax, expected_label) @pytest.mark.parametrize("column", [None, "b"]) def test_groupby_hist_frame_with_legend_raises(self, column): @@ -103,8 +103,8 @@ def test_groupby_hist_series_with_legend(self): g = df.groupby("c") for ax in g["a"].hist(legend=True): - self._check_axes_shape(ax, axes_num=1, layout=(1, 1)) - self._check_legend_labels(ax, ["1", "2"]) + _check_axes_shape(ax, axes_num=1, layout=(1, 1)) + _check_legend_labels(ax, ["1", "2"]) def test_groupby_hist_series_with_legend_raises(self): # GH 6279 - SeriesGroupBy histogram with legend and label raises diff --git a/pandas/tests/plotting/test_hist_method.py b/pandas/tests/plotting/test_hist_method.py index 3392c309e0329..d798ac9a88085 100644 --- a/pandas/tests/plotting/test_hist_method.py +++ b/pandas/tests/plotting/test_hist_method.py @@ -14,18 +14,27 @@ ) import pandas._testing as tm from pandas.tests.plotting.common import ( - TestPlotBase, + _check_ax_scales, + _check_axes_shape, + _check_colors, + _check_legend_labels, + _check_patches_all_filled, _check_plot_works, + _check_text_labels, + _check_ticks_props, + get_x_axis, + get_y_axis, ) +mpl = pytest.importorskip("matplotlib") + @pytest.fixture def ts(): return tm.makeTimeSeries(name="ts") -@td.skip_if_no_mpl -class TestSeriesPlots(TestPlotBase): +class TestSeriesPlots: def test_hist_legacy(self, ts): _check_plot_works(ts.hist) _check_plot_works(ts.hist, grid=False) @@ -36,13 +45,13 @@ def test_hist_legacy(self, ts): with tm.assert_produces_warning(UserWarning, check_stacklevel=False): _check_plot_works(ts.hist, by=ts.index.month, bins=5) - fig, ax = self.plt.subplots(1, 1) + fig, ax = mpl.pyplot.subplots(1, 1) _check_plot_works(ts.hist, ax=ax, default_axes=True) _check_plot_works(ts.hist, ax=ax, figure=fig, default_axes=True) _check_plot_works(ts.hist, figure=fig, default_axes=True) tm.close() - fig, (ax1, ax2) = self.plt.subplots(1, 2) + fig, (ax1, ax2) = mpl.pyplot.subplots(1, 2) _check_plot_works(ts.hist, figure=fig, ax=ax1, default_axes=True) _check_plot_works(ts.hist, figure=fig, ax=ax2, default_axes=True) @@ -76,34 +85,34 @@ def test_hist_layout_with_by(self, hist_df): # though we don't explicing pass one, see GH #13188 with tm.assert_produces_warning(UserWarning, check_stacklevel=False): axes = _check_plot_works(df.height.hist, by=df.gender, layout=(2, 1)) - self._check_axes_shape(axes, axes_num=2, layout=(2, 1)) + _check_axes_shape(axes, axes_num=2, layout=(2, 1)) with tm.assert_produces_warning(UserWarning, check_stacklevel=False): axes = _check_plot_works(df.height.hist, by=df.gender, layout=(3, -1)) - self._check_axes_shape(axes, axes_num=2, layout=(3, 1)) + _check_axes_shape(axes, axes_num=2, layout=(3, 1)) with tm.assert_produces_warning(UserWarning, check_stacklevel=False): axes = _check_plot_works(df.height.hist, by=df.category, layout=(4, 1)) - self._check_axes_shape(axes, axes_num=4, layout=(4, 1)) + _check_axes_shape(axes, axes_num=4, layout=(4, 1)) with tm.assert_produces_warning(UserWarning, check_stacklevel=False): axes = _check_plot_works(df.height.hist, by=df.category, layout=(2, -1)) - self._check_axes_shape(axes, axes_num=4, layout=(2, 2)) + _check_axes_shape(axes, axes_num=4, layout=(2, 2)) with tm.assert_produces_warning(UserWarning, check_stacklevel=False): axes = _check_plot_works(df.height.hist, by=df.category, layout=(3, -1)) - self._check_axes_shape(axes, axes_num=4, layout=(3, 2)) + _check_axes_shape(axes, axes_num=4, layout=(3, 2)) with tm.assert_produces_warning(UserWarning, check_stacklevel=False): axes = _check_plot_works(df.height.hist, by=df.category, layout=(-1, 4)) - self._check_axes_shape(axes, axes_num=4, layout=(1, 4)) + _check_axes_shape(axes, axes_num=4, layout=(1, 4)) with tm.assert_produces_warning(UserWarning, check_stacklevel=False): axes = _check_plot_works(df.height.hist, by=df.classroom, layout=(2, 2)) - self._check_axes_shape(axes, axes_num=3, layout=(2, 2)) + _check_axes_shape(axes, axes_num=3, layout=(2, 2)) axes = df.height.hist(by=df.category, layout=(4, 2), figsize=(12, 7)) - self._check_axes_shape(axes, axes_num=4, layout=(4, 2), figsize=(12, 7)) + _check_axes_shape(axes, axes_num=4, layout=(4, 2), figsize=(12, 7)) def test_hist_no_overlap(self): from matplotlib.pyplot import ( @@ -124,7 +133,7 @@ def test_hist_no_overlap(self): def test_hist_by_no_extra_plots(self, hist_df): df = hist_df df.height.hist(by=df.gender) - assert len(self.plt.get_fignums()) == 1 + assert len(mpl.pyplot.get_fignums()) == 1 def test_plot_fails_when_ax_differs_from_figure(self, ts): from pylab import figure @@ -149,7 +158,7 @@ def test_histtype_argument(self, histtype, expected): # GH23992 Verify functioning of histtype argument ser = Series(np.random.randint(1, 10)) ax = ser.hist(histtype=histtype) - self._check_patches_all_filled(ax, filled=expected) + _check_patches_all_filled(ax, filled=expected) @pytest.mark.parametrize( "by, expected_axes_num, expected_layout", [(None, 1, (1, 1)), ("b", 2, (1, 2))] @@ -162,8 +171,8 @@ def test_hist_with_legend(self, by, expected_axes_num, expected_layout): # Use default_axes=True when plotting method generate subplots itself axes = _check_plot_works(s.hist, default_axes=True, legend=True, by=by) - self._check_axes_shape(axes, axes_num=expected_axes_num, layout=expected_layout) - self._check_legend_labels(axes, "a") + _check_axes_shape(axes, axes_num=expected_axes_num, layout=expected_layout) + _check_legend_labels(axes, "a") @pytest.mark.parametrize("by", [None, "b"]) def test_hist_with_legend_raises(self, by): @@ -176,61 +185,60 @@ def test_hist_with_legend_raises(self, by): s.hist(legend=True, by=by, label="c") def test_hist_kwargs(self, ts): - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = ts.plot.hist(bins=5, ax=ax) assert len(ax.patches) == 5 - self._check_text_labels(ax.yaxis.get_label(), "Frequency") + _check_text_labels(ax.yaxis.get_label(), "Frequency") tm.close() - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = ts.plot.hist(orientation="horizontal", ax=ax) - self._check_text_labels(ax.xaxis.get_label(), "Frequency") + _check_text_labels(ax.xaxis.get_label(), "Frequency") tm.close() - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = ts.plot.hist(align="left", stacked=True, ax=ax) tm.close() @pytest.mark.xfail(reason="Api changed in 3.6.0") @td.skip_if_no_scipy def test_hist_kde(self, ts): - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = ts.plot.hist(logy=True, ax=ax) - self._check_ax_scales(ax, yaxis="log") + _check_ax_scales(ax, yaxis="log") xlabels = ax.get_xticklabels() # ticks are values, thus ticklabels are blank - self._check_text_labels(xlabels, [""] * len(xlabels)) + _check_text_labels(xlabels, [""] * len(xlabels)) ylabels = ax.get_yticklabels() - self._check_text_labels(ylabels, [""] * len(ylabels)) + _check_text_labels(ylabels, [""] * len(ylabels)) _check_plot_works(ts.plot.kde) _check_plot_works(ts.plot.density) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = ts.plot.kde(logy=True, ax=ax) - self._check_ax_scales(ax, yaxis="log") + _check_ax_scales(ax, yaxis="log") xlabels = ax.get_xticklabels() - self._check_text_labels(xlabels, [""] * len(xlabels)) + _check_text_labels(xlabels, [""] * len(xlabels)) ylabels = ax.get_yticklabels() - self._check_text_labels(ylabels, [""] * len(ylabels)) + _check_text_labels(ylabels, [""] * len(ylabels)) @td.skip_if_no_scipy def test_hist_kde_color(self, ts): - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = ts.plot.hist(logy=True, bins=10, color="b", ax=ax) - self._check_ax_scales(ax, yaxis="log") + _check_ax_scales(ax, yaxis="log") assert len(ax.patches) == 10 - self._check_colors(ax.patches, facecolors=["b"] * 10) + _check_colors(ax.patches, facecolors=["b"] * 10) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = ts.plot.kde(logy=True, color="r", ax=ax) - self._check_ax_scales(ax, yaxis="log") + _check_ax_scales(ax, yaxis="log") lines = ax.get_lines() assert len(lines) == 1 - self._check_colors(lines, ["r"]) + _check_colors(lines, ["r"]) -@td.skip_if_no_mpl -class TestDataFramePlots(TestPlotBase): +class TestDataFramePlots: @pytest.mark.slow def test_hist_df_legacy(self, hist_df): from matplotlib.patches import Rectangle @@ -250,7 +258,7 @@ def test_hist_df_legacy(self, hist_df): ) with tm.assert_produces_warning(UserWarning, check_stacklevel=False): axes = _check_plot_works(df.hist, grid=False) - self._check_axes_shape(axes, axes_num=3, layout=(2, 2)) + _check_axes_shape(axes, axes_num=3, layout=(2, 2)) assert not axes[1, 1].get_visible() _check_plot_works(df[[2]].hist) @@ -269,7 +277,7 @@ def test_hist_df_legacy(self, hist_df): ) with tm.assert_produces_warning(UserWarning, check_stacklevel=False): axes = _check_plot_works(df.hist, layout=(4, 2)) - self._check_axes_shape(axes, axes_num=6, layout=(4, 2)) + _check_axes_shape(axes, axes_num=6, layout=(4, 2)) # make sure sharex, sharey is handled with tm.assert_produces_warning(UserWarning, check_stacklevel=False): @@ -288,16 +296,12 @@ def test_hist_df_legacy(self, hist_df): xf, yf = 20, 18 xrot, yrot = 30, 40 axes = ser.hist(xlabelsize=xf, xrot=xrot, ylabelsize=yf, yrot=yrot) - self._check_ticks_props( - axes, xlabelsize=xf, xrot=xrot, ylabelsize=yf, yrot=yrot - ) + _check_ticks_props(axes, xlabelsize=xf, xrot=xrot, ylabelsize=yf, yrot=yrot) xf, yf = 20, 18 xrot, yrot = 30, 40 axes = df.hist(xlabelsize=xf, xrot=xrot, ylabelsize=yf, yrot=yrot) - self._check_ticks_props( - axes, xlabelsize=xf, xrot=xrot, ylabelsize=yf, yrot=yrot - ) + _check_ticks_props(axes, xlabelsize=xf, xrot=xrot, ylabelsize=yf, yrot=yrot) tm.close() @@ -309,7 +313,7 @@ def test_hist_df_legacy(self, hist_df): tm.close() ax = ser.hist(log=True) # scale of y must be 'log' - self._check_ax_scales(ax, yaxis="log") + _check_ax_scales(ax, yaxis="log") tm.close() @@ -368,7 +372,7 @@ def test_hist_layout(self): for layout_test in layout_to_expected_size: axes = df.hist(layout=layout_test["layout"]) expected = layout_test["expected_size"] - self._check_axes_shape(axes, axes_num=3, layout=expected) + _check_axes_shape(axes, axes_num=3, layout=expected) # layout too small for all 4 plots msg = "Layout of 1x1 must be larger than required size 3" @@ -396,7 +400,7 @@ def test_tight_layout(self): ) # Use default_axes=True when plotting method generate subplots itself _check_plot_works(df.hist, default_axes=True) - self.plt.tight_layout() + mpl.pyplot.tight_layout() tm.close() @@ -417,7 +421,7 @@ def test_hist_subplot_xrot(self): bins=5, xrot=0, ) - self._check_ticks_props(axes, xrot=0) + _check_ticks_props(axes, xrot=0) @pytest.mark.parametrize( "column, expected", @@ -461,7 +465,7 @@ def test_histtype_argument(self, histtype, expected): # GH23992 Verify functioning of histtype argument df = DataFrame(np.random.randint(1, 10, size=(100, 2)), columns=["a", "b"]) ax = df.hist(histtype=histtype) - self._check_patches_all_filled(ax, filled=expected) + _check_patches_all_filled(ax, filled=expected) @pytest.mark.parametrize("by", [None, "c"]) @pytest.mark.parametrize("column", [None, "b"]) @@ -485,11 +489,11 @@ def test_hist_with_legend(self, by, column): column=column, ) - self._check_axes_shape(axes, axes_num=expected_axes_num, layout=expected_layout) + _check_axes_shape(axes, axes_num=expected_axes_num, layout=expected_layout) if by is None and column is None: axes = axes[0] for expected_label, ax in zip(expected_labels, axes): - self._check_legend_labels(ax, expected_label) + _check_legend_labels(ax, expected_label) @pytest.mark.parametrize("by", [None, "c"]) @pytest.mark.parametrize("column", [None, "b"]) @@ -503,7 +507,7 @@ def test_hist_with_legend_raises(self, by, column): def test_hist_df_kwargs(self): df = DataFrame(np.random.randn(10, 2)) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = df.plot.hist(bins=5, ax=ax) assert len(ax.patches) == 10 @@ -513,11 +517,11 @@ def test_hist_df_with_nonnumerics(self): np.random.RandomState(42).randn(10, 4), columns=["A", "B", "C", "D"] ) df["E"] = ["x", "y"] * 5 - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = df.plot.hist(bins=5, ax=ax) assert len(ax.patches) == 20 - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = df.plot.hist(ax=ax) # bins=10 assert len(ax.patches) == 40 @@ -526,35 +530,35 @@ def test_hist_secondary_legend(self): df = DataFrame(np.random.randn(30, 4), columns=list("abcd")) # primary -> secondary - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = df["a"].plot.hist(legend=True, ax=ax) df["b"].plot.hist(ax=ax, legend=True, secondary_y=True) # both legends are drawn on left ax # left and right axis must be visible - self._check_legend_labels(ax, labels=["a", "b (right)"]) + _check_legend_labels(ax, labels=["a", "b (right)"]) assert ax.get_yaxis().get_visible() assert ax.right_ax.get_yaxis().get_visible() tm.close() # secondary -> secondary - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = df["a"].plot.hist(legend=True, secondary_y=True, ax=ax) df["b"].plot.hist(ax=ax, legend=True, secondary_y=True) # both legends are draw on left ax # left axis must be invisible, right axis must be visible - self._check_legend_labels(ax.left_ax, labels=["a (right)", "b (right)"]) + _check_legend_labels(ax.left_ax, labels=["a (right)", "b (right)"]) assert not ax.left_ax.get_yaxis().get_visible() assert ax.get_yaxis().get_visible() tm.close() # secondary -> primary - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = df["a"].plot.hist(legend=True, secondary_y=True, ax=ax) # right axes is returned df["b"].plot.hist(ax=ax, legend=True) # both legends are draw on left ax # left and right axis must be visible - self._check_legend_labels(ax.left_ax, labels=["a (right)", "b"]) + _check_legend_labels(ax.left_ax, labels=["a (right)", "b"]) assert ax.left_ax.get_yaxis().get_visible() assert ax.get_yaxis().get_visible() tm.close() @@ -572,11 +576,11 @@ def test_hist_with_nans_and_weights(self): from matplotlib.patches import Rectangle - _, ax0 = self.plt.subplots() + _, ax0 = mpl.pyplot.subplots() df.plot.hist(ax=ax0, weights=weights) rects = [x for x in ax0.get_children() if isinstance(x, Rectangle)] heights = [rect.get_height() for rect in rects] - _, ax1 = self.plt.subplots() + _, ax1 = mpl.pyplot.subplots() no_nan_df.plot.hist(ax=ax1, weights=no_nan_weights) no_nan_rects = [x for x in ax1.get_children() if isinstance(x, Rectangle)] no_nan_heights = [rect.get_height() for rect in no_nan_rects] @@ -586,12 +590,11 @@ def test_hist_with_nans_and_weights(self): msg = "weights must have the same shape as data, or be a single column" with pytest.raises(ValueError, match=msg): - _, ax2 = self.plt.subplots() + _, ax2 = mpl.pyplot.subplots() no_nan_df.plot.hist(ax=ax2, weights=idxerror_weights) -@td.skip_if_no_mpl -class TestDataFrameGroupByPlots(TestPlotBase): +class TestDataFrameGroupByPlots: def test_grouped_hist_legacy(self): from matplotlib.patches import Rectangle @@ -610,17 +613,17 @@ def test_grouped_hist_legacy(self): df["D"] = ["X"] * 500 axes = _grouped_hist(df.A, by=df.C) - self._check_axes_shape(axes, axes_num=4, layout=(2, 2)) + _check_axes_shape(axes, axes_num=4, layout=(2, 2)) tm.close() axes = df.hist(by=df.C) - self._check_axes_shape(axes, axes_num=4, layout=(2, 2)) + _check_axes_shape(axes, axes_num=4, layout=(2, 2)) tm.close() # group by a key with single value axes = df.hist(by="D", rot=30) - self._check_axes_shape(axes, axes_num=1, layout=(1, 1)) - self._check_ticks_props(axes, xrot=30) + _check_axes_shape(axes, axes_num=1, layout=(1, 1)) + _check_ticks_props(axes, xrot=30) tm.close() # make sure kwargs to hist are handled @@ -643,14 +646,12 @@ def test_grouped_hist_legacy(self): rects = [x for x in ax.get_children() if isinstance(x, Rectangle)] height = rects[-1].get_height() tm.assert_almost_equal(height, 1.0) - self._check_ticks_props( - axes, xlabelsize=xf, xrot=xrot, ylabelsize=yf, yrot=yrot - ) + _check_ticks_props(axes, xlabelsize=xf, xrot=xrot, ylabelsize=yf, yrot=yrot) tm.close() axes = _grouped_hist(df.A, by=df.C, log=True) # scale of y must be 'log' - self._check_ax_scales(axes, yaxis="log") + _check_ax_scales(axes, yaxis="log") tm.close() # propagate attr exception from matplotlib.Axes.hist @@ -670,7 +671,7 @@ def test_grouped_hist_legacy2(self): gb = df_int.groupby("gender") axes = gb.hist() assert len(axes) == 2 - assert len(self.plt.get_fignums()) == 2 + assert len(mpl.pyplot.get_fignums()) == 2 tm.close() @pytest.mark.slow @@ -692,22 +693,22 @@ def test_grouped_hist_layout(self, hist_df): axes = _check_plot_works( df.hist, column="height", by=df.gender, layout=(2, 1) ) - self._check_axes_shape(axes, axes_num=2, layout=(2, 1)) + _check_axes_shape(axes, axes_num=2, layout=(2, 1)) with tm.assert_produces_warning(UserWarning, check_stacklevel=False): axes = _check_plot_works( df.hist, column="height", by=df.gender, layout=(2, -1) ) - self._check_axes_shape(axes, axes_num=2, layout=(2, 1)) + _check_axes_shape(axes, axes_num=2, layout=(2, 1)) axes = df.hist(column="height", by=df.category, layout=(4, 1)) - self._check_axes_shape(axes, axes_num=4, layout=(4, 1)) + _check_axes_shape(axes, axes_num=4, layout=(4, 1)) axes = df.hist(column="height", by=df.category, layout=(-1, 1)) - self._check_axes_shape(axes, axes_num=4, layout=(4, 1)) + _check_axes_shape(axes, axes_num=4, layout=(4, 1)) axes = df.hist(column="height", by=df.category, layout=(4, 2), figsize=(12, 8)) - self._check_axes_shape(axes, axes_num=4, layout=(4, 2), figsize=(12, 8)) + _check_axes_shape(axes, axes_num=4, layout=(4, 2), figsize=(12, 8)) tm.close() # GH 6769 @@ -715,34 +716,34 @@ def test_grouped_hist_layout(self, hist_df): axes = _check_plot_works( df.hist, column="height", by="classroom", layout=(2, 2) ) - self._check_axes_shape(axes, axes_num=3, layout=(2, 2)) + _check_axes_shape(axes, axes_num=3, layout=(2, 2)) # without column with tm.assert_produces_warning(UserWarning, check_stacklevel=False): axes = _check_plot_works(df.hist, by="classroom") - self._check_axes_shape(axes, axes_num=3, layout=(2, 2)) + _check_axes_shape(axes, axes_num=3, layout=(2, 2)) axes = df.hist(by="gender", layout=(3, 5)) - self._check_axes_shape(axes, axes_num=2, layout=(3, 5)) + _check_axes_shape(axes, axes_num=2, layout=(3, 5)) axes = df.hist(column=["height", "weight", "category"]) - self._check_axes_shape(axes, axes_num=3, layout=(2, 2)) + _check_axes_shape(axes, axes_num=3, layout=(2, 2)) def test_grouped_hist_multiple_axes(self, hist_df): # GH 6970, GH 7069 df = hist_df - fig, axes = self.plt.subplots(2, 3) + fig, axes = mpl.pyplot.subplots(2, 3) returned = df.hist(column=["height", "weight", "category"], ax=axes[0]) - self._check_axes_shape(returned, axes_num=3, layout=(1, 3)) + _check_axes_shape(returned, axes_num=3, layout=(1, 3)) tm.assert_numpy_array_equal(returned, axes[0]) assert returned[0].figure is fig returned = df.hist(by="classroom", ax=axes[1]) - self._check_axes_shape(returned, axes_num=3, layout=(1, 3)) + _check_axes_shape(returned, axes_num=3, layout=(1, 3)) tm.assert_numpy_array_equal(returned, axes[1]) assert returned[0].figure is fig - fig, axes = self.plt.subplots(2, 3) + fig, axes = mpl.pyplot.subplots(2, 3) # pass different number of axes from required msg = "The number of passed axes must be 1, the same as the output plot" with pytest.raises(ValueError, match=msg): @@ -754,35 +755,35 @@ def test_axis_share_x(self, hist_df): ax1, ax2 = df.hist(column="height", by=df.gender, sharex=True) # share x - assert self.get_x_axis(ax1).joined(ax1, ax2) - assert self.get_x_axis(ax2).joined(ax1, ax2) + assert get_x_axis(ax1).joined(ax1, ax2) + assert get_x_axis(ax2).joined(ax1, ax2) # don't share y - assert not self.get_y_axis(ax1).joined(ax1, ax2) - assert not self.get_y_axis(ax2).joined(ax1, ax2) + assert not get_y_axis(ax1).joined(ax1, ax2) + assert not get_y_axis(ax2).joined(ax1, ax2) def test_axis_share_y(self, hist_df): df = hist_df ax1, ax2 = df.hist(column="height", by=df.gender, sharey=True) # share y - assert self.get_y_axis(ax1).joined(ax1, ax2) - assert self.get_y_axis(ax2).joined(ax1, ax2) + assert get_y_axis(ax1).joined(ax1, ax2) + assert get_y_axis(ax2).joined(ax1, ax2) # don't share x - assert not self.get_x_axis(ax1).joined(ax1, ax2) - assert not self.get_x_axis(ax2).joined(ax1, ax2) + assert not get_x_axis(ax1).joined(ax1, ax2) + assert not get_x_axis(ax2).joined(ax1, ax2) def test_axis_share_xy(self, hist_df): df = hist_df ax1, ax2 = df.hist(column="height", by=df.gender, sharex=True, sharey=True) # share both x and y - assert self.get_x_axis(ax1).joined(ax1, ax2) - assert self.get_x_axis(ax2).joined(ax1, ax2) + assert get_x_axis(ax1).joined(ax1, ax2) + assert get_x_axis(ax2).joined(ax1, ax2) - assert self.get_y_axis(ax1).joined(ax1, ax2) - assert self.get_y_axis(ax2).joined(ax1, ax2) + assert get_y_axis(ax1).joined(ax1, ax2) + assert get_y_axis(ax2).joined(ax1, ax2) @pytest.mark.parametrize( "histtype, expected", @@ -797,4 +798,4 @@ def test_histtype_argument(self, histtype, expected): # GH23992 Verify functioning of histtype argument df = DataFrame(np.random.randint(1, 10, size=(100, 2)), columns=["a", "b"]) ax = df.hist(by="a", histtype=histtype) - self._check_patches_all_filled(ax, filled=expected) + _check_patches_all_filled(ax, filled=expected) diff --git a/pandas/tests/plotting/test_misc.py b/pandas/tests/plotting/test_misc.py index a89956d1c14c8..e8797266fcbbe 100644 --- a/pandas/tests/plotting/test_misc.py +++ b/pandas/tests/plotting/test_misc.py @@ -15,10 +15,15 @@ ) import pandas._testing as tm from pandas.tests.plotting.common import ( - TestPlotBase, + _check_colors, + _check_legend_labels, _check_plot_works, + _check_text_labels, + _check_ticks_props, ) +mpl = pytest.importorskip("matplotlib") + @td.skip_if_mpl def test_import_error_message(): @@ -63,8 +68,7 @@ def test_get_accessor_args(): assert len(kwargs) == 24 -@td.skip_if_no_mpl -class TestSeriesPlots(TestPlotBase): +class TestSeriesPlots: def test_autocorrelation_plot(self): from pandas.plotting import autocorrelation_plot @@ -75,7 +79,7 @@ def test_autocorrelation_plot(self): _check_plot_works(autocorrelation_plot, series=ser.values) ax = autocorrelation_plot(ser, label="Test") - self._check_legend_labels(ax, labels=["Test"]) + _check_legend_labels(ax, labels=["Test"]) @pytest.mark.parametrize("kwargs", [{}, {"lag": 5}]) def test_lag_plot(self, kwargs): @@ -91,8 +95,7 @@ def test_bootstrap_plot(self): _check_plot_works(bootstrap_plot, series=ser, size=10) -@td.skip_if_no_mpl -class TestDataFramePlots(TestPlotBase): +class TestDataFramePlots: @td.skip_if_no_scipy @pytest.mark.parametrize("pass_axis", [False, True]) def test_scatter_matrix_axis(self, pass_axis): @@ -100,7 +103,7 @@ def test_scatter_matrix_axis(self, pass_axis): ax = None if pass_axis: - _, ax = self.plt.subplots(3, 3) + _, ax = mpl.pyplot.subplots(3, 3) df = DataFrame(np.random.RandomState(42).randn(100, 3)) @@ -116,8 +119,8 @@ def test_scatter_matrix_axis(self, pass_axis): # GH 5662 expected = ["-2", "0", "2"] - self._check_text_labels(axes0_labels, expected) - self._check_ticks_props(axes, xlabelsize=8, xrot=90, ylabelsize=8, yrot=0) + _check_text_labels(axes0_labels, expected) + _check_ticks_props(axes, xlabelsize=8, xrot=90, ylabelsize=8, yrot=0) df[0] = (df[0] - 2) / 3 @@ -131,8 +134,8 @@ def test_scatter_matrix_axis(self, pass_axis): ) axes0_labels = axes[0][0].yaxis.get_majorticklabels() expected = ["-1.0", "-0.5", "0.0"] - self._check_text_labels(axes0_labels, expected) - self._check_ticks_props(axes, xlabelsize=8, xrot=90, ylabelsize=8, yrot=0) + _check_text_labels(axes0_labels, expected) + _check_ticks_props(axes, xlabelsize=8, xrot=90, ylabelsize=8, yrot=0) @pytest.mark.slow def test_andrews_curves(self, iris): @@ -149,25 +152,19 @@ def test_andrews_curves(self, iris): ax = _check_plot_works( andrews_curves, frame=df, class_column="Name", color=rgba ) - self._check_colors( - ax.get_lines()[:10], linecolors=rgba, mapping=df["Name"][:10] - ) + _check_colors(ax.get_lines()[:10], linecolors=rgba, mapping=df["Name"][:10]) cnames = ["dodgerblue", "aquamarine", "seagreen"] ax = _check_plot_works( andrews_curves, frame=df, class_column="Name", color=cnames ) - self._check_colors( - ax.get_lines()[:10], linecolors=cnames, mapping=df["Name"][:10] - ) + _check_colors(ax.get_lines()[:10], linecolors=cnames, mapping=df["Name"][:10]) ax = _check_plot_works( andrews_curves, frame=df, class_column="Name", colormap=cm.jet ) cmaps = [cm.jet(n) for n in np.linspace(0, 1, df["Name"].nunique())] - self._check_colors( - ax.get_lines()[:10], linecolors=cmaps, mapping=df["Name"][:10] - ) + _check_colors(ax.get_lines()[:10], linecolors=cmaps, mapping=df["Name"][:10]) length = 10 df = DataFrame( @@ -185,31 +182,25 @@ def test_andrews_curves(self, iris): ax = _check_plot_works( andrews_curves, frame=df, class_column="Name", color=rgba ) - self._check_colors( - ax.get_lines()[:10], linecolors=rgba, mapping=df["Name"][:10] - ) + _check_colors(ax.get_lines()[:10], linecolors=rgba, mapping=df["Name"][:10]) cnames = ["dodgerblue", "aquamarine", "seagreen"] ax = _check_plot_works( andrews_curves, frame=df, class_column="Name", color=cnames ) - self._check_colors( - ax.get_lines()[:10], linecolors=cnames, mapping=df["Name"][:10] - ) + _check_colors(ax.get_lines()[:10], linecolors=cnames, mapping=df["Name"][:10]) ax = _check_plot_works( andrews_curves, frame=df, class_column="Name", colormap=cm.jet ) cmaps = [cm.jet(n) for n in np.linspace(0, 1, df["Name"].nunique())] - self._check_colors( - ax.get_lines()[:10], linecolors=cmaps, mapping=df["Name"][:10] - ) + _check_colors(ax.get_lines()[:10], linecolors=cmaps, mapping=df["Name"][:10]) colors = ["b", "g", "r"] df = DataFrame({"A": [1, 2, 3], "B": [1, 2, 3], "C": [1, 2, 3], "Name": colors}) ax = andrews_curves(df, "Name", color=colors) handles, labels = ax.get_legend_handles_labels() - self._check_colors(handles, linecolors=colors) + _check_colors(handles, linecolors=colors) @pytest.mark.slow def test_parallel_coordinates(self, iris): @@ -227,25 +218,19 @@ def test_parallel_coordinates(self, iris): ax = _check_plot_works( parallel_coordinates, frame=df, class_column="Name", color=rgba ) - self._check_colors( - ax.get_lines()[:10], linecolors=rgba, mapping=df["Name"][:10] - ) + _check_colors(ax.get_lines()[:10], linecolors=rgba, mapping=df["Name"][:10]) cnames = ["dodgerblue", "aquamarine", "seagreen"] ax = _check_plot_works( parallel_coordinates, frame=df, class_column="Name", color=cnames ) - self._check_colors( - ax.get_lines()[:10], linecolors=cnames, mapping=df["Name"][:10] - ) + _check_colors(ax.get_lines()[:10], linecolors=cnames, mapping=df["Name"][:10]) ax = _check_plot_works( parallel_coordinates, frame=df, class_column="Name", colormap=cm.jet ) cmaps = [cm.jet(n) for n in np.linspace(0, 1, df["Name"].nunique())] - self._check_colors( - ax.get_lines()[:10], linecolors=cmaps, mapping=df["Name"][:10] - ) + _check_colors(ax.get_lines()[:10], linecolors=cmaps, mapping=df["Name"][:10]) ax = _check_plot_works( parallel_coordinates, frame=df, class_column="Name", axvlines=False @@ -256,7 +241,7 @@ def test_parallel_coordinates(self, iris): df = DataFrame({"A": [1, 2, 3], "B": [1, 2, 3], "C": [1, 2, 3], "Name": colors}) ax = parallel_coordinates(df, "Name", color=colors) handles, labels = ax.get_legend_handles_labels() - self._check_colors(handles, linecolors=colors) + _check_colors(handles, linecolors=colors) # not sure if this is indicative of a problem @pytest.mark.filterwarnings("ignore:Attempting to set:UserWarning") @@ -299,17 +284,17 @@ def test_radviz(self, iris): ax = _check_plot_works(radviz, frame=df, class_column="Name", color=rgba) # skip Circle drawn as ticks patches = [p for p in ax.patches[:20] if p.get_label() != ""] - self._check_colors(patches[:10], facecolors=rgba, mapping=df["Name"][:10]) + _check_colors(patches[:10], facecolors=rgba, mapping=df["Name"][:10]) cnames = ["dodgerblue", "aquamarine", "seagreen"] _check_plot_works(radviz, frame=df, class_column="Name", color=cnames) patches = [p for p in ax.patches[:20] if p.get_label() != ""] - self._check_colors(patches, facecolors=cnames, mapping=df["Name"][:10]) + _check_colors(patches, facecolors=cnames, mapping=df["Name"][:10]) _check_plot_works(radviz, frame=df, class_column="Name", colormap=cm.jet) cmaps = [cm.jet(n) for n in np.linspace(0, 1, df["Name"].nunique())] patches = [p for p in ax.patches[:20] if p.get_label() != ""] - self._check_colors(patches, facecolors=cmaps, mapping=df["Name"][:10]) + _check_colors(patches, facecolors=cmaps, mapping=df["Name"][:10]) colors = [[0.0, 0.0, 1.0, 1.0], [0.0, 0.5, 1.0, 1.0], [1.0, 0.0, 0.0, 1.0]] df = DataFrame( @@ -317,7 +302,7 @@ def test_radviz(self, iris): ) ax = radviz(df, "Name", color=colors) handles, labels = ax.get_legend_handles_labels() - self._check_colors(handles, facecolors=colors) + _check_colors(handles, facecolors=colors) def test_subplot_titles(self, iris): df = iris.drop("Name", axis=1).head() @@ -478,7 +463,7 @@ def test_has_externally_shared_axis_x_axis(self): # Test _has_externally_shared_axis() works for x-axis func = plotting._matplotlib.tools._has_externally_shared_axis - fig = self.plt.figure() + fig = mpl.pyplot.figure() plots = fig.subplots(2, 4) # Create *externally* shared axes for first and third columns @@ -503,7 +488,7 @@ def test_has_externally_shared_axis_y_axis(self): # Test _has_externally_shared_axis() works for y-axis func = plotting._matplotlib.tools._has_externally_shared_axis - fig = self.plt.figure() + fig = mpl.pyplot.figure() plots = fig.subplots(4, 2) # Create *externally* shared axes for first and third rows @@ -529,7 +514,7 @@ def test_has_externally_shared_axis_invalid_compare_axis(self): # passed an invalid value as compare_axis parameter func = plotting._matplotlib.tools._has_externally_shared_axis - fig = self.plt.figure() + fig = mpl.pyplot.figure() plots = fig.subplots(4, 2) # Create arbitrary axes @@ -546,7 +531,7 @@ def test_externally_shared_axes(self): df = DataFrame({"a": np.random.randn(1000), "b": np.random.randn(1000)}) # Create figure - fig = self.plt.figure() + fig = mpl.pyplot.figure() plots = fig.subplots(2, 3) # Create *externally* shared axes diff --git a/pandas/tests/plotting/test_series.py b/pandas/tests/plotting/test_series.py index 755a1811c1356..c2dffdb6f7e47 100644 --- a/pandas/tests/plotting/test_series.py +++ b/pandas/tests/plotting/test_series.py @@ -18,10 +18,21 @@ ) import pandas._testing as tm from pandas.tests.plotting.common import ( - TestPlotBase, + _check_ax_scales, + _check_axes_shape, + _check_colors, + _check_grid_settings, + _check_has_errorbars, + _check_legend_labels, _check_plot_works, + _check_text_labels, + _check_ticks_props, + _unpack_cycler, + get_y_axis, ) +mpl = pytest.importorskip("matplotlib") + @pytest.fixture def ts(): @@ -38,23 +49,22 @@ def iseries(): return tm.makePeriodSeries(name="iseries") -@td.skip_if_no_mpl -class TestSeriesPlots(TestPlotBase): +class TestSeriesPlots: @pytest.mark.slow def test_plot(self, ts): _check_plot_works(ts.plot, label="foo") _check_plot_works(ts.plot, use_index=False) axes = _check_plot_works(ts.plot, rot=0) - self._check_ticks_props(axes, xrot=0) + _check_ticks_props(axes, xrot=0) ax = _check_plot_works(ts.plot, style=".", logy=True) - self._check_ax_scales(ax, yaxis="log") + _check_ax_scales(ax, yaxis="log") ax = _check_plot_works(ts.plot, style=".", logx=True) - self._check_ax_scales(ax, xaxis="log") + _check_ax_scales(ax, xaxis="log") ax = _check_plot_works(ts.plot, style=".", loglog=True) - self._check_ax_scales(ax, xaxis="log", yaxis="log") + _check_ax_scales(ax, xaxis="log", yaxis="log") _check_plot_works(ts[:10].plot.bar) _check_plot_works(ts.plot.area, stacked=False) @@ -81,35 +91,35 @@ def test_plot_series_barh(self, series): def test_plot_series_bar_ax(self): ax = _check_plot_works(Series(np.random.randn(10)).plot.bar, color="black") - self._check_colors([ax.patches[0]], facecolors=["black"]) + _check_colors([ax.patches[0]], facecolors=["black"]) def test_plot_6951(self, ts): # GH 6951 ax = _check_plot_works(ts.plot, subplots=True) - self._check_axes_shape(ax, axes_num=1, layout=(1, 1)) + _check_axes_shape(ax, axes_num=1, layout=(1, 1)) ax = _check_plot_works(ts.plot, subplots=True, layout=(-1, 1)) - self._check_axes_shape(ax, axes_num=1, layout=(1, 1)) + _check_axes_shape(ax, axes_num=1, layout=(1, 1)) ax = _check_plot_works(ts.plot, subplots=True, layout=(1, -1)) - self._check_axes_shape(ax, axes_num=1, layout=(1, 1)) + _check_axes_shape(ax, axes_num=1, layout=(1, 1)) def test_plot_figsize_and_title(self, series): # figsize and title - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = series.plot(title="Test", figsize=(16, 8), ax=ax) - self._check_text_labels(ax.title, "Test") - self._check_axes_shape(ax, axes_num=1, layout=(1, 1), figsize=(16, 8)) + _check_text_labels(ax.title, "Test") + _check_axes_shape(ax, axes_num=1, layout=(1, 1), figsize=(16, 8)) def test_dont_modify_rcParams(self): # GH 8242 key = "axes.prop_cycle" - colors = self.plt.rcParams[key] - _, ax = self.plt.subplots() + colors = mpl.pyplot.rcParams[key] + _, ax = mpl.pyplot.subplots() Series([1, 2, 3]).plot(ax=ax) - assert colors == self.plt.rcParams[key] + assert colors == mpl.pyplot.rcParams[key] def test_ts_line_lim(self, ts): - fig, ax = self.plt.subplots() + fig, ax = mpl.pyplot.subplots() ax = ts.plot(ax=ax) xmin, xmax = ax.get_xlim() lines = ax.get_lines() @@ -124,81 +134,81 @@ def test_ts_line_lim(self, ts): assert xmax >= lines[0].get_data(orig=False)[0][-1] def test_ts_area_lim(self, ts): - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = ts.plot.area(stacked=False, ax=ax) xmin, xmax = ax.get_xlim() line = ax.get_lines()[0].get_data(orig=False)[0] assert xmin <= line[0] assert xmax >= line[-1] - self._check_ticks_props(ax, xrot=0) + _check_ticks_props(ax, xrot=0) tm.close() # GH 7471 - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = ts.plot.area(stacked=False, x_compat=True, ax=ax) xmin, xmax = ax.get_xlim() line = ax.get_lines()[0].get_data(orig=False)[0] assert xmin <= line[0] assert xmax >= line[-1] - self._check_ticks_props(ax, xrot=30) + _check_ticks_props(ax, xrot=30) tm.close() tz_ts = ts.copy() tz_ts.index = tz_ts.tz_localize("GMT").tz_convert("CET") - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = tz_ts.plot.area(stacked=False, x_compat=True, ax=ax) xmin, xmax = ax.get_xlim() line = ax.get_lines()[0].get_data(orig=False)[0] assert xmin <= line[0] assert xmax >= line[-1] - self._check_ticks_props(ax, xrot=0) + _check_ticks_props(ax, xrot=0) tm.close() - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = tz_ts.plot.area(stacked=False, secondary_y=True, ax=ax) xmin, xmax = ax.get_xlim() line = ax.get_lines()[0].get_data(orig=False)[0] assert xmin <= line[0] assert xmax >= line[-1] - self._check_ticks_props(ax, xrot=0) + _check_ticks_props(ax, xrot=0) def test_area_sharey_dont_overwrite(self, ts): # GH37942 - fig, (ax1, ax2) = self.plt.subplots(1, 2, sharey=True) + fig, (ax1, ax2) = mpl.pyplot.subplots(1, 2, sharey=True) abs(ts).plot(ax=ax1, kind="area") abs(ts).plot(ax=ax2, kind="area") - assert self.get_y_axis(ax1).joined(ax1, ax2) - assert self.get_y_axis(ax2).joined(ax1, ax2) + assert get_y_axis(ax1).joined(ax1, ax2) + assert get_y_axis(ax2).joined(ax1, ax2) def test_label(self): s = Series([1, 2]) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = s.plot(label="LABEL", legend=True, ax=ax) - self._check_legend_labels(ax, labels=["LABEL"]) - self.plt.close() - _, ax = self.plt.subplots() + _check_legend_labels(ax, labels=["LABEL"]) + mpl.pyplot.close() + _, ax = mpl.pyplot.subplots() ax = s.plot(legend=True, ax=ax) - self._check_legend_labels(ax, labels=[""]) - self.plt.close() + _check_legend_labels(ax, labels=[""]) + mpl.pyplot.close() # get name from index s.name = "NAME" - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = s.plot(legend=True, ax=ax) - self._check_legend_labels(ax, labels=["NAME"]) - self.plt.close() + _check_legend_labels(ax, labels=["NAME"]) + mpl.pyplot.close() # override the default - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = s.plot(legend=True, label="LABEL", ax=ax) - self._check_legend_labels(ax, labels=["LABEL"]) - self.plt.close() + _check_legend_labels(ax, labels=["LABEL"]) + mpl.pyplot.close() # Add lebel info, but don't draw - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = s.plot(legend=False, label="LABEL", ax=ax) assert ax.get_legend() is None # Hasn't been drawn ax.legend() # draw it - self._check_legend_labels(ax, labels=["LABEL"]) + _check_legend_labels(ax, labels=["LABEL"]) def test_boolean(self): # GH 23719 @@ -231,11 +241,11 @@ def test_line_area_nan_series(self, index): def test_line_use_index_false(self): s = Series([1, 2, 3], index=["a", "b", "c"]) s.index.name = "The Index" - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = s.plot(use_index=False, ax=ax) label = ax.get_xlabel() assert label == "" - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax2 = s.plot.bar(use_index=False, ax=ax) label2 = ax2.get_xlabel() assert label2 == "" @@ -248,12 +258,12 @@ def test_line_use_index_false(self): def test_bar_log(self): expected = np.array([1e-1, 1e0, 1e1, 1e2, 1e3, 1e4]) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = Series([200, 500]).plot.bar(log=True, ax=ax) tm.assert_numpy_array_equal(ax.yaxis.get_ticklocs(), expected) tm.close() - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = Series([200, 500]).plot.barh(log=True, ax=ax) tm.assert_numpy_array_equal(ax.xaxis.get_ticklocs(), expected) tm.close() @@ -261,7 +271,7 @@ def test_bar_log(self): # GH 9905 expected = np.array([1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 1e0, 1e1]) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = Series([0.1, 0.01, 0.001]).plot(log=True, kind="bar", ax=ax) ymin = 0.0007943282347242822 ymax = 0.12589254117941673 @@ -271,7 +281,7 @@ def test_bar_log(self): tm.assert_numpy_array_equal(ax.yaxis.get_ticklocs(), expected) tm.close() - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = Series([0.1, 0.01, 0.001]).plot(log=True, kind="barh", ax=ax) res = ax.get_xlim() tm.assert_almost_equal(res[0], ymin) @@ -280,9 +290,9 @@ def test_bar_log(self): def test_bar_ignore_index(self): df = Series([1, 2, 3, 4], index=["a", "b", "c", "d"]) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = df.plot.bar(use_index=False, ax=ax) - self._check_text_labels(ax.get_xticklabels(), ["0", "1", "2", "3"]) + _check_text_labels(ax.get_xticklabels(), ["0", "1", "2", "3"]) def test_bar_user_colors(self): s = Series([1, 2, 3, 4]) @@ -299,13 +309,13 @@ def test_bar_user_colors(self): def test_rotation(self): df = DataFrame(np.random.randn(5, 5)) # Default rot 0 - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() axes = df.plot(ax=ax) - self._check_ticks_props(axes, xrot=0) + _check_ticks_props(axes, xrot=0) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() axes = df.plot(rot=30, ax=ax) - self._check_ticks_props(axes, xrot=30) + _check_ticks_props(axes, xrot=30) def test_irregular_datetime(self): from pandas.plotting._matplotlib.converter import DatetimeConverter @@ -313,19 +323,19 @@ def test_irregular_datetime(self): rng = date_range("1/1/2000", "3/1/2000") rng = rng[[0, 1, 2, 3, 5, 9, 10, 11, 12]] ser = Series(np.random.randn(len(rng)), rng) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = ser.plot(ax=ax) xp = DatetimeConverter.convert(datetime(1999, 1, 1), "", ax) ax.set_xlim("1/1/1999", "1/1/2001") assert xp == ax.get_xlim()[0] - self._check_ticks_props(ax, xrot=30) + _check_ticks_props(ax, xrot=30) def test_unsorted_index_xlim(self): ser = Series( [0.0, 1.0, np.nan, 3.0, 4.0, 5.0, 6.0], index=[1.0, 0.0, 3.0, 2.0, np.nan, 3.0, 2.0], ) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = ser.plot(ax=ax) xmin, xmax = ax.get_xlim() lines = ax.get_lines() @@ -339,26 +349,26 @@ def test_pie_series(self): np.random.randint(1, 5), index=["a", "b", "c", "d", "e"], name="YLABEL" ) ax = _check_plot_works(series.plot.pie) - self._check_text_labels(ax.texts, series.index) + _check_text_labels(ax.texts, series.index) assert ax.get_ylabel() == "YLABEL" # without wedge labels ax = _check_plot_works(series.plot.pie, labels=None) - self._check_text_labels(ax.texts, [""] * 5) + _check_text_labels(ax.texts, [""] * 5) # with less colors than elements color_args = ["r", "g", "b"] ax = _check_plot_works(series.plot.pie, colors=color_args) color_expected = ["r", "g", "b", "r", "g"] - self._check_colors(ax.patches, facecolors=color_expected) + _check_colors(ax.patches, facecolors=color_expected) # with labels and colors labels = ["A", "B", "C", "D", "E"] color_args = ["r", "g", "b", "c", "m"] ax = _check_plot_works(series.plot.pie, labels=labels, colors=color_args) - self._check_text_labels(ax.texts, labels) - self._check_colors(ax.patches, facecolors=color_args) + _check_text_labels(ax.texts, labels) + _check_colors(ax.patches, facecolors=color_args) # with autopct and fontsize ax = _check_plot_works( @@ -366,7 +376,7 @@ def test_pie_series(self): ) pcts = [f"{s*100:.2f}" for s in series.values / series.sum()] expected_texts = list(chain.from_iterable(zip(series.index, pcts))) - self._check_text_labels(ax.texts, expected_texts) + _check_text_labels(ax.texts, expected_texts) for t in ax.texts: assert t.get_fontsize() == 7 @@ -378,11 +388,11 @@ def test_pie_series(self): # includes nan series = Series([1, 2, np.nan, 4], index=["a", "b", "c", "d"], name="YLABEL") ax = _check_plot_works(series.plot.pie) - self._check_text_labels(ax.texts, ["a", "b", "", "d"]) + _check_text_labels(ax.texts, ["a", "b", "", "d"]) def test_pie_nan(self): s = Series([1, np.nan, 1, 1]) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = s.plot.pie(legend=True, ax=ax) expected = ["0", "", "2", "3"] result = [x.get_text() for x in ax.texts] @@ -394,59 +404,59 @@ def test_df_series_secondary_legend(self): s = Series(np.random.randn(30), name="x") # primary -> secondary (without passing ax) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = df.plot(ax=ax) s.plot(legend=True, secondary_y=True, ax=ax) # both legends are drawn on left ax # left and right axis must be visible - self._check_legend_labels(ax, labels=["a", "b", "c", "x (right)"]) + _check_legend_labels(ax, labels=["a", "b", "c", "x (right)"]) assert ax.get_yaxis().get_visible() assert ax.right_ax.get_yaxis().get_visible() tm.close() # primary -> secondary (with passing ax) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = df.plot(ax=ax) s.plot(ax=ax, legend=True, secondary_y=True) # both legends are drawn on left ax # left and right axis must be visible - self._check_legend_labels(ax, labels=["a", "b", "c", "x (right)"]) + _check_legend_labels(ax, labels=["a", "b", "c", "x (right)"]) assert ax.get_yaxis().get_visible() assert ax.right_ax.get_yaxis().get_visible() tm.close() # secondary -> secondary (without passing ax) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = df.plot(secondary_y=True, ax=ax) s.plot(legend=True, secondary_y=True, ax=ax) # both legends are drawn on left ax # left axis must be invisible and right axis must be visible expected = ["a (right)", "b (right)", "c (right)", "x (right)"] - self._check_legend_labels(ax.left_ax, labels=expected) + _check_legend_labels(ax.left_ax, labels=expected) assert not ax.left_ax.get_yaxis().get_visible() assert ax.get_yaxis().get_visible() tm.close() # secondary -> secondary (with passing ax) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = df.plot(secondary_y=True, ax=ax) s.plot(ax=ax, legend=True, secondary_y=True) # both legends are drawn on left ax # left axis must be invisible and right axis must be visible expected = ["a (right)", "b (right)", "c (right)", "x (right)"] - self._check_legend_labels(ax.left_ax, expected) + _check_legend_labels(ax.left_ax, expected) assert not ax.left_ax.get_yaxis().get_visible() assert ax.get_yaxis().get_visible() tm.close() # secondary -> secondary (with passing ax) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = df.plot(secondary_y=True, mark_right=False, ax=ax) s.plot(ax=ax, legend=True, secondary_y=True) # both legends are drawn on left ax # left axis must be invisible and right axis must be visible expected = ["a", "b", "c", "x (right)"] - self._check_legend_labels(ax.left_ax, expected) + _check_legend_labels(ax.left_ax, expected) assert not ax.left_ax.get_yaxis().get_visible() assert ax.get_yaxis().get_visible() tm.close() @@ -468,7 +478,7 @@ def test_secondary_logy(self, input_logy, expected_scale): def test_plot_fails_with_dupe_color_and_style(self): x = Series(np.random.randn(2)) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() msg = ( "Cannot pass 'style' string with a color symbol and 'color' keyword " "argument. Please use one or the other or pass 'style' without a color " @@ -485,10 +495,10 @@ def test_kde_kwargs(self, ts): _check_plot_works(ts.plot.kde, bw_method=None, ind=np.int_(20)) _check_plot_works(ts.plot.kde, bw_method=0.5, ind=sample_points) _check_plot_works(ts.plot.density, bw_method=0.5, ind=sample_points) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = ts.plot.kde(logy=True, bw_method=0.5, ind=sample_points, ax=ax) - self._check_ax_scales(ax, yaxis="log") - self._check_text_labels(ax.yaxis.get_label(), "Density") + _check_ax_scales(ax, yaxis="log") + _check_text_labels(ax.yaxis.get_label(), "Density") @td.skip_if_no_scipy def test_kde_missing_vals(self): @@ -501,13 +511,13 @@ def test_kde_missing_vals(self): @pytest.mark.xfail(reason="Api changed in 3.6.0") def test_boxplot_series(self, ts): - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = ts.plot.box(logy=True, ax=ax) - self._check_ax_scales(ax, yaxis="log") + _check_ax_scales(ax, yaxis="log") xlabels = ax.get_xticklabels() - self._check_text_labels(xlabels, [ts.name]) + _check_text_labels(xlabels, [ts.name]) ylabels = ax.get_yticklabels() - self._check_text_labels(ylabels, [""] * len(ylabels)) + _check_text_labels(ylabels, [""] * len(ylabels)) @td.skip_if_no_scipy @pytest.mark.parametrize( @@ -516,17 +526,17 @@ def test_boxplot_series(self, ts): ) def test_kind_both_ways(self, kind): s = Series(range(3)) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() s.plot(kind=kind, ax=ax) - self.plt.close() - _, ax = self.plt.subplots() + mpl.pyplot.close() + _, ax = mpl.pyplot.subplots() getattr(s.plot, kind)() - self.plt.close() + mpl.pyplot.close() @pytest.mark.parametrize("kind", plotting.PlotAccessor._common_kinds) def test_invalid_plot_data(self, kind): s = Series(list("abcd")) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() msg = "no numeric data to plot" with pytest.raises(TypeError, match=msg): s.plot(kind=kind, ax=ax) @@ -540,7 +550,7 @@ def test_valid_object_plot(self, kind): @pytest.mark.parametrize("kind", plotting.PlotAccessor._common_kinds) def test_partially_invalid_plot_data(self, kind): s = Series(["a", "b", 1.0, 2]) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() msg = "no numeric data to plot" with pytest.raises(TypeError, match=msg): s.plot(kind=kind, ax=ax) @@ -589,18 +599,18 @@ def test_errorbar_plot(self): kinds = ["line", "bar"] for kind in kinds: ax = _check_plot_works(s.plot, yerr=Series(s_err), kind=kind) - self._check_has_errorbars(ax, xerr=0, yerr=1) + _check_has_errorbars(ax, xerr=0, yerr=1) ax = _check_plot_works(s.plot, yerr=s_err, kind=kind) - self._check_has_errorbars(ax, xerr=0, yerr=1) + _check_has_errorbars(ax, xerr=0, yerr=1) ax = _check_plot_works(s.plot, yerr=s_err.tolist(), kind=kind) - self._check_has_errorbars(ax, xerr=0, yerr=1) + _check_has_errorbars(ax, xerr=0, yerr=1) ax = _check_plot_works(s.plot, yerr=d_err, kind=kind) - self._check_has_errorbars(ax, xerr=0, yerr=1) + _check_has_errorbars(ax, xerr=0, yerr=1) ax = _check_plot_works(s.plot, xerr=0.2, yerr=0.2, kind=kind) - self._check_has_errorbars(ax, xerr=1, yerr=1) + _check_has_errorbars(ax, xerr=1, yerr=1) ax = _check_plot_works(s.plot, xerr=s_err) - self._check_has_errorbars(ax, xerr=1, yerr=0) + _check_has_errorbars(ax, xerr=1, yerr=0) # test time series plotting ix = date_range("1/1/2000", "1/1/2001", freq="M") @@ -609,9 +619,9 @@ def test_errorbar_plot(self): td_err = DataFrame(np.abs(np.random.randn(12, 2)), index=ix, columns=["x", "y"]) ax = _check_plot_works(ts.plot, yerr=ts_err) - self._check_has_errorbars(ax, xerr=0, yerr=1) + _check_has_errorbars(ax, xerr=0, yerr=1) ax = _check_plot_works(ts.plot, yerr=td_err) - self._check_has_errorbars(ax, xerr=0, yerr=1) + _check_has_errorbars(ax, xerr=0, yerr=1) # check incorrect lengths and types with tm.external_error_raised(ValueError): @@ -630,7 +640,7 @@ def test_table(self, series): @td.skip_if_no_scipy def test_series_grid_settings(self): # Make sure plot defaults to rcParams['axes.grid'] setting, GH 9792 - self._check_grid_settings( + _check_grid_settings( Series([1, 2, 3]), plotting.PlotAccessor._series_kinds + plotting.PlotAccessor._common_kinds, ) @@ -686,39 +696,39 @@ def test_standard_colors_all(self): def test_series_plot_color_kwargs(self): # GH1890 - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = Series(np.arange(12) + 1).plot(color="green", ax=ax) - self._check_colors(ax.get_lines(), linecolors=["green"]) + _check_colors(ax.get_lines(), linecolors=["green"]) def test_time_series_plot_color_kwargs(self): # #1890 - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = Series(np.arange(12) + 1, index=date_range("1/1/2000", periods=12)).plot( color="green", ax=ax ) - self._check_colors(ax.get_lines(), linecolors=["green"]) + _check_colors(ax.get_lines(), linecolors=["green"]) def test_time_series_plot_color_with_empty_kwargs(self): import matplotlib as mpl - def_colors = self._unpack_cycler(mpl.rcParams) + def_colors = _unpack_cycler(mpl.rcParams) index = date_range("1/1/2000", periods=12) s = Series(np.arange(1, 13), index=index) ncolors = 3 - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() for i in range(ncolors): ax = s.plot(ax=ax) - self._check_colors(ax.get_lines(), linecolors=def_colors[:ncolors]) + _check_colors(ax.get_lines(), linecolors=def_colors[:ncolors]) def test_xticklabels(self): # GH11529 s = Series(np.arange(10), index=[f"P{i:02d}" for i in range(10)]) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = s.plot(xticks=[0, 3, 5, 9], ax=ax) exp = [f"P{i:02d}" for i in [0, 3, 5, 9]] - self._check_text_labels(ax.get_xticklabels(), exp) + _check_text_labels(ax.get_xticklabels(), exp) def test_xtick_barPlot(self): # GH28172 @@ -749,12 +759,12 @@ def test_custom_business_day_freq(self): ) def test_plot_accessor_updates_on_inplace(self): ser = Series([1, 2, 3, 4]) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() ax = ser.plot(ax=ax) before = ax.xaxis.get_ticklocs() ser.drop([0, 1], inplace=True) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() after = ax.xaxis.get_ticklocs() tm.assert_numpy_array_equal(before, after) @@ -763,7 +773,7 @@ def test_plot_xlim_for_series(self, kind): # test if xlim is also correctly plotted in Series for line and area # GH 27686 s = Series([2, 3]) - _, ax = self.plt.subplots() + _, ax = mpl.pyplot.subplots() s.plot(kind=kind, ax=ax) xlims = ax.get_xlim() @@ -853,5 +863,5 @@ def test_series_none_color(self): # GH51953 series = Series([1, 2, 3]) ax = series.plot(color=None) - expected = self._unpack_cycler(self.plt.rcParams)[:1] - self._check_colors(ax.get_lines(), linecolors=expected) + expected = _unpack_cycler(mpl.pyplot.rcParams)[:1] + _check_colors(ax.get_lines(), linecolors=expected)