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, 2)) df[2] = to_datetime( np.random.randint( self.start_date_to_int64, self.end_date_to_int64, size=100, dtype=np.int64, )) 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() _check_plot_works(df[[2]].hist) df = DataFrame(randn(100, 1)) _check_plot_works(df.hist) # make sure layout is handled df = DataFrame(randn(100, 5)) df[5] = to_datetime( np.random.randint( self.start_date_to_int64, self.end_date_to_int64, size=100, dtype=np.int64, )) 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() ax = ser.hist(cumulative=True, bins=4, density=True) # 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_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_tight_layout(self): df = DataFrame(randn(100, 3)) _check_plot_works(df.hist) self.plt.tight_layout() 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() # secondary -> 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_grouped_hist_legacy(self): from matplotlib.patches import Rectangle from pandas.plotting._matplotlib.hist import _grouped_hist df = DataFrame(np.random.randn(500, 1), columns=["A"]) df["B"] = to_datetime( np.random.randint( self.start_date_to_int64, self.end_date_to_int64, size=500, dtype=np.int64, )) 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_boxplot_colors(self): def _check_colors(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) df = DataFrame(np.random.randn(5, 5)) bp = df.plot.box(return_type="dict") _check_colors(bp, default_colors[0], default_colors[0], default_colors[2]) tm.close() dict_colors = { "boxes": "#572923", "whiskers": "#982042", "medians": "#804823", "caps": "#123456", } bp = df.plot.box(color=dict_colors, sym="r+", return_type="dict") _check_colors( bp, dict_colors["boxes"], dict_colors["whiskers"], dict_colors["medians"], dict_colors["caps"], "r", ) tm.close() # 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") tm.close() from matplotlib import cm # 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]) 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]) 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") # 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") with pytest.raises(ValueError): # Color contains invalid key results in ValueError df.plot.box(color={"boxes": "red", "xxxx": "blue"})
def teardown_method(self, method): tm.close()
def test_kde_colors_and_styles_subplots(self): from matplotlib import cm default_colors = self._unpack_cycler(self.plt.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]) 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"]) 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"]) 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]) 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]) 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"]) # single character static axes = df.plot(kind="kde", style="r", subplots=True) for ax in axes: self._check_colors(ax.get_lines(), linecolors=["r"]) tm.close() # list of static 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]) tm.close()
def test_line_colors(self): from matplotlib import cm custom_colors = "rgcby" df = DataFrame(np.random.randn(5, 5)) ax = df.plot(color=custom_colors) self._check_colors(ax.get_lines(), linecolors=custom_colors) tm.close() ax2 = df.plot(color=custom_colors) lines2 = ax2.get_lines() for l1, l2 in zip(ax.get_lines(), lines2): assert l1.get_color() == l2.get_color() tm.close() 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) 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) 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"]) ax = df.plot(color="red") self._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) tm.close()
def test_bar_colors(self): import matplotlib.pyplot as plt default_colors = self._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]) tm.close() custom_colors = "rgcby" ax = df.plot.bar(color=custom_colors) self._check_colors(ax.patches[::5], facecolors=custom_colors) tm.close() from matplotlib import cm # 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) 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) tm.close() ax = df.loc[:, [0]].plot.bar(color="DodgerBlue") self._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) 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_subplots_multiple_axes(self): # GH 5353, 6970, GH 7069 fig, axes = self.plt.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)) 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)) assert returned.shape == (3, ) assert returned[0].figure is fig self._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) # pass different number of axes from required df.plot(subplots=True, ax=axes) # pass 2-dim axes and invalid layout # 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) with warnings.catch_warnings(): warnings.simplefilter("ignore", UserWarning) df = DataFrame(np.random.rand(10, 4), index=list(string.ascii_letters[:10])) 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)) 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)) 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)) assert returned.shape == (4, ) # single column fig, axes = self.plt.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)) assert axes.shape == (1, )