def test_ts_plot_format_coord(self): def check_format_of_first_point(ax, expected_string): first_line = ax.get_lines()[0] first_x = first_line.get_xdata()[0].ordinal first_y = first_line.get_ydata()[0] try: assert expected_string == ax.format_coord(first_x, first_y) except (ValueError): pytest.skip("skipping test because issue forming " "test comparison GH7664") annual = Series(1, index=date_range('2014-01-01', periods=3, freq='A-DEC')) _, ax = self.plt.subplots() annual.plot(ax=ax) check_format_of_first_point(ax, 't = 2014 y = 1.000000') # note this is added to the annual plot already in existence, and # changes its freq field daily = Series(1, index=date_range('2014-01-01', periods=3, freq='D')) daily.plot(ax=ax) check_format_of_first_point(ax, 't = 2014-01-01 y = 1.000000') tm.close() # tsplot _, ax = self.plt.subplots() from pandas.tseries.plotting import tsplot tsplot(annual, self.plt.Axes.plot, ax=ax) check_format_of_first_point(ax, 't = 2014 y = 1.000000') tsplot(daily, self.plt.Axes.plot, ax=ax) check_format_of_first_point(ax, 't = 2014-01-01 y = 1.000000')
def _check_plot_works(f, *args, **kwargs): import matplotlib.pyplot as plt try: try: fig = kwargs['figure'] except KeyError: fig = plt.gcf() plt.clf() ax = kwargs.get('ax', fig.add_subplot(211)) ret = f(*args, **kwargs) assert_is_valid_plot_return_object(ret) try: kwargs['ax'] = fig.add_subplot(212) ret = f(*args, **kwargs) except Exception: pass else: assert_is_valid_plot_return_object(ret) with ensure_clean(return_filelike=True) as path: plt.savefig(path) finally: tm.close(fig)
def _check_plot_works(f, filterwarnings='always', **kwargs): import matplotlib.pyplot as plt ret = None with warnings.catch_warnings(): warnings.simplefilter(filterwarnings) try: try: fig = kwargs['figure'] except KeyError: fig = plt.gcf() plt.clf() ax = kwargs.get('ax', fig.add_subplot(211)) # noqa ret = f(**kwargs) assert_is_valid_plot_return_object(ret) try: kwargs['ax'] = fig.add_subplot(212) ret = f(**kwargs) except Exception: pass else: assert_is_valid_plot_return_object(ret) with ensure_clean(return_filelike=True) as path: plt.savefig(path) finally: tm.close(fig) return ret
def test_ts_plot_format_coord(self): def check_format_of_first_point(ax, expected_string): first_line = ax.get_lines()[0] first_x = first_line.get_xdata()[0].ordinal first_y = first_line.get_ydata()[0] try: self.assertEqual(expected_string, ax.format_coord(first_x, first_y)) except (ValueError): raise nose.SkipTest("skipping test because issue forming " "test comparison GH7664") annual = Series(1, index=date_range('2014-01-01', periods=3, freq='A-DEC')) check_format_of_first_point(annual.plot(), 't = 2014 y = 1.000000') # note this is added to the annual plot already in existence, and # changes its freq field daily = Series(1, index=date_range('2014-01-01', periods=3, freq='D')) check_format_of_first_point(daily.plot(), 't = 2014-01-01 y = 1.000000') tm.close() # tsplot import matplotlib.pyplot as plt from pandas.tseries.plotting import tsplot tsplot(annual, plt.Axes.plot) check_format_of_first_point(plt.gca(), 't = 2014 y = 1.000000') tsplot(daily, plt.Axes.plot) check_format_of_first_point(plt.gca(), 't = 2014-01-01 y = 1.000000')
def test_from_weekly_resampling(self): idxh = date_range('1/1/1999', periods=52, freq='W') 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) low.plot() ax = high.plot() expected_h = idxh.to_period().asi8.astype(np.float64) expected_l = np.array([1514, 1519, 1523, 1527, 1531, 1536, 1540, 1544, 1549, 1553, 1558, 1562], dtype=np.float64) for l in ax.get_lines(): self.assertTrue(PeriodIndex(data=l.get_xdata()).freq, idxh.freq) xdata = l.get_xdata(orig=False) if len(xdata) == 12: # idxl lines self.assert_numpy_array_equal(xdata, expected_l) else: self.assert_numpy_array_equal(xdata, expected_h) tm.close() # tsplot from pandas.tseries.plotting import tsplot import matplotlib.pyplot as plt tsplot(low, plt.Axes.plot) lines = tsplot(high, plt.Axes.plot) for l in lines: self.assertTrue(PeriodIndex(data=l.get_xdata()).freq, idxh.freq) xdata = l.get_xdata(orig=False) if len(xdata) == 12: # idxl lines self.assert_numpy_array_equal(xdata, expected_l) else: self.assert_numpy_array_equal(xdata, expected_h)
def test_tight_layout(self): if self.mpl_ge_2_0_1: df = DataFrame(randn(100, 3)) _check_plot_works(df.hist) self.plt.tight_layout() tm.close()
def test_plot_submethod_works(self): df = DataFrame({'x': [1, 2, 3, 4, 5], 'y': [1, 2, 3, 2, 1], 'z': list('ababa')}) df.groupby('z').plot.scatter('x', 'y') tm.close() df.groupby('z')['x'].plot.line() tm.close()
def test_df_series_secondary_legend(self): # GH 9779 df = DataFrame(np.random.randn(30, 3), columns=list('abc')) s = Series(np.random.randn(30), name='x') # primary -> secondary (without passing ax) ax = df.plot() s.plot(legend=True, secondary_y=True) # both legends are dran on left ax # left and right axis must be visible self._check_legend_labels(ax, labels=['a', 'b', 'c', 'x (right)']) self.assertTrue(ax.get_yaxis().get_visible()) self.assertTrue(ax.right_ax.get_yaxis().get_visible()) tm.close() # primary -> secondary (with passing ax) ax = df.plot() s.plot(ax=ax, legend=True, secondary_y=True) # both legends are dran on left ax # left and right axis must be visible self._check_legend_labels(ax, labels=['a', 'b', 'c', 'x (right)']) self.assertTrue(ax.get_yaxis().get_visible()) self.assertTrue(ax.right_ax.get_yaxis().get_visible()) tm.close() # seconcary -> secondary (without passing ax) ax = df.plot(secondary_y=True) s.plot(legend=True, secondary_y=True) # both legends are dran 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) self.assertFalse(ax.left_ax.get_yaxis().get_visible()) self.assertTrue(ax.get_yaxis().get_visible()) tm.close() # secondary -> secondary (with passing ax) ax = df.plot(secondary_y=True) s.plot(ax=ax, legend=True, secondary_y=True) # both legends are dran 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) self.assertFalse(ax.left_ax.get_yaxis().get_visible()) self.assertTrue(ax.get_yaxis().get_visible()) tm.close() # secondary -> secondary (with passing ax) ax = df.plot(secondary_y=True, mark_right=False) s.plot(ax=ax, legend=True, secondary_y=True) # both legends are dran 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) self.assertFalse(ax.left_ax.get_yaxis().get_visible()) self.assertTrue(ax.get_yaxis().get_visible()) tm.close()
def test_plotting_with_float_index_works(self): # GH 7025 df = DataFrame({'def': [1, 1, 1, 2, 2, 2, 3, 3, 3], 'val': np.random.randn(9)}, index=[1.0, 2.0, 3.0, 1.0, 2.0, 3.0, 1.0, 2.0, 3.0]) df.groupby('def')['val'].plot() tm.close() df.groupby('def')['val'].apply(lambda x: x.plot()) tm.close()
def _check_data(self, xp, rs): xp_lines = xp.get_lines() rs_lines = rs.get_lines() def check_line(xpl, rsl): xpdata = xpl.get_xydata() rsdata = rsl.get_xydata() assert_array_equal(xpdata, rsdata) [check_line(xpl, rsl) for xpl, rsl in zip(xp_lines, rs_lines)] tm.close()
def test_grouped_hist_legacy(self): from matplotlib.patches import Rectangle df = DataFrame(randn(500, 2), columns=['A', 'B']) df['C'] = np.random.randint(0, 4, 500) df['D'] = ['X'] * 500 axes = grouped_hist(df.A, by=df.C) self._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)) 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) tm.close() # make sure kwargs to hist are handled xf, yf = 20, 18 xrot, yrot = 30, 40 if _mpl_ge_2_2_0(): kwargs = {"density": True} else: kwargs = {"normed": True} axes = grouped_hist(df.A, by=df.C, cumulative=True, bins=4, xlabelsize=xf, xrot=xrot, ylabelsize=yf, yrot=yrot, **kwargs) # height of last bin (index 5) must be 1.0 for ax in axes.ravel(): 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) 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') tm.close() # propagate attr exception from matplotlib.Axes.hist with pytest.raises(AttributeError): grouped_hist(df.A, by=df.C, foo='bar') with tm.assert_produces_warning(FutureWarning): df.hist(by='C', figsize='default')
def test_grouped_hist_layout(self): df = self.hist_df msg = "Layout of 1x1 must be larger than required size 2" with pytest.raises(ValueError, match=msg): df.hist(column='weight', by=df.gender, layout=(1, 1)) msg = "Layout of 1x3 must be larger than required size 4" with pytest.raises(ValueError, match=msg): df.hist(column='height', by=df.category, layout=(1, 3)) msg = "At least one dimension of layout must be positive" with pytest.raises(ValueError, match=msg): df.hist(column='height', by=df.category, layout=(-1, -1)) with tm.assert_produces_warning(UserWarning): 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)) with tm.assert_produces_warning(UserWarning): 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)) axes = df.hist(column='height', by=df.category, layout=(4, 1)) self._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)) 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)) tm.close() # GH 6769 with tm.assert_produces_warning(UserWarning): axes = _check_plot_works( df.hist, column='height', by='classroom', layout=(2, 2)) self._check_axes_shape(axes, axes_num=3, layout=(2, 2)) # without column with tm.assert_produces_warning(UserWarning): axes = _check_plot_works(df.hist, by='classroom') self._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)) axes = df.hist(column=['height', 'weight', 'category']) self._check_axes_shape(axes, axes_num=3, layout=(2, 2))
def test_ts_line_lim(self): ax = self.ts.plot() xmin, xmax = ax.get_xlim() lines = ax.get_lines() assert xmin == lines[0].get_data(orig=False)[0][0] assert xmax == lines[0].get_data(orig=False)[0][-1] tm.close() ax = self.ts.plot(secondary_y=True) xmin, xmax = ax.get_xlim() lines = ax.get_lines() assert xmin == lines[0].get_data(orig=False)[0][0] assert xmax == lines[0].get_data(orig=False)[0][-1]
def test_grouped_hist_legacy2(self): n = 10 weight = Series(np.random.normal(166, 20, size=n)) height = Series(np.random.normal(60, 10, size=n)) with tm.RNGContext(42): gender_int = np.random.choice([0, 1], size=n) df_int = DataFrame({'height': height, 'weight': weight, 'gender': gender_int}) gb = df_int.groupby('gender') axes = gb.hist() self.assertEqual(len(axes), 2) self.assertEqual(len(self.plt.get_fignums()), 2) tm.close()
def test_ts_line_lim(self): ax = self.ts.plot() xmin, xmax = ax.get_xlim() lines = ax.get_lines() self.assertEqual(xmin, lines[0].get_data(orig=False)[0][0]) self.assertEqual(xmax, lines[0].get_data(orig=False)[0][-1]) tm.close() ax = self.ts.plot(secondary_y=True) xmin, xmax = ax.get_xlim() lines = ax.get_lines() self.assertEqual(xmin, lines[0].get_data(orig=False)[0][0]) self.assertEqual(xmax, lines[0].get_data(orig=False)[0][-1])
def test_grouped_hist(self): import matplotlib.pyplot as plt df = DataFrame(randn(500, 2), columns=['A', 'B']) df['C'] = np.random.randint(0, 4, 500) axes = plotting.grouped_hist(df.A, by=df.C) self.assertEqual(len(axes.ravel()), 4) tm.close() axes = df.hist(by=df.C) self.assertEqual(axes.ndim, 2) self.assertEqual(len(axes.ravel()), 4) for ax in axes.ravel(): self.assert_(len(ax.patches) > 0) tm.close() # make sure kwargs to hist are handled axes = plotting.grouped_hist(df.A, by=df.C, normed=True, cumulative=True, bins=4) # height of last bin (index 5) must be 1.0 for ax in axes.ravel(): height = ax.get_children()[5].get_height() self.assertAlmostEqual(height, 1.0) tm.close() axes = plotting.grouped_hist(df.A, by=df.C, log=True) # scale of y must be 'log' for ax in axes.ravel(): self.assertEqual(ax.get_yscale(), 'log') tm.close() # propagate attr exception from matplotlib.Axes.hist with tm.assertRaises(AttributeError): plotting.grouped_hist(df.A, by=df.C, foo='bar')
def test_ts_line_lim(self): fig, ax = self.plt.subplots() ax = self.ts.plot(ax=ax) xmin, xmax = ax.get_xlim() lines = ax.get_lines() assert xmin <= lines[0].get_data(orig=False)[0][0] assert xmax >= lines[0].get_data(orig=False)[0][-1] tm.close() ax = self.ts.plot(secondary_y=True, ax=ax) xmin, xmax = ax.get_xlim() lines = ax.get_lines() assert xmin <= lines[0].get_data(orig=False)[0][0] assert xmax >= lines[0].get_data(orig=False)[0][-1]
def test_xcompat(self): import pandas as pd import matplotlib.pyplot as plt df = tm.makeTimeDataFrame() ax = df.plot(x_compat=True) lines = ax.get_lines() self.assert_(not isinstance(lines[0].get_xdata(), PeriodIndex)) tm.close() pd.plot_params['xaxis.compat'] = True ax = df.plot() lines = ax.get_lines() self.assert_(not isinstance(lines[0].get_xdata(), PeriodIndex)) tm.close() pd.plot_params['x_compat'] = False ax = df.plot() lines = ax.get_lines() tm.assert_isinstance(lines[0].get_xdata(), PeriodIndex) tm.close() # useful if you're plotting a bunch together with pd.plot_params.use('x_compat', True): ax = df.plot() lines = ax.get_lines() self.assert_(not isinstance(lines[0].get_xdata(), PeriodIndex)) tm.close() ax = df.plot() lines = ax.get_lines() tm.assert_isinstance(lines[0].get_xdata(), PeriodIndex)
def test_bar_colors(self): import matplotlib.pyplot as plt import matplotlib.colors as colors default_colors = plt.rcParams.get('axes.color_cycle') custom_colors = 'rgcby' df = DataFrame(randn(5, 5)) ax = df.plot(kind='bar') rects = ax.patches conv = colors.colorConverter for i, rect in enumerate(rects[::5]): xp = conv.to_rgba(default_colors[i % len(default_colors)]) rs = rect.get_facecolor() self.assertEqual(xp, rs) tm.close() ax = df.plot(kind='bar', color=custom_colors) rects = ax.patches conv = colors.colorConverter for i, rect in enumerate(rects[::5]): xp = conv.to_rgba(custom_colors[i]) rs = rect.get_facecolor() self.assertEqual(xp, rs) tm.close() from matplotlib import cm # Test str -> colormap functionality ax = df.plot(kind='bar', colormap='jet') rects = ax.patches rgba_colors = lmap(cm.jet, np.linspace(0, 1, 5)) for i, rect in enumerate(rects[::5]): xp = rgba_colors[i] rs = rect.get_facecolor() self.assertEqual(xp, rs) tm.close() # Test colormap functionality ax = df.plot(kind='bar', colormap=cm.jet) rects = ax.patches rgba_colors = lmap(cm.jet, np.linspace(0, 1, 5)) for i, rect in enumerate(rects[::5]): xp = rgba_colors[i] rs = rect.get_facecolor() self.assertEqual(xp, rs) tm.close() df.ix[:, [0]].plot(kind='bar', color='DodgerBlue')
def test_grouped_hist_layout(self): df = self.hist_df pytest.raises(ValueError, df.hist, column='weight', by=df.gender, layout=(1, 1)) pytest.raises(ValueError, df.hist, column='height', by=df.category, layout=(1, 3)) pytest.raises(ValueError, df.hist, column='height', by=df.category, layout=(-1, -1)) with tm.assert_produces_warning(UserWarning): 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)) with tm.assert_produces_warning(UserWarning): 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)) axes = df.hist(column='height', by=df.category, layout=(4, 1)) self._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)) 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)) tm.close() # GH 6769 with tm.assert_produces_warning(UserWarning): axes = _check_plot_works( df.hist, column='height', by='classroom', layout=(2, 2)) self._check_axes_shape(axes, axes_num=3, layout=(2, 2)) # without column with tm.assert_produces_warning(UserWarning): axes = _check_plot_works(df.hist, by='classroom') self._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)) axes = df.hist(column=['height', 'weight', 'category']) self._check_axes_shape(axes, axes_num=3, layout=(2, 2))
def test_line_colors(self): import matplotlib.pyplot as plt import sys from matplotlib import cm custom_colors = 'rgcby' df = DataFrame(randn(5, 5)) ax = df.plot(color=custom_colors) lines = ax.get_lines() for i, l in enumerate(lines): xp = custom_colors[i] rs = l.get_color() self.assertEqual(xp, rs) tmp = sys.stderr sys.stderr = StringIO() try: tm.close() ax2 = df.plot(colors=custom_colors) lines2 = ax2.get_lines() for l1, l2 in zip(lines, lines2): self.assertEqual(l1.get_color(), l2.get_color()) finally: sys.stderr = tmp tm.close() ax = df.plot(colormap='jet') rgba_colors = lmap(cm.jet, np.linspace(0, 1, len(df))) lines = ax.get_lines() for i, l in enumerate(lines): xp = rgba_colors[i] rs = l.get_color() self.assertEqual(xp, rs) tm.close() ax = df.plot(colormap=cm.jet) rgba_colors = lmap(cm.jet, np.linspace(0, 1, len(df))) lines = ax.get_lines() for i, l in enumerate(lines): xp = rgba_colors[i] rs = l.get_color() self.assertEqual(xp, rs) # make color a list if plotting one column frame # handles cases like df.plot(color='DodgerBlue') tm.close() df.ix[:, [0]].plot(color='DodgerBlue')
def test_grouped_hist_legacy(self): df = DataFrame(randn(500, 2), columns=['A', 'B']) df['C'] = np.random.randint(0, 4, 500) df['D'] = ['X'] * 500 axes = plotting.grouped_hist(df.A, by=df.C) self._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)) 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) tm.close() # make sure kwargs to hist are handled xf, yf = 20, 18 xrot, yrot = 30, 40 axes = plotting.grouped_hist(df.A, by=df.C, normed=True, cumulative=True, bins=4, xlabelsize=xf, xrot=xrot, ylabelsize=yf, yrot=yrot) # height of last bin (index 5) must be 1.0 for ax in axes.ravel(): height = ax.get_children()[5].get_height() self.assertAlmostEqual(height, 1.0) self._check_ticks_props(axes, xlabelsize=xf, xrot=xrot, ylabelsize=yf, yrot=yrot) tm.close() axes = plotting.grouped_hist(df.A, by=df.C, log=True) # scale of y must be 'log' self._check_ax_scales(axes, yaxis='log') tm.close() # propagate attr exception from matplotlib.Axes.hist with tm.assertRaises(AttributeError): plotting.grouped_hist(df.A, by=df.C, foo='bar') with tm.assert_produces_warning(FutureWarning): df.hist(by='C', figsize='default')
def test_hist_legacy(self): _check_plot_works(self.ts.hist) _check_plot_works(self.ts.hist, grid=False) _check_plot_works(self.ts.hist, figsize=(8, 10)) _check_plot_works(self.ts.hist, by=self.ts.index.month) _check_plot_works(self.ts.hist, by=self.ts.index.month, bins=5) fig, ax = self.plt.subplots(1, 1) _check_plot_works(self.ts.hist, ax=ax) _check_plot_works(self.ts.hist, ax=ax, figure=fig) _check_plot_works(self.ts.hist, figure=fig) tm.close() fig, (ax1, ax2) = self.plt.subplots(1, 2) _check_plot_works(self.ts.hist, figure=fig, ax=ax1) _check_plot_works(self.ts.hist, figure=fig, ax=ax2) with tm.assertRaises(ValueError): self.ts.hist(by=self.ts.index, figure=fig)
def test_hist(self): _check_plot_works(self.ts.hist) _check_plot_works(self.ts.hist, grid=False) _check_plot_works(self.ts.hist, figsize=(8, 10)) _check_plot_works(self.ts.hist, by=self.ts.index.month) import matplotlib.pyplot as plt fig, ax = plt.subplots(1, 1) _check_plot_works(self.ts.hist, ax=ax) _check_plot_works(self.ts.hist, ax=ax, figure=fig) _check_plot_works(self.ts.hist, figure=fig) tm.close() fig, (ax1, ax2) = plt.subplots(1, 2) _check_plot_works(self.ts.hist, figure=fig, ax=ax1) _check_plot_works(self.ts.hist, figure=fig, ax=ax2) with tm.assertRaises(ValueError): self.ts.hist(by=self.ts.index, figure=fig)
def test_mixed_freq_second_millisecond(self): # GH 7772, GH 7760 idxh = date_range('2014-07-01 09:00', freq='S', periods=50) idxl = date_range('2014-07-01 09:00', freq='100L', periods=500) high = Series(np.random.randn(len(idxh)), idxh) low = Series(np.random.randn(len(idxl)), idxl) # high to low high.plot() ax = low.plot() self.assertEqual(len(ax.get_lines()), 2) for l in ax.get_lines(): self.assertEqual(PeriodIndex(data=l.get_xdata()).freq, 'L') tm.close() # low to high low.plot() ax = high.plot() self.assertEqual(len(ax.get_lines()), 2) for l in ax.get_lines(): self.assertEqual(PeriodIndex(data=l.get_xdata()).freq, 'L')
def test_errorbar_asymmetrical(self): np.random.seed(0) err = np.random.rand(3, 2, 5) data = np.random.randn(5, 3) df = DataFrame(data) ax = df.plot(yerr=err, xerr=err/2) self.assertEqual(ax.lines[7].get_ydata()[0], data[0,1]-err[1,0,0]) self.assertEqual(ax.lines[8].get_ydata()[0], data[0,1]+err[1,1,0]) self.assertEqual(ax.lines[5].get_xdata()[0], -err[1,0,0]/2) self.assertEqual(ax.lines[6].get_xdata()[0], err[1,1,0]/2) with tm.assertRaises(ValueError): df.plot(yerr=err.T) tm.close()
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() def check_line(xpl, rsl): xpdata = xpl.get_xydata() rsdata = rsl.get_xydata() tm.assert_almost_equal(xpdata, rsdata) assert len(xp_lines) == len(rs_lines) [check_line(xpl, rsl) for xpl, rsl in zip(xp_lines, rs_lines)] tm.close()
def test_bar_log(self): expected = np.array([1e-1, 1e0, 1e1, 1e2, 1e3, 1e4]) _, ax = self.plt.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 = Series([200, 500]).plot.barh(log=True, ax=ax) tm.assert_numpy_array_equal(ax.xaxis.get_ticklocs(), expected) tm.close() # GH 9905 expected = np.array([1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 1e0, 1e1]) _, ax = self.plt.subplots() ax = Series([0.1, 0.01, 0.001]).plot(log=True, kind='bar', ax=ax) ymin = 0.0007943282347242822 ymax = 0.12589254117941673 res = ax.get_ylim() tm.assert_almost_equal(res[0], ymin) tm.assert_almost_equal(res[1], ymax) tm.assert_numpy_array_equal(ax.yaxis.get_ticklocs(), expected) tm.close() _, ax = self.plt.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) tm.assert_almost_equal(res[1], ymax) tm.assert_numpy_array_equal(ax.xaxis.get_ticklocs(), expected)
def test_hist_secondary_legend(self): # GH 9610 df = DataFrame(np.random.randn(30, 4), columns=list('abcd')) # primary -> secondary ax = df['a'].plot.hist(legend=True) df['b'].plot.hist(ax=ax, legend=True, secondary_y=True) # both legends are dran on left ax # left and right axis must be visible self._check_legend_labels(ax, labels=['a', 'b (right)']) self.assertTrue(ax.get_yaxis().get_visible()) self.assertTrue(ax.right_ax.get_yaxis().get_visible()) tm.close() # secondary -> secondary ax = df['a'].plot.hist(legend=True, secondary_y=True) 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)']) self.assertFalse(ax.left_ax.get_yaxis().get_visible()) self.assertTrue(ax.get_yaxis().get_visible()) tm.close() # secondary -> primary ax = df['a'].plot.hist(legend=True, secondary_y=True) # 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']) self.assertTrue(ax.left_ax.get_yaxis().get_visible()) self.assertTrue(ax.get_yaxis().get_visible()) tm.close()
def test_ts_area_lim(self): _, ax = self.plt.subplots() ax = self.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] tm.close() # GH 7471 _, ax = self.plt.subplots() ax = self.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] tm.close() tz_ts = self.ts.copy() tz_ts.index = tz_ts.tz_localize('GMT').tz_convert('CET') _, ax = self.plt.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] tm.close() _, ax = self.plt.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]
def test_grouped_plot_fignums(self): n = 10 weight = Series(np.random.normal(166, 20, size=n)) height = Series(np.random.normal(60, 10, size=n)) with tm.RNGContext(42): gender = tm.choice(['male', 'female'], size=n) df = DataFrame({'height': height, 'weight': weight, 'gender': gender}) gb = df.groupby('gender') res = gb.plot() self.assertEqual(len(self.plt.get_fignums()), 2) self.assertEqual(len(res), 2) tm.close() res = gb.boxplot(return_type='axes') self.assertEqual(len(self.plt.get_fignums()), 1) self.assertEqual(len(res), 2) tm.close() # now works with GH 5610 as gender is excluded res = df.groupby('gender').hist() tm.close()
def test_grouped_plot_fignums(self): n = 10 weight = Series(np.random.normal(166, 20, size=n)) height = Series(np.random.normal(60, 10, size=n)) with tm.RNGContext(42): gender = np.random.choice(["male", "female"], size=n) df = DataFrame({"height": height, "weight": weight, "gender": gender}) gb = df.groupby("gender") res = gb.plot() assert len(self.plt.get_fignums()) == 2 assert len(res) == 2 tm.close() res = gb.boxplot(return_type="axes") assert len(self.plt.get_fignums()) == 1 assert len(res) == 2 tm.close() # now works with GH 5610 as gender is excluded res = df.groupby("gender").hist() tm.close()
def test_hist_secondary_legend(self): # GH 9610 df = DataFrame(np.random.randn(30, 4), columns=list('abcd')) # primary -> secondary _, ax = self.plt.subplots() ax = df['a'].plot.hist(legend=True, ax=ax) df['b'].plot.hist(ax=ax, legend=True, secondary_y=True) # both legends are dran on left ax # left and right axis must be visible self._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 = 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)']) assert not ax.left_ax.get_yaxis().get_visible() assert ax.get_yaxis().get_visible() tm.close() # secondary -> primary _, ax = self.plt.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']) assert ax.left_ax.get_yaxis().get_visible() assert ax.get_yaxis().get_visible() tm.close()
def test_bar_log(self): expected = np.array([1., 10., 100., 1000.]) if not self.mpl_le_1_2_1: expected = np.hstack((.1, expected, 1e4)) ax = Series([200, 500]).plot.bar(log=True) tm.assert_numpy_array_equal(ax.yaxis.get_ticklocs(), expected) tm.close() ax = Series([200, 500]).plot.barh(log=True) tm.assert_numpy_array_equal(ax.xaxis.get_ticklocs(), expected) tm.close() # GH 9905 expected = np.array([1.0e-03, 1.0e-02, 1.0e-01, 1.0e+00]) if not self.mpl_le_1_2_1: expected = np.hstack((1.0e-04, expected, 1.0e+01)) if self.mpl_ge_2_0_0: expected = np.hstack((1.0e-05, expected)) ax = Series([0.1, 0.01, 0.001]).plot(log=True, kind='bar') ymin = 0.0007943282347242822 if self.mpl_ge_2_0_0 else 0.001 ymax = 0.12589254117941673 if self.mpl_ge_2_0_0 else .10000000000000001 res = ax.get_ylim() self.assertAlmostEqual(res[0], ymin) self.assertAlmostEqual(res[1], ymax) tm.assert_numpy_array_equal(ax.yaxis.get_ticklocs(), expected) tm.close() ax = Series([0.1, 0.01, 0.001]).plot(log=True, kind='barh') res = ax.get_xlim() self.assertAlmostEqual(res[0], ymin) self.assertAlmostEqual(res[1], ymax) tm.assert_numpy_array_equal(ax.xaxis.get_ticklocs(), expected)
def teardown_method(self): tm.close()
def test_df_series_secondary_legend(self): # GH 9779 df = DataFrame(np.random.randn(30, 3), columns=list('abc')) s = Series(np.random.randn(30), name='x') # primary -> secondary (without passing ax) _, ax = self.plt.subplots() ax = df.plot(ax=ax) s.plot(legend=True, secondary_y=True, ax=ax) # both legends are dran on left ax # left and right axis must be visible self._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 = df.plot(ax=ax) s.plot(ax=ax, legend=True, secondary_y=True) # both legends are dran on left ax # left and right axis must be visible self._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() # seconcary -> secondary (without passing ax) _, ax = self.plt.subplots() ax = df.plot(secondary_y=True, ax=ax) s.plot(legend=True, secondary_y=True, ax=ax) # both legends are dran 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) 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 = df.plot(secondary_y=True, ax=ax) s.plot(ax=ax, legend=True, secondary_y=True) # both legends are dran 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) 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 = df.plot(secondary_y=True, mark_right=False, ax=ax) s.plot(ax=ax, legend=True, secondary_y=True) # both legends are dran 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) assert not ax.left_ax.get_yaxis().get_visible() assert ax.get_yaxis().get_visible() tm.close()
def test_hist(self): import matplotlib.pyplot as plt df = DataFrame(randn(100, 4)) _check_plot_works(df.hist) _check_plot_works(df.hist, grid=False) # make sure layout is handled df = DataFrame(randn(100, 3)) _check_plot_works(df.hist) axes = df.hist(grid=False) self.assert_(not axes[1, 1].get_visible()) df = DataFrame(randn(100, 1)) _check_plot_works(df.hist) # make sure layout is handled df = DataFrame(randn(100, 6)) _check_plot_works(df.hist) # make sure sharex, sharey is handled _check_plot_works(df.hist, sharex=True, sharey=True) # handle figsize arg _check_plot_works(df.hist, figsize=(8, 10)) # make sure xlabelsize and xrot are handled ser = df[0] xf, yf = 20, 20 xrot, yrot = 30, 30 ax = ser.hist(xlabelsize=xf, xrot=30, ylabelsize=yf, yrot=30) ytick = ax.get_yticklabels()[0] xtick = ax.get_xticklabels()[0] self.assertAlmostEqual(ytick.get_fontsize(), yf) self.assertAlmostEqual(ytick.get_rotation(), yrot) self.assertAlmostEqual(xtick.get_fontsize(), xf) self.assertAlmostEqual(xtick.get_rotation(), xrot) xf, yf = 20, 20 xrot, yrot = 30, 30 axes = df.hist(xlabelsize=xf, xrot=30, ylabelsize=yf, yrot=30) for i, ax in enumerate(axes.ravel()): if i < len(df.columns): ytick = ax.get_yticklabels()[0] xtick = ax.get_xticklabels()[0] self.assertAlmostEqual(ytick.get_fontsize(), yf) self.assertAlmostEqual(ytick.get_rotation(), yrot) self.assertAlmostEqual(xtick.get_fontsize(), xf) self.assertAlmostEqual(xtick.get_rotation(), xrot) tm.close() # make sure kwargs to hist are handled ax = ser.hist(normed=True, cumulative=True, bins=4) # height of last bin (index 5) must be 1.0 self.assertAlmostEqual(ax.get_children()[5].get_height(), 1.0) tm.close() ax = ser.hist(log=True) # scale of y must be 'log' self.assertEqual(ax.get_yscale(), 'log') tm.close() # propagate attr exception from matplotlib.Axes.hist with tm.assertRaises(AttributeError): ser.hist(foo='bar')
def tearDown(self): tm.close()
def test_grouped_hist_layout(self): df = self.hist_df pytest.raises(ValueError, df.hist, column='weight', by=df.gender, layout=(1, 1)) pytest.raises(ValueError, df.hist, column='height', by=df.category, layout=(1, 3)) pytest.raises(ValueError, df.hist, column='height', by=df.category, layout=(-1, -1)) with tm.assert_produces_warning(UserWarning): 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)) with tm.assert_produces_warning(UserWarning): 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)) axes = df.hist(column='height', by=df.category, layout=(4, 1)) self._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)) 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)) tm.close() # GH 6769 with tm.assert_produces_warning(UserWarning): axes = _check_plot_works(df.hist, column='height', by='classroom', layout=(2, 2)) self._check_axes_shape(axes, axes_num=3, layout=(2, 2)) # without column with tm.assert_produces_warning(UserWarning): axes = _check_plot_works(df.hist, by='classroom') self._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)) axes = df.hist(column=['height', 'weight', 'category']) self._check_axes_shape(axes, axes_num=3, layout=(2, 2))
def test_hist_df_legacy(self): from matplotlib.patches import Rectangle with tm.assert_produces_warning(UserWarning): _check_plot_works(self.hist_df.hist) # make sure layout is handled df = DataFrame(randn(100, 3)) with tm.assert_produces_warning(UserWarning): axes = _check_plot_works(df.hist, grid=False) self._check_axes_shape(axes, axes_num=3, layout=(2, 2)) assert not axes[1, 1].get_visible() df = DataFrame(randn(100, 1)) _check_plot_works(df.hist) # make sure layout is handled df = DataFrame(randn(100, 6)) with tm.assert_produces_warning(UserWarning): axes = _check_plot_works(df.hist, layout=(4, 2)) self._check_axes_shape(axes, axes_num=6, layout=(4, 2)) # make sure sharex, sharey is handled with tm.assert_produces_warning(UserWarning): _check_plot_works(df.hist, sharex=True, sharey=True) # handle figsize arg with tm.assert_produces_warning(UserWarning): _check_plot_works(df.hist, figsize=(8, 10)) # check bins argument with tm.assert_produces_warning(UserWarning): _check_plot_works(df.hist, bins=5) # make sure xlabelsize and xrot are handled ser = df[0] 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) 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) tm.close() # make sure kwargs to hist are handled ax = ser.hist(normed=True, cumulative=True, bins=4) # height of last bin (index 5) must be 1.0 rects = [x for x in ax.get_children() if isinstance(x, Rectangle)] tm.assert_almost_equal(rects[-1].get_height(), 1.0) tm.close() ax = ser.hist(log=True) # scale of y must be 'log' self._check_ax_scales(ax, yaxis='log') tm.close() # propagate attr exception from matplotlib.Axes.hist with pytest.raises(AttributeError): ser.hist(foo='bar')
def test_grouped_hist_legacy(self): from matplotlib.patches import Rectangle from pandas.plotting._matplotlib.hist import _grouped_hist df = DataFrame(randn(500, 2), columns=["A", "B"]) df["C"] = np.random.randint(0, 4, 500) df["D"] = ["X"] * 500 axes = _grouped_hist(df.A, by=df.C) self._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)) 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) tm.close() # make sure kwargs to hist are handled xf, yf = 20, 18 xrot, yrot = 30, 40 axes = _grouped_hist( df.A, by=df.C, cumulative=True, bins=4, xlabelsize=xf, xrot=xrot, ylabelsize=yf, yrot=yrot, density=True, ) # height of last bin (index 5) must be 1.0 for ax in axes.ravel(): 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) 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") tm.close() # propagate attr exception from matplotlib.Axes.hist with pytest.raises(AttributeError): _grouped_hist(df.A, by=df.C, foo="bar") msg = "Specify figure size by tuple instead" with pytest.raises(ValueError, match=msg): df.hist(by="C", figsize="default")
def test_tight_layout(self): df = DataFrame(randn(100, 3)) _check_plot_works(df.hist) self.plt.tight_layout() tm.close()
def test_grouped_hist_layout(self): df = self.hist_df msg = "Layout of 1x1 must be larger than required size 2" with pytest.raises(ValueError, match=msg): df.hist(column='weight', by=df.gender, layout=(1, 1)) msg = "Layout of 1x3 must be larger than required size 4" with pytest.raises(ValueError, match=msg): df.hist(column='height', by=df.category, layout=(1, 3)) msg = "At least one dimension of layout must be positive" with pytest.raises(ValueError, match=msg): df.hist(column='height', by=df.category, layout=(-1, -1)) with tm.assert_produces_warning(UserWarning): 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)) with tm.assert_produces_warning(UserWarning): 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)) axes = df.hist(column='height', by=df.category, layout=(4, 1)) self._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)) 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)) tm.close() # GH 6769 with tm.assert_produces_warning(UserWarning): axes = _check_plot_works(df.hist, column='height', by='classroom', layout=(2, 2)) self._check_axes_shape(axes, axes_num=3, layout=(2, 2)) # without column with tm.assert_produces_warning(UserWarning): axes = _check_plot_works(df.hist, by='classroom') self._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)) axes = df.hist(column=['height', 'weight', 'category']) self._check_axes_shape(axes, axes_num=3, layout=(2, 2))
def test_grouped_hist_legacy(self): from matplotlib.patches import Rectangle df = DataFrame(randn(500, 2), columns=['A', 'B']) df['C'] = np.random.randint(0, 4, 500) df['D'] = ['X'] * 500 axes = grouped_hist(df.A, by=df.C) self._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)) 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) tm.close() # make sure kwargs to hist are handled xf, yf = 20, 18 xrot, yrot = 30, 40 if _mpl_ge_2_2_0(): kwargs = {"density": True} else: kwargs = {"normed": True} axes = grouped_hist(df.A, by=df.C, cumulative=True, bins=4, xlabelsize=xf, xrot=xrot, ylabelsize=yf, yrot=yrot, **kwargs) # height of last bin (index 5) must be 1.0 for ax in axes.ravel(): 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) 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') tm.close() # propagate attr exception from matplotlib.Axes.hist with pytest.raises(AttributeError): grouped_hist(df.A, by=df.C, foo='bar') with tm.assert_produces_warning(FutureWarning): df.hist(by='C', figsize='default')